Compare commits
54 Commits
wip-is-cache
...
wip
| Author | SHA1 | Date | |
|---|---|---|---|
| c532b9c839 | |||
| 447c6debab | |||
| 50470ae3cf | |||
| 993be652c9 | |||
| b3bfbd0b58 | |||
| 49b3dc8b60 | |||
| 71ffcfb839 | |||
| 73f76a6654 | |||
| 645de1d868 | |||
| 8f40478695 | |||
| 056fcc3818 | |||
| 0ed0eb9d5f | |||
| 3ddc846648 | |||
| f98f6ef852 | |||
| 4192d721a0 | |||
| a0f3ef9d86 | |||
| 6b29288de6 | |||
| 285fc6314c | |||
| 50fd83e96b | |||
| cc51138a6a | |||
| 918df0bf7f | |||
| c852199901 | |||
| fd95d3de47 | |||
| c3dd6dabe1 | |||
| b0e81ac2d1 | |||
| 30f4cdf545 | |||
| ee9441474e | |||
| 8846202270 | |||
| 17a900ae9a | |||
| 66bc243b41 | |||
| a2bda8f449 | |||
| a2c2a4df0f | |||
| b4e237244a | |||
| b541ad8d18 | |||
| 64f29a7dba | |||
| 6d25b7ef3c | |||
| c3a608ef59 | |||
| af1f5c34d2 | |||
| f5378e060e | |||
| 47407acc42 | |||
| d7f3428824 | |||
| 63e339b88b | |||
| 98761809fd | |||
| 8cb013b686 | |||
| f2fe376982 | |||
| 603452de1f | |||
| 40bd96d21c | |||
| a14d160a07 | |||
| df28a5520f | |||
| 0d096944cc | |||
| 963d3414d8 | |||
| 4414451f5e | |||
| e0ddb92b81 | |||
| 6f551ad67f |
+1
-1
@@ -57,7 +57,7 @@ tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
version = trousers + "-" + aeversion + "-" + aechannel + "-" + aebuild + "-" + trousersversion
|
||||
version = aeversion + "-" + aechannel + "-" + aebuild + "-" + extended + "-" + extendedversion
|
||||
group = aegroup
|
||||
archivesBaseName = aebasename
|
||||
|
||||
|
||||
+2
-5
@@ -3,20 +3,18 @@ aechannel=stable
|
||||
aebuild=7
|
||||
aegroup=appeng
|
||||
aebasename=appliedenergistics2
|
||||
trousers=trousers_edition
|
||||
trousersversion=v49s
|
||||
extended=extended_life
|
||||
extendedversion=v50j
|
||||
#########################################################
|
||||
# Versions #
|
||||
#########################################################
|
||||
minecraft_version=1.12.2
|
||||
mcp_mappings=snapshot_20171003
|
||||
forge_version=14.23.5.2847
|
||||
|
||||
#########################################################
|
||||
# Installable #
|
||||
#########################################################
|
||||
hwyla_version=1.8.26-B41_1.12.2
|
||||
|
||||
#########################################################
|
||||
# Provided APIs #
|
||||
#########################################################
|
||||
@@ -28,7 +26,6 @@ cofhcore_version=1.12.2-4.5.2.19
|
||||
crafttweaker_version=4.1.8.9
|
||||
inventorytweaks_version=1.63
|
||||
ctm_version=MC1.12.2-0.3.1.16
|
||||
|
||||
#########################################################
|
||||
# Deployment #
|
||||
#########################################################
|
||||
|
||||
@@ -59,7 +59,7 @@ repositories {
|
||||
url "http://maven.k-4u.nl/"
|
||||
}
|
||||
|
||||
maven { // CraftTweaker
|
||||
maven { // CraftTweaker
|
||||
name 'jared maven'
|
||||
url "http://maven.blamejared.com/"
|
||||
}
|
||||
@@ -70,9 +70,9 @@ repositories {
|
||||
//}
|
||||
|
||||
maven {
|
||||
name = "CurseForge"
|
||||
url = "https://minecraft.curseforge.com/api/maven/"
|
||||
}
|
||||
name = "CurseForge"
|
||||
url = "https://minecraft.curseforge.com/api/maven/"
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
@@ -80,8 +80,7 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly "gregtechce:gregtech:1.12.2:1.15.1.735"
|
||||
|
||||
deobfCompile "gregtechce:gregtech:1.12.2:1.15.1.735"
|
||||
// installable runtime dependencies
|
||||
mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
|
||||
mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev"
|
||||
@@ -95,7 +94,7 @@ dependencies {
|
||||
compileOnly "mcjty.theoneprobe:TheOneProbe-1.12:${top_version}:api"
|
||||
compileOnly "cofh:CoFHCore:${cofhcore_version}:deobf"
|
||||
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 "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
|
||||
|
||||
|
||||
@@ -28,7 +28,8 @@ public enum PowerUnits
|
||||
{
|
||||
AE( "gui.appliedenergistics2.units.appliedenergstics" ), // Native Units - AE Energy
|
||||
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.
|
||||
@@ -46,14 +47,13 @@ public enum PowerUnits
|
||||
|
||||
/**
|
||||
* do power conversion using AE's conversion rates.
|
||||
*
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
* @param target target power unit
|
||||
* @param value value
|
||||
*
|
||||
* @param value value
|
||||
* @return value converted to target units, from this units.
|
||||
*/
|
||||
public double convertTo( final PowerUnits target, final double value )
|
||||
|
||||
@@ -29,6 +29,7 @@ public enum TunnelType
|
||||
ME, // Network Tunnel
|
||||
IC2_POWER, // EU Tunnel
|
||||
FE_POWER, // Forge Energy tunnel
|
||||
GTEU_POWER, // Forge Energy tunnel
|
||||
REDSTONE, // Redstone Tunnel
|
||||
FLUID, // Fluid Tunnel
|
||||
ITEM, // Item Tunnel
|
||||
|
||||
@@ -88,6 +88,8 @@ public interface IParts
|
||||
|
||||
IItemDefinition p2PTunnelFE();
|
||||
|
||||
IItemDefinition p2PTunnelGTEU();
|
||||
|
||||
IItemDefinition p2PTunnelLight();
|
||||
|
||||
// IItemDefinition p2PTunnelOpenComputers();
|
||||
|
||||
@@ -119,6 +119,10 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
|
||||
*
|
||||
* @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
|
||||
protected IProperty[] getAEStates()
|
||||
{
|
||||
return new IProperty[] { POWERED };
|
||||
return new IProperty[]{POWERED};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,4 +108,14 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
|
||||
|
||||
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,6 +20,7 @@ package appeng.capabilities;
|
||||
|
||||
|
||||
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
|
||||
import gregtech.api.capability.IEnergyContainer;
|
||||
import net.darkhax.tesla.api.ITeslaConsumer;
|
||||
import net.darkhax.tesla.api.ITeslaHolder;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
@@ -57,6 +58,8 @@ public final class Capabilities
|
||||
|
||||
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY;
|
||||
|
||||
public static Capability<IEnergyContainer> GTCE_ENERGY;
|
||||
|
||||
/**
|
||||
* Register AE2 provided capabilities.
|
||||
*/
|
||||
@@ -103,7 +106,19 @@ public final class Capabilities
|
||||
}
|
||||
|
||||
@CapabilityInject( IItemRepository.class )
|
||||
private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap ) { ITEM_REPOSITORY_CAPABILITY = cap; }
|
||||
private static void capIItemRepositoryRegistered( Capability<IItemRepository> 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
|
||||
private static <T> Capability.IStorage<T> createNullStorage()
|
||||
|
||||
+55
-20
@@ -1,37 +1,46 @@
|
||||
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.ContainerPartOreDictStorageBus;
|
||||
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 GuiPartOreDictStorageBus extends AEBaseGui
|
||||
public class GuiOreDictStorageBus extends AEBaseGui
|
||||
{
|
||||
private final ContainerOreDictStorageBus container;
|
||||
PartOreDicStorageBus part;
|
||||
private GuiTabButton priority;
|
||||
private GuiImgButton partition;
|
||||
|
||||
private static final Pattern ORE_DICTIONARY_FILTER = Pattern.compile( "\\*?[a-zA-Z0-9_|\\\\+(){,}?!=\\-\\[:\\]&^$]*\\*?" );
|
||||
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 GuiPartOreDictStorageBus( final InventoryPlayer inventoryPlayer, final PartOreDicStorageBus te )
|
||||
public GuiOreDictStorageBus( final InventoryPlayer inventoryPlayer, final PartOreDicStorageBus te )
|
||||
{
|
||||
super( new ContainerPartOreDictStorageBus( inventoryPlayer, te ) );
|
||||
super( new ContainerOreDictStorageBus( inventoryPlayer, te ) );
|
||||
this.container = (ContainerOreDictStorageBus) super.inventorySlots;
|
||||
part = te;
|
||||
this.ySize = 84;
|
||||
}
|
||||
@@ -51,6 +60,8 @@ public class GuiPartOreDictStorageBus extends AEBaseGui
|
||||
|
||||
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
|
||||
{
|
||||
@@ -72,21 +83,31 @@ public class GuiPartOreDictStorageBus extends AEBaseGui
|
||||
protected void actionPerformed( final GuiButton btn ) throws IOException
|
||||
{
|
||||
super.actionPerformed( btn );
|
||||
if( btn == this.priority )
|
||||
|
||||
final boolean backwards = Mouse.isButtonDown( 1 );
|
||||
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketSwitchGuis( GuiBridge.GUI_PRIORITY ) );
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
if( btn == this.partition )
|
||||
catch( final IOException e )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "StorageBus.Action", "Partition" ) );
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.getRegex", "1" ) );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +124,7 @@ public class GuiPartOreDictStorageBus extends AEBaseGui
|
||||
|
||||
if( !searchFieldInputs.isFocused() && wasFocused )
|
||||
{
|
||||
searchFieldInputs.setText( OreDictFilterMatcher.validateExp( searchFieldInputs.getText() ) );
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.save", searchFieldInputs.getText() ) );
|
||||
}
|
||||
|
||||
@@ -125,8 +147,21 @@ public class GuiPartOreDictStorageBus extends AEBaseGui
|
||||
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(), 8, 36, 4210752 );
|
||||
this.fontRenderer.drawSplitString( "Supports regex. Or use * as a wildcard", 6, 48, 174, 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
|
||||
@@ -87,6 +87,7 @@ 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 + 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 + 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( 0, Settings.REDSTONE_CONTROLLED, RedstoneMode.LOW_SIGNAL, ButtonToolTips.RedstoneMode, ButtonToolTips.ActiveWithoutSignal );
|
||||
@@ -108,15 +109,11 @@ 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 + 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 + 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 + 8, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_StandardKeep );
|
||||
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 * 2 + 8, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_StandardKeep );
|
||||
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 * 4 + 3, Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Item );
|
||||
@@ -174,19 +171,15 @@ 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 + 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 + 6, Settings.STORAGE_FILTER, StorageFilter.NONE, ButtonToolTips.ReportInaccessibleItems,
|
||||
ButtonToolTips.ReportInaccessibleItemsYes );
|
||||
this.registerApp( 16 * 3 + 5, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY, ButtonToolTips.ReportInaccessibleItems, 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 + 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 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode,
|
||||
ButtonToolTips.SchedulingModeRoundRobin );
|
||||
this.registerApp( 16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode,
|
||||
ButtonToolTips.SchedulingModeRandom );
|
||||
this.registerApp( 16 * 15 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRoundRobin );
|
||||
this.registerApp( 16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRandom );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +329,7 @@ public class GuiImgButton extends GuiButton implements ITooltip
|
||||
{
|
||||
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" );
|
||||
}
|
||||
|
||||
@@ -150,6 +150,7 @@ public class ContainerCraftConfirm extends AEBaseContainer
|
||||
if( ccr.getCpu() == c )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
-14
@@ -1,27 +1,20 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.StorageFilter;
|
||||
import appeng.api.config.*;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
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.helpers.ItemHandlerUtil;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import appeng.util.item.OreReference;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -30,11 +23,17 @@ import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class ContainerPartOreDictStorageBus extends AEBaseContainer
|
||||
public class ContainerOreDictStorageBus extends AEBaseContainer
|
||||
{
|
||||
private final PartOreDicStorageBus part;
|
||||
|
||||
public ContainerPartOreDictStorageBus( final InventoryPlayer ip, final PartOreDicStorageBus anchor )
|
||||
@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;
|
||||
@@ -45,9 +44,12 @@ public class ContainerPartOreDictStorageBus extends AEBaseContainer
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
if( Platform.isClient() )
|
||||
this.verifyPermissions( SecurityPermissions.BUILD, false );
|
||||
|
||||
if( Platform.isServer() )
|
||||
{
|
||||
return;
|
||||
this.setReadWriteMode( (AccessRestriction) part.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||
this.setStorageFilter( (StorageFilter) part.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
||||
}
|
||||
|
||||
super.detectAndSendChanges();
|
||||
@@ -57,6 +59,11 @@ public class ContainerPartOreDictStorageBus extends AEBaseContainer
|
||||
{
|
||||
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() ) )
|
||||
@@ -103,11 +110,31 @@ public class ContainerPartOreDictStorageBus extends AEBaseContainer
|
||||
{
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendTo( new PacketValueConfig( "OreDictStorageBus.sendRegex", part.getOreMatch() ), (EntityPlayerMP) getInventoryPlayer().player );
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,7 @@ package appeng.core;
|
||||
|
||||
|
||||
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.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -64,13 +60,67 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
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" };
|
||||
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"
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
// 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;
|
||||
|
||||
private final IConfigManager settings = new ConfigManager( this );
|
||||
@@ -90,10 +140,10 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
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 };
|
||||
private final int[] craftByStacks = {1, 10, 100, 1000};
|
||||
private final int[] priorityByStacks = {1, 10, 100, 1000};
|
||||
private final int[] levelByStacks = {1, 10, 100, 1000};
|
||||
private final int[] levelByMillibuckets = {10, 100, 1000, 10000};
|
||||
|
||||
// Spatial IO/Dimension
|
||||
private int storageProviderID = -1;
|
||||
@@ -125,7 +175,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
private int minMeteoriteDistanceSq = this.minMeteoriteDistance * this.minMeteoriteDistance;
|
||||
private double meteoriteClusterChance = 0.1;
|
||||
private int meteoriteMaximumSpawnHeight = 180;
|
||||
private int[] meteoriteDimensionWhitelist = { 0 };
|
||||
private int[] meteoriteDimensionWhitelist = {0};
|
||||
|
||||
// Wireless
|
||||
private double wirelessBaseCost = 8;
|
||||
@@ -148,6 +198,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
|
||||
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.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 );
|
||||
PowerMultiplier.CONFIG.multiplier = Math.max( 0.01, usageEffective );
|
||||
@@ -155,32 +206,24 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
CondenserOutput.MATTER_BALLS.requiredPower = this.get( "Condenser", "MatterBalls", 256 ).getInt( 256 );
|
||||
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( "GrindStone",
|
||||
"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." )
|
||||
.getStringList();
|
||||
this.grinderBlackList = Sets.newHashSet(
|
||||
this.get( "GrindStone", "blacklist", new String[] {}, "Blacklists the exact oredict name from being handled by any recipe." )
|
||||
.getStringList() );
|
||||
this.oreDoublePercentage = this
|
||||
.get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage, "Chance to actually get an output with stacksize > 1." )
|
||||
.getDouble( this.oreDoublePercentage );
|
||||
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.nonBlockingItems = this.get( "BlockingMode", "nonBlockingItems", nonBlockingItems, "NonBlockingItems" ).getStringList();
|
||||
|
||||
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'" );
|
||||
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.get( "GrindStone", "blacklist", new String[]{}, "Blacklists the exact oredict name from being handled by any recipe." ).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.TERMINAL_STYLE, TerminalStyle.TALL );
|
||||
this.settings.registerSetting( Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH );
|
||||
|
||||
this.spawnChargedChance = (float) ( 1.0 - this.get( "worldGen", "spawnChargedChance", 1.0 - this.spawnChargedChance )
|
||||
.getDouble(
|
||||
1.0 - this.spawnChargedChance ) );
|
||||
this.spawnChargedChance = (float) ( 1.0 - this.get( "worldGen", "spawnChargedChance", 1.0 - this.spawnChargedChance ).getDouble( 1.0 - this.spawnChargedChance ) );
|
||||
this.minMeteoriteDistance = this.get( "worldGen", "minMeteoriteDistance", this.minMeteoriteDistance ).getInt( this.minMeteoriteDistance );
|
||||
this.meteoriteClusterChance = this.get( "worldGen", "meteoriteClusterChance", this.meteoriteClusterChance ).getDouble( this.meteoriteClusterChance );
|
||||
this.meteoriteMaximumSpawnHeight = this.get( "worldGen", "meteoriteMaximumSpawnHeight", this.meteoriteMaximumSpawnHeight )
|
||||
.getInt(
|
||||
this.meteoriteMaximumSpawnHeight );
|
||||
this.meteoriteMaximumSpawnHeight = this.get( "worldGen", "meteoriteMaximumSpawnHeight", this.meteoriteMaximumSpawnHeight ).getInt( this.meteoriteMaximumSpawnHeight );
|
||||
this.meteoriteDimensionWhitelist = this.get( "worldGen", "meteoriteDimensionWhitelist", this.meteoriteDimensionWhitelist ).getIntList();
|
||||
|
||||
this.quartzOresPerCluster = this.get( "worldGen", "quartzOresPerCluster", this.quartzOresPerCluster ).getInt( this.quartzOresPerCluster );
|
||||
@@ -188,23 +231,16 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
|
||||
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.wirelessCostMultiplier = this.get( "wireless", "wirelessCostMultiplier", this.wirelessCostMultiplier ).getDouble( this.wirelessCostMultiplier );
|
||||
this.wirelessBaseRange = this.get( "wireless", "wirelessBaseRange", this.wirelessBaseRange ).getDouble( this.wirelessBaseRange );
|
||||
this.wirelessBoosterRangeMultiplier = this.get( "wireless", "wirelessBoosterRangeMultiplier", this.wirelessBoosterRangeMultiplier )
|
||||
.getDouble(
|
||||
this.wirelessBoosterRangeMultiplier );
|
||||
this.wirelessBoosterRangeMultiplier = this.get( "wireless", "wirelessBoosterRangeMultiplier", this.wirelessBoosterRangeMultiplier ).getDouble( this.wirelessBoosterRangeMultiplier );
|
||||
this.wirelessBoosterExp = this.get( "wireless", "wirelessBoosterExp", this.wirelessBoosterExp ).getDouble( this.wirelessBoosterExp );
|
||||
this.wirelessTerminalDrainMultiplier = this.get( "wireless", "wirelessTerminalDrainMultiplier", this.wirelessTerminalDrainMultiplier )
|
||||
.getDouble(
|
||||
this.wirelessTerminalDrainMultiplier );
|
||||
this.wirelessTerminalDrainMultiplier = this.get( "wireless", "wirelessTerminalDrainMultiplier", this.wirelessTerminalDrainMultiplier ).getDouble( this.wirelessTerminalDrainMultiplier );
|
||||
|
||||
this.formationPlaneEntityLimit = this.get( "automation", "formationPlaneEntityLimit", this.formationPlaneEntityLimit )
|
||||
.getInt(
|
||||
this.formationPlaneEntityLimit );
|
||||
this.formationPlaneEntityLimit = this.get( "automation", "formationPlaneEntityLimit", this.formationPlaneEntityLimit ).getInt( this.formationPlaneEntityLimit );
|
||||
|
||||
this.wirelessTerminalBattery = this.get( "battery", "wirelessTerminal", this.wirelessTerminalBattery ).getInt( this.wirelessTerminalBattery );
|
||||
this.chargedStaffBattery = this.get( "battery", "chargedStaff", this.chargedStaffBattery ).getInt( this.chargedStaffBattery );
|
||||
@@ -245,8 +281,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
|
||||
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 )
|
||||
{
|
||||
@@ -262,17 +297,13 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
{
|
||||
this.storageProviderID = this.get( "spatialio", "storageProviderID", this.storageProviderID ).getInt( this.storageProviderID );
|
||||
this.storageDimensionID = this.get( "spatialio", "storageDimensionID", this.storageDimensionID ).getInt( this.storageDimensionID );
|
||||
this.spatialPowerMultiplier = this.get( "spatialio", "spatialPowerMultiplier", this.spatialPowerMultiplier )
|
||||
.getDouble(
|
||||
this.spatialPowerMultiplier );
|
||||
this.spatialPowerMultiplier = this.get( "spatialio", "spatialPowerMultiplier", this.spatialPowerMultiplier ).getDouble( this.spatialPowerMultiplier );
|
||||
this.spatialPowerExponent = this.get( "spatialio", "spatialPowerExponent", this.spatialPowerExponent ).getDouble( this.spatialPowerExponent );
|
||||
}
|
||||
|
||||
if( this.isFeatureEnabled( AEFeature.CRAFTING_CPU ) )
|
||||
{
|
||||
this.craftingCalculationTimePerTick = this.get( "craftingCPU", "craftingCalculationTimePerTick", this.craftingCalculationTimePerTick )
|
||||
.getInt(
|
||||
this.craftingCalculationTimePerTick );
|
||||
this.craftingCalculationTimePerTick = this.get( "craftingCPU", "craftingCalculationTimePerTick", this.craftingCalculationTimePerTick ).getInt( this.craftingCalculationTimePerTick );
|
||||
}
|
||||
|
||||
this.updatable = true;
|
||||
@@ -446,8 +477,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
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 );
|
||||
p.setComment( "OreDictionary Names: " + mt.getOreName() );
|
||||
|
||||
@@ -715,6 +745,11 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
return this.quartzOresClusterAmount;
|
||||
}
|
||||
|
||||
public String[] getNonBlockingItems()
|
||||
{
|
||||
return nonBlockingItems;
|
||||
}
|
||||
|
||||
public int getChargedChange()
|
||||
{
|
||||
return this.chargedChange;
|
||||
|
||||
@@ -183,8 +183,7 @@ public final class AppEng
|
||||
AELog.info( "Pre Initialization ( ended after " + watch.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
|
||||
|
||||
// Instantiate all Plugins
|
||||
List<Object> injectables = Lists.newArrayList(
|
||||
AEApi.instance() );
|
||||
List<Object> injectables = Lists.newArrayList( AEApi.instance() );
|
||||
new PluginLoader().loadPlugins( injectables, event.getAsmData() );
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ public final class ApiParts implements IParts
|
||||
private final IItemDefinition p2PTunnelFluids;
|
||||
private final IItemDefinition p2PTunnelEU;
|
||||
private final IItemDefinition p2PTunnelFE;
|
||||
private final IItemDefinition p2PTunnelGTEU;
|
||||
private final IItemDefinition p2PTunnelLight;
|
||||
// private final IItemDefinition p2PTunnelOpenComputers;
|
||||
private final IItemDefinition cableAnchor;
|
||||
@@ -91,9 +92,7 @@ public final class ApiParts implements IParts
|
||||
public ApiParts( FeatureFactory registry, PartModels partModels )
|
||||
{
|
||||
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
|
||||
for( PartType partType : PartType.values() )
|
||||
@@ -122,8 +121,7 @@ public final class ApiParts implements IParts
|
||||
this.levelEmitter = new DamagedItemDefinition( "part.level_emitter", itemPart.createPart( PartType.LEVEL_EMITTER ) );
|
||||
this.fluidLevelEmitter = new DamagedItemDefinition( "part.fluid_level_emitter", itemPart.createPart( PartType.FLUID_LEVEL_EMITTER ) );
|
||||
this.annihilationPlane = new DamagedItemDefinition( "part.plane.annihilation", itemPart.createPart( PartType.ANNIHILATION_PLANE ) );
|
||||
this.identityAnnihilationPlane = new DamagedItemDefinition( "part.plane.annihiliation.identity", itemPart
|
||||
.createPart( PartType.IDENTITY_ANNIHILATION_PLANE ) );
|
||||
this.identityAnnihilationPlane = new DamagedItemDefinition( "part.plane.annihiliation.identity", itemPart.createPart( PartType.IDENTITY_ANNIHILATION_PLANE ) );
|
||||
this.fluidAnnihilationPlane = new DamagedItemDefinition( "part.plane.fluid_annihilation", itemPart.createPart( PartType.FLUID_ANNIHILATION_PLANE ) );
|
||||
this.formationPlane = new DamagedItemDefinition( "part.plane.formation", itemPart.createPart( PartType.FORMATION_PLANE ) );
|
||||
this.fluidFormationPlane = new DamagedItemDefinition( "part.plane.fluid_formation", itemPart.createPart( PartType.FLUID_FORMATION_PLANE ) );
|
||||
@@ -133,6 +131,7 @@ public final class ApiParts implements IParts
|
||||
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.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.p2PTunnelOpenComputers = new DamagedItemDefinition( itemMultiPart.createPart(
|
||||
// PartType.P2PTunnelOpenComputers ) );
|
||||
@@ -339,6 +338,11 @@ public final class ApiParts implements IParts
|
||||
return this.p2PTunnelFE;
|
||||
}
|
||||
|
||||
public IItemDefinition p2PTunnelGTEU()
|
||||
{
|
||||
return this.p2PTunnelGTEU;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition p2PTunnelLight()
|
||||
{
|
||||
|
||||
@@ -25,13 +25,13 @@ public enum AEFeature
|
||||
// is just flat out required by tons of
|
||||
// important stuff.
|
||||
CORE( "Core", null )
|
||||
{
|
||||
@Override
|
||||
public boolean isVisible()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
@Override
|
||||
public boolean isVisible()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
CERTUS_QUARTZ_WORLD_GEN( "CertusQuartzWorldGen", Constants.CATEGORY_WORLD ),
|
||||
METEORITE_WORLD_GEN( "MeteoriteWorldGen", Constants.CATEGORY_WORLD ),
|
||||
@@ -126,6 +126,7 @@ public enum AEFeature
|
||||
P2P_TUNNEL_REDSTONE( "P2PTunnelRedstone", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2P_TUNNEL_EU( "P2PTunnelEU", 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_LIGHT( "P2PTunnelLight", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2P_TUNNEL_OPEN_COMPUTERS( "P2PTunnelOpenComputers", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
@@ -163,7 +164,6 @@ public enum AEFeature
|
||||
MOLECULAR_ASSEMBLER( "MolecularAssembler", Constants.CATEGORY_CRAFTING_FEATURES ),
|
||||
PATTERNS( "Patterns", 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 ),
|
||||
ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ),
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
package appeng.core.features.registries;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import appeng.util.item.OreHelper;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
@@ -67,6 +68,25 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
this.addNewAttunement( new ItemStack( Blocks.TORCH ), 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
|
||||
*/
|
||||
@@ -127,12 +147,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
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", 1 ), TunnelType.ITEM ); // itemduct
|
||||
// (opaque)
|
||||
// (opaque)
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 2 ), TunnelType.ITEM ); // impulse
|
||||
// itemduct
|
||||
// itemduct
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 3 ), TunnelType.ITEM ); // impulse
|
||||
// itemduct
|
||||
// (opaque)
|
||||
// itemduct
|
||||
// (opaque)
|
||||
|
||||
/**
|
||||
* attune based on lots of random item related stuff
|
||||
@@ -148,12 +168,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
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", 1 ), TunnelType.FLUID ); // fluiduct
|
||||
// (opaque)
|
||||
// (opaque)
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 2 ), TunnelType.FLUID ); // fluiduct
|
||||
// hardened
|
||||
// hardened
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 3 ), TunnelType.FLUID ); // fluiduct
|
||||
// hardened
|
||||
// (opaque)
|
||||
// hardened
|
||||
// (opaque)
|
||||
|
||||
for( final AEColor c : AEColor.values() )
|
||||
{
|
||||
|
||||
@@ -99,6 +99,7 @@ public enum GuiText
|
||||
OCTunnel,
|
||||
LightTunnel,
|
||||
FETunnel,
|
||||
GTEUTunnel,
|
||||
PressureTunnel,
|
||||
|
||||
// spatial
|
||||
|
||||
@@ -141,7 +141,7 @@ public enum GuiBridge implements IGuiHandler
|
||||
|
||||
GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_OREDICTSTORAGEBUS( ContainerPartOreDictStorageBus.class, PartOreDicStorageBus.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 ),
|
||||
|
||||
|
||||
@@ -298,19 +298,17 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
|
||||
con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) );
|
||||
|
||||
if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) )
|
||||
{
|
||||
IItemHandler outputSlots = cct.getInventoryByName( "output" );
|
||||
|
||||
for( int i = 0; i < this.output.size(); ++i )
|
||||
{
|
||||
if( this.output.get( i ) == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output.get( i ) );
|
||||
}
|
||||
|
||||
if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) ) {
|
||||
IItemHandler outputSlots = cct.getInventoryByName("output");
|
||||
for (int i = 0; i < outputSlots.getSlots(); ++i) {
|
||||
ItemHandlerUtil.setStackInSlot(outputSlots, i, ItemStack.EMPTY);
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.client.gui.implementations.GuiPartOreDictStorageBus;
|
||||
import appeng.client.gui.implementations.GuiOreDictStorageBus;
|
||||
import appeng.container.implementations.*;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -276,9 +276,10 @@ public class PacketValueConfig extends AppEngPacket
|
||||
{
|
||||
( (ContainerFluidStorageBus) c ).partition();
|
||||
}
|
||||
else if( c instanceof ContainerPartOreDictStorageBus )
|
||||
else if( c instanceof ContainerOreDictStorageBus )
|
||||
{
|
||||
( (ContainerPartOreDictStorageBus) c ).partition();
|
||||
( (ContainerOreDictStorageBus) c ).partition();
|
||||
( (ContainerOreDictStorageBus) c ).sendRegex();
|
||||
}
|
||||
}
|
||||
else if( this.Value.equals( "Clear" ) )
|
||||
@@ -296,15 +297,15 @@ public class PacketValueConfig extends AppEngPacket
|
||||
}
|
||||
else if( this.Name.startsWith( "OreDictStorageBus" ) )
|
||||
{
|
||||
if( c instanceof ContainerPartOreDictStorageBus )
|
||||
if( c instanceof ContainerOreDictStorageBus )
|
||||
{
|
||||
if( this.Name.equals( "OreDictStorageBus.save" ) )
|
||||
{
|
||||
( (ContainerPartOreDictStorageBus) c ).saveOreMatch( this.Value );
|
||||
( (ContainerOreDictStorageBus) c ).saveOreMatch( this.Value );
|
||||
}
|
||||
if( this.Name.equals( "OreDictStorageBus.getRegex" ) )
|
||||
{
|
||||
( (ContainerPartOreDictStorageBus) c ).sendRegex();
|
||||
( (ContainerOreDictStorageBus) c ).sendRegex();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -387,9 +388,9 @@ public class PacketValueConfig extends AppEngPacket
|
||||
else if( this.Name.equals( "OreDictStorageBus.sendRegex" ) )
|
||||
{
|
||||
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
|
||||
if( gs instanceof GuiPartOreDictStorageBus )
|
||||
if( gs instanceof GuiOreDictStorageBus )
|
||||
{
|
||||
( (GuiPartOreDictStorageBus) gs ).fillRegex( this.Value );
|
||||
( (GuiOreDictStorageBus) gs ).fillRegex( this.Value );
|
||||
}
|
||||
}
|
||||
else if( c instanceof IConfigurableObject )
|
||||
|
||||
@@ -22,6 +22,7 @@ package appeng.crafting;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import appeng.me.cache.GridStorageCache;
|
||||
import com.google.common.base.Stopwatch;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -50,18 +51,23 @@ import appeng.hooks.TickHandler;
|
||||
|
||||
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 ms";
|
||||
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_MACHINE_SOURCE_DETAILS = "Machine[object=%s, %s]";
|
||||
|
||||
private final MECraftingInventory original;
|
||||
private final World world;
|
||||
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> usedWhileBuilding = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final IItemList<IAEItemStack> uniques = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
|
||||
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
|
||||
private final Object monitor = new Object();
|
||||
private final Stopwatch watch = Stopwatch.createUnstarted();
|
||||
private final Stopwatch tickSpreadingWatch = Stopwatch.createUnstarted();
|
||||
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
|
||||
private CraftingTreeNode tree;
|
||||
private final IAEItemStack output;
|
||||
private long expectedOutput;
|
||||
private boolean simulate = false;
|
||||
private MECraftingInventory availableCheck;
|
||||
private long bytes = 0;
|
||||
@@ -84,15 +90,25 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
this.actionSrc = actionSrc;
|
||||
|
||||
this.callback = callback;
|
||||
|
||||
final ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
|
||||
final IStorageGrid sg = grid.getCache( IStorageGrid.class );
|
||||
this.original = new MECraftingInventory( sg
|
||||
.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), actionSrc, false, false, false );
|
||||
final GridStorageCache sg = grid.getCache( IStorageGrid.class );
|
||||
this.original = new MECraftingInventory( sg.getExtractableList( actionSrc ) );
|
||||
|
||||
this.setTree( this.getCraftingTree( cc, what ) );
|
||||
this.availableCheck = null;
|
||||
}
|
||||
|
||||
public long getExpectedOutput()
|
||||
{
|
||||
return expectedOutput;
|
||||
}
|
||||
|
||||
public void incExpectedOutput( long amount )
|
||||
{
|
||||
this.expectedOutput += amount;
|
||||
}
|
||||
|
||||
private CraftingTreeNode getCraftingTree( final ICraftingGrid cc, final IAEItemStack what )
|
||||
{
|
||||
return new CraftingTreeNode( cc, this, what, null, -1, 0 );
|
||||
@@ -103,11 +119,26 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
this.availableCheck.injectItems( o, Actionable.MODULATE, this.actionSrc );
|
||||
}
|
||||
|
||||
public IItemList<IAEItemStack> getUsedWhileBuilding()
|
||||
{
|
||||
return usedWhileBuilding;
|
||||
}
|
||||
|
||||
public IItemList<IAEItemStack> getUniques()
|
||||
{
|
||||
return uniques;
|
||||
}
|
||||
|
||||
IAEItemStack checkUse( final IAEItemStack available )
|
||||
{
|
||||
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
|
||||
}
|
||||
|
||||
IAEItemStack checkAvailable( final IAEItemStack available )
|
||||
{
|
||||
return this.original.extractItems( available.copy().setStackSize( Long.MAX_VALUE ), Actionable.SIMULATE, this.actionSrc );
|
||||
}
|
||||
|
||||
public void writeToNBT( final NBTTagCompound out )
|
||||
{
|
||||
|
||||
@@ -139,7 +170,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
|
||||
this.handlePausing();
|
||||
|
||||
final Stopwatch timer = Stopwatch.createStarted();
|
||||
craftingTreeWatch.start();
|
||||
|
||||
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
||||
craftingInventory.ignore( this.output );
|
||||
@@ -154,9 +185,8 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
||||
}
|
||||
|
||||
this.logCraftingJob( "real", timer );
|
||||
// if ( mode == Actionable.MODULATE )
|
||||
// craftingInventory.moveItemsToStorage( storage );
|
||||
craftingTreeWatch.stop();
|
||||
this.logCraftingJob( "real, success", craftingTreeWatch );
|
||||
}
|
||||
catch( final CraftBranchFailure e )
|
||||
{
|
||||
@@ -164,23 +194,32 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
|
||||
try
|
||||
{
|
||||
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() )
|
||||
if( actionSrc.player().isPresent() )
|
||||
{
|
||||
final TwoIntegers ti = this.opsAndMultiplier.get( s );
|
||||
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
||||
}
|
||||
craftingTreeWatch.reset().start();
|
||||
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
||||
craftingInventory.ignore( this.output );
|
||||
|
||||
this.logCraftingJob( "simulate", timer );
|
||||
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 TwoIntegers ti = this.opsAndMultiplier.get( s );
|
||||
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
||||
}
|
||||
|
||||
craftingTreeWatch.stop();
|
||||
this.logCraftingJob( "simulate", craftingTreeWatch );
|
||||
}
|
||||
else
|
||||
{
|
||||
craftingTreeWatch.stop();
|
||||
this.logCraftingJob( "real, failed", craftingTreeWatch );
|
||||
}
|
||||
}
|
||||
catch( final CraftBranchFailure e1 )
|
||||
{
|
||||
@@ -226,10 +265,11 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
this.incTime = 0;
|
||||
synchronized ( this.monitor )
|
||||
{
|
||||
if( this.watch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
|
||||
if( this.tickSpreadingWatch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
|
||||
{
|
||||
this.running = false;
|
||||
this.watch.stop();
|
||||
this.craftingTreeWatch.stop();
|
||||
this.tickSpreadingWatch.stop();
|
||||
this.monitor.notify();
|
||||
}
|
||||
|
||||
@@ -245,12 +285,13 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
AELog.craftingDebug( "crafting job now active" );
|
||||
}
|
||||
}
|
||||
|
||||
if( Thread.interrupted() )
|
||||
{
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
if( Thread.interrupted() )
|
||||
{
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
this.incTime++;
|
||||
}
|
||||
|
||||
@@ -263,7 +304,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
|
||||
this.availableCheck = null;
|
||||
|
||||
synchronized( this.monitor )
|
||||
synchronized ( this.monitor )
|
||||
{
|
||||
this.running = false;
|
||||
this.done = true;
|
||||
@@ -311,7 +352,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
/**
|
||||
* @return true if this needs more simulation
|
||||
*/
|
||||
public boolean simulateFor(final int milli)
|
||||
public boolean simulateFor( final int milli )
|
||||
{
|
||||
this.time = milli;
|
||||
|
||||
@@ -323,8 +364,8 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
}
|
||||
if( !this.actionSrc.player().isPresent() )
|
||||
{
|
||||
this.watch.reset();
|
||||
this.watch.start();
|
||||
this.tickSpreadingWatch.reset();
|
||||
this.tickSpreadingWatch.start();
|
||||
this.monitor.notify();
|
||||
}
|
||||
this.running = true;
|
||||
@@ -353,7 +394,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
if( AELog.isCraftingLogEnabled() )
|
||||
{
|
||||
final String itemToOutput = this.output.toString();
|
||||
final long elapsedTime = timer.elapsed( TimeUnit.MILLISECONDS );
|
||||
final long elapsedTime = timer.elapsed( TimeUnit.MICROSECONDS );
|
||||
final String actionSource;
|
||||
|
||||
if( this.actionSrc.player().isPresent() )
|
||||
|
||||
@@ -23,14 +23,12 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
@@ -81,94 +79,32 @@ public class CraftingTreeNode
|
||||
for( final ICraftingPatternDetails details : cc.getCraftingFor( this.what, this.parent == null ? null : this.parent.details, slot, this.world ) )// in
|
||||
// order.
|
||||
{
|
||||
if( this.parent == null || this.parent.notRecursive( details ) )
|
||||
if( this.parent == null || job.getExpectedOutput() < job.getOutput().getStackSize() )
|
||||
{
|
||||
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean notRecursive( final ICraftingPatternDetails details )
|
||||
{
|
||||
IAEItemStack[] o = details.getCondensedOutputs();
|
||||
|
||||
for( final IAEItemStack i : o )
|
||||
{
|
||||
if( i.equals( this.what ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
{
|
||||
this.job.handlePausing();
|
||||
|
||||
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
||||
final List<IAEItemStack> thingsUsed = new ArrayList<>();
|
||||
|
||||
this.what.setStackSize( l );
|
||||
IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
|
||||
{
|
||||
if( !this.exhausted )
|
||||
Collection<IAEItemStack> itemList = new ArrayList<>();
|
||||
|
||||
if( this.parent.getContainerItems() != null && !this.parent.getContainerItems().findFuzzy( this.what, FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||
{
|
||||
final IAEItemStack is = this.job.checkUse( available );
|
||||
|
||||
if( is != null )
|
||||
{
|
||||
thingsUsed.add( is.copy() );
|
||||
this.used.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
this.bytes += available.getStackSize();
|
||||
l -= available.getStackSize();
|
||||
|
||||
if( l == 0 )
|
||||
{
|
||||
return available;
|
||||
}
|
||||
}
|
||||
|
||||
else if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
|
||||
{
|
||||
final Collection<IAEItemStack> itemList;
|
||||
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
||||
|
||||
if( this.parent.details.canSubstitute() )
|
||||
{
|
||||
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs( this.slot );
|
||||
itemList = new ArrayList<>( substitutes.size() );
|
||||
|
||||
for( IAEItemStack stack : substitutes )
|
||||
{
|
||||
itemList.addAll( inventoryList.findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
|
||||
}
|
||||
itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL );
|
||||
}
|
||||
else
|
||||
{
|
||||
itemList = Lists.newArrayList();
|
||||
|
||||
final IAEItemStack item = inventoryList.findPrecise( this.what );
|
||||
|
||||
if( item != null )
|
||||
{
|
||||
itemList.add( item );
|
||||
@@ -177,12 +113,12 @@ public class CraftingTreeNode
|
||||
|
||||
for( IAEItemStack fuzz : itemList )
|
||||
{
|
||||
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().setStackSize( 1 ).createItemStack(), this.world ) )
|
||||
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().getCachedItemStack( 1 ), this.world ) )
|
||||
{
|
||||
fuzz = fuzz.copy();
|
||||
fuzz.setStackSize( l );
|
||||
|
||||
available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
||||
final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
@@ -208,6 +144,32 @@ public class CraftingTreeNode
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
if( !this.exhausted )
|
||||
{
|
||||
final IAEItemStack is = this.job.checkUse( available );
|
||||
|
||||
if( is != null )
|
||||
{
|
||||
thingsUsed.add( is.copy() );
|
||||
this.used.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
this.bytes += available.getStackSize();
|
||||
l -= available.getStackSize();
|
||||
|
||||
if( l == 0 )
|
||||
{
|
||||
return available;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( this.canEmit )
|
||||
{
|
||||
@@ -234,7 +196,7 @@ public class CraftingTreeNode
|
||||
|
||||
madeWhat.setStackSize( l );
|
||||
|
||||
available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
|
||||
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
@@ -264,7 +226,7 @@ public class CraftingTreeNode
|
||||
pro.request( subInv, 1, src );
|
||||
|
||||
this.what.setStackSize( l );
|
||||
available = subInv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
final IAEItemStack available = subInv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
|
||||
@@ -19,43 +19,41 @@
|
||||
package appeng.crafting;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
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 net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.container.ContainerNull;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
public class CraftingTreeProcess
|
||||
{
|
||||
|
||||
private final CraftingTreeNode parent;
|
||||
final ICraftingPatternDetails details;
|
||||
private final CraftingJob job;
|
||||
private final Map<CraftingTreeNode, Long> nodes = new HashMap<>();
|
||||
private final Object2LongArrayMap<CraftingTreeNode> nodes = new Object2LongArrayMap<>();
|
||||
private final int depth;
|
||||
boolean possible = true;
|
||||
private World world;
|
||||
private long crafts = 0;
|
||||
private boolean containerItems;
|
||||
private IItemList<IAEItemStack> containerItems;
|
||||
private boolean limitQty;
|
||||
private boolean fullSimulation;
|
||||
private final List<IAEItemStack> craftingResultList = new ArrayList<>();
|
||||
private long bytes = 0;
|
||||
|
||||
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, final CraftingTreeNode craftingTreeNode, final int depth )
|
||||
@@ -66,168 +64,256 @@ public class CraftingTreeProcess
|
||||
this.depth = depth;
|
||||
final World world = job.getWorld();
|
||||
|
||||
if( details.isCraftable() )
|
||||
final IAEItemStack[] list = details.getInputs();
|
||||
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
final IAEItemStack[] list = details.getInputs();
|
||||
|
||||
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
final IAEItemStack[] is = details.getInputs();
|
||||
for( int x = 0; x < ic.getSizeInventory(); x++ )
|
||||
if( part.getItem().hasContainerItem( part.getDefinition() ) )
|
||||
{
|
||||
ic.setInventorySlotContents( x, is[x] == null ? ItemStack.EMPTY : is[x].createItemStack() );
|
||||
}
|
||||
|
||||
for( int x = 0; x < ic.getSizeInventory(); x++ )
|
||||
{
|
||||
final ItemStack g = ic.getStackInSlot( x );
|
||||
if( !g.isEmpty() && g.getCount() > 1 )
|
||||
if( containerItems == null )
|
||||
{
|
||||
this.fullSimulation = true;
|
||||
containerItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
}
|
||||
containerItems.add( part );
|
||||
this.limitQty = true;
|
||||
//break;
|
||||
}
|
||||
}
|
||||
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
for( final IAEItemStack part : details.getCondensedOutputs() )
|
||||
{
|
||||
if( part.equals( job.getOutput() ) )
|
||||
{
|
||||
final ItemStack g = part.createItemStack();
|
||||
job.incExpectedOutput( part.getStackSize() );
|
||||
}
|
||||
}
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
if( part.equals( job.getOutput() ) )
|
||||
{
|
||||
job.incExpectedOutput( -part.getStackSize() );
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAnInput = false;
|
||||
for( final IAEItemStack a : details.getCondensedOutputs() )
|
||||
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
|
||||
for( IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
if( part == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for( int x = 0; x < list.length; x++ )
|
||||
{
|
||||
final IAEItemStack comparePart = list[x];
|
||||
if( part.equals( comparePart ) )
|
||||
{
|
||||
if( !g.isEmpty() && a != null && a.equals( g ) )
|
||||
boolean isPartContainer = false;
|
||||
if( containerItems != null && !containerItems.findFuzzy( list[x], FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||
{
|
||||
isAnInput = true;
|
||||
part = list[x];
|
||||
isPartContainer = true;
|
||||
}
|
||||
}
|
||||
long wantedSize = part.getStackSize();
|
||||
|
||||
if( isAnInput )
|
||||
{
|
||||
this.limitQty = true;
|
||||
}
|
||||
|
||||
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 )
|
||||
if( !isPartContainer )
|
||||
{
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
|
||||
}
|
||||
}
|
||||
}
|
||||
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++ )
|
||||
{
|
||||
final IAEItemStack comparePart = list[x];
|
||||
if( part != null && part.equals( comparePart ) )
|
||||
IAEItemStack found = job.checkAvailable( part );
|
||||
IAEItemStack used;
|
||||
long requestAmount;
|
||||
|
||||
long remaining = 0;
|
||||
if( found != null )
|
||||
{
|
||||
// use the first slot...
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
|
||||
break;
|
||||
used = job.getUsedWhileBuilding().findPrecise( part );
|
||||
remaining = found.getStackSize();
|
||||
if( used != null )
|
||||
{
|
||||
if( used.getStackSize() >= found.getStackSize() )
|
||||
{
|
||||
remaining = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
remaining -= used.getStackSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( remaining > 0 )
|
||||
{
|
||||
if( remaining >= wantedSize )
|
||||
{
|
||||
requestAmount = wantedSize;
|
||||
wantedSize = 0;
|
||||
//we have the items
|
||||
}
|
||||
else
|
||||
{
|
||||
requestAmount = remaining;
|
||||
wantedSize -= remaining;
|
||||
}
|
||||
part = part.copy().setStackSize( requestAmount );
|
||||
job.getUsedWhileBuilding().addStorage( part );
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), requestAmount );
|
||||
if( wantedSize == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( wantedSize > 0 )
|
||||
{
|
||||
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
||||
{
|
||||
//try to extract substitutes
|
||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||
{
|
||||
if( subs.equals( part ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
found = job.checkAvailable( subs );
|
||||
remaining = 0;
|
||||
|
||||
if( found != null )
|
||||
{
|
||||
used = job.getUsedWhileBuilding().findPrecise( subs );
|
||||
remaining = found.getStackSize();
|
||||
if( used != null )
|
||||
{
|
||||
if( used.getStackSize() >= found.getStackSize() )
|
||||
{
|
||||
remaining = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
remaining -= used.getStackSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( remaining > 0 )
|
||||
{
|
||||
if( remaining >= wantedSize )
|
||||
{
|
||||
requestAmount = wantedSize;
|
||||
wantedSize = 0;
|
||||
//we have the items
|
||||
}
|
||||
else
|
||||
{
|
||||
requestAmount = remaining;
|
||||
wantedSize -= remaining;
|
||||
}
|
||||
subs = subs.copy().setStackSize( requestAmount );
|
||||
job.getUsedWhileBuilding().addStorage( subs );
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, subs, this, x, depth + 1 ), requestAmount );
|
||||
}
|
||||
if( wantedSize == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( wantedSize > 0 )
|
||||
{
|
||||
//try to order the crafting of a substitute
|
||||
ICraftingPatternDetails prioritizedPattern = null;
|
||||
IAEItemStack prioritizedIAE = null;
|
||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||
{
|
||||
if( subs.equals( part ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
prioritizedIAE = subs;
|
||||
}
|
||||
}
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), this, x, depth + 1 ), wantedSize );
|
||||
wantedSize = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( wantedSize == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( wantedSize > 0 )
|
||||
{
|
||||
part = part.copy();
|
||||
// use the first slot...
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), wantedSize );
|
||||
wantedSize = 0;
|
||||
}
|
||||
if( !isPartContainer && wantedSize == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
for( final IAEItemStack part : details.getCondensedOutputs() )
|
||||
{
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
for( final IAEItemStack o : 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 )
|
||||
if( part.equals( o ) )
|
||||
{
|
||||
this.limitQty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, -1, depth + 1 ), part.getStackSize() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean notRecursive( final ICraftingPatternDetails details )
|
||||
IItemList<IAEItemStack> getContainerItems()
|
||||
{
|
||||
return this.parent == null || this.parent.notRecursive( details );
|
||||
return this.containerItems;
|
||||
}
|
||||
|
||||
long getTimes( final long remaining, final long stackSize )
|
||||
{
|
||||
if( this.limitQty || this.fullSimulation )
|
||||
if( this.limitQty )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return ( remaining / stackSize ) + ( remaining % stackSize != 0 ? 1 : 0 );
|
||||
}
|
||||
|
||||
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
void request( final MECraftingInventory inv, final long amountOfTimes, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
{
|
||||
this.job.handlePausing();
|
||||
if( this.fullSimulation )
|
||||
|
||||
// request and remove inputs...
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
final IAEItemStack craftableStack = entry.getKey().getStack( entry.getValue() );
|
||||
final IAEItemStack stack = entry.getKey().request( inv, craftableStack.getStackSize() * amountOfTimes, src );
|
||||
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.entrySet() )
|
||||
if( containerItems != null && !this.containerItems.findFuzzy( stack, FuzzyMode.IGNORE_ALL ).isEmpty() )
|
||||
{
|
||||
final IAEItemStack item = entry.getKey().getStack( entry.getValue() );
|
||||
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 );
|
||||
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
|
||||
final IAEItemStack o = AEItemStack.fromItemStack( is );
|
||||
if( o != null )
|
||||
{
|
||||
this.bytes++;
|
||||
inv.injectItems( o, Actionable.MODULATE, src );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// request and remove inputs...
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.entrySet() )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
craftingResultList.add( o );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,21 +324,32 @@ public class CraftingTreeProcess
|
||||
for( final IAEItemStack out : this.details.getCondensedOutputs() )
|
||||
{
|
||||
final IAEItemStack o = out.copy();
|
||||
o.setStackSize( o.getStackSize() * i );
|
||||
inv.injectItems( o, Actionable.MODULATE, src );
|
||||
o.setStackSize( o.getStackSize() * amountOfTimes );
|
||||
craftingResultList.add( o );
|
||||
}
|
||||
this.crafts += i;
|
||||
|
||||
for( IAEItemStack i : craftingResultList )
|
||||
{
|
||||
inv.injectItems( i, Actionable.MODULATE, src );
|
||||
}
|
||||
|
||||
this.crafts += amountOfTimes;
|
||||
}
|
||||
|
||||
public List<IAEItemStack> getCraftingResultList()
|
||||
{
|
||||
return craftingResultList;
|
||||
}
|
||||
|
||||
void dive( final CraftingJob job )
|
||||
{
|
||||
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts, this.details, this.depth );
|
||||
for( final CraftingTreeNode pro : this.nodes.keySet() )
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
pro.dive( job );
|
||||
entry.getKey().dive( job );
|
||||
}
|
||||
|
||||
job.addBytes( this.crafts + 8 + this.bytes );
|
||||
job.addBytes( this.crafts * 8 + this.bytes );
|
||||
}
|
||||
|
||||
IAEItemStack getAmountCrafted( IAEItemStack what2 )
|
||||
@@ -286,9 +383,9 @@ public class CraftingTreeProcess
|
||||
this.crafts = 0;
|
||||
this.bytes = 0;
|
||||
|
||||
for( final CraftingTreeNode pro : this.nodes.keySet() )
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
pro.setSimulate();
|
||||
entry.getKey().setSimulate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,9 +393,9 @@ public class CraftingTreeProcess
|
||||
{
|
||||
craftingCPUCluster.addCrafting( this.details, this.crafts );
|
||||
|
||||
for( final CraftingTreeNode pro : this.nodes.keySet() )
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
pro.setJob( storage, craftingCPUCluster, src );
|
||||
entry.getKey().setJob( storage, craftingCPUCluster, src );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,9 +408,9 @@ public class CraftingTreeProcess
|
||||
plan.addRequestable( i );
|
||||
}
|
||||
|
||||
for( final CraftingTreeNode pro : this.nodes.keySet() )
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
pro.getPlan( plan );
|
||||
entry.getKey().getPlan( plan );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.helpers.PlayerSource;
|
||||
import appeng.util.inv.ItemListIgnoreCrafting;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
|
||||
@@ -97,8 +96,7 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
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;
|
||||
}
|
||||
@@ -313,15 +311,14 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
{
|
||||
if( result == null )
|
||||
{
|
||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could not extract anything" ), false );
|
||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could not extract anything" ), false );
|
||||
}
|
||||
else
|
||||
{
|
||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could only extract " + result.getStackSize() ), false );
|
||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could only extract " + result.getStackSize() ), false );
|
||||
}
|
||||
}
|
||||
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 )
|
||||
{
|
||||
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 53, 16, 68 ) );
|
||||
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 57, 16, 64 ) );
|
||||
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() );
|
||||
final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) );
|
||||
|
||||
int iconHeightRemainder = scaledHeight % this.getHeight();
|
||||
int iconHeightRemainder = scaledHeight % 16;
|
||||
if( iconHeightRemainder > 0 )
|
||||
{
|
||||
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, this.getWidth(), iconHeightRemainder );
|
||||
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, 16, iconHeightRemainder );
|
||||
}
|
||||
for( int i = 0; i < scaledHeight / this.getHeight(); i++ )
|
||||
for( int i = 0; i < scaledHeight / 16; i++ )
|
||||
{
|
||||
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, this.getWidth(), this.getHeight() );
|
||||
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +113,7 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
|
||||
@Override
|
||||
public int yPos()
|
||||
{
|
||||
return this.y - 1;
|
||||
return this.y - 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +125,7 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
return this.height + 1;
|
||||
return this.height + 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,15 +23,15 @@ import java.util.*;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
|
||||
import appeng.util.inv.BlockingInventoryAdaptor;
|
||||
import appeng.util.*;
|
||||
import appeng.util.inv.*;
|
||||
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 gregtech.api.metatileentity.MetaTileEntityHolder;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Items;
|
||||
@@ -108,14 +108,14 @@ import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
|
||||
|
||||
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost
|
||||
{
|
||||
private int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
|
||||
|
||||
public static final int NUMBER_OF_STORAGE_SLOTS = 9;
|
||||
public static final int NUMBER_OF_CONFIG_SLOTS = 9;
|
||||
public static final int NUMBER_OF_PATTERN_SLOTS = 36;
|
||||
|
||||
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 AENetworkProxy gridProxy;
|
||||
private final IInterfaceHost iHost;
|
||||
@@ -125,12 +125,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
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 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<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance()
|
||||
.storage()
|
||||
.getStorageChannel( IFluidStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().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 boolean hasConfig = false;
|
||||
private int priority;
|
||||
@@ -141,7 +137,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
private final Accessor accessor = new Accessor();
|
||||
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
|
||||
private EnumMap<EnumFacing, List<ItemStack>> waitingToSendFacing = new EnumMap<>( EnumFacing.class );
|
||||
private GTCEInventoryAdaptor GTad;
|
||||
private boolean resetConfigCache = true;
|
||||
private IMEMonitor<IAEItemStack> configCachedHandler;
|
||||
|
||||
@@ -245,12 +240,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
NBTTagCompound sidedWaitList = new NBTTagCompound();
|
||||
|
||||
if (this.waitingToSendFacing != null)
|
||||
if( this.waitingToSendFacing != null )
|
||||
{
|
||||
for( EnumFacing s : this.iHost.getTargets() )
|
||||
{
|
||||
NBTTagList waitingListSided = new NBTTagList();
|
||||
if (this.waitingToSendFacing.containsKey( s ))
|
||||
if( this.waitingToSendFacing.containsKey( s ) )
|
||||
{
|
||||
for( final ItemStack is : this.waitingToSendFacing.get( s ) )
|
||||
{
|
||||
@@ -358,8 +353,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.waitingToSendFacing == null){
|
||||
this.waitingToSendFacing = new EnumMap<>(EnumFacing.class);
|
||||
if( this.waitingToSendFacing == null )
|
||||
{
|
||||
this.waitingToSendFacing = new EnumMap<>( EnumFacing.class );
|
||||
}
|
||||
|
||||
this.waitingToSendFacing.computeIfAbsent( f, k -> new ArrayList<>() );
|
||||
@@ -416,7 +412,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
// :P
|
||||
}
|
||||
}
|
||||
|
||||
this.notifyNeighbors();
|
||||
}
|
||||
|
||||
@@ -430,15 +425,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return;
|
||||
}
|
||||
|
||||
boolean removed = false;
|
||||
|
||||
if( this.craftingList != null )
|
||||
{
|
||||
final Iterator<ICraftingPatternDetails> i = this.craftingList.iterator();
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final ICraftingPatternDetails details = i.next();
|
||||
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 );
|
||||
if( details.getPattern() == is )
|
||||
@@ -449,41 +446,49 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
if( !found )
|
||||
{
|
||||
removed = true;
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( int x = 0; x < accountedFor.length ; x++ )
|
||||
boolean newPattern = false;
|
||||
|
||||
for( int x = 0; x < accountedFor.length; x++ )
|
||||
{
|
||||
if( !accountedFor[x] )
|
||||
{
|
||||
newPattern = true;
|
||||
this.addToCraftingList( this.patterns.getStackInSlot( x ) );
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
|
||||
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
catch( GridAccessException e )
|
||||
{
|
||||
// :P
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasWorkToDo() {
|
||||
private boolean hasWorkToDo()
|
||||
{
|
||||
|
||||
if (hasItemsToSend()){
|
||||
if( hasItemsToSend() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(hasItemsToSendFacing()){
|
||||
if( hasItemsToSendFacing() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (final IAEItemStack requiredWork : this.requireWork) {
|
||||
if (requiredWork != null) {
|
||||
for( final IAEItemStack requiredWork : this.requireWork )
|
||||
{
|
||||
if( requiredWork != null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -594,7 +599,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
private boolean hasItemsToSendFacing()
|
||||
{
|
||||
if (waitingToSendFacing != null)
|
||||
if( waitingToSendFacing != null )
|
||||
{
|
||||
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
|
||||
{
|
||||
@@ -614,10 +619,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
List<ItemStack> dropList = new ArrayList<>();
|
||||
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 );
|
||||
if( is.isEmpty() ) continue;
|
||||
if( is.isEmpty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dropList.add( patterns.extractItem( invSlot, Integer.MAX_VALUE, false ) );
|
||||
}
|
||||
}
|
||||
@@ -634,8 +642,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
@Override
|
||||
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 )
|
||||
{
|
||||
return true;
|
||||
@@ -709,7 +716,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
this.pushItemsOut( this.iHost.getTargets() );
|
||||
}
|
||||
|
||||
if (hasItemsToSendFacing())
|
||||
if( hasItemsToSendFacing() )
|
||||
{
|
||||
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
|
||||
{
|
||||
@@ -732,7 +739,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final World w = tile.getWorld();
|
||||
|
||||
final Iterator<ItemStack> i = this.waitingToSend.iterator();
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
ItemStack whatToSend = i.next();
|
||||
|
||||
@@ -779,8 +786,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -793,17 +800,18 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return;
|
||||
}
|
||||
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
|
||||
final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator();
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
ItemStack whatToSend = i.next();
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( ad != null )
|
||||
{
|
||||
final ItemStack result = ad.addItems( whatToSend );
|
||||
if( !result.isEmpty() )
|
||||
{
|
||||
whatToSend.setCount( whatToSend.getCount() - ( whatToSend.getCount() - result.getCount() ) );
|
||||
whatToSend.setCount( result.getCount() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -844,42 +852,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
this.destination = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
final IEnergySource src = this.gridProxy.getEnergy();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
IAEItemStack storedStack = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findPrecise( itemStack );
|
||||
if( storedStack != null )
|
||||
{
|
||||
if( storedStack.getStackSize() > 0 )
|
||||
{
|
||||
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 if( storedStack.isCraftable() )
|
||||
{
|
||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( itemStack.getStackSize() < 0 )
|
||||
if( itemStack.getStackSize() < 0 )
|
||||
{
|
||||
IAEItemStack toStore = itemStack.copy();
|
||||
toStore.setStackSize( -toStore.getStackSize() );
|
||||
@@ -917,6 +890,50 @@ 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();
|
||||
}
|
||||
else
|
||||
{
|
||||
itemStack.setCachedItemStack( inputStack );
|
||||
}
|
||||
|
||||
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() )
|
||||
{
|
||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||
}
|
||||
}
|
||||
}
|
||||
// else wtf?
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
@@ -944,17 +961,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null )
|
||||
{
|
||||
if (this.failedCraftTriesSlot[x] <= 0)
|
||||
{
|
||||
boolean crafted = this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
|
||||
this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
|
||||
|
||||
if (crafted) this.failedCraftTriesSlot[x] = 0;
|
||||
else{
|
||||
this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
return this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(), this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
@@ -1094,12 +1101,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
private boolean invIsBlocked( InventoryAdaptor inv )
|
||||
{
|
||||
return (inv.containsItems());
|
||||
return ( inv.containsItems() );
|
||||
}
|
||||
|
||||
private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv )
|
||||
private static boolean invIsCustomBlocking( BlockingInventoryAdaptor inv )
|
||||
{
|
||||
return ( !inv.canRemoveAllExceptCircuits() );
|
||||
return ( inv.containsBlockingItems() );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1156,24 +1163,26 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.isBlocking() )
|
||||
{
|
||||
IPhantomTile phantomTE = null;
|
||||
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
|
||||
IPhantomTile phantomTE;
|
||||
if( Loader.isModLoaded( "actuallyadditions" ) && te instanceof IPhantomTile )
|
||||
{
|
||||
phantomTE = ( (IPhantomTile) te );
|
||||
if( phantomTE.hasBoundPosition() )
|
||||
{
|
||||
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
||||
if( phantom instanceof MetaTileEntityHolder && isGTCEblocked( phantom, s ) )
|
||||
if( NonBlockingItems.INSTANCE.getMap().containsKey( phantom.getBlockType().getRegistryName().getResourceDomain() ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
if( isCustomInvBlocking( phantom, s ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
|
||||
else if( NonBlockingItems.INSTANCE.getMap().containsKey( te.getBlockType().getRegistryName().getResourceDomain() ) )
|
||||
{
|
||||
if( isGTCEblocked( te, s ) )
|
||||
if( isCustomInvBlocking( te, s ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
@@ -1228,28 +1237,31 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
for( final EnumFacing s : possibleDirections )
|
||||
{
|
||||
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
|
||||
IPhantomTile phantomTE = null;
|
||||
IPhantomTile phantomTE;
|
||||
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( ad != null )
|
||||
{
|
||||
if( Loader.isModLoaded( "actuallyadditions") && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
|
||||
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
|
||||
{
|
||||
phantomTE = ( (IPhantomTile) te );
|
||||
if( phantomTE.hasBoundPosition() )
|
||||
{
|
||||
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
||||
if( phantom instanceof MetaTileEntityHolder && !isGTCEblocked( phantom, s ) )
|
||||
if( NonBlockingItems.INSTANCE.getMap().containsKey( phantom.getBlockType().getRegistryName().getResourceDomain() ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
if( !isCustomInvBlocking( phantom, s ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
|
||||
else if( NonBlockingItems.INSTANCE.getMap().containsKey( te.getBlockType().getRegistryName().getResourceDomain() ) )
|
||||
{
|
||||
if( !isGTCEblocked( te, s ) )
|
||||
if( !isCustomInvBlocking( te, s ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
@@ -1268,10 +1280,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return busy;
|
||||
}
|
||||
|
||||
boolean isGTCEblocked(TileEntity te, EnumFacing s)
|
||||
boolean isCustomInvBlocking( TileEntity te, EnumFacing s )
|
||||
{
|
||||
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
return invIsBlockedGTCE( GTad );
|
||||
BlockingInventoryAdaptor blockingInventoryAdaptor = BlockingInventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
return invIsCustomBlocking( blockingInventoryAdaptor );
|
||||
}
|
||||
|
||||
private boolean sameGrid( final IGrid grid ) throws GridAccessException
|
||||
@@ -1294,7 +1306,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !ad.simulateAdd( is.copy() ).isEmpty() )
|
||||
if( !ad.simulateAdd( is ).isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1331,13 +1343,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1467,9 +1479,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final Block directedBlock = directedBlockState.getBlock();
|
||||
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 = getMetaTileEntity(hostWorld, targ);
|
||||
MetaTileEntity metaTileEntity = getMetaTileEntity( hostWorld, targ );
|
||||
return metaTileEntity.getMetaFullName();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.Future;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -83,57 +84,70 @@ 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 )
|
||||
{
|
||||
if( ais != null && d.simulateAdd( ais.createItemStack() ).isEmpty() )
|
||||
if( ais != null )
|
||||
{
|
||||
final Future<ICraftingJob> craftingJob = this.getJob( x );
|
||||
ItemStack inputStack = ais.getCachedItemStack( ais.getStackSize() );
|
||||
|
||||
if( this.getLink( x ) != null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if( craftingJob != null )
|
||||
{
|
||||
ItemStack remaining = d.simulateAdd( inputStack );
|
||||
|
||||
try
|
||||
if( remaining.isEmpty() )
|
||||
{
|
||||
ais.setCachedItemStack( inputStack );
|
||||
|
||||
final Future<ICraftingJob> craftingJob = this.getJob( x );
|
||||
|
||||
if( this.getLink( x ) != null )
|
||||
{
|
||||
ICraftingJob job = null;
|
||||
if( craftingJob.isDone() )
|
||||
return false;
|
||||
}
|
||||
else if( craftingJob != null )
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
job = craftingJob.get();
|
||||
}
|
||||
|
||||
if( job != null )
|
||||
{
|
||||
final ICraftingLink link = cg.submitJob( job, this.owner, null, false, mySrc );
|
||||
|
||||
this.setJob( x, null );
|
||||
|
||||
if( link != null )
|
||||
ICraftingJob job = null;
|
||||
if( craftingJob.isDone() )
|
||||
{
|
||||
this.setLink( x, link );
|
||||
job = craftingJob.get();
|
||||
}
|
||||
|
||||
return true;
|
||||
if( job != null )
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
catch( final InterruptedException e )
|
||||
else
|
||||
{
|
||||
// :P
|
||||
}
|
||||
catch( final ExecutionException e )
|
||||
{
|
||||
// :P
|
||||
if( this.getLink( x ) == null )
|
||||
{
|
||||
final IAEItemStack aisC = ais.copy();
|
||||
aisC.setStackSize( itemToCraft );
|
||||
|
||||
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( this.getLink( x ) == null )
|
||||
{
|
||||
final IAEItemStack aisC = ais.copy();
|
||||
aisC.setStackSize( itemToCraft );
|
||||
|
||||
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
|
||||
}
|
||||
ais.setCachedItemStack( remaining );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package appeng.helpers;
|
||||
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
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" ) )
|
||||
{
|
||||
for( MetaItem<?> metaItem : MetaItem.getMetaItems() )
|
||||
{
|
||||
MetaItem<?>.MetaValueItem metaItem2 = metaItem.getItem( ModItemMeta[1] );
|
||||
if( metaItem.getItem( ModItemMeta[1] ) != null )
|
||||
{
|
||||
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;
|
||||
} );
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.error( "Item not found on nonBlocking config: " + s );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -190,10 +190,11 @@ public class TickHandler
|
||||
synchronized ( this.craftingJobs )
|
||||
{
|
||||
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
|
||||
if (!jobSet.isEmpty()) {
|
||||
if( !jobSet.isEmpty() )
|
||||
{
|
||||
final int jobSize = jobSet.size();
|
||||
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 ) );
|
||||
}
|
||||
@@ -206,7 +207,7 @@ public class TickHandler
|
||||
this.tickColors( this.srvPlayerColors );
|
||||
// ready tiles.
|
||||
final HandlerRep repo = this.getRepo();
|
||||
while( !repo.tiles.isEmpty() )
|
||||
while ( !repo.tiles.isEmpty() )
|
||||
{
|
||||
final AEBaseTile bt = repo.tiles.poll();
|
||||
if( !bt.isInvalid() )
|
||||
@@ -238,7 +239,7 @@ public class TickHandler
|
||||
private void tickColors( final HashMap<Integer, PlayerColor> playerSet )
|
||||
{
|
||||
final Iterator<PlayerColor> i = playerSet.values().iterator();
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final PlayerColor pc = i.next();
|
||||
if( pc.ticksLeft <= 0 )
|
||||
@@ -259,7 +260,7 @@ public class TickHandler
|
||||
final Stopwatch sw = Stopwatch.createStarted();
|
||||
|
||||
IWorldCallable<?> c = null;
|
||||
while( ( c = queue.poll() ) != null )
|
||||
while ( ( c = queue.poll() ) != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -275,15 +276,11 @@ public class TickHandler
|
||||
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 )
|
||||
{
|
||||
synchronized( this.craftingJobs )
|
||||
synchronized ( this.craftingJobs )
|
||||
{
|
||||
this.craftingJobs.put( world, craftingJob );
|
||||
}
|
||||
|
||||
@@ -30,35 +30,37 @@ import appeng.integration.modules.waila.WailaModule;
|
||||
public enum IntegrationType
|
||||
{
|
||||
IC2( IntegrationSide.BOTH, "Industrial Craft 2", "ic2" )
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return Integrations.setIc2( new IC2Module() );
|
||||
}
|
||||
},
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return Integrations.setIc2( new IC2Module() );
|
||||
}
|
||||
},
|
||||
|
||||
GTCE( IntegrationSide.BOTH, "GregTech", "gregtech" ),
|
||||
|
||||
RC( IntegrationSide.BOTH, "Railcraft", "railcraft" ),
|
||||
|
||||
MFR( IntegrationSide.BOTH, "Mine Factory Reloaded", "minefactoryreloaded" ),
|
||||
|
||||
Waila( IntegrationSide.BOTH, "Waila", "waila" )
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return new WailaModule();
|
||||
}
|
||||
},
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return new WailaModule();
|
||||
}
|
||||
},
|
||||
|
||||
InvTweaks( IntegrationSide.CLIENT, "Inventory Tweaks", "inventorytweaks" )
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return Integrations.setInvTweaks( new InventoryTweaksModule() );
|
||||
}
|
||||
},
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return Integrations.setInvTweaks( new InventoryTweaksModule() );
|
||||
}
|
||||
},
|
||||
|
||||
JEI( IntegrationSide.CLIENT, "Just Enough Items", "jei" )
|
||||
{
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
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();
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
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 );
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import appeng.parts.misc.*;
|
||||
import appeng.parts.p2p.*;
|
||||
import appeng.parts.reporting.*;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
@@ -65,13 +66,6 @@ import appeng.parts.networking.PartCableSmart;
|
||||
import appeng.parts.networking.PartDenseCableCovered;
|
||||
import appeng.parts.networking.PartDenseCableSmart;
|
||||
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.util.Platform;
|
||||
|
||||
|
||||
@@ -80,96 +74,84 @@ public enum PartType
|
||||
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 )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
|
||||
CABLE_SMART( 40, "cable_smart", EnumSet.of( AEFeature.CHANNELS, AEFeature.SMART_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableSmart.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
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.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartDenseCableSmart.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
CABLE_DENSE_SMART( 60, "cable_dense_smart", EnumSet.of( AEFeature.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartDenseCableSmart.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
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.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartDenseCableCovered.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
CABLE_DENSE_COVERED( 500, "cable_dense_covered", EnumSet.of( AEFeature.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartDenseCableCovered.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
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 ),
|
||||
|
||||
@@ -275,25 +257,32 @@ public enum PartType
|
||||
@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 )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
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 )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
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(
|
||||
// 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 );
|
||||
|
||||
@@ -334,8 +323,7 @@ public enum PartType
|
||||
this.oreName = oreDict;
|
||||
|
||||
// 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 )
|
||||
{
|
||||
|
||||
@@ -19,12 +19,8 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.networking.IGrid;
|
||||
@@ -220,9 +216,7 @@ public class Grid implements IGrid
|
||||
@Override
|
||||
public MENetworkEvent postEvent( final MENetworkEvent ev )
|
||||
{
|
||||
CraftingGridCache.pauseRebuilds();
|
||||
final MENetworkEvent ret = this.eventBus.postEvent( this, ev );
|
||||
CraftingGridCache.unpauseRebuilds();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ import net.minecraftforge.common.util.Constants;
|
||||
public class GridNode implements IGridNode, IPathItem
|
||||
{
|
||||
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 IGridBlock gridProxy;
|
||||
@@ -166,8 +166,6 @@ public class GridNode implements IGridNode, IPathItem
|
||||
{
|
||||
final Object tracker = new Object();
|
||||
|
||||
CraftingGridCache.pauseRebuilds();
|
||||
|
||||
Deque<GridNode> nextRun = new ArrayDeque<>();
|
||||
nextRun.add( this );
|
||||
|
||||
@@ -178,9 +176,9 @@ public class GridNode implements IGridNode, IPathItem
|
||||
final Deque<IGridConnection> nextConn = new ArrayDeque<>();
|
||||
final IGridConnectionVisitor gcv = (IGridConnectionVisitor) g;
|
||||
|
||||
while( !nextRun.isEmpty() )
|
||||
while ( !nextRun.isEmpty() )
|
||||
{
|
||||
while( !nextConn.isEmpty() )
|
||||
while ( !nextConn.isEmpty() )
|
||||
{
|
||||
gcv.visitConnection( nextConn.poll() );
|
||||
}
|
||||
@@ -196,7 +194,7 @@ public class GridNode implements IGridNode, IPathItem
|
||||
}
|
||||
else
|
||||
{
|
||||
while( !nextRun.isEmpty() )
|
||||
while ( !nextRun.isEmpty() )
|
||||
{
|
||||
final Iterable<GridNode> thisRun = nextRun;
|
||||
nextRun = new ArrayDeque<>();
|
||||
@@ -207,7 +205,6 @@ public class GridNode implements IGridNode, IPathItem
|
||||
}
|
||||
}
|
||||
}
|
||||
CraftingGridCache.unpauseRebuilds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -269,7 +266,7 @@ public class GridNode implements IGridNode, IPathItem
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
while( !this.connections.isEmpty() )
|
||||
while ( !this.connections.isEmpty() )
|
||||
{
|
||||
// not part of this network for real anymore.
|
||||
if( this.connections.size() == 1 )
|
||||
@@ -378,7 +375,7 @@ public class GridNode implements IGridNode, IPathItem
|
||||
@Override
|
||||
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
|
||||
|
||||
+34
-63
@@ -113,9 +113,9 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
private final GenericInterestManager<CraftingWatcher> interestManager = new GenericInterestManager<>( this.interests );
|
||||
private IStorageGrid storageGrid;
|
||||
private IEnergyGrid energyGrid;
|
||||
int i;
|
||||
private boolean updateList = false;
|
||||
private static int pauseRebuilds = 0;
|
||||
private static Set<CraftingGridCache> rebuildNeeded = new HashSet<>();
|
||||
private boolean updatePatterns = false;
|
||||
|
||||
public CraftingGridCache( final IGrid grid )
|
||||
{
|
||||
@@ -140,8 +140,14 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
this.updateCPUClusters();
|
||||
}
|
||||
|
||||
if( updatePatterns )
|
||||
{
|
||||
this.recalculateCraftingPatterns();
|
||||
this.updatePatterns = false;
|
||||
}
|
||||
|
||||
final Iterator<CraftingLinkNexus> craftingLinkIterator = this.craftingLinks.values().iterator();
|
||||
while( craftingLinkIterator.hasNext() )
|
||||
while ( craftingLinkIterator.hasNext() )
|
||||
{
|
||||
if( craftingLinkIterator.next().isDead( this.grid, this ) )
|
||||
{
|
||||
@@ -187,7 +193,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
if( machine instanceof ICraftingProvider )
|
||||
{
|
||||
this.craftingProviders.remove( machine );
|
||||
this.updatePatterns();
|
||||
this.updatePatterns = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +227,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
if( machine instanceof ICraftingProvider )
|
||||
{
|
||||
this.craftingProviders.add( (ICraftingProvider) machine );
|
||||
this.updatePatterns();
|
||||
this.updatePatterns = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,36 +248,15 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
// nothing!
|
||||
}
|
||||
|
||||
public static void pauseRebuilds()
|
||||
{
|
||||
pauseRebuilds++;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
this.updatePatterns = true;
|
||||
}
|
||||
|
||||
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>(this.craftableItems);
|
||||
final Set<IAEItemStack> oldEmitableItems = new HashSet<>(this.emitableItems);
|
||||
private void recalculateCraftingPatterns()
|
||||
{
|
||||
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>( this.craftableItems );
|
||||
final Set<IAEItemStack> oldEmitableItems = new HashSet<>( this.emitableItems );
|
||||
|
||||
// erase list.
|
||||
this.craftingMethods.clear();
|
||||
@@ -312,25 +297,29 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
|
||||
}
|
||||
|
||||
Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftablesChanged = new Object2ObjectArrayMap<>();
|
||||
List<IAEItemStack> craftablesChanged = new ArrayList<>();
|
||||
|
||||
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet();
|
||||
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i) {
|
||||
if (!this.craftableItems.containsKey( ais.getKey() )) {
|
||||
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i )
|
||||
{
|
||||
if( !this.craftableItems.containsKey( ais.getKey() ) )
|
||||
{
|
||||
IAEItemStack changedStack = ais.getKey().copy();
|
||||
changedStack.reset();
|
||||
changedStack.setCraftable( false );
|
||||
craftablesChanged.put( changedStack, ais.getValue() );
|
||||
craftablesChanged.add( changedStack );
|
||||
}
|
||||
}
|
||||
|
||||
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
|
||||
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j) {
|
||||
if (!oldItems.containsKey( ais )){
|
||||
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j )
|
||||
{
|
||||
if( !oldItems.containsKey( ais ) )
|
||||
{
|
||||
IAEItemStack changedStack = ais.getKey().copy();
|
||||
changedStack.reset();
|
||||
changedStack.setCraftable( true );
|
||||
craftablesChanged.put( changedStack, ais.getValue() );
|
||||
craftablesChanged.add( changedStack );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +330,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
IAEItemStack changedStack = st.copy();
|
||||
changedStack.reset();
|
||||
changedStack.setCraftable( false );
|
||||
craftablesChanged.put( changedStack, null );
|
||||
craftablesChanged.add( changedStack );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,12 +341,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
IAEItemStack changedStack = st.copy();
|
||||
changedStack.reset();
|
||||
changedStack.setCraftable( true );
|
||||
craftablesChanged.put( changedStack, null );
|
||||
craftablesChanged.add( changedStack );
|
||||
}
|
||||
}
|
||||
|
||||
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged.keySet(),
|
||||
new BaseActionSource() );
|
||||
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged, new BaseActionSource() );
|
||||
}
|
||||
|
||||
private void updateCPUClusters()
|
||||
@@ -535,22 +523,6 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -596,8 +568,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort( validCpusClusters, ( firstCluster, nextCluster ) ->
|
||||
{
|
||||
Collections.sort( validCpusClusters, ( firstCluster, nextCluster ) -> {
|
||||
if( prioritizePower )
|
||||
{
|
||||
final int comparison1 = Long.compare( nextCluster.getCoProcessors(), firstCluster.getCoProcessors() );
|
||||
@@ -676,7 +647,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
|
||||
public boolean hasCpu( final ICraftingCPU cpu )
|
||||
{
|
||||
if (cpu instanceof CraftingCPUCluster)
|
||||
if( cpu instanceof CraftingCPUCluster )
|
||||
{
|
||||
return this.craftingCPUClusters.contains( (CraftingCPUCluster) cpu );
|
||||
}
|
||||
@@ -710,7 +681,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
|
||||
private void findNext()
|
||||
{
|
||||
while( this.iterator.hasNext() && this.cpuCluster == null )
|
||||
while ( this.iterator.hasNext() && this.cpuCluster == null )
|
||||
{
|
||||
this.cpuCluster = this.iterator.next();
|
||||
if( !this.cpuCluster.isActive() || this.cpuCluster.isDestroyed() )
|
||||
|
||||
+43
-11
@@ -19,13 +19,12 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
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 java.util.*;
|
||||
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.crafting.MECraftingInventory;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
@@ -55,6 +54,8 @@ import appeng.me.helpers.GenericInterestManager;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import appeng.me.storage.ItemWatcher;
|
||||
import appeng.me.storage.NetworkInventoryHandler;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
|
||||
public class GridStorageCache implements IStorageGrid
|
||||
@@ -66,8 +67,11 @@ public class GridStorageCache implements IStorageGrid
|
||||
private final SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
|
||||
private final GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<>( this.interests );
|
||||
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>();
|
||||
private Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
||||
private Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
||||
private MECraftingInventory localCache = null;
|
||||
private final Int2ObjectMap<MECraftingInventory> extractableItemPriorityMap = new Int2ObjectOpenHashMap<>();
|
||||
private int localDepth;
|
||||
|
||||
public GridStorageCache( final IGrid g )
|
||||
{
|
||||
@@ -81,6 +85,8 @@ public class GridStorageCache implements IStorageGrid
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
this.localCache = null;
|
||||
this.extractableItemPriorityMap.clear();
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.onTick() );
|
||||
}
|
||||
|
||||
@@ -168,6 +174,28 @@ public class GridStorageCache implements IStorageGrid
|
||||
return (IMEMonitor<T>) this.storageMonitors.get( channel );
|
||||
}
|
||||
|
||||
public MECraftingInventory getExtractableList( IActionSource src )
|
||||
{
|
||||
if( src instanceof MachineSource )
|
||||
{
|
||||
if( src.machine().isPresent() )
|
||||
{
|
||||
IActionHost machine = src.machine().get();
|
||||
if( machine instanceof IInterfaceHost )
|
||||
{
|
||||
extractableItemPriorityMap.putIfAbsent( ( (IPriorityHost) machine ).getPriority(), new MECraftingInventory( getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), src, false, false, false ) );
|
||||
return extractableItemPriorityMap.get( ( (IPriorityHost) machine ).getPriority() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
if( this.inactiveCellProviders.contains( cc ) )
|
||||
@@ -197,8 +225,7 @@ public class GridStorageCache implements IStorageGrid
|
||||
|
||||
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 ) )
|
||||
{
|
||||
tracker.postChanges( channel, -1, h, actionSrc );
|
||||
@@ -212,6 +239,11 @@ public class GridStorageCache implements IStorageGrid
|
||||
@MENetworkEventSubscribe
|
||||
public void cellUpdate( final MENetworkCellArrayUpdate ev )
|
||||
{
|
||||
if( localDepth > 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
localDepth++;
|
||||
this.storageNetworks.clear();
|
||||
|
||||
final List<ICellProvider> ll = new ArrayList<ICellProvider>();
|
||||
@@ -247,7 +279,7 @@ public class GridStorageCache implements IStorageGrid
|
||||
}
|
||||
}
|
||||
tracker.applyChanges();
|
||||
|
||||
localDepth--;
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.setForceUpdate( true ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -239,7 +239,8 @@ 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
|
||||
// items during storeItems
|
||||
if (input == null || isComplete) {
|
||||
if( input == null || isComplete )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -375,7 +376,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
{
|
||||
final ImmutableList<IAEItemStack> single = ImmutableList.of( diff.copy() );
|
||||
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> o = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEItemStack> receiver = o.getKey();
|
||||
@@ -495,15 +496,14 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean canCraft(final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs)
|
||||
private boolean canCraft( final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs )
|
||||
{
|
||||
if( !details.isCraftable() )
|
||||
{
|
||||
// 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() )
|
||||
{
|
||||
@@ -516,7 +516,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
// When substitutions are allowed, we have to keep track of which items we've reserved
|
||||
IAEItemStack[] inputs = details.getInputs();
|
||||
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 );
|
||||
if( substitutes.isEmpty() )
|
||||
@@ -525,9 +525,9 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
}
|
||||
|
||||
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 );
|
||||
if( fuzz.getStackSize() - alreadyConsumed <= 0 )
|
||||
@@ -537,8 +537,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
|
||||
fuzz = fuzz.copy();
|
||||
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 )
|
||||
{
|
||||
@@ -565,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
|
||||
// each type of item should only occur once
|
||||
for ( IAEItemStack g : condensedInputs )
|
||||
for( IAEItemStack g : condensedInputs )
|
||||
{
|
||||
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.setStackSize( g.getStackSize() );
|
||||
@@ -675,8 +674,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
{
|
||||
this.somethingChanged = false;
|
||||
this.executeCrafting( eg, cc );
|
||||
}
|
||||
while( this.somethingChanged && this.remainingOperations > 0 );
|
||||
} while ( this.somethingChanged && this.remainingOperations > 0 );
|
||||
}
|
||||
this.usedOps[2] = this.usedOps[1];
|
||||
this.usedOps[1] = this.usedOps[0];
|
||||
@@ -692,7 +690,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
{
|
||||
final Iterator<Entry<ICraftingPatternDetails, TaskProgress>> i = this.tasks.entrySet().iterator();
|
||||
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final Entry<ICraftingPatternDetails, TaskProgress> e = i.next();
|
||||
|
||||
@@ -708,12 +706,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
{
|
||||
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();
|
||||
@@ -773,52 +771,58 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
{
|
||||
itemList.addAll( this.inventory.getItemList().findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
|
||||
}
|
||||
} else {
|
||||
itemList = new ArrayList<>(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
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) {
|
||||
itemList.add(item);
|
||||
if( item != null )
|
||||
{
|
||||
itemList.add( item );
|
||||
}
|
||||
}
|
||||
|
||||
for (IAEItemStack fuzz : itemList) {
|
||||
for( IAEItemStack fuzz : itemList )
|
||||
{
|
||||
fuzz = fuzz.copy();
|
||||
fuzz.setStackSize(input[x].getStackSize());
|
||||
fuzz.setStackSize( input[x].getStackSize() );
|
||||
|
||||
if (details.isValidItemForSlot(x, fuzz.createItemStack(),
|
||||
this.getWorld())) {
|
||||
final IAEItemStack ais = this.inventory.extractItems(fuzz,
|
||||
Actionable.MODULATE, this.machineSrc);
|
||||
final ItemStack is = ais == null ? ItemStack.EMPTY
|
||||
: ais.createItemStack();
|
||||
if( details.isValidItemForSlot( x, fuzz.createItemStack(), this.getWorld() ) )
|
||||
{
|
||||
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.MODULATE, this.machineSrc );
|
||||
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
|
||||
|
||||
if (!is.isEmpty()) {
|
||||
this.postChange(AEItemStack.fromItemStack(is), this.machineSrc);
|
||||
ic.setInventorySlotContents(x, is);
|
||||
if( !is.isEmpty() )
|
||||
{
|
||||
this.postChange( AEItemStack.fromItemStack( is ), this.machineSrc );
|
||||
ic.setInventorySlotContents( x, is );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final IAEItemStack ais = this.inventory.extractItems(input[x].copy(),
|
||||
Actionable.MODULATE, this.machineSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
final IAEItemStack ais = this.inventory.extractItems( input[x].copy(), Actionable.MODULATE, this.machineSrc );
|
||||
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
|
||||
|
||||
if (!is.isEmpty()) {
|
||||
this.postChange(input[x], this.machineSrc);
|
||||
ic.setInventorySlotContents(x, is);
|
||||
if (is.getCount() == input[x].getStackSize()) {
|
||||
if( !is.isEmpty() )
|
||||
{
|
||||
this.postChange( input[x], this.machineSrc );
|
||||
ic.setInventorySlotContents( x, is );
|
||||
if( is.getCount() == input[x].getStackSize() )
|
||||
{
|
||||
found = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if( !found )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -902,7 +906,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
|
||||
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();
|
||||
|
||||
if( g == null )
|
||||
@@ -1016,8 +1020,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
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() )
|
||||
{
|
||||
@@ -1075,8 +1078,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
final int hash = System.identityHashCode( this );
|
||||
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 )
|
||||
@@ -1103,7 +1105,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
|
||||
public void getListOfItem( final IItemList<IAEItemStack> list, final CraftingItemList whichList )
|
||||
{
|
||||
switch( whichList )
|
||||
switch ( whichList )
|
||||
{
|
||||
case ACTIVE:
|
||||
for( final IAEItemStack ais : this.waitingFor )
|
||||
@@ -1174,7 +1176,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
||||
{
|
||||
IAEItemStack is;
|
||||
|
||||
switch( storage2 )
|
||||
switch ( storage2 )
|
||||
{
|
||||
case STORAGE:
|
||||
is = this.inventory.getItemList().findPrecise( what );
|
||||
|
||||
@@ -22,6 +22,7 @@ package appeng.parts.automation;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -70,8 +71,6 @@ import appeng.util.item.AEItemStack;
|
||||
|
||||
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" );
|
||||
|
||||
@PartModels
|
||||
@@ -131,10 +130,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
try
|
||||
{
|
||||
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 ICraftingGrid cg = this.getProxy().getCrafting();
|
||||
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
|
||||
@@ -150,21 +146,17 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
|
||||
final IAEItemStack ais = this.getConfig().getAEStackInSlot( slotToExport );
|
||||
|
||||
if( ais == null || this.itemToSend <= 0 ) continue;
|
||||
|
||||
if ( this.craftOnly() ) {
|
||||
if (this.failedCraftTriesSlot[x] <= 0) {
|
||||
|
||||
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
|
||||
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
|
||||
|
||||
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
|
||||
else this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
if( ais == null || this.itemToSend <= 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( this.craftOnly() )
|
||||
{
|
||||
this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething;
|
||||
|
||||
}
|
||||
|
||||
final long before = this.itemToSend;
|
||||
|
||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||
@@ -188,15 +180,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
|
||||
if( this.itemToSend == before && this.isCraftingEnabled() )
|
||||
{
|
||||
if (this.failedCraftTriesSlot[x] <= 0) {
|
||||
|
||||
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
|
||||
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
|
||||
|
||||
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
|
||||
else this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,11 +262,30 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
|
||||
if( energy.extractAEPower( power, mode, PowerMultiplier.CONFIG ) > power - 0.01 )
|
||||
{
|
||||
if( mode == Actionable.MODULATE )
|
||||
ItemStack inputStack = items.getCachedItemStack( items.getStackSize() );
|
||||
|
||||
ItemStack remaining;
|
||||
|
||||
if( mode == Actionable.SIMULATE )
|
||||
{
|
||||
return AEItemStack.fromItemStack( d.addItems( items.createItemStack() ) );
|
||||
remaining = d.simulateAdd( inputStack );
|
||||
items.setCachedItemStack( inputStack );
|
||||
}
|
||||
return AEItemStack.fromItemStack( d.simulateAdd( items.createItemStack() ) );
|
||||
else
|
||||
{
|
||||
remaining = d.addItems( inputStack );
|
||||
if( !remaining.isEmpty() )
|
||||
{
|
||||
items.setCachedItemStack( remaining );
|
||||
}
|
||||
}
|
||||
|
||||
if( remaining == inputStack )
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
return AEItemStack.fromItemStack( remaining );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,11 +321,21 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
|
||||
private void pushItemIntoTarget( final InventoryAdaptor d, final IEnergyGrid energy, final IMEInventory<IAEItemStack> inv, IAEItemStack ais )
|
||||
{
|
||||
final ItemStack is = ais.createItemStack();
|
||||
is.setCount( (int) this.itemToSend );
|
||||
ItemStack inputStack = ais.getCachedItemStack( ais.getStackSize() );
|
||||
|
||||
final ItemStack o = d.simulateAdd( is );
|
||||
final long canFit = o.isEmpty() ? this.itemToSend : this.itemToSend - o.getCount();
|
||||
ItemStack remaining = d.simulateAdd( inputStack );
|
||||
|
||||
// Store the stack in the cache for next time.
|
||||
if( !remaining.isEmpty() )
|
||||
{
|
||||
ais.setCachedItemStack( remaining );
|
||||
if( remaining == inputStack )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final long canFit = remaining.isEmpty() ? this.itemToSend : this.itemToSend - remaining.getCount();
|
||||
|
||||
if( canFit > 0 )
|
||||
{
|
||||
@@ -334,7 +347,9 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
{
|
||||
this.itemToSend -= itemsToAdd.getStackSize();
|
||||
|
||||
final ItemStack failed = d.addItems( itemsToAdd.createItemStack() );
|
||||
inputStack.setCount( Ints.saturatedCast( itemsToAdd.getStackSize() ) );
|
||||
|
||||
final ItemStack failed = d.addItems( inputStack );
|
||||
if( !failed.isEmpty() )
|
||||
{
|
||||
ais.setStackSize( failed.getCount() );
|
||||
|
||||
@@ -62,8 +62,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
private StorageFilter mode;
|
||||
private AccessRestriction access;
|
||||
|
||||
private ItemStack stackCache = null;
|
||||
|
||||
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
|
||||
{
|
||||
this.itemHandler = itemHandler;
|
||||
@@ -82,39 +80,31 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
|
||||
{
|
||||
// Try to reuse the cached stack
|
||||
@Nullable ItemStack currentCached = stackCache;
|
||||
stackCache = null;
|
||||
ItemStack inputStack = iox.getCachedItemStack( iox.getStackSize() );
|
||||
|
||||
ItemStack remaining = inputStack;
|
||||
|
||||
ItemStack orgInput;
|
||||
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++ )
|
||||
{
|
||||
remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE );
|
||||
}
|
||||
|
||||
// Store the stack in the cache for next time.
|
||||
if( !remaining.isEmpty() && remaining != orgInput )
|
||||
if( type == Actionable.SIMULATE )
|
||||
{
|
||||
stackCache = remaining;
|
||||
iox.setCachedItemStack( inputStack );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !remaining.isEmpty() )
|
||||
{
|
||||
iox.setCachedItemStack( remaining );
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, we still have some items left...
|
||||
if( remaining == orgInput )
|
||||
if( remaining == inputStack )
|
||||
{
|
||||
// The stack remained unmodified, target inventory is full
|
||||
return iox;
|
||||
@@ -147,7 +137,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
ItemStack gathered = ItemStack.EMPTY;
|
||||
|
||||
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 );
|
||||
|
||||
@@ -172,8 +162,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
{
|
||||
// Something broke. It should never return more than we requested...
|
||||
// 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.", this.itemHandler.getClass().getName(), extracted.toString(), remainingCurrentSlot );
|
||||
extracted.setCount( remainingCurrentSlot );
|
||||
}
|
||||
|
||||
@@ -329,17 +318,17 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
currentlyOnStorage.add( is.getAEItemStack() );
|
||||
}
|
||||
|
||||
for ( final IAEItemStack is : currentlyCached )
|
||||
for( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
|
||||
for ( final IAEItemStack is : currentlyOnStorage )
|
||||
for( final IAEItemStack is : currentlyOnStorage )
|
||||
{
|
||||
currentlyCached.add( is );
|
||||
}
|
||||
|
||||
for ( final IAEItemStack is : currentlyCached )
|
||||
for( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
|
||||
@@ -35,232 +35,225 @@ import java.util.*;
|
||||
|
||||
class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
|
||||
{
|
||||
private final Object2ObjectMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new Object2ObjectOpenHashMap<>();
|
||||
private IActionSource mySource;
|
||||
private final IItemRepository itemRepository;
|
||||
private final IGridProxyable proxyable;
|
||||
private final InventoryCache cache;
|
||||
private AccessRestriction access;
|
||||
private final Object2ObjectMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new Object2ObjectOpenHashMap<>();
|
||||
private IActionSource mySource;
|
||||
private final IItemRepository itemRepository;
|
||||
private final IGridProxyable proxyable;
|
||||
private final InventoryCache cache;
|
||||
private AccessRestriction access;
|
||||
|
||||
private ItemStack stackCache;
|
||||
ItemRepositoryAdapter( IItemRepository itemRepository, IGridProxyable proxy )
|
||||
{
|
||||
this.itemRepository = itemRepository;
|
||||
this.proxyable = proxy;
|
||||
this.cache = new InventoryCache( this.itemRepository );
|
||||
if( this.proxyable instanceof PartStorageBus )
|
||||
{
|
||||
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
||||
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||
}
|
||||
this.cache.update();
|
||||
}
|
||||
|
||||
ItemRepositoryAdapter( IItemRepository itemRepository, IGridProxyable proxy )
|
||||
{
|
||||
this.itemRepository = itemRepository;
|
||||
this.proxyable = proxy;
|
||||
this.cache = new InventoryCache( this.itemRepository );
|
||||
if( this.proxyable instanceof PartStorageBus )
|
||||
{
|
||||
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
||||
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||
}
|
||||
this.cache.update();
|
||||
}
|
||||
@Override
|
||||
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
|
||||
{
|
||||
// Try to reuse the cached stack
|
||||
ItemStack inputStack = iox.getCachedItemStack( iox.getStackSize() );
|
||||
|
||||
@Override
|
||||
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
|
||||
{
|
||||
// Try to reuse the cached stack
|
||||
@Nullable ItemStack currentCached = stackCache;
|
||||
stackCache = null;
|
||||
ItemStack remaining;
|
||||
|
||||
ItemStack orgInput;
|
||||
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 = this.itemRepository.insertItem( orgInput, type == Actionable.SIMULATE );
|
||||
remaining = this.itemRepository.insertItem( inputStack, type == Actionable.SIMULATE );
|
||||
|
||||
// Store the stack in the cache for next time.
|
||||
if( !remaining.isEmpty() && remaining != orgInput )
|
||||
{
|
||||
stackCache = remaining;
|
||||
}
|
||||
// Store the stack in the cache for next time.
|
||||
if( type == Actionable.SIMULATE )
|
||||
{
|
||||
iox.setCachedItemStack( inputStack );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !remaining.isEmpty() )
|
||||
{
|
||||
iox.setCachedItemStack( remaining );
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, we still have some items left...
|
||||
if( remaining == orgInput )
|
||||
{
|
||||
// The stack remained unmodified, target inventory is full
|
||||
return iox;
|
||||
}
|
||||
// At this point, we still have some items left...
|
||||
if( remaining == inputStack )
|
||||
{
|
||||
// The stack remained unmodified, target inventory is full
|
||||
return iox;
|
||||
}
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
|
||||
this.cache.currentlyCached.add( added );
|
||||
this.postDifference( Collections.singletonList( added ) );
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
|
||||
this.cache.currentlyCached.add( added );
|
||||
this.postDifference( Collections.singletonList( added ) );
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
|
||||
return AEItemStack.fromItemStack( remaining );
|
||||
return AEItemStack.fromItemStack( remaining );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
||||
{
|
||||
int remainingSize = Ints.saturatedCast( request.getStackSize() );
|
||||
@Override
|
||||
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
||||
{
|
||||
int remainingSize = Ints.saturatedCast( request.getStackSize() );
|
||||
|
||||
final boolean simulate = ( mode == Actionable.SIMULATE );
|
||||
final boolean simulate = ( mode == Actionable.SIMULATE );
|
||||
|
||||
ItemStack extracted = this.itemRepository.extractItem( request.getDefinition(), remainingSize, simulate );
|
||||
ItemStack extracted = this.itemRepository.extractItem( request.getDefinition(), remainingSize, simulate );
|
||||
|
||||
if( extracted.getCount() > remainingSize )
|
||||
{
|
||||
// Something broke. It should never return more than we requested...
|
||||
// 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.itemRepository.getClass().getName(), extracted.toString(), remainingSize );
|
||||
extracted.setCount( remainingSize );
|
||||
}
|
||||
if( extracted.getCount() > remainingSize )
|
||||
{
|
||||
// Something broke. It should never return more than we requested...
|
||||
// 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.itemRepository.getClass().getName(), extracted.toString(), remainingSize );
|
||||
extracted.setCount( remainingSize );
|
||||
}
|
||||
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
IAEItemStack extractedAEItemStack = AEItemStack.fromItemStack( extracted );
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
|
||||
if (cachedStack != null)
|
||||
{
|
||||
cachedStack.decStackSize( extractedAEItemStack.getStackSize() );
|
||||
this.postDifference( Collections.singletonList( extractedAEItemStack.copy().setStackSize( -extractedAEItemStack.getStackSize() ) ) );
|
||||
}
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
return extractedAEItemStack;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
IAEItemStack extractedAEItemStack = AEItemStack.fromItemStack( extracted );
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
|
||||
if( cachedStack != null )
|
||||
{
|
||||
cachedStack.decStackSize( extractedAEItemStack.getStackSize() );
|
||||
this.postDifference( Collections.singletonList( extractedAEItemStack.copy().setStackSize( -extractedAEItemStack.getStackSize() ) ) );
|
||||
}
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
return extractedAEItemStack;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
||||
{
|
||||
return this.cache.getAvailableItems( out );
|
||||
}
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
||||
{
|
||||
return this.cache.getAvailableItems( out );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<IAEItemStack> getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel<IAEItemStack> getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken )
|
||||
{
|
||||
this.listeners.put( l, verificationToken );
|
||||
}
|
||||
@Override
|
||||
public void addListener( IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken )
|
||||
{
|
||||
this.listeners.put( l, verificationToken );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( IMEMonitorHandlerReceiver<IAEItemStack> l )
|
||||
{
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
@Override
|
||||
public void removeListener( IMEMonitorHandlerReceiver<IAEItemStack> l )
|
||||
{
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
|
||||
private void postDifference( Iterable<IAEItemStack> a )
|
||||
{
|
||||
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||
if( key.isValid( l.getValue() ) )
|
||||
{
|
||||
key.postChange( this, a, this.mySource );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
private void postDifference( Iterable<IAEItemStack> a )
|
||||
{
|
||||
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||
if( key.isValid( l.getValue() ) )
|
||||
{
|
||||
key.postChange( this, a, this.mySource );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
List<IAEItemStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
return TickRateModulation.URGENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TickRateModulation.SLOWER;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
List<IAEItemStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
return TickRateModulation.URGENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TickRateModulation.SLOWER;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionSource( final IActionSource mySource )
|
||||
{
|
||||
this.mySource = mySource;
|
||||
}
|
||||
@Override
|
||||
public void setActionSource( final IActionSource mySource )
|
||||
{
|
||||
this.mySource = mySource;
|
||||
}
|
||||
|
||||
private static class InventoryCache
|
||||
{
|
||||
private IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final IItemRepository iItemRepository;
|
||||
private static class InventoryCache
|
||||
{
|
||||
private IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final IItemRepository iItemRepository;
|
||||
|
||||
public InventoryCache( IItemRepository iItemRepository )
|
||||
{
|
||||
this.iItemRepository = iItemRepository;
|
||||
}
|
||||
public InventoryCache( IItemRepository iItemRepository )
|
||||
{
|
||||
this.iItemRepository = iItemRepository;
|
||||
}
|
||||
|
||||
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
||||
{
|
||||
currentlyCached.iterator().forEachRemaining( out::add );
|
||||
return out;
|
||||
}
|
||||
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
||||
{
|
||||
currentlyCached.iterator().forEachRemaining( out::add );
|
||||
return out;
|
||||
}
|
||||
|
||||
public List<IAEItemStack> update()
|
||||
{
|
||||
final List<IAEItemStack> changes = new ArrayList<>();
|
||||
public List<IAEItemStack> update()
|
||||
{
|
||||
final List<IAEItemStack> changes = new ArrayList<>();
|
||||
|
||||
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
this.iItemRepository.getAllItems().stream().map( s -> AEItemStack.fromItemStack( s.itemPrototype ).setStackSize( s.count ) ).forEach( currentlyOnStorage::add );
|
||||
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
this.iItemRepository.getAllItems().stream().map( s -> AEItemStack.fromItemStack( s.itemPrototype ).setStackSize( s.count ) ).forEach( currentlyOnStorage::add );
|
||||
|
||||
for ( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
for( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
|
||||
for ( final IAEItemStack is : currentlyOnStorage )
|
||||
{
|
||||
currentlyCached.add( is );
|
||||
}
|
||||
for( final IAEItemStack is : currentlyOnStorage )
|
||||
{
|
||||
currentlyCached.add( is );
|
||||
}
|
||||
|
||||
for ( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
changes.add( is );
|
||||
}
|
||||
}
|
||||
for( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
changes.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
currentlyCached = currentlyOnStorage;
|
||||
currentlyCached = currentlyOnStorage;
|
||||
|
||||
return changes;
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import appeng.parts.PartModel;
|
||||
import appeng.util.ConfigManager;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.OreHelper;
|
||||
import appeng.util.prioritylist.IPartitionList;
|
||||
import appeng.util.prioritylist.OreDictPriorityList;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -40,8 +41,7 @@ public class PartOreDicStorageBus extends PartStorageBus
|
||||
@PartModels
|
||||
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_has_channel" ) );
|
||||
|
||||
|
||||
public String oreMatch;
|
||||
public String oreExp = "";
|
||||
OreDictPriorityList<IAEItemStack> priorityList;
|
||||
|
||||
public PartOreDicStorageBus( ItemStack is )
|
||||
@@ -53,15 +53,15 @@ public class PartOreDicStorageBus extends PartStorageBus
|
||||
public void readFromNBT( NBTTagCompound data )
|
||||
{
|
||||
super.readFromNBT( data );
|
||||
this.oreMatch = data.getString( "oreMatch" );
|
||||
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreMatch ), oreMatch );
|
||||
this.oreExp = data.getString( "oreMatch" );
|
||||
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT( NBTTagCompound data )
|
||||
{
|
||||
super.writeToNBT( data );
|
||||
data.setString( "oreMatch", getOreMatch() );
|
||||
data.setString( "oreMatch", getOreExp() );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,7 +126,7 @@ public class PartOreDicStorageBus extends PartStorageBus
|
||||
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
|
||||
this.handler.setPriority( this.priority );
|
||||
|
||||
this.handler.setPartitionList( priorityList );
|
||||
this.handler.setPartitionList( this.getPriorityList() );
|
||||
|
||||
if( inv instanceof IBaseMonitor )
|
||||
{
|
||||
@@ -172,21 +172,31 @@ public class PartOreDicStorageBus extends PartStorageBus
|
||||
return this.handler;
|
||||
}
|
||||
|
||||
public String getOreMatch()
|
||||
private IPartitionList<IAEItemStack> getPriorityList()
|
||||
{
|
||||
if( this.oreMatch == null )
|
||||
if( priorityList == null )
|
||||
{
|
||||
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp );
|
||||
}
|
||||
return priorityList;
|
||||
}
|
||||
|
||||
public String getOreExp()
|
||||
{
|
||||
if( this.oreExp == null )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return oreMatch;
|
||||
return oreExp;
|
||||
}
|
||||
|
||||
public void saveOreMatch( String oreMatch )
|
||||
{
|
||||
if( !this.oreMatch.equals( oreMatch ) )
|
||||
if( !this.oreExp.equals( oreMatch ) )
|
||||
{
|
||||
this.oreMatch = oreMatch;
|
||||
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreMatch ), oreMatch );
|
||||
this.oreExp = oreMatch;
|
||||
|
||||
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp );
|
||||
if( this.handler != null )
|
||||
{
|
||||
handler.setPartitionList( this.priorityList );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,308 @@
|
||||
package appeng.parts.p2p;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import appeng.api.parts.IPartModel;
|
||||
import appeng.items.parts.PartModels;
|
||||
import appeng.me.GridAccessException;
|
||||
import gregtech.api.capability.GregtechCapabilities;
|
||||
import gregtech.api.capability.IEnergyContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fml.common.Optional;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
|
||||
public class PartP2PGTCEPower extends PartP2PTunnel<PartP2PGTCEPower>
|
||||
{
|
||||
private static final P2PModels MODELS = new P2PModels( "part/p2p/p2p_tunnel_gteu" );
|
||||
private static final IEnergyContainer NULL_ENERGY_STORAGE = new NullEnergyStorage();
|
||||
private final IEnergyContainer inputHandler = new InputEnergyStorage();
|
||||
private final IEnergyContainer outputHandler = new OutputEnergyStorage();
|
||||
private final Queue<PartP2PGTCEPower> outputs = new ArrayDeque<>();
|
||||
|
||||
public PartP2PGTCEPower( ItemStack is )
|
||||
{
|
||||
super( is );
|
||||
}
|
||||
|
||||
@PartModels
|
||||
public static List<IPartModel> getModels()
|
||||
{
|
||||
return MODELS.getModels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPartModel getStaticModels()
|
||||
{
|
||||
return MODELS.getModel( this.isPowered(), this.isActive() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTunnelNetworkChange()
|
||||
{
|
||||
this.getHost().notifyNeighbors();
|
||||
}
|
||||
|
||||
private IEnergyContainer getAttachedEnergyStorage()
|
||||
{
|
||||
if( this.isActive() )
|
||||
{
|
||||
final TileEntity self = this.getTile();
|
||||
final TileEntity te = self.getWorld().getTileEntity( self.getPos().offset( this.getSide().getFacing() ) );
|
||||
|
||||
if( te != null && te.hasCapability( GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, this.getSide().getOpposite().getFacing() ) )
|
||||
{
|
||||
return te.getCapability( GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, this.getSide().getOpposite().getFacing() );
|
||||
}
|
||||
}
|
||||
return NULL_ENERGY_STORAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCapability( @Nonnull Capability<?> capability )
|
||||
{
|
||||
if( capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return super.hasCapability( capability );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getCapability( @Nonnull Capability<T> capability )
|
||||
{
|
||||
if( capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER )
|
||||
{
|
||||
if( this.isOutput() )
|
||||
{
|
||||
return (T) this.outputHandler;
|
||||
}
|
||||
return (T) this.inputHandler;
|
||||
}
|
||||
return super.getCapability( capability );
|
||||
}
|
||||
|
||||
class InputEnergyStorage implements IEnergyContainer
|
||||
{
|
||||
@Override
|
||||
public long getEnergyCanBeInserted()
|
||||
{
|
||||
long canInsert = 0;
|
||||
if( outputs.isEmpty() )
|
||||
{
|
||||
try
|
||||
{
|
||||
for( PartP2PGTCEPower o : PartP2PGTCEPower.this.getOutputs() )
|
||||
outputs.add( o );
|
||||
}
|
||||
catch( GridAccessException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
while ( !outputs.isEmpty() )
|
||||
{
|
||||
PartP2PGTCEPower target = outputs.poll();
|
||||
final IEnergyContainer output = target.getAttachedEnergyStorage();
|
||||
|
||||
if( output == null || output.getEnergyCanBeInserted() <= 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
canInsert += output.getEnergyCanBeInserted();
|
||||
}
|
||||
return canInsert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long acceptEnergyFromNetwork( EnumFacing facing, long voltage, long amperage )
|
||||
{
|
||||
long amperesUsed = 0L;
|
||||
|
||||
if( outputs.isEmpty() )
|
||||
{
|
||||
try
|
||||
{
|
||||
for( PartP2PGTCEPower o : PartP2PGTCEPower.this.getOutputs() )
|
||||
outputs.add( o );
|
||||
}
|
||||
catch( GridAccessException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
while ( !outputs.isEmpty() )
|
||||
{
|
||||
PartP2PGTCEPower target = outputs.poll();
|
||||
final IEnergyContainer output = target.getAttachedEnergyStorage();
|
||||
|
||||
if( output == null || !output.inputsEnergy( facing ) || output.getEnergyCanBeInserted() <= 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( voltage > 0 )
|
||||
{
|
||||
amperesUsed += output.acceptEnergyFromNetwork( facing, voltage, amperage - amperesUsed );
|
||||
}
|
||||
|
||||
if( amperage == amperesUsed )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return amperesUsed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inputsEnergy( EnumFacing enumFacing )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long changeEnergy( long l )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyStored()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyCapacity()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInputAmperage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInputVoltage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
class OutputEnergyStorage implements IEnergyContainer
|
||||
{
|
||||
@Override
|
||||
public long acceptEnergyFromNetwork( EnumFacing facing, long voltage, long amperage )
|
||||
{
|
||||
if( facing == getSide().getFacing() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
final IEnergyContainer output = getAttachedEnergyStorage();
|
||||
voltage *= 0.95;
|
||||
if( voltage > 0 )
|
||||
{
|
||||
return output.acceptEnergyFromNetwork( facing, voltage, amperage );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inputsEnergy( EnumFacing enumFacing )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outputsEnergy( EnumFacing side )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long changeEnergy( long l )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyStored()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyCapacity()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInputAmperage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInputVoltage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static class NullEnergyStorage implements IEnergyContainer
|
||||
{
|
||||
@Override
|
||||
public long acceptEnergyFromNetwork( EnumFacing enumFacing, long l, long l1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inputsEnergy( EnumFacing enumFacing )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long changeEnergy( long l )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyStored()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyCapacity()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInputAmperage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInputVoltage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
|
||||
super.writeToStream( data );
|
||||
data.writeShort( this.getFrequency() );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void chanRender( final MENetworkChannelsChanged c )
|
||||
@@ -205,10 +205,11 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
boolean pasteAsOutput = true;
|
||||
ItemStack is = player.getHeldItem( hand );
|
||||
if (is.isEmpty()) {
|
||||
if( is.isEmpty() )
|
||||
{
|
||||
pasteAsOutput = false;
|
||||
is = player.getHeldItemOffhand();
|
||||
}
|
||||
@@ -250,7 +251,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
|
||||
if( newBus instanceof PartP2PTunnel )
|
||||
{
|
||||
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
|
||||
|
||||
|
||||
if( pasteAsOutput )
|
||||
{
|
||||
newTunnel.setOutput( true );
|
||||
@@ -282,7 +283,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
|
||||
|
||||
final IParts parts = AEApi.instance().definitions().parts();
|
||||
|
||||
switch( tt )
|
||||
switch ( tt )
|
||||
{
|
||||
case LIGHT:
|
||||
newType = parts.p2PTunnelLight().maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
@@ -292,6 +293,10 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
|
||||
newType = parts.p2PTunnelFE().maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
break;
|
||||
|
||||
case GTEU_POWER:
|
||||
newType = parts.p2PTunnelGTEU().maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
break;
|
||||
|
||||
case FLUID:
|
||||
newType = parts.p2PTunnelFluids().maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
break;
|
||||
@@ -451,8 +456,10 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
|
||||
|
||||
final AEColor[] colors = Platform.p2p().toColors( this.getFrequency() );
|
||||
final int[] colorCode = new int[]{
|
||||
colors[0].ordinal(), colors[0].ordinal(), colors[1].ordinal(), colors[1].ordinal(),
|
||||
colors[2].ordinal(), colors[2].ordinal(), colors[3].ordinal(), colors[3].ordinal(),
|
||||
colors[0].ordinal(), colors[0].ordinal(),
|
||||
colors[1].ordinal(), colors[1].ordinal(),
|
||||
colors[2].ordinal(), colors[2].ordinal(),
|
||||
colors[3].ordinal(), colors[3].ordinal(),
|
||||
};
|
||||
|
||||
data.setIntArray( "colorCode", colorCode );
|
||||
|
||||
@@ -17,6 +17,8 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static appeng.helpers.PatternHelper.PROCESSING_INPUT_LIMIT;
|
||||
import static appeng.helpers.PatternHelper.PROCESSING_OUTPUT_LIMIT;
|
||||
|
||||
@@ -43,6 +45,18 @@ public class PartExpandedProcessingPatternTerminal extends AbstractPartTerminal
|
||||
super( is );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDrops( final List<ItemStack> drops, final boolean wrenched )
|
||||
{
|
||||
for( final ItemStack is : this.pattern )
|
||||
{
|
||||
if( !is.isEmpty() )
|
||||
{
|
||||
drops.add( is );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT( NBTTagCompound data )
|
||||
{
|
||||
|
||||
@@ -20,8 +20,18 @@ package appeng.tile.crafting;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.IStorageMonitorable;
|
||||
import appeng.api.storage.IStorageMonitorableAccessor;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.capabilities.Capabilities;
|
||||
import appeng.helpers.PatternHelper;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
@@ -30,6 +40,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
@@ -86,6 +97,7 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
private final AppEngInternalInventory patternInv = new AppEngInternalInventory( this, 1, 1 );
|
||||
private final IItemHandler gridInvExt = new WrapperFilteredItemHandler( this.gridInv, new CraftingGridFilter() );
|
||||
private final IItemHandler internalInv = new WrapperChainedItemHandler( this.gridInv, this.patternInv );
|
||||
private final EnumMap<EnumFacing, Object> neighbors = new EnumMap<>( EnumFacing.class );
|
||||
private final IConfigManager settings;
|
||||
private final UpgradeInventory upgrades;
|
||||
private boolean isPowered = false;
|
||||
@@ -96,6 +108,7 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
private boolean isAwake = false;
|
||||
private boolean forcePlan = false;
|
||||
private boolean reboot = true;
|
||||
private final IActionSource mySrc = new MachineSource( this );
|
||||
|
||||
public TileMolecularAssembler()
|
||||
{
|
||||
@@ -114,6 +127,126 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
return 5;
|
||||
}
|
||||
|
||||
public void updateNeighbors()
|
||||
{
|
||||
for( EnumFacing f : EnumFacing.VALUES )
|
||||
{
|
||||
TileEntity te = world.getTileEntity( pos.offset( f ) );
|
||||
Object capability = null;
|
||||
if( te != null )
|
||||
{
|
||||
// Prioritize a handler to directly link to another ME network
|
||||
IStorageMonitorableAccessor accessor = te.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, f.getOpposite() );
|
||||
|
||||
if( accessor != null )
|
||||
{
|
||||
IStorageMonitorable inventory = accessor.getInventory( this.mySrc );
|
||||
if( inventory != null )
|
||||
{
|
||||
capability = inventory;
|
||||
}
|
||||
}
|
||||
|
||||
if( capability == null )
|
||||
{
|
||||
capability = InventoryAdaptor.getAdaptor( te, f.getOpposite() );
|
||||
}
|
||||
}
|
||||
|
||||
if( capability != null )
|
||||
{
|
||||
neighbors.put( f, capability );
|
||||
}
|
||||
else
|
||||
{
|
||||
neighbors.remove( f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReady()
|
||||
{
|
||||
super.onReady();
|
||||
updateNeighbors();
|
||||
}
|
||||
|
||||
public void updateNeighbors( IBlockAccess w, BlockPos pos, BlockPos neighbor )
|
||||
{
|
||||
EnumFacing updateFromFacing;
|
||||
if( pos.getX() != neighbor.getX() )
|
||||
{
|
||||
if( pos.getX() > neighbor.getX() )
|
||||
{
|
||||
updateFromFacing = EnumFacing.WEST;
|
||||
}
|
||||
else
|
||||
{
|
||||
updateFromFacing = EnumFacing.EAST;
|
||||
}
|
||||
}
|
||||
else if( pos.getY() != neighbor.getY() )
|
||||
{
|
||||
if( pos.getY() > neighbor.getY() )
|
||||
{
|
||||
updateFromFacing = EnumFacing.DOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
updateFromFacing = EnumFacing.UP;
|
||||
}
|
||||
}
|
||||
else if( pos.getZ() != neighbor.getZ() )
|
||||
{
|
||||
if( pos.getZ() > neighbor.getZ() )
|
||||
{
|
||||
updateFromFacing = EnumFacing.NORTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
updateFromFacing = EnumFacing.SOUTH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( pos.offset( updateFromFacing ).equals( neighbor ) )
|
||||
{
|
||||
TileEntity te = w.getTileEntity( neighbor );
|
||||
Object capability = null;
|
||||
if( te != null )
|
||||
{
|
||||
// Prioritize a handler to directly link to another ME network
|
||||
IStorageMonitorableAccessor accessor = te.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, updateFromFacing.getOpposite() );
|
||||
|
||||
if( accessor != null )
|
||||
{
|
||||
IStorageMonitorable inventory = accessor.getInventory( this.mySrc );
|
||||
if( inventory != null )
|
||||
{
|
||||
capability = inventory;
|
||||
}
|
||||
}
|
||||
|
||||
if( capability == null )
|
||||
{
|
||||
capability = InventoryAdaptor.getAdaptor( te, updateFromFacing.getOpposite() );
|
||||
}
|
||||
}
|
||||
|
||||
if( capability != null )
|
||||
{
|
||||
neighbors.put( updateFromFacing, capability );
|
||||
}
|
||||
else
|
||||
{
|
||||
neighbors.remove( updateFromFacing );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table, final EnumFacing where )
|
||||
{
|
||||
@@ -143,7 +276,7 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
private void updateSleepiness()
|
||||
{
|
||||
final boolean wasEnabled = this.isAwake;
|
||||
this.isAwake = this.myPlan != null && this.hasMats() || this.canPush();
|
||||
this.isAwake = this.canPush() || this.myPlan != null && this.hasMats();
|
||||
if( wasEnabled != this.isAwake )
|
||||
{
|
||||
try
|
||||
@@ -179,9 +312,13 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
for( int x = 0; x < this.craftingInv.getSizeInventory(); x++ )
|
||||
{
|
||||
this.craftingInv.setInventorySlotContents( x, this.gridInv.getStackInSlot( x ) );
|
||||
if( !myPlan.isValidItemForSlot( x, craftingInv.getStackInSlot( x ), world ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !this.myPlan.getOutput( this.craftingInv, this.getWorld() ).isEmpty();
|
||||
return this.myPlan.getOutputs().length > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -425,7 +562,7 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
|
||||
this.reboot = false;
|
||||
int speed = 10;
|
||||
switch( this.upgrades.getInstalledUpgrades( Upgrades.SPEED ) )
|
||||
switch ( this.upgrades.getInstalledUpgrades( Upgrades.SPEED ) )
|
||||
{
|
||||
case 0:
|
||||
this.progress += this.userPower( ticksSinceLastCall, speed = 10, 1.0 );
|
||||
@@ -458,7 +595,7 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
final ItemStack output = this.myPlan.getOutput( this.craftingInv, this.getWorld() );
|
||||
if( !output.isEmpty() )
|
||||
{
|
||||
this.pushOut( output.copy() );
|
||||
this.pushOut( output );
|
||||
|
||||
for( int x = 0; x < this.craftingInv.getSizeInventory(); x++ )
|
||||
{
|
||||
@@ -519,10 +656,7 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
{
|
||||
try
|
||||
{
|
||||
return (int) ( this.getProxy()
|
||||
.getEnergy()
|
||||
.extractAEPower( ticksPassed * bonusValue * acceleratorTax, Actionable.MODULATE,
|
||||
PowerMultiplier.CONFIG ) / acceleratorTax );
|
||||
return (int) ( this.getProxy().getEnergy().extractAEPower( ticksPassed * bonusValue * acceleratorTax, Actionable.MODULATE, PowerMultiplier.CONFIG ) / acceleratorTax );
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
@@ -534,9 +668,13 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
{
|
||||
if( this.pushDirection == AEPartLocation.INTERNAL )
|
||||
{
|
||||
for( final EnumFacing d : EnumFacing.VALUES )
|
||||
for( final Map.Entry<EnumFacing, Object> d : neighbors.entrySet() )
|
||||
{
|
||||
output = this.pushTo( output, d );
|
||||
output = this.pushTo( output, d.getKey() );
|
||||
if( output.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -560,27 +698,42 @@ public class TileMolecularAssembler extends AENetworkInvTile implements IUpgrade
|
||||
return output;
|
||||
}
|
||||
|
||||
final TileEntity te = this.getWorld().getTileEntity( this.pos.offset( d ) );
|
||||
|
||||
if( te == null )
|
||||
Object capability = neighbors.get( d );
|
||||
if( capability instanceof IStorageMonitorable )
|
||||
{
|
||||
return output;
|
||||
// Prioritize a handler to directly link to another ME network
|
||||
IStorageMonitorable inventory = (IStorageMonitorable) capability;
|
||||
IAEItemStack toInsert = AEItemStack.fromItemStack( output );
|
||||
IMEMonitor<IAEItemStack> inv = inventory.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
IAEItemStack remainder = inv.injectItems( toInsert, Actionable.SIMULATE, this.mySrc );
|
||||
if( remainder == null )
|
||||
{
|
||||
inv.injectItems( toInsert, Actionable.MODULATE, this.mySrc );
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( remainder.getStackSize() == toInsert.getStackSize() )
|
||||
{
|
||||
return output;
|
||||
}
|
||||
inv.injectItems( toInsert.setStackSize( toInsert.getStackSize() - remainder.getStackSize() ), Actionable.MODULATE, this.mySrc );
|
||||
this.saveChanges();
|
||||
return remainder.createItemStack();
|
||||
}
|
||||
}
|
||||
|
||||
final InventoryAdaptor adaptor = InventoryAdaptor.getAdaptor( te, d.getOpposite() );
|
||||
|
||||
if( adaptor == null )
|
||||
else if( capability instanceof InventoryAdaptor )
|
||||
{
|
||||
return output;
|
||||
}
|
||||
InventoryAdaptor adaptor = (InventoryAdaptor) capability;
|
||||
|
||||
final int size = output.getCount();
|
||||
output = adaptor.addItems( output );
|
||||
final int newSize = output.isEmpty() ? 0 : output.getCount();
|
||||
final int size = output.getCount();
|
||||
output = adaptor.addItems( output );
|
||||
final int newSize = output.isEmpty() ? 0 : output.getCount();
|
||||
|
||||
if( size != newSize )
|
||||
{
|
||||
this.saveChanges();
|
||||
if( size != newSize )
|
||||
{
|
||||
this.saveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
@@ -77,6 +77,10 @@ public class AppEngInternalInventory extends ItemStackHandler implements Iterabl
|
||||
@Override
|
||||
public void setStackInSlot( int slot, @Nonnull ItemStack stack )
|
||||
{
|
||||
if( stack == this.getStackInSlot( slot ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.previousStack = this.getStackInSlot( slot ).copy();
|
||||
super.setStackInSlot( slot, stack );
|
||||
}
|
||||
@@ -119,14 +123,15 @@ public class AppEngInternalInventory extends ItemStackHandler implements Iterabl
|
||||
if( this.getTileEntity() != null && this.eventsEnabled() && !this.dirtyFlag )
|
||||
{
|
||||
this.dirtyFlag = true;
|
||||
ItemStack newStack = this.getStackInSlot( slot ).copy();
|
||||
ItemStack newStack = this.getStackInSlot( slot );
|
||||
ItemStack oldStack = this.previousStack;
|
||||
InvOperation op = InvOperation.SET;
|
||||
|
||||
if( newStack.isEmpty() || oldStack.isEmpty() || ( oldStack.getCount() < oldStack.getMaxStackSize() && oldStack.getCount() < this.getSlotLimit( slot ) && ItemStack.areItemsEqual( newStack, oldStack ) ) )
|
||||
if( newStack.isEmpty() || oldStack.isEmpty() || oldStack.getCount() != newStack.getCount() && ItemStack.areItemsEqual( newStack, oldStack ) )
|
||||
{
|
||||
if( newStack.getCount() > oldStack.getCount() )
|
||||
{
|
||||
newStack = newStack.copy();
|
||||
newStack.shrink( oldStack.getCount() );
|
||||
oldStack = ItemStack.EMPTY;
|
||||
op = InvOperation.INSERT;
|
||||
|
||||
@@ -57,10 +57,16 @@ public class TileEnergyAcceptor extends AENetworkPowerTile
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
return this.getInternalMaxPower();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getInternalMaxPower()
|
||||
{
|
||||
return getFunnelPowerDemand( Long.MAX_VALUE );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double funnelPowerIntoStorage( final double power, final Actionable mode )
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@ public abstract class AEBasePoweredTile extends AEBaseInvTile implements IAEPowe
|
||||
private EnumSet<EnumFacing> internalPowerSides = EnumSet.allOf( EnumFacing.class );
|
||||
private final IEnergyStorage forgeEnergyAdapter;
|
||||
private Object teslaEnergyAdapter;
|
||||
|
||||
private GTCEEnergyAdapter gtceEnergyAdapter = null;
|
||||
private IC2PowerSink ic2Sink;
|
||||
|
||||
public AEBasePoweredTile()
|
||||
@@ -63,6 +63,11 @@ public abstract class AEBasePoweredTile extends AEBaseInvTile implements IAEPowe
|
||||
{
|
||||
this.teslaEnergyAdapter = new TeslaEnergyAdapter( this );
|
||||
}
|
||||
if( Capabilities.GTCE_ENERGY != null )
|
||||
{
|
||||
this.gtceEnergyAdapter = new GTCEEnergyAdapter( this );
|
||||
}
|
||||
|
||||
this.ic2Sink = Integrations.ic2().createPowerSink( this, this );
|
||||
this.ic2Sink.setValidFaces( this.internalPowerSides );
|
||||
}
|
||||
@@ -284,6 +289,13 @@ public abstract class AEBasePoweredTile extends AEBaseInvTile implements IAEPowe
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( capability == Capabilities.GTCE_ENERGY )
|
||||
{
|
||||
if( this.getPowerSides().contains( facing ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.hasCapability( capability, facing );
|
||||
}
|
||||
@@ -306,7 +318,14 @@ public abstract class AEBasePoweredTile extends AEBaseInvTile implements IAEPowe
|
||||
return (T) this.teslaEnergyAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
else if( capability == Capabilities.GTCE_ENERGY )
|
||||
{
|
||||
if( this.getPowerSides().contains( facing ) )
|
||||
{
|
||||
return (T) this.gtceEnergyAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
return super.getCapability( capability, facing );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package appeng.tile.powersink;
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.PowerUnits;
|
||||
import gregtech.api.capability.IEnergyContainer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
|
||||
public class GTCEEnergyAdapter implements IEnergyContainer
|
||||
{
|
||||
private final IExternalPowerSink sink;
|
||||
|
||||
double EUBuffer;
|
||||
|
||||
GTCEEnergyAdapter( IExternalPowerSink sink )
|
||||
{
|
||||
this.sink = sink;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long acceptEnergyFromNetwork( EnumFacing enumFacing, long voltage, long amperage )
|
||||
{
|
||||
final double power = voltage * amperage;
|
||||
final double oldBuffer = EUBuffer;
|
||||
|
||||
EUBuffer = this.sink.injectExternalPower( PowerUnits.GTEU, power + EUBuffer, Actionable.MODULATE );
|
||||
|
||||
// if the overflow went down, all inputs were consumed
|
||||
if( EUBuffer <= oldBuffer )
|
||||
{
|
||||
return amperage;
|
||||
}
|
||||
// if overflow is greater than the inputs, nothing was consumed
|
||||
if( EUBuffer >= power )
|
||||
{
|
||||
EUBuffer -= power;
|
||||
return 0;
|
||||
}
|
||||
// determine how many amps are being used
|
||||
final double usedEU = power + oldBuffer - EUBuffer;
|
||||
final long ampsUsed = (long) Math.ceil( usedEU / ( (double) voltage ) );
|
||||
// adjust the overflow
|
||||
EUBuffer += usedEU % voltage;
|
||||
|
||||
return ampsUsed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inputsEnergy( EnumFacing enumFacing )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long changeEnergy( long l )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyStored()
|
||||
{
|
||||
return (long) Math.floor( PowerUnits.AE.convertTo( PowerUnits.GTEU, this.sink.getAECurrentPower() ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyCapacity()
|
||||
{
|
||||
return (long) Math.floor( PowerUnits.AE.convertTo( PowerUnits.GTEU, this.sink.getAEMaxPower() ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInputAmperage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInputVoltage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnergyCanBeInserted()
|
||||
{
|
||||
return this.getEnergyCapacity() - this.getEnergyStored();
|
||||
}
|
||||
}
|
||||
@@ -1226,7 +1226,7 @@ public class Platform
|
||||
Preconditions.checkNotNull( src );
|
||||
Preconditions.checkNotNull( mode );
|
||||
|
||||
final T possible = cell.injectItems( input.copy(), Actionable.SIMULATE, src );
|
||||
final T possible = cell.injectItems( input, Actionable.SIMULATE, src );
|
||||
|
||||
long stored = input.getStackSize();
|
||||
if( possible != null )
|
||||
|
||||
@@ -223,26 +223,28 @@ public class AdaptorItemHandler extends InventoryAdaptor
|
||||
return this.addItems( toBeSimulated, true );
|
||||
}
|
||||
|
||||
protected ItemStack addItems( final ItemStack itemsToAdd, final boolean simulate )
|
||||
protected ItemStack addItems( ItemStack itemsToAdd, final boolean simulate )
|
||||
{
|
||||
if( itemsToAdd.isEmpty() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
ItemStack left = itemsToAdd.copy();
|
||||
|
||||
for( int slot = 0; slot < this.itemHandler.getSlots(); slot++ )
|
||||
{
|
||||
left = this.itemHandler.insertItem( slot, left, simulate );
|
||||
if( !simulate )
|
||||
{
|
||||
itemsToAdd = itemsToAdd.copy();
|
||||
}
|
||||
itemsToAdd = this.itemHandler.insertItem( slot, itemsToAdd, simulate );
|
||||
|
||||
if( left.isEmpty() )
|
||||
if( itemsToAdd.isEmpty() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
return left;
|
||||
return itemsToAdd;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,198 +12,201 @@ import java.util.Iterator;
|
||||
|
||||
public class AdaptorItemRepository extends InventoryAdaptor
|
||||
{
|
||||
protected final IItemRepository itemRepository;
|
||||
protected final IItemRepository itemRepository;
|
||||
|
||||
public AdaptorItemRepository( IItemRepository itemRepository )
|
||||
{
|
||||
this.itemRepository = itemRepository;
|
||||
}
|
||||
public AdaptorItemRepository( IItemRepository itemRepository )
|
||||
{
|
||||
this.itemRepository = itemRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItems( int amount, ItemStack filter, IInventoryDestination destination )
|
||||
{
|
||||
ItemStack rv = ItemStack.EMPTY;
|
||||
ItemStack extracted = ItemStack.EMPTY;
|
||||
@Override
|
||||
public ItemStack removeItems( int amount, ItemStack filter, IInventoryDestination destination )
|
||||
{
|
||||
ItemStack rv = ItemStack.EMPTY;
|
||||
ItemStack extracted = ItemStack.EMPTY;
|
||||
|
||||
if( !filter.isEmpty() )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( filter, amount, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !filter.isEmpty() )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( filter, amount, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( destination != null )
|
||||
{
|
||||
if( destination != null )
|
||||
{
|
||||
|
||||
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extracted = this.itemRepository.extractItem( filter, amount, false );
|
||||
extracted = this.itemRepository.extractItem( filter.isEmpty() ? extracted : filter, amount, false );
|
||||
|
||||
return extracted;
|
||||
}
|
||||
return extracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack simulateRemove( int amount, ItemStack filter, IInventoryDestination destination )
|
||||
{
|
||||
ItemStack rv = ItemStack.EMPTY;
|
||||
ItemStack extracted = ItemStack.EMPTY;
|
||||
@Override
|
||||
public ItemStack simulateRemove( int amount, ItemStack filter, IInventoryDestination destination )
|
||||
{
|
||||
ItemStack rv = ItemStack.EMPTY;
|
||||
ItemStack extracted = ItemStack.EMPTY;
|
||||
|
||||
if( !filter.isEmpty() )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( filter, amount, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !filter.isEmpty() )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( filter, amount, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( destination != null )
|
||||
{
|
||||
if( destination != null )
|
||||
{
|
||||
|
||||
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return extracted;
|
||||
}
|
||||
return extracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeSimilarItems( int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination )
|
||||
{
|
||||
ItemStack rv = ItemStack.EMPTY;
|
||||
ItemStack extracted = ItemStack.EMPTY;
|
||||
@Override
|
||||
public ItemStack removeSimilarItems( int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination )
|
||||
{
|
||||
ItemStack rv = ItemStack.EMPTY;
|
||||
ItemStack extracted = ItemStack.EMPTY;
|
||||
|
||||
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
|
||||
{
|
||||
if( Platform.itemComparisons().isFuzzyEqualItem( record.itemPrototype, filter, fuzzyMode ) )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
|
||||
}
|
||||
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
|
||||
{
|
||||
if( Platform.itemComparisons().isFuzzyEqualItem( record.itemPrototype, filter, fuzzyMode ) )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
|
||||
}
|
||||
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( destination != null )
|
||||
{
|
||||
if( destination != null )
|
||||
{
|
||||
|
||||
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extracted = this.itemRepository.extractItem( extracted, amount, false );
|
||||
extracted = this.itemRepository.extractItem( extracted, amount, false );
|
||||
|
||||
return extracted;
|
||||
}
|
||||
return extracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack simulateSimilarRemove( int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination )
|
||||
{
|
||||
ItemStack rv = ItemStack.EMPTY;
|
||||
ItemStack extracted = ItemStack.EMPTY;
|
||||
@Override
|
||||
public ItemStack simulateSimilarRemove( int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination )
|
||||
{
|
||||
ItemStack rv = ItemStack.EMPTY;
|
||||
ItemStack extracted = ItemStack.EMPTY;
|
||||
|
||||
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
|
||||
{
|
||||
if( Platform.itemComparisons().isFuzzyEqualItem( record.itemPrototype, filter, fuzzyMode ) )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
|
||||
}
|
||||
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
|
||||
{
|
||||
if( Platform.itemComparisons().isFuzzyEqualItem( record.itemPrototype, filter, fuzzyMode ) )
|
||||
{
|
||||
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
|
||||
}
|
||||
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( destination != null )
|
||||
{
|
||||
if( destination != null )
|
||||
{
|
||||
|
||||
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return extracted;
|
||||
}
|
||||
return extracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack addItems( ItemStack toBeAdded )
|
||||
{
|
||||
return this.addItems( toBeAdded, false );
|
||||
}
|
||||
@Override
|
||||
public ItemStack addItems( ItemStack toBeAdded )
|
||||
{
|
||||
return this.addItems( toBeAdded, false );
|
||||
}
|
||||
|
||||
protected ItemStack addItems( final ItemStack itemsToAdd, final boolean simulate )
|
||||
{
|
||||
if( itemsToAdd.isEmpty() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
protected ItemStack addItems( ItemStack itemsToAdd, final boolean simulate )
|
||||
{
|
||||
if( itemsToAdd.isEmpty() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
ItemStack left = itemsToAdd.copy();
|
||||
if( !simulate )
|
||||
{
|
||||
itemsToAdd = itemsToAdd.copy();
|
||||
}
|
||||
|
||||
left = this.itemRepository.insertItem( left, simulate );
|
||||
itemsToAdd = this.itemRepository.insertItem( itemsToAdd, simulate );
|
||||
|
||||
if( left.isEmpty() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
if( itemsToAdd.isEmpty() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
return left;
|
||||
}
|
||||
return itemsToAdd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack simulateAdd( ItemStack toBeSimulated )
|
||||
{
|
||||
return this.addItems( toBeSimulated, true );
|
||||
}
|
||||
@Override
|
||||
public ItemStack simulateAdd( ItemStack toBeSimulated )
|
||||
{
|
||||
return this.addItems( toBeSimulated, true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsItems()
|
||||
{
|
||||
return !this.itemRepository.getAllItems().isEmpty();
|
||||
}
|
||||
@Override
|
||||
public boolean containsItems()
|
||||
{
|
||||
return !this.itemRepository.getAllItems().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSlots()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean hasSlots()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ItemSlot> iterator()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Iterator<ItemSlot> iterator()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package appeng.util.inv;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
|
||||
public abstract class BlockingInventoryAdaptor implements Iterable<ItemSlot>
|
||||
{
|
||||
public static BlockingInventoryAdaptor 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 BlockingItemHandler( itemHandler, te.getBlockType().getRegistryName().getResourceDomain() );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract boolean containsBlockingItems();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package appeng.util.inv;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.helpers.NonBlockingItems;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import gregtech.common.items.MetaTool;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class BlockingItemHandler extends BlockingInventoryAdaptor
|
||||
{
|
||||
protected final IItemHandler itemHandler;
|
||||
private final String domain;
|
||||
|
||||
public BlockingItemHandler( IItemHandler itemHandler, String domain )
|
||||
{
|
||||
this.itemHandler = itemHandler;
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
boolean isBlockableItem( ItemStack stack )
|
||||
{
|
||||
Object2ObjectOpenHashMap<Item, IntSet> map = NonBlockingItems.INSTANCE.getMap().get( domain );
|
||||
if( map.get( stack.getItem() ) != null )
|
||||
{
|
||||
return !map.get( stack.getItem() ).contains( stack.getItemDamage() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsBlockingItems()
|
||||
{
|
||||
int slots = this.itemHandler.getSlots();
|
||||
for( int slot = 0; slot < slots; slot++ )
|
||||
{
|
||||
ItemStack is = this.itemHandler.getStackInSlot( slot );
|
||||
if( !is.isEmpty() && isBlockableItem( is ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ItemSlot> iterator()
|
||||
{
|
||||
return new ItemHandlerIterator( this.itemHandler );
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
package appeng.util.item;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -25,6 +26,7 @@ import java.util.Optional;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -41,279 +43,352 @@ import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.core.Api;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack {
|
||||
private static final String NBT_STACKSIZE = "Cnt";
|
||||
private static final String NBT_REQUESTABLE = "Req";
|
||||
private static final String NBT_CRAFTABLE = "Craft";
|
||||
|
||||
private final AESharedItemStack sharedStack;
|
||||
private Optional<OreReference> oreReference;
|
||||
public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
|
||||
{
|
||||
private static final String NBT_STACKSIZE = "Cnt";
|
||||
private static final String NBT_REQUESTABLE = "Req";
|
||||
private static final String NBT_CRAFTABLE = "Craft";
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private String displayName;
|
||||
@SideOnly(Side.CLIENT)
|
||||
private List<String> tooltip;
|
||||
private final AESharedItemStack sharedStack;
|
||||
private Optional<OreReference> oreReference;
|
||||
|
||||
private AEItemStack(final AEItemStack is) {
|
||||
this.setStackSize(is.getStackSize());
|
||||
this.setCraftable(is.isCraftable());
|
||||
this.setCountRequestable(is.getCountRequestable());
|
||||
this.sharedStack = is.sharedStack;
|
||||
this.oreReference = is.oreReference;
|
||||
}
|
||||
@SideOnly( Side.CLIENT )
|
||||
private String displayName;
|
||||
@SideOnly( Side.CLIENT )
|
||||
private List<String> tooltip;
|
||||
private ItemStack cachedItemStack;
|
||||
|
||||
private AEItemStack(final AESharedItemStack is, long size) {
|
||||
this.sharedStack = is;
|
||||
this.setStackSize(size);
|
||||
this.setCraftable(false);
|
||||
this.setCountRequestable(0);
|
||||
this.oreReference = OreHelper.INSTANCE.getOre( is.getDefinition() );
|
||||
}
|
||||
private AEItemStack( final AEItemStack is )
|
||||
{
|
||||
this.setStackSize( is.getStackSize() );
|
||||
this.setCraftable( is.isCraftable() );
|
||||
this.setCountRequestable( is.getCountRequestable() );
|
||||
this.sharedStack = is.sharedStack;
|
||||
this.oreReference = is.oreReference;
|
||||
this.cachedItemStack = is.cachedItemStack;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AEItemStack fromItemStack(@Nonnull final ItemStack stack) {
|
||||
if (stack.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
private AEItemStack( final AESharedItemStack is, long size )
|
||||
{
|
||||
this.sharedStack = is;
|
||||
this.setStackSize( size );
|
||||
this.setCraftable( false );
|
||||
this.setCountRequestable( 0 );
|
||||
this.oreReference = OreHelper.INSTANCE.getOre( is.getDefinition() );
|
||||
}
|
||||
|
||||
return new AEItemStack(AEItemStackRegistry.getRegisteredStack(stack), stack.getCount());
|
||||
}
|
||||
@Nullable
|
||||
public static AEItemStack fromItemStack( @Nonnull final ItemStack stack )
|
||||
{
|
||||
if( stack.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IAEItemStack fromNBT( final NBTTagCompound i )
|
||||
{
|
||||
if( i == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new AEItemStack( AEItemStackRegistry.getRegisteredStack( stack ), stack.getCount() );
|
||||
}
|
||||
|
||||
final ItemStack itemstack = new ItemStack( i );
|
||||
if( itemstack.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public static IAEItemStack fromNBT( final NBTTagCompound i )
|
||||
{
|
||||
if( i == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final AEItemStack item = AEItemStack.fromItemStack( itemstack );
|
||||
final ItemStack itemstack = new ItemStack( i );
|
||||
if( itemstack.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
item.setStackSize(i.getLong(NBT_STACKSIZE));
|
||||
item.setCountRequestable(i.getLong(NBT_REQUESTABLE));
|
||||
item.setCraftable(i.getBoolean(NBT_CRAFTABLE));
|
||||
return item;
|
||||
}
|
||||
final AEItemStack item = AEItemStack.fromItemStack( itemstack );
|
||||
|
||||
@Override
|
||||
public void writeToNBT(final NBTTagCompound i) {
|
||||
this.getDefinition().writeToNBT( i );
|
||||
item.setStackSize( i.getLong( NBT_STACKSIZE ) );
|
||||
item.setCountRequestable( i.getLong( NBT_REQUESTABLE ) );
|
||||
item.setCraftable( i.getBoolean( NBT_CRAFTABLE ) );
|
||||
return item;
|
||||
}
|
||||
|
||||
i.setLong(NBT_STACKSIZE, this.getStackSize());
|
||||
i.setLong(NBT_REQUESTABLE, this.getCountRequestable());
|
||||
i.setBoolean(NBT_CRAFTABLE, this.isCraftable());
|
||||
}
|
||||
@Override
|
||||
public void writeToNBT( final NBTTagCompound i )
|
||||
{
|
||||
this.getDefinition().writeToNBT( i );
|
||||
|
||||
public static AEItemStack fromPacket( final ByteBuf data )
|
||||
{
|
||||
final byte mask = data.readByte();
|
||||
final byte stackType = (byte) ( ( mask & 0x0C ) >> 2 );
|
||||
final byte countReqType = (byte) ( ( mask & 0x30 ) >> 4 );
|
||||
final boolean isCraftable = ( mask & 0x40 ) > 0;
|
||||
i.setLong( NBT_STACKSIZE, this.getStackSize() );
|
||||
i.setLong( NBT_REQUESTABLE, this.getCountRequestable() );
|
||||
i.setBoolean( NBT_CRAFTABLE, this.isCraftable() );
|
||||
}
|
||||
|
||||
final ItemStack itemstack = new ItemStack( ByteBufUtils.readTag( data ) );
|
||||
final long stackSize = getPacketValue( stackType, data );
|
||||
final long countRequestable = getPacketValue( countReqType, data );
|
||||
public static AEItemStack fromPacket( final ByteBuf data )
|
||||
{
|
||||
final byte mask = data.readByte();
|
||||
final byte stackType = (byte) ( ( mask & 0x0C ) >> 2 );
|
||||
final byte countReqType = (byte) ( ( mask & 0x30 ) >> 4 );
|
||||
final boolean isCraftable = ( mask & 0x40 ) > 0;
|
||||
|
||||
if( itemstack.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final ItemStack itemstack = new ItemStack( ByteBufUtils.readTag( data ) );
|
||||
final long stackSize = getPacketValue( stackType, data );
|
||||
final long countRequestable = getPacketValue( countReqType, data );
|
||||
|
||||
final AEItemStack item = new AEItemStack( AEItemStackRegistry.getRegisteredStack( itemstack ), stackSize );
|
||||
item.setCountRequestable( countRequestable );
|
||||
item.setCraftable( isCraftable );
|
||||
return item;
|
||||
}
|
||||
if( itemstack.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToPacket( final ByteBuf i )
|
||||
{
|
||||
final byte mask = (byte) ( ( this.getType( this.getStackSize() ) << 2 ) | ( this
|
||||
.getType( this.getCountRequestable() ) << 4 ) | ( (byte) ( this.isCraftable() ? 1 : 0 ) << 6 ) | ( this.hasTagCompound() ? 1 : 0 ) << 7 );
|
||||
final AEItemStack item = new AEItemStack( AEItemStackRegistry.getRegisteredStack( itemstack ), stackSize );
|
||||
item.setCountRequestable( countRequestable );
|
||||
item.setCraftable( isCraftable );
|
||||
return item;
|
||||
}
|
||||
|
||||
i.writeByte( mask );
|
||||
ByteBufUtils.writeTag( i, this.getDefinition().serializeNBT() );
|
||||
this.putPacketValue( i, this.getStackSize() );
|
||||
this.putPacketValue( i, this.getCountRequestable() );
|
||||
}
|
||||
@Override
|
||||
public void writeToPacket( final ByteBuf i )
|
||||
{
|
||||
final byte mask = (byte) ( ( this.getType( this.getStackSize() ) << 2 ) | ( this.getType( this.getCountRequestable() ) << 4 ) | ( (byte) ( this.isCraftable() ? 1 : 0 ) << 6 ) | ( this.hasTagCompound() ? 1 : 0 ) << 7 );
|
||||
|
||||
@Override
|
||||
public void add(final IAEItemStack option) {
|
||||
if (option == null) {
|
||||
return;
|
||||
}
|
||||
i.writeByte( mask );
|
||||
ByteBufUtils.writeTag( i, this.getDefinition().serializeNBT() );
|
||||
this.putPacketValue( i, this.getStackSize() );
|
||||
this.putPacketValue( i, this.getCountRequestable() );
|
||||
}
|
||||
|
||||
this.incStackSize(option.getStackSize());
|
||||
this.setCountRequestable(this.getCountRequestable() + option.getCountRequestable());
|
||||
this.setCraftable(this.isCraftable() || option.isCraftable());
|
||||
}
|
||||
@Override
|
||||
public void add( final IAEItemStack option )
|
||||
{
|
||||
if( option == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fuzzyComparison(final IAEItemStack other, final FuzzyMode mode) {
|
||||
final ItemStack itemStack = this.getDefinition();
|
||||
final ItemStack otherStack = other.getDefinition();
|
||||
this.incStackSize( option.getStackSize() );
|
||||
this.setCountRequestable( this.getCountRequestable() + option.getCountRequestable() );
|
||||
this.setCraftable( this.isCraftable() || option.isCraftable() );
|
||||
}
|
||||
|
||||
return this.fuzzyItemStackComparison(itemStack, otherStack, mode);
|
||||
}
|
||||
@Override
|
||||
public boolean fuzzyComparison( final IAEItemStack other, final FuzzyMode mode )
|
||||
{
|
||||
final ItemStack itemStack = this.getDefinition();
|
||||
final ItemStack otherStack = other.getDefinition();
|
||||
|
||||
@Override
|
||||
public IAEItemStack copy() {
|
||||
return new AEItemStack(this);
|
||||
}
|
||||
return this.fuzzyItemStackComparison( itemStack, otherStack, mode );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItem()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public IAEItemStack copy()
|
||||
{
|
||||
return new AEItemStack( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluid()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isItem()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<IAEItemStack> getChannel() {
|
||||
return Api.INSTANCE.storage().getStorageChannel(IItemStorageChannel.class);
|
||||
}
|
||||
@Override
|
||||
public boolean isFluid()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createItemStack() {
|
||||
return ItemHandlerHelper.copyStackWithSize(this.getDefinition(),
|
||||
(int) Math.min(Integer.MAX_VALUE, this.getStackSize()));
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel<IAEItemStack> getChannel()
|
||||
{
|
||||
return Api.INSTANCE.storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItem() {
|
||||
return this.getDefinition().getItem();
|
||||
}
|
||||
@Override
|
||||
public ItemStack createItemStack()
|
||||
{
|
||||
return ItemHandlerHelper.copyStackWithSize( this.getDefinition(), (int) Math.min( Integer.MAX_VALUE, this.getStackSize() ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemDamage() {
|
||||
return this.sharedStack.getItemDamage();
|
||||
}
|
||||
@Override
|
||||
public Item getItem()
|
||||
{
|
||||
return this.getDefinition().getItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sameOre( final IAEItemStack is )
|
||||
{
|
||||
return OreHelper.INSTANCE.sameOre( this, is );
|
||||
}
|
||||
@Override
|
||||
public int getItemDamage()
|
||||
{
|
||||
return this.sharedStack.getItemDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameType(final IAEItemStack otherStack) {
|
||||
if (otherStack == null) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean sameOre( final IAEItemStack is )
|
||||
{
|
||||
return OreHelper.INSTANCE.sameOre( this, is );
|
||||
}
|
||||
|
||||
return Objects.equals(this.sharedStack, ((AEItemStack) otherStack).sharedStack);
|
||||
}
|
||||
@Override
|
||||
public boolean isSameType( final IAEItemStack otherStack )
|
||||
{
|
||||
if( otherStack == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameType(final ItemStack otherStack) {
|
||||
if (otherStack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
int oldSize = otherStack.getCount();
|
||||
return Objects.equals( this.sharedStack, ( (AEItemStack) otherStack ).sharedStack );
|
||||
}
|
||||
|
||||
otherStack.setCount(1);
|
||||
boolean ret = ItemStack.areItemStacksEqual(this.getDefinition(), otherStack);
|
||||
otherStack.setCount(oldSize);
|
||||
@Override
|
||||
public boolean isSameType( final ItemStack otherStack )
|
||||
{
|
||||
if( otherStack.isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int oldSize = otherStack.getCount();
|
||||
|
||||
return ret;
|
||||
}
|
||||
otherStack.setCount( 1 );
|
||||
boolean ret = ItemStack.areItemStacksEqual( this.getDefinition(), otherStack );
|
||||
otherStack.setCount( oldSize );
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.sharedStack.hashCode();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object ia) {
|
||||
if (ia instanceof AEItemStack) {
|
||||
return this.isSameType((AEItemStack) ia);
|
||||
} else if (ia instanceof ItemStack) {
|
||||
// this actually breaks the equals contract (being equals to unrelated classes)
|
||||
return equals((ItemStack) ia);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return this.sharedStack.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ItemStack is) {
|
||||
return this.isSameType(is);
|
||||
}
|
||||
@Override
|
||||
public boolean equals( final Object ia )
|
||||
{
|
||||
if( ia instanceof AEItemStack )
|
||||
{
|
||||
return this.isSameType( (AEItemStack) ia );
|
||||
}
|
||||
else if( ia instanceof ItemStack )
|
||||
{
|
||||
// this actually breaks the equals contract (being equals to unrelated classes)
|
||||
return equals( (ItemStack) ia );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getStackSize() + "x" + this.getDefinition().getItem().getRegistryName();
|
||||
}
|
||||
@Override
|
||||
public boolean equals( final ItemStack is )
|
||||
{
|
||||
return this.isSameType( is );
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public List<String> getToolTip() {
|
||||
if (this.tooltip == null) {
|
||||
this.tooltip = Platform.getTooltip(this.asItemStackRepresentation());
|
||||
}
|
||||
return this.tooltip;
|
||||
}
|
||||
@Override
|
||||
public ItemStack getCachedItemStack( long stackSize )
|
||||
{
|
||||
ItemStack currentCached = null;
|
||||
if( this.cachedItemStack != null )
|
||||
{
|
||||
currentCached = this.cachedItemStack;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public String getDisplayName() {
|
||||
if (this.displayName == null) {
|
||||
this.displayName = Platform.getItemDisplayName(this.asItemStackRepresentation());
|
||||
}
|
||||
return this.displayName;
|
||||
}
|
||||
ItemStack itemStack;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public String getModID() {
|
||||
return this.getDefinition().getItem().getRegistryName().getResourceDomain();
|
||||
}
|
||||
if( currentCached != null )
|
||||
{
|
||||
// Cache is suitable, just update the count
|
||||
itemStack = currentCached;
|
||||
currentCached.setCount( Ints.saturatedCast( stackSize ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need a new stack :-(
|
||||
itemStack = this.createItemStack();
|
||||
}
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public Optional<OreReference> getOre()
|
||||
{
|
||||
return this.oreReference;
|
||||
}
|
||||
@Override
|
||||
public void setCachedItemStack( ItemStack itemStack )
|
||||
{
|
||||
this.cachedItemStack = itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTagCompound() {
|
||||
return this.getDefinition().hasTagCompound();
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return this.getStackSize() + "x" + this.getDefinition().getItem().getRegistryName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack asItemStackRepresentation() {
|
||||
return this.getDefinition().copy();
|
||||
}
|
||||
@SideOnly( Side.CLIENT )
|
||||
public List<String> getToolTip()
|
||||
{
|
||||
if( this.tooltip == null )
|
||||
{
|
||||
this.tooltip = Platform.getTooltip( this.asItemStackRepresentation() );
|
||||
}
|
||||
return this.tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getDefinition() {
|
||||
return this.sharedStack.getDefinition();
|
||||
}
|
||||
@SideOnly( Side.CLIENT )
|
||||
public String getDisplayName()
|
||||
{
|
||||
if( this.displayName == null )
|
||||
{
|
||||
this.displayName = Platform.getItemDisplayName( this.asItemStackRepresentation() );
|
||||
}
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
AESharedItemStack getSharedStack() {
|
||||
return this.sharedStack;
|
||||
}
|
||||
@SideOnly( Side.CLIENT )
|
||||
public String getModID()
|
||||
{
|
||||
return this.getDefinition().getItem().getRegistryName().getResourceDomain();
|
||||
}
|
||||
|
||||
private boolean fuzzyItemStackComparison(ItemStack a, ItemStack b, FuzzyMode mode) {
|
||||
if (a.getItem() == b.getItem() && a.getItem().isDamageable()) {
|
||||
if (mode == FuzzyMode.IGNORE_ALL) {
|
||||
return true;
|
||||
} else if (mode == FuzzyMode.PERCENT_99) {
|
||||
return a.getItemDamage() > 1 == b.getItemDamage() > 1;
|
||||
} else {
|
||||
final float percentDamageOfA = (float) a.getItemDamage() / a.getMaxDamage();
|
||||
final float percentDamageOfB = (float) b.getItemDamage() / b.getMaxDamage();
|
||||
public Optional<OreReference> getOre()
|
||||
{
|
||||
return this.oreReference;
|
||||
}
|
||||
|
||||
return percentDamageOfA > mode.breakPoint == percentDamageOfB > mode.breakPoint;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean hasTagCompound()
|
||||
{
|
||||
return this.getDefinition().hasTagCompound();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public ItemStack asItemStackRepresentation()
|
||||
{
|
||||
return this.getDefinition().copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getDefinition()
|
||||
{
|
||||
return this.sharedStack.getDefinition();
|
||||
}
|
||||
|
||||
AESharedItemStack getSharedStack()
|
||||
{
|
||||
return this.sharedStack;
|
||||
}
|
||||
|
||||
private boolean fuzzyItemStackComparison( ItemStack a, ItemStack b, FuzzyMode mode )
|
||||
{
|
||||
if( a.getItem() == b.getItem() && a.getItem().isDamageable() )
|
||||
{
|
||||
if( mode == FuzzyMode.IGNORE_ALL )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( mode == FuzzyMode.PERCENT_99 )
|
||||
{
|
||||
return a.getItemDamage() > 1 == b.getItemDamage() > 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
final float percentDamageOfA = (float) a.getItemDamage() / a.getMaxDamage();
|
||||
final float percentDamageOfB = (float) b.getItemDamage() / b.getMaxDamage();
|
||||
|
||||
return percentDamageOfA > mode.breakPoint == percentDamageOfB > mode.breakPoint;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,72 +22,78 @@ import java.util.Objects;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
final class AESharedItemStack {
|
||||
|
||||
private final ItemStack itemStack;
|
||||
private final int itemId;
|
||||
private final int itemDamage;
|
||||
private final int hashCode;
|
||||
final class AESharedItemStack
|
||||
{
|
||||
|
||||
public AESharedItemStack(final ItemStack itemStack) {
|
||||
this(itemStack, itemStack.getItemDamage());
|
||||
}
|
||||
private final ItemStack itemStack;
|
||||
private final int itemDamage;
|
||||
private final int hashCode;
|
||||
|
||||
/**
|
||||
* A constructor to explicitly set the damage value and not fetch it from the {@link ItemStack}
|
||||
*
|
||||
* @param itemStack The {@link ItemStack} to filter
|
||||
* @param damage The damage of the item
|
||||
*/
|
||||
private AESharedItemStack(ItemStack itemStack, int damage) {
|
||||
this.itemStack = itemStack;
|
||||
this.itemId = Item.getIdFromItem(itemStack.getItem());
|
||||
this.itemDamage = damage;
|
||||
public AESharedItemStack( final ItemStack itemStack )
|
||||
{
|
||||
this( itemStack, itemStack.getItemDamage() );
|
||||
}
|
||||
|
||||
// Ensure this is always called last.
|
||||
this.hashCode = this.makeHashCode();
|
||||
}
|
||||
/**
|
||||
* A constructor to explicitly set the damage value and not fetch it from the {@link ItemStack}
|
||||
*
|
||||
* @param itemStack The {@link ItemStack} to filter
|
||||
* @param damage The damage of the item
|
||||
*/
|
||||
private AESharedItemStack( ItemStack itemStack, int damage )
|
||||
{
|
||||
this.itemStack = itemStack;
|
||||
this.itemDamage = damage;
|
||||
|
||||
ItemStack getDefinition() {
|
||||
return this.itemStack;
|
||||
}
|
||||
// Ensure this is always called last.
|
||||
this.hashCode = this.makeHashCode();
|
||||
}
|
||||
|
||||
int getItemDamage() {
|
||||
return this.itemDamage;
|
||||
}
|
||||
ItemStack getDefinition()
|
||||
{
|
||||
return this.itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.hashCode;
|
||||
}
|
||||
int getItemDamage()
|
||||
{
|
||||
return this.itemDamage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof AESharedItemStack)) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return this.hashCode;
|
||||
}
|
||||
|
||||
final AESharedItemStack other = (AESharedItemStack) obj;
|
||||
Preconditions.checkState(this.itemStack.getCount() == 1, "ItemStack#getCount() has to be 1");
|
||||
Preconditions.checkArgument(other.getDefinition().getCount() == 1, "ItemStack#getCount() has to be 1");
|
||||
@Override
|
||||
public boolean equals( final Object obj )
|
||||
{
|
||||
if( this == obj )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if( !( obj instanceof AESharedItemStack ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.itemStack == other.itemStack) {
|
||||
return true;
|
||||
}
|
||||
return ItemStack.areItemStacksEqual(this.itemStack, other.itemStack);
|
||||
}
|
||||
final AESharedItemStack other = (AESharedItemStack) obj;
|
||||
Preconditions.checkState( this.itemStack.getCount() == 1, "ItemStack#getCount() has to be 1" );
|
||||
Preconditions.checkArgument( other.getDefinition().getCount() == 1, "ItemStack#getCount() has to be 1" );
|
||||
|
||||
private int makeHashCode() {
|
||||
return Objects.hash(
|
||||
this.itemId,
|
||||
this.itemDamage,
|
||||
this.itemStack.hasTagCompound() ? this.itemStack.getTagCompound() : 0);
|
||||
}
|
||||
if( this.itemStack == other.itemStack )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return ItemStack.areItemStacksEqual( this.itemStack, other.itemStack );
|
||||
}
|
||||
|
||||
private int makeHashCode()
|
||||
{
|
||||
return Objects.hash( this.itemStack.getItem(), this.itemDamage, this.itemStack.hasTagCompound() ? this.itemStack.getTagCompound() : 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
package appeng.util.item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author brachy84
|
||||
* @butcherer PrototypeTrousers
|
||||
*/
|
||||
public class OreDictFilterMatcher
|
||||
{
|
||||
|
||||
/**
|
||||
* Parses the given expression and creates a List.
|
||||
*
|
||||
* @param expression expr to parse
|
||||
* @return match rule list
|
||||
*/
|
||||
public static List<MatchRule> parseExpression( String expression )
|
||||
{
|
||||
List<MatchRule> rules = new ArrayList<>();
|
||||
parseExpression( rules, expression );
|
||||
return rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given expression and puts them into the given list.
|
||||
*
|
||||
* @param rules list to fill
|
||||
* @param expression expr to parse
|
||||
* @return the position of the expr. Is only relevant for sub rules
|
||||
*/
|
||||
public static int parseExpression( List<MatchRule> rules, String expression )
|
||||
{
|
||||
rules.clear();
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for( int i = 0; i < expression.length(); i++ )
|
||||
{
|
||||
char c = expression.charAt( i );
|
||||
if( c == ' ' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( c == '(' )
|
||||
{
|
||||
List<MatchRule> subRules = new ArrayList<>();
|
||||
i = parseExpression( subRules, expression.substring( i + 1 ) ) + i + 1;
|
||||
rules.add( MatchRule.group( subRules, builder.toString() ) );
|
||||
builder = new StringBuilder();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case '&':
|
||||
rules.add( new MatchRule( builder.toString() ) );
|
||||
rules.add( new MatchRule( MatchLogic.AND ) );
|
||||
builder = new StringBuilder();
|
||||
break;
|
||||
case '|':
|
||||
rules.add( new MatchRule( builder.toString() ) );
|
||||
rules.add( new MatchRule( MatchLogic.OR ) );
|
||||
builder = new StringBuilder();
|
||||
break;
|
||||
case '^':
|
||||
rules.add( new MatchRule( builder.toString() ) );
|
||||
rules.add( new MatchRule( MatchLogic.XOR ) );
|
||||
builder = new StringBuilder();
|
||||
break;
|
||||
case ')':
|
||||
rules.add( new MatchRule( builder.toString() ) );
|
||||
return i + 1;
|
||||
default:
|
||||
builder.append( c );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( builder.length() > 0 )
|
||||
{
|
||||
rules.add( new MatchRule( builder.toString() ) );
|
||||
}
|
||||
return expression.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the given string against a list of rules.
|
||||
* The string does not have to be an oreDict.
|
||||
*
|
||||
* @param rules to check against
|
||||
* @param oreDict string to check
|
||||
* @return if the string matches the rules
|
||||
*/
|
||||
public static boolean matches( List<MatchRule> rules, String oreDict )
|
||||
{
|
||||
boolean first = true;
|
||||
boolean lastResult = false;
|
||||
MatchLogic lastLogic = null;
|
||||
for( MatchRule rule : rules )
|
||||
{
|
||||
if( lastLogic == null )
|
||||
{
|
||||
if( rule.logic == MatchLogic.AND || rule.logic == MatchLogic.OR || rule.logic == MatchLogic.XOR )
|
||||
{
|
||||
lastLogic = rule.logic;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( lastLogic != null || first )
|
||||
{
|
||||
if( lastLogic != null )
|
||||
{
|
||||
switch ( lastLogic )
|
||||
{
|
||||
case AND:
|
||||
{
|
||||
if( !lastResult )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OR:
|
||||
{
|
||||
if( lastResult )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean newResult;
|
||||
if( rule.isGroup() )
|
||||
{
|
||||
newResult = rule.logic == MatchLogic.NOT ^ matches( rule.subRules, oreDict );
|
||||
}
|
||||
else
|
||||
{
|
||||
newResult = matches( rule, oreDict );
|
||||
}
|
||||
|
||||
if( lastLogic == MatchLogic.XOR )
|
||||
{
|
||||
if( lastResult == newResult )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lastLogic = null;
|
||||
lastResult = newResult;
|
||||
first = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return lastResult;
|
||||
}
|
||||
|
||||
private static boolean matches( MatchRule rule, String oreDict )
|
||||
{
|
||||
String filter = rule.expression;
|
||||
|
||||
if( filter.equals( "*" ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean startWild = filter.startsWith( "*" ), endWild = filter.endsWith( "*" );
|
||||
if( startWild )
|
||||
{
|
||||
filter = filter.substring( 1 );
|
||||
}
|
||||
|
||||
String[] parts = filter.split( "\\*+" );
|
||||
|
||||
return ( rule.logic == MatchLogic.NOT ) ^ matches( parts, oreDict, startWild, endWild );
|
||||
}
|
||||
|
||||
private static boolean matches( String[] filter, String oreDict, boolean startWild, boolean endWild )
|
||||
{
|
||||
String lastlastPart = filter[0];
|
||||
String lastPart = filter[0];
|
||||
int index = oreDict.indexOf( lastPart );
|
||||
if( ( !startWild && index != 0 ) || index < 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
boolean didGoBack = false;
|
||||
|
||||
for( int i = 1; i < filter.length; i++ )
|
||||
{
|
||||
String part = filter[i];
|
||||
int newIndex = oreDict.indexOf( part, index + lastPart.length() );
|
||||
if( newIndex < 0 )
|
||||
{
|
||||
if( i > 1 && !didGoBack )
|
||||
{
|
||||
i -= 2;
|
||||
lastPart = lastlastPart;
|
||||
didGoBack = true;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
lastlastPart = lastPart;
|
||||
lastPart = part;
|
||||
index = newIndex;
|
||||
if( didGoBack )
|
||||
{
|
||||
didGoBack = false;
|
||||
}
|
||||
}
|
||||
|
||||
if( endWild || lastPart.length() + index == oreDict.length() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for( int i = filter.length - 1; i < filter.length; i++ )
|
||||
{
|
||||
String part = filter[i];
|
||||
int newIndex = oreDict.indexOf( part, index + lastPart.length() );
|
||||
if( newIndex < 0 )
|
||||
{
|
||||
if( i > 1 && !didGoBack )
|
||||
{
|
||||
i -= 2;
|
||||
lastPart = lastlastPart;
|
||||
didGoBack = true;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
lastlastPart = lastPart;
|
||||
lastPart = part;
|
||||
index = newIndex;
|
||||
if( didGoBack )
|
||||
{
|
||||
didGoBack = false;
|
||||
}
|
||||
}
|
||||
return lastPart.length() + index == oreDict.length();
|
||||
}
|
||||
|
||||
public static String validateExp( String input )
|
||||
{
|
||||
// remove all operators that are double
|
||||
input = input.replaceAll( "\\*{2,}", "*" );
|
||||
input = input.replaceAll( "&{2,}", "&" );
|
||||
input = input.replaceAll( "\\|{2,}", "|" );
|
||||
input = input.replaceAll( "!{2,}", "!" );
|
||||
input = input.replaceAll( "\\^{2,}", "^" );
|
||||
input = input.replaceAll( " {2,}", " " );
|
||||
// move ( and ) so it doesn't create invalid expressions f.e. xxx (& yyy) => xxx & (yyy)
|
||||
// append or prepend ( and ) if the amount is not equal
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int unclosed = 0;
|
||||
char last = ' ';
|
||||
for( int i = 0; i < input.length(); i++ )
|
||||
{
|
||||
char c = input.charAt( i );
|
||||
if( c == ' ' )
|
||||
{
|
||||
if( last != '(' )
|
||||
{
|
||||
builder.append( " " );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( c == '(' )
|
||||
{
|
||||
unclosed++;
|
||||
}
|
||||
else if( c == ')' )
|
||||
{
|
||||
unclosed--;
|
||||
if( last == '&' || last == '|' || last == '^' )
|
||||
{
|
||||
int l = builder.lastIndexOf( " " + last );
|
||||
int l2 = builder.lastIndexOf( "" + last );
|
||||
builder.insert( l == l2 - 1 ? l : l2, ")" );
|
||||
continue;
|
||||
}
|
||||
if( i > 0 && builder.charAt( builder.length() - 1 ) == ' ' )
|
||||
{
|
||||
builder.deleteCharAt( builder.length() - 1 );
|
||||
}
|
||||
}
|
||||
else if( ( c == '&' || c == '|' || c == '^' ) && last == '(' )
|
||||
{
|
||||
builder.deleteCharAt( builder.lastIndexOf( "(" ) );
|
||||
builder.append( c ).append( " (" );
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.append( c );
|
||||
last = c;
|
||||
}
|
||||
if( unclosed > 0 )
|
||||
{
|
||||
for( int i = 0; i < unclosed; i++ )
|
||||
{
|
||||
builder.append( ")" );
|
||||
}
|
||||
}
|
||||
else if( unclosed < 0 )
|
||||
{
|
||||
unclosed = -unclosed;
|
||||
for( int i = 0; i < unclosed; i++ )
|
||||
{
|
||||
builder.insert( 0, "(" );
|
||||
}
|
||||
}
|
||||
input = builder.toString();
|
||||
input = input.replaceAll( " {2,}", " " );
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
public static class MatchRule
|
||||
{
|
||||
public final MatchLogic logic;
|
||||
public final String expression;
|
||||
private final List<MatchRule> subRules;
|
||||
|
||||
private MatchRule( MatchLogic logic, String expression, List<MatchRule> subRules )
|
||||
{
|
||||
if( expression.startsWith( "!" ) )
|
||||
{
|
||||
logic = MatchLogic.NOT;
|
||||
expression = expression.substring( 1 );
|
||||
}
|
||||
this.logic = logic;
|
||||
this.expression = expression;
|
||||
this.subRules = subRules;
|
||||
}
|
||||
|
||||
public MatchRule( MatchLogic logic, String expression )
|
||||
{
|
||||
this( logic, expression, null );
|
||||
}
|
||||
|
||||
public MatchRule( MatchLogic logic )
|
||||
{
|
||||
this( logic, "" );
|
||||
}
|
||||
|
||||
public MatchRule( String expression )
|
||||
{
|
||||
this( MatchLogic.ANY, expression );
|
||||
}
|
||||
|
||||
public static MatchRule not( String expression, boolean not )
|
||||
{
|
||||
return new MatchRule( not ? MatchLogic.NOT : MatchLogic.ANY, expression );
|
||||
}
|
||||
|
||||
public static MatchRule group( List<MatchRule> subRules, String expression )
|
||||
{
|
||||
MatchLogic logic = expression.startsWith( "!" ) ? MatchLogic.NOT : MatchLogic.ANY;
|
||||
return new MatchRule( logic, "", subRules );
|
||||
}
|
||||
|
||||
public boolean isGroup()
|
||||
{
|
||||
return subRules != null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum MatchLogic
|
||||
{
|
||||
OR,
|
||||
AND,
|
||||
XOR,
|
||||
NOT,
|
||||
ANY
|
||||
}
|
||||
}
|
||||
@@ -19,244 +19,208 @@
|
||||
package appeng.util.item;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class OreHelper
|
||||
{
|
||||
|
||||
public static final OreHelper INSTANCE = new OreHelper();
|
||||
public static final OreHelper INSTANCE = new OreHelper();
|
||||
|
||||
/**
|
||||
* A local cache to speed up OreDictionary lookups.
|
||||
*/
|
||||
private final LoadingCache<String, List<ItemStack>> oreDictCache = CacheBuilder.newBuilder().build( new CacheLoader<String, List<ItemStack>>()
|
||||
{
|
||||
@Override
|
||||
public List<ItemStack> load( final String oreName )
|
||||
{
|
||||
return OreDictionary.getOres( oreName );
|
||||
}
|
||||
} );
|
||||
/**
|
||||
* A local cache to speed up OreDictionary lookups.
|
||||
*/
|
||||
private final LoadingCache<String, List<ItemStack>> oreDictCache = CacheBuilder.newBuilder().build( new CacheLoader<String, List<ItemStack>>()
|
||||
{
|
||||
@Override
|
||||
public List<ItemStack> load( final String oreName )
|
||||
{
|
||||
return OreDictionary.getOres( oreName );
|
||||
}
|
||||
} );
|
||||
|
||||
private final Map<ItemRef, OreReference> references = new HashMap<>();
|
||||
private final Map<ItemRef, OreReference> references = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Test if the passed {@link ItemStack} is an ore.
|
||||
*
|
||||
* @param itemStack the itemstack to test
|
||||
*
|
||||
* @return true if an ore entry exists, false otherwise
|
||||
*/
|
||||
public Optional<OreReference> getOre( final ItemStack itemStack )
|
||||
{
|
||||
final ItemRef ir = new ItemRef( itemStack );
|
||||
/**
|
||||
* Test if the passed {@link ItemStack} is an ore.
|
||||
*
|
||||
* @param itemStack the itemstack to test
|
||||
* @return true if an ore entry exists, false otherwise
|
||||
*/
|
||||
public Optional<OreReference> getOre( final ItemStack itemStack )
|
||||
{
|
||||
final ItemRef ir = new ItemRef( itemStack );
|
||||
|
||||
if( !this.references.containsKey( ir ) )
|
||||
{
|
||||
final OreReference ref = new OreReference();
|
||||
final Collection<Integer> ores = ref.getOres();
|
||||
final Collection<String> set = ref.getEquivalents();
|
||||
if( !this.references.containsKey( ir ) )
|
||||
{
|
||||
final OreReference ref = new OreReference();
|
||||
final Collection<Integer> ores = ref.getOres();
|
||||
final Collection<String> set = ref.getEquivalents();
|
||||
|
||||
final Set<String> toAdd = new HashSet<>();
|
||||
final Set<String> toAdd = new HashSet<>();
|
||||
|
||||
for( final String ore : OreDictionary.getOreNames() )
|
||||
{
|
||||
// skip ore if it is a match already or null.
|
||||
if( ore == null || toAdd.contains( ore ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for( final String ore : OreDictionary.getOreNames() )
|
||||
{
|
||||
// skip ore if it is a match already or null.
|
||||
if( ore == null || toAdd.contains( ore ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for( final ItemStack oreItem : this.oreDictCache.getUnchecked( ore ) )
|
||||
{
|
||||
if( OreDictionary.itemMatches( oreItem, itemStack, false ) )
|
||||
{
|
||||
toAdd.add( ore );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for( final ItemStack oreItem : this.oreDictCache.getUnchecked( ore ) )
|
||||
{
|
||||
if( OreDictionary.itemMatches( oreItem, itemStack, false ) )
|
||||
{
|
||||
toAdd.add( ore );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( final String ore : toAdd )
|
||||
{
|
||||
set.add( ore );
|
||||
ores.add( OreDictionary.getOreID( ore ) );
|
||||
}
|
||||
for( final String ore : toAdd )
|
||||
{
|
||||
set.add( ore );
|
||||
ores.add( OreDictionary.getOreID( ore ) );
|
||||
}
|
||||
|
||||
if( !set.isEmpty() )
|
||||
{
|
||||
this.references.put( ir, ref );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.references.put( ir, null );
|
||||
}
|
||||
}
|
||||
if( !set.isEmpty() )
|
||||
{
|
||||
this.references.put( ir, ref );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.references.put( ir, null );
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.ofNullable( this.references.get( ir ) );
|
||||
}
|
||||
return Optional.ofNullable( this.references.get( ir ) );
|
||||
}
|
||||
|
||||
boolean sameOre( final AEItemStack aeItemStack, final IAEItemStack is )
|
||||
{
|
||||
final OreReference a = aeItemStack.getOre().orElse( null );
|
||||
final OreReference b = ( (AEItemStack) is ).getOre().orElse( null );
|
||||
boolean sameOre( final AEItemStack aeItemStack, final IAEItemStack is )
|
||||
{
|
||||
final OreReference a = aeItemStack.getOre().orElse( null );
|
||||
final OreReference b = ( (AEItemStack) is ).getOre().orElse( null );
|
||||
|
||||
return this.sameOre( a, b );
|
||||
}
|
||||
return this.sameOre( a, b );
|
||||
}
|
||||
|
||||
public boolean sameOre( final OreReference a, final OreReference b )
|
||||
{
|
||||
if( a == null || b == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public boolean sameOre( final OreReference a, final OreReference b )
|
||||
{
|
||||
if( a == null || b == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( a == b )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if( a == b )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
final Collection<Integer> bOres = b.getOres();
|
||||
for( final Integer ore : a.getOres() )
|
||||
{
|
||||
if( bOres.contains( ore ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final Collection<Integer> bOres = b.getOres();
|
||||
for( final Integer ore : a.getOres() )
|
||||
{
|
||||
if( bOres.contains( ore ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean sameOre( final AEItemStack aeItemStack, final ItemStack o )
|
||||
{
|
||||
return aeItemStack.getOre().map( a ->
|
||||
{
|
||||
for( final String oreName : a.getEquivalents() )
|
||||
{
|
||||
for( final ItemStack oreItem : this.oreDictCache.getUnchecked( oreName ) )
|
||||
{
|
||||
if( OreDictionary.itemMatches( oreItem, o, false ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} ).orElse( false );
|
||||
}
|
||||
boolean sameOre( final AEItemStack aeItemStack, final ItemStack o )
|
||||
{
|
||||
return aeItemStack.getOre().map( a -> {
|
||||
for( final String oreName : a.getEquivalents() )
|
||||
{
|
||||
for( final ItemStack oreItem : this.oreDictCache.getUnchecked( oreName ) )
|
||||
{
|
||||
if( OreDictionary.itemMatches( oreItem, o, false ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} ).orElse( false );
|
||||
}
|
||||
|
||||
public Set<Integer> getMatchingOre( String allow )
|
||||
{
|
||||
List<String> matchingOres = new ArrayList<>();
|
||||
ConcurrentMap<String, List<ItemStack>> oreKeys = oreDictCache.asMap();
|
||||
public Set<Integer> getMatchingOre( String oreExp )
|
||||
{
|
||||
Set<Integer> matchingIds = new HashSet<>();
|
||||
|
||||
oreKeys.forEach( ( s, l ) -> {
|
||||
List<OreDictFilterMatcher.MatchRule> rulesList = OreDictFilterMatcher.parseExpression( oreExp );
|
||||
for( String ore : OreDictionary.getOreNames() )
|
||||
{
|
||||
if( OreDictFilterMatcher.matches( rulesList, ore ) )
|
||||
{
|
||||
matchingIds.add( OreDictionary.getOreID( ore ) );
|
||||
}
|
||||
}
|
||||
return matchingIds;
|
||||
}
|
||||
|
||||
if( allow.startsWith( "*" ) && allow.endsWith( "*" ) )
|
||||
{
|
||||
if( s.contains( allow.substring( 1, allow.length() - 1 ) ) )
|
||||
{
|
||||
matchingOres.add( s );
|
||||
}
|
||||
}
|
||||
else if( allow.startsWith( "*" ) )
|
||||
{
|
||||
if( s.endsWith( allow.substring( 1 ) ) )
|
||||
{
|
||||
matchingOres.add( s );
|
||||
}
|
||||
}
|
||||
else if( allow.endsWith( "*" ) )
|
||||
{
|
||||
if( s.startsWith( allow.substring( 0, allow.length() - 1 ) ) )
|
||||
{
|
||||
matchingOres.add( s );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( s.matches( allow ) )
|
||||
{
|
||||
matchingOres.add( s );
|
||||
}
|
||||
}
|
||||
} );
|
||||
public List<ItemStack> getCachedOres( final String oreName )
|
||||
{
|
||||
return this.oreDictCache.getUnchecked( oreName );
|
||||
}
|
||||
|
||||
Set<Integer> oreIDs = new HashSet<>();
|
||||
for( String matchingOre : matchingOres )
|
||||
{
|
||||
oreIDs.add( OreDictionary.getOreID( matchingOre ) );
|
||||
}
|
||||
private static class ItemRef
|
||||
{
|
||||
|
||||
return oreIDs;
|
||||
}
|
||||
private final Item ref;
|
||||
private final int damage;
|
||||
private final int hash;
|
||||
|
||||
List<ItemStack> getCachedOres( final String oreName )
|
||||
{
|
||||
return this.oreDictCache.getUnchecked( oreName );
|
||||
}
|
||||
ItemRef( final ItemStack stack )
|
||||
{
|
||||
this.ref = stack.getItem();
|
||||
|
||||
private static class ItemRef
|
||||
{
|
||||
if( stack.getItem().isDamageable() )
|
||||
{
|
||||
this.damage = 0; // IGNORED
|
||||
}
|
||||
else
|
||||
{
|
||||
this.damage = stack.getItemDamage(); // might be important...
|
||||
}
|
||||
|
||||
private final Item ref;
|
||||
private final int damage;
|
||||
private final int hash;
|
||||
this.hash = this.ref.hashCode() ^ this.damage;
|
||||
}
|
||||
|
||||
ItemRef( final ItemStack stack )
|
||||
{
|
||||
this.ref = stack.getItem();
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
if( stack.getItem().isDamageable() )
|
||||
{
|
||||
this.damage = 0; // IGNORED
|
||||
}
|
||||
else
|
||||
{
|
||||
this.damage = stack.getItemDamage(); // might be important...
|
||||
}
|
||||
@Override
|
||||
public boolean equals( final Object obj )
|
||||
{
|
||||
if( obj == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( this.getClass() != obj.getClass() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final ItemRef other = (ItemRef) obj;
|
||||
return this.damage == other.damage && this.ref == other.ref;
|
||||
}
|
||||
|
||||
this.hash = this.ref.hashCode() ^ this.damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( final Object obj )
|
||||
{
|
||||
if( obj == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( this.getClass() != obj.getClass() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final ItemRef other = (ItemRef) obj;
|
||||
return this.damage == other.damage && this.ref == other.ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ItemRef [ref=" + this.ref.getUnlocalizedName() + ", damage=" + this.damage + ", hash=" + this.hash + ']';
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ItemRef [ref=" + this.ref.getUnlocalizedName() + ", damage=" + this.damage + ", hash=" + this.hash + ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,6 +102,7 @@ gui.appliedenergistics2.FluidTunnel=Fluid
|
||||
gui.appliedenergistics2.RedstoneTunnel=Redstone
|
||||
gui.appliedenergistics2.EUTunnel=EU
|
||||
gui.appliedenergistics2.FETunnel=FE
|
||||
gui.appliedenergistics2.GTEUTunnel=GTEU
|
||||
gui.appliedenergistics2.LightTunnel=Light
|
||||
gui.appliedenergistics2.OCTunnel=OpenComputers
|
||||
gui.appliedenergistics2.PressureTunnel=Pressure
|
||||
@@ -375,6 +376,7 @@ gui.tooltips.appliedenergistics2.HighlightInterface=Highlight interface
|
||||
gui.appliedenergistics2.units.appliedenergstics=AE
|
||||
gui.appliedenergistics2.units.ic2=Energy Units
|
||||
gui.appliedenergistics2.units.rf=Redstone Flux
|
||||
gui.appliedenergistics2.units.gteu=GTEU
|
||||
|
||||
// Colors
|
||||
gui.appliedenergistics2.White=White
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "appliedenergistics2:item/part/p2p_tunnel",
|
||||
"textures": {
|
||||
"type": "appliedenergistics2:parts/p2p/power_gteu"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "appliedenergistics2:part/p2p/p2p_tunnel_base",
|
||||
"textures": {
|
||||
"type": "appliedenergistics2:parts/p2p/power_gteu"
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"type": "forge:and",
|
||||
"values": [
|
||||
{
|
||||
"type": "appliedenergistics2:part_exists",
|
||||
"part": "part.storage_bus"
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item_exists",
|
||||
"item": "appliedenergistics2:interface"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"type": "appliedenergistics2:part",
|
||||
"part": "part.oredict_storage_bus"
|
||||
},
|
||||
"type": "appliedenergistics2:part_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:sticky_piston"
|
||||
},
|
||||
{
|
||||
"item": "#appliedenergistics2:interface"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:piston"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:book"
|
||||
}
|
||||
]
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"type": "forge:and",
|
||||
"values": [
|
||||
{
|
||||
"type": "appliedenergistics2:part_exists",
|
||||
"part": "part.storage_bus"
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item_exists",
|
||||
"item": "appliedenergistics2:interface"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"type": "appliedenergistics2:part",
|
||||
"part": "part.oredict_storage_bus"
|
||||
},
|
||||
"type": "appliedenergistics2:part_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"type": "appliedenergistics2:part",
|
||||
"part": "part.storage_bus"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:book"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 206 B |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "base:items/wrench"
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
[
|
||||
{
|
||||
"modid":"appliedenergistics2",
|
||||
"name":"Applied Energistics 2 Trousers Edition",
|
||||
"description":"A Mod about Matter, Energy and using them to conquer the world..",
|
||||
"version":"${version}",
|
||||
"mcversion":"${mcversion}",
|
||||
"url":"https://github.com/PrototypeTrousers/Applied-Energistics-2",
|
||||
"updateUrl":"",
|
||||
"authorList":[
|
||||
"AlgorithmX2"
|
||||
"modid": "appliedenergistics2",
|
||||
"name": "AE2 Unofficial Extended Life",
|
||||
"description": "A Mod about Matter, Energy and using them to conquer the world..",
|
||||
"version": "${version}",
|
||||
"mcversion": "${mcversion}",
|
||||
"url": "https://github.com/PrototypeTrousers/Applied-Energistics-2",
|
||||
"updateUrl": "",
|
||||
"authorList": [
|
||||
"AlgorithmX2"
|
||||
],
|
||||
"credits":"AlgorithmX2",
|
||||
"logoFile":"assets/appliedenergistics2/meta/logo.png",
|
||||
"credits": "AlgorithmX2",
|
||||
"logoFile": "assets/appliedenergistics2/meta/logo.png",
|
||||
"screenshots":[]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user