Compare commits

..

24 Commits

Author SHA1 Message Date
PrototypeTrousers 7dbea08961 item cost review 2021-11-29 00:51:39 -03:00
PrototypeTrousers 685bf7c6d2 tweak crafting byte costs 2021-11-02 17:55:42 -03:00
PrototypeTrousers 7c937afe7a version 2021-11-02 15:37:13 -03:00
PrototypeTrousers 7854673b45 cut crafting tree earlier if the item is available
fix job byte size to 8 per crafting + 1 per item used/stored
2021-11-02 15:33:25 -03:00
PrototypeTrousers 69cad513f3 log if non-patterned items go missing before starting a craft 2021-11-02 02:04:08 -03:00
PrototypeTrousers ff82fb6f4c potential fix for showing proper item names when failing to start craft 2021-11-01 23:23:53 -03:00
PrototypeTrousers b018985a54 update directly instead of relying on forge events 2021-10-29 15:12:30 -03:00
PrototypeTrousers 0c9544b5fb version 2021-10-29 14:19:10 -03:00
PrototypeTrousers b2bbcfbf93 backported #5349 2021-10-29 14:18:37 -03:00
PrototypeTrousers 48da4eaa06 potential fix for an infinite loop while adding nodes 2021-10-29 14:09:31 -03:00
Salomão 2a466a0e66 extra null check 2021-10-01 11:12:35 -03:00
PrototypeTrousers cfb6b28a33 fixes that didnt make it 2021-09-29 14:41:33 -03:00
PrototypeTrousers 058e91b7e4 v47 2021-09-18 22:11:35 -03:00
PrototypeTrousers 67bdd885d5 Revert all the energy "fixes". Will crash on concurrent modifications. 2021-09-18 21:48:53 -03:00
PrototypeTrousers 188e3a75cc simplify monitor passthrough listener logic 2021-09-18 21:45:03 -03:00
PrototypeTrousers b9f6029005 borrowed some fancy, colored, fluid rendering from gregicality
thank you @Yefancy
2021-09-18 21:42:21 -03:00
PrototypeTrousers b607e018e6 try to fix #51 2021-09-18 21:42:10 -03:00
PrototypeTrousers e6ccc24ae0 fix #49. you can now actually clear storage and conversion monitors 2021-09-18 21:41:57 -03:00
PrototypeTrousers 2cb452fd9e hash drawers handler by the amount of slots 2021-09-18 21:40:42 -03:00
PrototypeTrousers 855c6f61a9 fix JEI targeting disabled slots as valid 2021-09-18 21:40:24 -03:00
PrototypeTrousers 89a5ba46b1 fluid containers can now be drained/filled from fluid interfaces 2021-09-18 21:39:51 -03:00
PrototypeTrousers 69a3268549 small optimization to import/export busses 2021-09-18 21:39:34 -03:00
PrototypeTrousers 4b42e478f1 fix broken recipes resulting in item dupes 2021-09-18 21:38:57 -03:00
BalaM314 6d03c860c5 Fix #27
Not sure exactly what method is causing a crash, but added a catch to just say it is located in another dimension
2021-09-18 21:38:39 -03:00
143 changed files with 4554 additions and 8266 deletions
+2 -13
View File
@@ -15,10 +15,6 @@ Fixes:
- Exclusive Blocking mode for GTCE ( shapes, molds and configured circuits do not block GTCE machines )
- Blocking modes default to block on any item in the iventory the entity exposes
- Fuzzy includes items that report that they're damageable, but report a maxDamage of 0 ( auto-crafting of basic capacitors -> resonant capacitors is now possible ) <- Broken item implementation.
- Fix CME exceptions on the energy grid
- Fix AE going offline even with enough power by extracting from the local buffer always last
- Fix IO-Port copying craftable flag into items
- Fix NBT of old items not clearing on drives that reached 64 types once
Performance:
@@ -28,9 +24,6 @@ Performance:
- Count items set in interfaces before queuing crafting for them needlessly
- Backported b7ca98d ( Avoid copying items on simulated item extraction )
- Cache some level emitters functions
- Reduced import bus insert simulation to 1 before real insertion (if possible)
- Backported itemlist re-implementation along with pattern changes to avoid CraftingManager fallback issues
- Instead of recalculating all the content of the network on every change, track the changes properly and apply them to the cached list of items
QOL:
@@ -38,7 +31,7 @@ QOL:
- Added bar on the interface terminal that search by inputs ( The one on the LEFT, also searchs by interface name )
- Shortcut to molecular assemblers with free slots on the terminal interface by @Theisyat
- Toggle button on interface terminal to hide full interfaces
- JEI "U", "R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
- JEI "U""R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
- Patterns can now be made with items currently showing on JEI. ( This is overriden by Just Enough Energistics. )
- Added multiplier buttons to processing pattern gui
- Switched crafting terminal JEI search to fuzzy mode. If the recipe uses a damageable item, AE will try to grab it ( damaged tools )
@@ -46,11 +39,7 @@ QOL:
- Encoded patterns can be draggred on the interface terminal.
- Storage Monitor and Conversion Monitor now also ccepts fluids
- Draggable JEI ghost items (also works on bookmarked items. SHIFT + Click will move the hovered item into the first free target slot)
- JEI auto switches between crafting and processing patterns
- GTCE Blocking mode work through phantom itemfaces
- Shift-clicking blank patterns into the pattern terminal will try to fill the blank pattern slots first
- Mismached simulated/real item count ( most often due to compacting drawers ) will now tell the player wich item cause the failure when trying to start a craft
- Added 'pattern expansion' cards that adds an extra row of patterns to interfaces. up to 3 card on an interface. (each card will increase the interface idle power draw by 4 times)
-JEI auto switches between crafting and processing patterns
HOTKEYS:
+1 -1
View File
@@ -57,7 +57,7 @@ tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
version = aeversion + "-" + aechannel + "-" + aebuild + "-" + extended + "-" + extendedversion
version = aeversion + "-" + aechannel + "-" + aebuild + " " + trousers
group = aegroup
archivesBaseName = aebasename
+5 -3
View File
@@ -3,18 +3,20 @@ aechannel=stable
aebuild=7
aegroup=appeng
aebasename=appliedenergistics2
extended=extended_life
extendedversion=v52b
trousers=omni-fixes-v47i
#########################################################
# 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 #
#########################################################
@@ -26,7 +28,7 @@ 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
forestry_version=5.8.2.387
#########################################################
# Deployment #
#########################################################
+8 -9
View File
@@ -31,7 +31,7 @@ repositories {
maven {
name = "Tesla repo"
url "https://maven.mcmoddev.com"
url "http://maven.mcmoddev.com"
}
maven {
@@ -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,7 +80,8 @@ configurations {
}
dependencies {
deobfCompile "gregtechce:gregtech:1.12.2:1.15.1.735"
compileOnly "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"
@@ -94,11 +95,9 @@ 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"
deobfCompile "net.sengir.forestry:forestry_${minecraft_version}:$forestry_version"
// at runtime, use the full JEI jar
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
@@ -28,8 +28,7 @@ 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
GTEU( "gui.appliedenergistics2.units.gteu" ); // RF - Redstone Flux
RF( "gui.appliedenergistics2.units.rf" ); // RF - Redstone Flux
/**
* unlocalized name for the power unit.
@@ -47,13 +46,14 @@ 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,7 +29,6 @@ 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
@@ -58,8 +58,6 @@ public interface IParts
IItemDefinition storageBus();
IItemDefinition oreDictStorageBus();
IItemDefinition importBus();
IItemDefinition exportBus();
@@ -88,8 +86,6 @@ public interface IParts
IItemDefinition p2PTunnelFE();
IItemDefinition p2PTunnelGTEU();
IItemDefinition p2PTunnelLight();
// IItemDefinition p2PTunnelOpenComputers();
@@ -106,8 +102,6 @@ public interface IParts
IItemDefinition patternTerminal();
IItemDefinition expandedProcessingPatternTerminal();
IItemDefinition craftingTerminal();
IItemDefinition terminal();
@@ -44,7 +44,10 @@ public interface IStackWatcherHost
/**
* Called when a watched item changes amounts.
*
* @param o changed item list
* @param fullStack old stack
* @param diffStack new stack
* @param src action source
* @param chan storage channel
*/
void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan );
@@ -51,7 +51,6 @@ public interface IStorageGrid extends IGridCache, IStorageMonitorable
* @param input injected items
*/
void postAlterationOfStoredItems( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src );
void postCraftablesChanges( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src);
/**
* Used to add a cell provider to the storage system
@@ -119,10 +119,6 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
*
* @param is An item stack
*/
boolean equals( ItemStack is );
ItemStack getCachedItemStack( long stackSize );
void setCachedItemStack( ItemStack is );
boolean equals(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,14 +108,4 @@ 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,7 +20,6 @@ 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;
@@ -58,8 +57,6 @@ public final class Capabilities
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY;
public static Capability<IEnergyContainer> GTCE_ENERGY;
/**
* Register AE2 provided capabilities.
*/
@@ -106,19 +103,7 @@ public final class Capabilities
}
@CapabilityInject( IItemRepository.class )
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;
}
}
private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap ) { ITEM_REPOSITORY_CAPABILITY = cap; }
// Create a storage implementation that does not do anything
private static <T> Capability.IStorage<T> createNullStorage()
+37 -24
View File
@@ -33,7 +33,6 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import appeng.container.slot.*;
import appeng.util.Platform;
import com.google.common.base.Joiner;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
@@ -160,7 +159,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
final List<Slot> slots = this.getInventorySlots();
final Iterator<Slot> i = slots.iterator();
while ( i.hasNext() )
while( i.hasNext() )
{
if( i.next() instanceof SlotME )
{
@@ -209,17 +208,13 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
}
}
GlStateManager.enableDepth();
if( Platform.isModLoaded( "jei" ) )
{
bookmarkedJEIghostItem( mouseX, mouseY );
}
bookmarkedJEIghostItem(mouseX,mouseY);
GlStateManager.disableDepth();
}
@Optional.Method( modid = "jei" )
void bookmarkedJEIghostItem( final int mouseX, final int mouseY )
{
if( !isJeiGhostItem )
void bookmarkedJEIghostItem(final int mouseX, final int mouseY) {
if (!isJeiGhostItem)
{
bookmarkedIngredient = runtime.getBookmarkOverlay().getIngredientUnderMouse();
}
@@ -253,9 +248,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
}
}
}
private void drawTargets( int mouseX, int mouseY )
{
private void drawTargets(int mouseX, int mouseY) {
GlStateManager.disableLighting();
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{
@@ -384,13 +377,17 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
final AppEngSlot aeSlot = (AppEngSlot) slot;
if( aeSlot.isSlotEnabled() )
{
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18 );
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1,
18,
18 );
}
else
{
GlStateManager.color( 1.0F, 1.0F, 1.0F, 0.4F );
GlStateManager.enableBlend();
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18 );
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1,
18,
18 );
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
}
}
@@ -509,7 +506,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{
final EntityPlayer player = Minecraft.getMinecraft().player;
if( this.isJeiGhostItem && isDraggingJeiGhostItem )
if( this.isJeiGhostItem && isDraggingJeiGhostItem)
{
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{
@@ -762,8 +759,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
this.disableShiftClick = false;
}
if( clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem )
{
if (clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem) {
this.isDraggingJeiGhostItem = true;
return;
}
@@ -883,7 +879,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
if( stack != ItemStack.EMPTY )
{
InventoryAction direction = wheel > 0 ? InventoryAction.PLACE_SINGLE : InventoryAction.PICKUP_SINGLE;
final PacketInventoryAction p = new PacketInventoryAction( direction, slot.slotNumber, 0 );
final PacketInventoryAction p = new PacketInventoryAction( direction , slot.slotNumber , 0);
NetworkHandler.instance().sendToServer( p );
}
}
@@ -1036,11 +1032,27 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
final float f1 = 0.00390625F;
final float f = 0.00390625F;
final float par6 = 16;
vb.pos( par1 + 0, par2 + par6, this.zLevel ).tex( ( par3 + 0 ) * f, ( par4 + par6 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
vb.pos( par1 + 0, par2 + par6, this.zLevel )
.tex( ( par3 + 0 ) * f, ( par4 + par6 ) * f1 )
.color( 1.0f, 1.0f, 1.0f,
aes.getOpacityOfIcon() )
.endVertex();
final float par5 = 16;
vb.pos( par1 + par5, par2 + par6, this.zLevel ).tex( ( par3 + par5 ) * f, ( par4 + par6 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
vb.pos( par1 + par5, par2 + 0, this.zLevel ).tex( ( par3 + par5 ) * f, ( par4 + 0 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
vb.pos( par1 + 0, par2 + 0, this.zLevel ).tex( ( par3 + 0 ) * f, ( par4 + 0 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
vb.pos( par1 + par5, par2 + par6, this.zLevel )
.tex( ( par3 + par5 ) * f, ( par4 + par6 ) * f1 )
.color( 1.0f, 1.0f, 1.0f,
aes.getOpacityOfIcon() )
.endVertex();
vb.pos( par1 + par5, par2 + 0, this.zLevel )
.tex( ( par3 + par5 ) * f, ( par4 + 0 ) * f1 )
.color( 1.0f, 1.0f, 1.0f,
aes.getOpacityOfIcon() )
.endVertex();
vb.pos( par1 + 0, par2 + 0, this.zLevel )
.tex( ( par3 + 0 ) * f, ( par4 + 0 ) * f1 )
.color( 1.0f, 1.0f, 1.0f,
aes.getOpacityOfIcon() )
.endVertex();
tessellator.draw();
}
@@ -1054,7 +1066,8 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{
if( ( (AppEngSlot) s ).getIsValid() == hasCalculatedValidness.NotAvailable )
{
boolean isValid = s.isItemValid( is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled || s instanceof SlotInaccessible || s instanceof SlotFake || s instanceof SlotRestrictedInput || s instanceof SlotDisconnected;
boolean isValid = s.isItemValid(
is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled || s instanceof SlotInaccessible || s instanceof SlotFake || s instanceof SlotRestrictedInput || s instanceof SlotDisconnected;
if( isValid && s instanceof SlotRestrictedInput )
{
try
@@ -104,7 +104,7 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
}
if( doStart && GuiScreen.isShiftKeyDown() && Mouse.isButtonDown( 0 ) )
{
if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm || gui instanceof GuiExpandedProcessingPatternTerm )
if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm )
{
IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui );
for( Target<I> target : targets )
@@ -21,7 +21,6 @@ package appeng.client.gui.implementations;
import java.io.IOException;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
@@ -124,12 +123,6 @@ public class GuiCraftAmount extends AEBaseGui
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
}
if( target instanceof PartExpandedProcessingPatternTerminal )
{
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
if( this.originalGui != null && !myIcon.isEmpty() )
{
this.buttonList.add( this.originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender ) );
@@ -25,7 +25,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import com.google.common.base.Joiner;
import org.lwjgl.input.Mouse;
@@ -105,11 +104,6 @@ public class GuiCraftConfirm extends AEBaseGui
{
this.OriginalGui = GuiBridge.GUI_PATTERN_TERMINAL;
}
if( te instanceof PartExpandedProcessingPatternTerminal )
{
this.OriginalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
}
boolean isAutoStart()
@@ -25,7 +25,6 @@ package appeng.client.gui.implementations;
import java.io.IOException;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import org.lwjgl.input.Mouse;
import net.minecraft.client.gui.GuiButton;
@@ -96,12 +95,6 @@ public class GuiCraftingStatus extends GuiCraftingCPU
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
}
if( target instanceof PartExpandedProcessingPatternTerminal )
{
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
}
@Override
@@ -1,277 +0,0 @@
package appeng.client.gui.implementations;
import appeng.api.config.ActionItems;
import appeng.api.config.ItemSubstitution;
import appeng.api.config.Settings;
import appeng.api.storage.ITerminalHost;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.SlotFake;
import appeng.core.AELog;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.*;
public class GuiExpandedProcessingPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
{
private static final String BACKGROUND_EXPANDED_PROCESSING_MODE = "guis/pattern_processing_expanded.png";
private static final String SUBSITUTION_DISABLE = "0";
private static final String SUBSITUTION_ENABLE = "1";
private static final String CRAFTMODE_CRFTING = "1";
private static final String CRAFTMODE_PROCESSING = "0";
private GuiTabButton tabCraftButton;
private GuiTabButton tabProcessButton;
private GuiImgButton substitutionsEnabledBtn;
private GuiImgButton substitutionsDisabledBtn;
private GuiImgButton encodeBtn;
private GuiImgButton clearBtn;
private GuiImgButton x2Btn;
private GuiImgButton x3Btn;
private GuiImgButton plusOneBtn;
private GuiImgButton divTwoBtn;
private GuiImgButton divThreeBtn;
private GuiImgButton minusOneBtn;
private GuiImgButton maxCountBtn;
public Map<IGhostIngredientHandler.Target<?>, Object> mapTargetSlot = new HashMap<>();
public GuiExpandedProcessingPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
super( inventoryPlayer, te, new ContainerExpandedProcessingPatternTerm( inventoryPlayer, te ) );
this.setReservedSpace( 81 );
}
@Override
protected void actionPerformed( final GuiButton btn )
{
super.actionPerformed( btn );
try
{
if( this.tabCraftButton == btn || this.tabProcessButton == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
}
if( this.encodeBtn == btn )
{
if( isShiftKeyDown() )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "2" ) );
}
else
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "1" ) );
}
}
if( this.clearBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Clear", "1" ) );
}
if( this.x2Btn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByTwo", "1" ) );
}
if( this.x3Btn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByThree", "1" ) );
}
if( this.divTwoBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByTwo", "1" ) );
}
if( this.divThreeBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByThree", "1" ) );
}
if( this.plusOneBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.IncreaseByOne", "1" ) );
}
if( this.minusOneBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DecreaseByOne", "1" ) );
}
if( this.maxCountBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MaximizeCount", "1" ) );
}
if( this.substitutionsEnabledBtn == btn || this.substitutionsDisabledBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
}
}
catch( final IOException e )
{
AELog.error( e );
}
}
@Override
public void initGui()
{
super.initGui();
this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.CRAFTING_TABLE ), GuiText.CraftingPattern.getLocal(), this.itemRender );
this.buttonList.add( this.tabCraftButton );
this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.FURNACE ), GuiText.ProcessingPattern.getLocal(), this.itemRender );
this.buttonList.add( this.tabProcessButton );
this.substitutionsEnabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.ENABLED );
this.substitutionsEnabledBtn.setHalfSize( true );
this.buttonList.add( this.substitutionsEnabledBtn );
this.substitutionsDisabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.DISABLED );
this.substitutionsDisabledBtn.setHalfSize( true );
this.buttonList.add( this.substitutionsDisabledBtn );
this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE );
this.clearBtn.setHalfSize( true );
this.buttonList.add( this.clearBtn );
this.x3Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.MULTIPLY_BY_THREE );
this.x3Btn.setHalfSize( true );
this.buttonList.add( this.x3Btn );
this.x2Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.MULTIPLY_BY_TWO );
this.x2Btn.setHalfSize( true );
this.buttonList.add( this.x2Btn );
this.plusOneBtn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.INCREASE_BY_ONE );
this.plusOneBtn.setHalfSize( true );
this.buttonList.add( this.plusOneBtn );
this.divThreeBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.DIVIDE_BY_THREE );
this.divThreeBtn.setHalfSize( true );
this.buttonList.add( this.divThreeBtn );
this.divTwoBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.DIVIDE_BY_TWO );
this.divTwoBtn.setHalfSize( true );
this.buttonList.add( this.divTwoBtn );
this.minusOneBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.DECREASE_BY_ONE );
this.minusOneBtn.setHalfSize( true );
this.buttonList.add( this.minusOneBtn );
//this.maxCountBtn = new GuiImgButton( this.guiLeft + 128, this.guiTop + this.ySize - 108, Settings.ACTIONS, ActionItems.MAX_COUNT );
//this.maxCountBtn.setHalfSize( true );
//this.buttonList.add( this.maxCountBtn );
this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE );
this.buttonList.add( this.encodeBtn );
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.tabCraftButton.visible = false;
this.tabProcessButton.visible = true;
this.substitutionsEnabledBtn.visible = false;
this.substitutionsDisabledBtn.visible = false;
this.x2Btn.visible = true;
this.x3Btn.visible = true;
this.divTwoBtn.visible = true;
this.divThreeBtn.visible = true;
this.plusOneBtn.visible = true;
this.minusOneBtn.visible = true;
//this.maxCountBtn.visible = true;
super.drawFG( offsetX, offsetY, mouseX, mouseY );
this.fontRenderer.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.getReservedSpace(), 4210752 );
}
@Override
protected String getBackground()
{
return BACKGROUND_EXPANDED_PROCESSING_MODE;
}
@Override
protected void repositionSlot( final AppEngSlot s )
{
final int offsetPlayerSide = s.isPlayerSide() ? 5 : 3;
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
}
@Override
public List<IGhostIngredientHandler.Target<?>> getPhantomTargets( Object ingredient )
{
if( !( ingredient instanceof ItemStack ) )
{
return Collections.emptyList();
}
List<IGhostIngredientHandler.Target<?>> targets = new ArrayList<>();
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotFake )
{
ItemStack itemStack = (ItemStack) ingredient;
IGhostIngredientHandler.Target<Object> target = new IGhostIngredientHandler.Target<Object>()
{
@Override
public Rectangle getArea()
{
return new Rectangle( getGuiLeft() + slot.xPos, getGuiTop() + slot.yPos, 16, 16 );
}
@Override
public void accept( Object ingredient )
{
final PacketInventoryAction p;
try
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (SlotFake) slot, AEItemStack.fromItemStack( itemStack ) );
NetworkHandler.instance().sendToServer( p );
}
catch( IOException e )
{
e.printStackTrace();
}
}
};
targets.add( target );
mapTargetSlot.putIfAbsent( target, slot );
}
}
return targets;
}
@Override
public Map<IGhostIngredientHandler.Target<?>, Object> getFakeSlotTargetMap()
{
return mapTargetSlot;
}
}
@@ -1,179 +0,0 @@
package appeng.client.gui.implementations;
import appeng.api.config.AccessRestriction;
import appeng.api.config.ActionItems;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.container.implementations.ContainerOreDictStorageBus;
import appeng.core.AELog;
import appeng.core.localization.GuiText;
import appeng.core.sync.GuiBridge;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketConfigButton;
import appeng.core.sync.packets.PacketSwitchGuis;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.util.item.OreDictFilterMatcher;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import org.lwjgl.input.Mouse;
import java.io.IOException;
import java.util.regex.Pattern;
public class GuiOreDictStorageBus extends AEBaseGui
{
private final ContainerOreDictStorageBus container;
PartOreDicStorageBus part;
private GuiTabButton priority;
private GuiImgButton partition;
private GuiImgButton storageFilter;
private GuiImgButton rwMode;
private static final Pattern ORE_DICTIONARY_FILTER = Pattern.compile( "[(!]* *[0-9a-zA-Z*]* *\\)*( *[&|^]? *[(!]* *[0-9a-zA-Z*]* *\\)*)*" );
private MEGuiTextField searchFieldInputs;
public GuiOreDictStorageBus( final InventoryPlayer inventoryPlayer, final PartOreDicStorageBus te )
{
super( new ContainerOreDictStorageBus( inventoryPlayer, te ) );
this.container = (ContainerOreDictStorageBus) super.inventorySlots;
part = te;
this.ySize = 84;
}
@Override
public void initGui()
{
super.initGui();
this.searchFieldInputs = new MEGuiTextField( this.fontRenderer, this.guiLeft + 3, this.guiTop + 22, 170, 12 );
this.searchFieldInputs.setEnableBackgroundDrawing( false );
this.searchFieldInputs.setMaxStringLength( 512 );
this.searchFieldInputs.setTextColor( 0xFFFFFF );
this.searchFieldInputs.setVisible( true );
this.searchFieldInputs.setFocused( false );
this.searchFieldInputs.setValidator( str -> ORE_DICTIONARY_FILTER.matcher( str ).matches() );
this.buttonList.add( this.priority = new GuiTabButton( this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender ) );
this.buttonList.add( this.partition = new GuiImgButton( this.guiLeft - 18, this.guiTop + 28, Settings.ACTIONS, ActionItems.WRENCH ) );
this.buttonList.add( this.rwMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 48, Settings.ACCESS, AccessRestriction.READ_WRITE ) );
this.buttonList.add( this.storageFilter = new GuiImgButton( this.guiLeft - 18, this.guiTop + 68, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY ) );
try
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.getRegex", "1" ) );
}
catch( IOException e )
{
e.printStackTrace();
}
}
public void fillRegex( String regex )
{
this.searchFieldInputs.setText( regex );
}
@Override
protected void actionPerformed( final GuiButton btn ) throws IOException
{
super.actionPerformed( btn );
final boolean backwards = Mouse.isButtonDown( 1 );
try
{
if( btn == this.priority )
{
NetworkHandler.instance().sendToServer( new PacketSwitchGuis( GuiBridge.GUI_PRIORITY ) );
}
else if( btn == this.partition )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "StorageBus.Action", "Partition" ) );
}
else if( btn == this.rwMode )
{
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.rwMode.getSetting(), backwards ) );
}
else if( btn == this.storageFilter )
{
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.storageFilter.getSetting(), backwards ) );
}
}
catch( final IOException e )
{
AELog.debug( e );
}
}
@Override
protected void mouseClicked( final int xCoord, final int yCoord, final int btn ) throws IOException
{
boolean wasFocused = this.searchFieldInputs.isFocused();
this.searchFieldInputs.mouseClicked( xCoord, yCoord, btn );
if( btn == 1 && this.searchFieldInputs.isMouseIn( xCoord, yCoord ) )
{
this.searchFieldInputs.setText( "" );
}
if( !searchFieldInputs.isFocused() && wasFocused )
{
searchFieldInputs.setText( OreDictFilterMatcher.validateExp( searchFieldInputs.getText() ) );
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.save", searchFieldInputs.getText() ) );
}
super.mouseClicked( xCoord, yCoord, btn );
}
@Override
protected void keyTyped( final char character, final int key ) throws IOException
{
if( !this.checkHotbarKeys( key ) )
{
if( !this.searchFieldInputs.textboxKeyTyped( character, key ) )
{
super.keyTyped( character, key );
}
}
}
@Override
public void drawFG( int offsetX, int offsetY, int mouseX, int mouseY )
{
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.OreDictStorageBus.getLocal() ), 8, 6, 4210752 );
this.fontRenderer.drawString( this.searchFieldInputs.getText().length() + " / " + this.searchFieldInputs.getMaxStringLength(), 120, 36, 4210752 );
this.fontRenderer.drawString( "& = AND " + "| = OR", 8, 36, 4210752 );
this.fontRenderer.drawString( "^ = XOR " + "! = NOT", 8, 48, 4210752 );
this.fontRenderer.drawString( "() for priority " + "* for wildcard", 8, 60, 4210752 );
this.fontRenderer.drawString( "Ex.: *Redstone*&!dustRedstone", 8, 72, 4210752 );
if( this.storageFilter != null )
{
this.storageFilter.set( container.getStorageFilter() );
}
if( this.rwMode != null )
{
this.rwMode.set( container.getReadWriteMode() );
}
}
@Override
public void drawBG( int offsetX, int offsetY, int mouseX, int mouseY )
{
this.bindTexture( "guis/oredictstoragebus.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, 175, 85 );
if( this.searchFieldInputs != null )
{
this.searchFieldInputs.drawTextBox();
}
}
}
@@ -87,7 +87,6 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 16 * 10, Settings.POWER_UNITS, PowerUnits.AE, ButtonToolTips.PowerUnits, PowerUnits.AE.unlocalizedName );
this.registerApp( 16 * 10 + 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 );
@@ -109,11 +108,15 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 16 * 2 + 3, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Auto );
this.registerApp( 16 * 2 + 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 );
@@ -171,15 +174,19 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 16 * 11 + 2, Settings.CRAFT_VIA_REDSTONE, YesNo.YES, ButtonToolTips.EmitterMode, ButtonToolTips.CraftViaRedstone );
this.registerApp( 16 * 11 + 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 );
}
}
@@ -329,7 +336,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" );
}
@@ -19,9 +19,14 @@
package appeng.client.render.model;
import appeng.block.storage.BlockDrive;
import appeng.block.storage.DriveSlotState;
import appeng.block.storage.DriveSlotsState;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -32,12 +37,9 @@ import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.property.IExtendedBlockState;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import appeng.block.storage.BlockDrive;
import appeng.block.storage.DriveSlotState;
import appeng.block.storage.DriveSlotsState;
public class DriveBakedModel implements IBakedModel
@@ -55,17 +57,13 @@ public class DriveBakedModel implements IBakedModel
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
List<BakedQuad> result = new ArrayList<>( this.bakedBase.getQuads( state, side, rand ) );
List<BakedQuad> result = new ArrayList<>();
result.addAll( this.bakedBase.getQuads( state, side, rand ) );
if( side == null && state instanceof IExtendedBlockState )
{
IExtendedBlockState extState = (IExtendedBlockState) state;
if (!extState.getUnlistedNames().contains( BlockDrive.SLOTS_STATE ))
{
return result;
}
DriveSlotsState slotsState = extState.getValue( BlockDrive.SLOTS_STATE );
for( int row = 0; row < 5; row++ )
@@ -26,7 +26,6 @@ import java.util.concurrent.Future;
import javax.annotation.Nonnull;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import com.google.common.collect.ImmutableSet;
import net.minecraft.entity.player.EntityPlayer;
@@ -150,7 +149,6 @@ public class ContainerCraftConfirm extends AEBaseContainer
if( ccr.getCpu() == c )
{
found = true;
break;
}
}
@@ -347,15 +345,11 @@ public class ContainerCraftConfirm extends AEBaseContainer
originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
}
if( ah instanceof PartExpandedProcessingPatternTerminal )
{
originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
if( this.result != null && !this.isSimulation() )
{
final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class );
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true, this.getActionSrc() );
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true,
this.getActionSrc() );
this.setAutoStart( false );
if( g != null && originalGui != null && this.getOpenContext() != null )
{
@@ -1,528 +0,0 @@
package appeng.container.implementations;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.storage.ITerminalHost;
import appeng.container.slot.*;
import appeng.helpers.IContainerCraftingPacket;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import appeng.util.Platform;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.InvOperation;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.PlayerInvWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static appeng.helpers.PatternHelper.PROCESSING_INPUT_LIMIT;
import static appeng.helpers.PatternHelper.PROCESSING_OUTPUT_LIMIT;
public class ContainerExpandedProcessingPatternTerm extends ContainerMEMonitorable implements IAEAppEngInventory, IOptionalSlotHost, IContainerCraftingPacket
{
private final IItemHandler crafting;
private final SlotFakeCraftingMatrix[] gridSlots = new SlotFakeCraftingMatrix[PROCESSING_INPUT_LIMIT];
private final OptionalSlotFake[] outputSlots = new OptionalSlotFake[PROCESSING_OUTPUT_LIMIT];
private final SlotRestrictedInput patternSlotIN;
private final SlotRestrictedInput patternSlotOUT;
private final PartExpandedProcessingPatternTerminal expandedProcessingPatternTerminal;
public ContainerExpandedProcessingPatternTerm( InventoryPlayer ip, ITerminalHost monitorable )
{
super( ip, monitorable, false );
this.expandedProcessingPatternTerminal = (PartExpandedProcessingPatternTerminal) monitorable;
final IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
final IItemHandler output = this.getExpandedPatternTerminal().getInventoryByName( "output" );
this.crafting = this.getExpandedPatternTerminal().getInventoryByName( "crafting" );
for( int y = 0; y < 4; y++ )
{
for( int x = 0; x < 4; x++ )
{
this.addSlotToContainer( this.gridSlots[x + y * 4] = new SlotFakeCraftingMatrix( this.crafting, x + y * 4, 4 + x * 18, -85 + y * 18 ) );
}
}
for( int y = 0; y < 3; y++ )
{
for( int x = 0; x < 2; x++ )
{
this.addSlotToContainer( this.outputSlots[x + y * 2] = new SlotPatternOutputs( output, this, x + y * 2, 96 + x * 18, -76 + y * 18, 0, 0, 1 ) );
this.outputSlots[x + y * 2].setRenderDisabled( false );
this.outputSlots[x + y * 2].setIIcon( -1 );
}
}
this.addSlotToContainer( this.patternSlotIN = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.BLANK_PATTERN, patternInv, 0, 147, -72 - 9, this.getInventoryPlayer() ) );
this.addSlotToContainer( this.patternSlotOUT = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, patternInv, 1, 147, -72 + 34, this.getInventoryPlayer() ) );
this.patternSlotOUT.setStackLimit( 1 );
this.bindPlayerInventory( ip, 0, 0 );
}
@Override
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
{
if( Platform.isClient() )
{
return ItemStack.EMPTY;
}
if( this.inventorySlots.get( idx ) instanceof SlotPlayerInv || this.inventorySlots.get( idx ) instanceof SlotPlayerHotBar )
{
final AppEngSlot clickSlot = (AppEngSlot) this.inventorySlots.get( idx ); // require AE SLots!
ItemStack itemStack = clickSlot.getStack();
if( AEApi.instance().definitions().materials().blankPattern().isSameAs( itemStack ) )
{
IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
clickSlot.putStack( remainder );
}
}
return super.transferStackInSlot( p, idx );
}
@Override
public void saveChanges()
{
}
@Override
public void onChangeInventory( final IItemHandler inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
{
}
public void encodeAndMoveToInventory()
{
encode();
ItemStack output = this.patternSlotOUT.getStack();
if( !output.isEmpty() )
{
if( !getPlayerInv().addItemStackToInventory( output ) )
{
getPlayerInv().player.dropItem( output, false );
}
this.patternSlotOUT.putStack( ItemStack.EMPTY );
}
}
public void encode()
{
ItemStack output = this.patternSlotOUT.getStack();
final ItemStack[] in = this.getInputs();
final ItemStack[] out = this.getOutputs();
// if there is no input, this would be silly.
if( in == null || out == null )
{
return;
}
// first check the output slots, should either be null, or a pattern
if( !output.isEmpty() && !this.isPattern( output ) )
{
return;
} // if nothing is there we should snag a new pattern.
else if( output.isEmpty() )
{
output = this.patternSlotIN.getStack();
if( output.isEmpty() || !this.isPattern( output ) )
{
return; // no blanks.
}
// remove one, and clear the input slot.
output.setCount( output.getCount() - 1 );
if( output.getCount() == 0 )
{
this.patternSlotIN.putStack( ItemStack.EMPTY );
}
// add a new encoded pattern.
Optional<ItemStack> maybePattern = AEApi.instance().definitions().items().encodedPattern().maybeStack( 1 );
if( maybePattern.isPresent() )
{
output = maybePattern.get();
this.patternSlotOUT.putStack( output );
}
}
// encode the slot.
final NBTTagCompound encodedValue = new NBTTagCompound();
final NBTTagList tagIn = new NBTTagList();
final NBTTagList tagOut = new NBTTagList();
for( final ItemStack i : in )
{
tagIn.appendTag( this.createItemTag( i ) );
}
for( final ItemStack i : out )
{
tagOut.appendTag( this.createItemTag( i ) );
}
encodedValue.setTag( "in", tagIn );
encodedValue.setTag( "out", tagOut );
encodedValue.setBoolean( "crafting", false );
encodedValue.setBoolean( "substitute", false );
output.setTagCompound( encodedValue );
}
boolean isPattern( final ItemStack output )
{
if( output.isEmpty() )
{
return false;
}
final IDefinitions definitions = AEApi.instance().definitions();
boolean isPattern = definitions.items().encodedPattern().isSameAs( output );
isPattern |= definitions.materials().blankPattern().isSameAs( output );
return isPattern;
}
NBTBase createItemTag( final ItemStack i )
{
final NBTTagCompound c = new NBTTagCompound();
if( !i.isEmpty() )
{
i.writeToNBT( c );
}
return c;
}
@Override
public boolean isSlotEnabled( final int idx )
{
return true;
}
protected ItemStack[] getInputs()
{
final ItemStack[] input = new ItemStack[16];
boolean hasValue = false;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() )
{
hasValue = true;
}
}
if( hasValue )
{
return input;
}
return null;
}
protected ItemStack[] getOutputs()
{
final List<ItemStack> list = new ArrayList<>( 3 );
boolean hasValue = false;
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() > 0 )
{
list.add( out );
hasValue = true;
}
}
if( hasValue )
{
return list.toArray( new ItemStack[0] );
}
return null;
}
public void clear()
{
for( final Slot s : this.gridSlots )
{
s.putStack( ItemStack.EMPTY );
}
for( final Slot s : this.outputSlots )
{
s.putStack( ItemStack.EMPTY );
}
this.detectAndSendChanges();
}
@Override
public IItemHandler getInventoryByName( final String name )
{
if( name.equals( "player" ) )
{
return new PlayerInvWrapper( this.getInventoryPlayer() );
}
return this.getExpandedPatternTerminal().getInventoryByName( name );
}
@Override
public boolean useRealItems()
{
return false;
}
public PartExpandedProcessingPatternTerminal getExpandedPatternTerminal()
{
return this.expandedProcessingPatternTerminal;
}
public void multiply( int multiple )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canMultiplyInputs = true;
boolean canMultiplyOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() * multiple > input[x].getMaxStackSize() )
{
canMultiplyInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() * multiple > out.getMaxStackSize() )
{
canMultiplyOutputs = false;
}
}
if( canMultiplyInputs && canMultiplyOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() * multiple );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() * multiple );
}
}
}
}
public void divide( int divide )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canDivideInputs = true;
boolean canDivideOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() % divide != 0 )
{
canDivideInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() % divide != 0 )
{
canDivideOutputs = false;
}
}
if( canDivideInputs && canDivideOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() / divide );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() / divide );
}
}
}
}
public void increase( int increase )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canIncreaseInputs = true;
boolean canIncreaseOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() + increase > input[x].getMaxStackSize() )
{
canIncreaseInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() + increase > out.getMaxStackSize() )
{
canIncreaseOutputs = false;
}
}
if( canIncreaseInputs && canIncreaseOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() + increase );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() + increase );
}
}
}
}
public void decrease( int decrease )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canDecreaseInputs = true;
boolean canDecreaseOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() - decrease < 1 )
{
canDecreaseInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() - decrease < 1 )
{
canDecreaseOutputs = false;
}
}
if( canDecreaseInputs && canDecreaseOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() - decrease );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() - decrease );
}
}
}
}
public void maximizeCount()
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canGrowInputs = true;
boolean canGrowOutputs = true;
int maxInputStackGrowth = 0;
int maxOutputStackGrowth = 0;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getMaxStackSize() - input[x].getCount() > maxInputStackGrowth )
{
maxInputStackGrowth = input[x].getMaxStackSize() - input[x].getCount();
}
if( !input[x].isEmpty() && input[x].getCount() + maxInputStackGrowth > input[x].getMaxStackSize() )
{
canGrowInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
{
maxOutputStackGrowth = out.getMaxStackSize() - out.getCount();
}
if( !out.isEmpty() && out.getCount() + maxOutputStackGrowth > out.getMaxStackSize() )
{
canGrowOutputs = false;
}
}
if( canGrowInputs && canGrowOutputs )
{
int maxStackGrowth = Math.min( maxInputStackGrowth, maxOutputStackGrowth );
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
}
}
}
}
}
@@ -1,140 +0,0 @@
package appeng.container.implementations;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.AEBaseContainer;
import appeng.container.guisync.GuiSync;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import appeng.util.item.OreReference;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraftforge.oredict.OreDictionary;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class ContainerOreDictStorageBus extends AEBaseContainer
{
private final PartOreDicStorageBus part;
@GuiSync( 3 )
public AccessRestriction rwMode = AccessRestriction.READ_WRITE;
@GuiSync( 4 )
public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY;
public ContainerOreDictStorageBus( final InventoryPlayer ip, final PartOreDicStorageBus anchor )
{
super( ip, anchor );
this.part = anchor;
this.bindPlayerInventory( ip, 14, 256 - /* height of player inventory */82 );
}
@Override
public void detectAndSendChanges()
{
this.verifyPermissions( SecurityPermissions.BUILD, false );
if( Platform.isServer() )
{
this.setReadWriteMode( (AccessRestriction) part.getConfigManager().getSetting( Settings.ACCESS ) );
this.setStorageFilter( (StorageFilter) part.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
super.detectAndSendChanges();
}
public void partition()
{
final IMEInventory<IAEItemStack> cellInv = this.part.getInternalHandler();
if( cellInv == null )
{
return;
}
Set<Integer> oreIDs = new HashSet<>();
for( IAEItemStack itemStack : cellInv.getAvailableItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) )
{
OreReference ref = ( (AEItemStack) itemStack ).getOre().orElse( null );
if( ref != null )
{
oreIDs.addAll( ref.getOres() );
}
}
String oreMatch = "(";
String append = "";
for( Iterator<Integer> it = oreIDs.iterator(); it.hasNext(); )
{
int oreID = it.next();
if( it.hasNext() )
{
append = ")|(";
}
else
{
append = ")";
}
oreMatch = oreMatch.concat( OreDictionary.getOreName( oreID ) + append );
}
if( oreMatch.equals( "(" ) )
{
oreMatch = "";
}
part.saveOreMatch( oreMatch );
this.detectAndSendChanges();
}
public void saveOreMatch( String value )
{
part.saveOreMatch( value );
}
public void sendRegex()
{
try
{
NetworkHandler.instance().sendTo( new PacketValueConfig( "OreDictStorageBus.sendRegex", part.getOreExp() ), (EntityPlayerMP) getInventoryPlayer().player );
}
catch( IOException e )
{
e.printStackTrace();
}
}
public AccessRestriction getReadWriteMode()
{
return this.rwMode;
}
private void setReadWriteMode( final AccessRestriction rwMode )
{
this.rwMode = rwMode;
}
public StorageFilter getStorageFilter()
{
return this.storageFilter;
}
private void setStorageFilter( final StorageFilter storageFilter )
{
this.storageFilter = storageFilter;
}
}
@@ -178,7 +178,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
this.getAndUpdateOutput();
}
protected ItemStack getAndUpdateOutput()
private ItemStack getAndUpdateOutput()
{
final World world = this.getPlayerInv().player.world;
final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 );
@@ -505,7 +505,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
}
}
protected ItemStack[] getInputs()
private ItemStack[] getInputs()
{
final ItemStack[] input = new ItemStack[9];
boolean hasValue = false;
@@ -527,7 +527,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return null;
}
protected ItemStack[] getOutputs()
private ItemStack[] getOutputs()
{
if( this.isCraftingMode() )
{
@@ -535,7 +535,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
if( !out.isEmpty() && out.getCount() > 0 )
{
return new ItemStack[]{out};
return new ItemStack[] { out };
}
}
else
@@ -563,7 +563,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return null;
}
boolean isPattern( final ItemStack output )
private boolean isPattern( final ItemStack output )
{
if( output.isEmpty() )
{
@@ -578,7 +578,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return isPattern;
}
NBTBase createItemTag( final ItemStack i )
private NBTBase createItemTag( final ItemStack i )
{
final NBTTagCompound c = new NBTTagCompound();
@@ -824,7 +824,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return this.patternTerminal;
}
boolean isSubstitute()
private boolean isSubstitute()
{
return this.substitute;
}
+53 -88
View File
@@ -20,7 +20,11 @@ package appeng.core;
import java.io.File;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import com.google.common.collect.Sets;
@@ -60,67 +64,13 @@ 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 String[] nonBlockingItems = {
"[gregtech|actuallyadditions]", "gregtech:circuit.integrated",
"gregtech:shape.mold.plate", "gregtech:shape.mold.gear",
"gregtech:shape.mold.credit", "gregtech:shape.mold.bottle",
"gregtech:shape.mold.ingot", "gregtech:shape.mold.ball",
"gregtech:shape.mold.block", "gregtech:shape.mold.nugget",
"gregtech:shape.mold.cylinder", "gregtech:shape.mold.anvil",
"gregtech:shape.mold.name", "gregtech:shape.mold.gear.small",
"gregtech:shape.mold.rotor", "gregtech:shape.extruder.plate",
"gregtech:shape.extruder.rod", "gregtech:shape.extruder.bolt",
"gregtech:shape.extruder.ring", "gregtech:shape.extruder.cell",
"gregtech:shape.extruder.ingot", "gregtech:shape.extruder.wire",
"gregtech:shape.extruder.pipe.tiny",
"gregtech:shape.extruder.pipe.small",
"gregtech:shape.extruder.pipe.medium",
"gregtech:shape.extruder.pipe.normal",
"gregtech:shape.extruder.pipe.large",
"gregtech:shape.extruder.pipe.huge",
"gregtech:shape.extruder.block", "gregtech:shape.extruder.sword",
"gregtech:shape.extruder.pickaxe", "gregtech:shape.extruder.shovel",
"gregtech:shape.extruder.axe", "gregtech:shape.extruder.hoe",
"gregtech:shape.extruder.hammer", "gregtech:shape.extruder.file",
"gregtech:shape.extruder.saw", "gregtech:shape.extruder.gear",
"gregtech:shape.extruder.bottle", "gregtech:shape.extruder.foil",
"gregtech:shape.extruder.gear_small",
"gregtech:shape.extruder.rod_long", "gregtech:shape.extruder.rotor",
"gregtech:glass_lens.white", "gregtech:glass_lens.orange",
"gregtech:glass_lens.magenta", "gregtech:glass_lens.light_blue",
"gregtech:glass_lens.yellow", "gregtech:glass_lens.lime",
"gregtech:glass_lens.pink", "gregtech:glass_lens.gray",
"gregtech:glass_lens.light_gray", "gregtech:glass_lens.cyan",
"gregtech:glass_lens.purple", "gregtech:glass_lens.blue",
"gregtech:glass_lens.brown", "gregtech:glass_lens.green",
"gregtech:glass_lens.red", "gregtech:glass_lens.black",
"contenttweaker:smallgearextrudershape",
"contenttweaker:creativeportabletankmold", "ore:lensAlmandine",
"ore:lensBlueTopaz", "ore:lensDiamond", "ore:lensEmerald",
"ore:lensGreenSapphire", "ore:lensRutile", "ore:lensRuby",
"ore:lensSapphire", "ore:lensTopaz", "ore:lensJasper",
"ore:lensGlass", "ore:lensOlivine", "ore:lensOpal",
"ore:lensAmethyst", "ore:lensLapis", "ore:lensEnderPearl",
"ore:lensEnderEye", "ore:lensGarnetRed", "ore:lensGarnetYellow",
"ore:lensVinteum", "ore:lensNetherStar",
};
private static final String[] ORES_VANILLA = { "Obsidian", "Ender", "EnderPearl", "Coal", "Iron", "Gold", "Charcoal", "NetherQuartz" };
private static final String[] ORES_AE = { "CertusQuartz", "Wheat", "Fluix" };
private static final String[] ORES_COMMON = { "Copper", "Tin", "Silver", "Lead", "Bronze" };
private static final String[] ORES_MISC = { "Brass", "Platinum", "Nickel", "Invar", "Aluminium", "Electrum", "Osmium", "Zinc" };
// Default Energy Conversion Rates
private static final double DEFAULT_IC2_EXCHANGE = 2.0;
private static final double DEFAULT_GTEU_EXCHANGE = 2.0;
private static final double DEFAULT_RF_EXCHANGE = 0.5;
private final IConfigManager settings = new ConfigManager( this );
@@ -140,10 +90,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;
@@ -175,7 +125,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;
@@ -198,7 +148,6 @@ public final class AEConfig extends Configuration implements IConfigurableObject
PowerUnits.EU.conversionRatio = this.get( "PowerRatios", "IC2", DEFAULT_IC2_EXCHANGE ).getDouble( DEFAULT_IC2_EXCHANGE );
PowerUnits.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 );
@@ -206,24 +155,32 @@ 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( "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.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 );
@@ -231,16 +188,23 @@ 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 );
@@ -281,7 +245,8 @@ 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 )
{
@@ -297,13 +262,17 @@ public final class AEConfig extends Configuration implements IConfigurableObject
{
this.storageProviderID = this.get( "spatialio", "storageProviderID", this.storageProviderID ).getInt( this.storageProviderID );
this.storageDimensionID = this.get( "spatialio", "storageDimensionID", this.storageDimensionID ).getInt( this.storageDimensionID );
this.spatialPowerMultiplier = this.get( "spatialio", "spatialPowerMultiplier", this.spatialPowerMultiplier ).getDouble( this.spatialPowerMultiplier );
this.spatialPowerMultiplier = this.get( "spatialio", "spatialPowerMultiplier", this.spatialPowerMultiplier )
.getDouble(
this.spatialPowerMultiplier );
this.spatialPowerExponent = this.get( "spatialio", "spatialPowerExponent", this.spatialPowerExponent ).getDouble( this.spatialPowerExponent );
}
if( this.isFeatureEnabled( AEFeature.CRAFTING_CPU ) )
{
this.craftingCalculationTimePerTick = this.get( "craftingCPU", "craftingCalculationTimePerTick", this.craftingCalculationTimePerTick ).getInt( this.craftingCalculationTimePerTick );
this.craftingCalculationTimePerTick = this.get( "craftingCPU", "craftingCalculationTimePerTick", this.craftingCalculationTimePerTick )
.getInt(
this.craftingCalculationTimePerTick );
}
this.updatable = true;
@@ -477,7 +446,8 @@ 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() );
@@ -745,11 +715,6 @@ public final class AEConfig extends Configuration implements IConfigurableObject
return this.quartzOresClusterAmount;
}
public String[] getNonBlockingItems()
{
return nonBlockingItems;
}
public int getChargedChange()
{
return this.chargedChange;
+2 -4
View File
@@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import appeng.helpers.NonBlockingItems;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
@@ -184,7 +183,8 @@ public final class AppEng
AELog.info( "Pre Initialization ( ended after " + watch.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
// Instantiate all Plugins
List<Object> injectables = Lists.newArrayList( AEApi.instance() );
List<Object> injectables = Lists.newArrayList(
AEApi.instance() );
new PluginLoader().loadPlugins( injectables, event.getAsmData() );
}
@@ -239,8 +239,6 @@ public final class AppEng
AppEng.proxy.postInit();
AEConfig.instance().save();
NonBlockingItems.INSTANCE.init();
NetworkRegistry.INSTANCE.registerGuiHandler( this, GuiBridge.GUI_Handler );
NetworkHandler.init( "AE2" );
@@ -52,7 +52,6 @@ public final class ApiParts implements IParts
private final IItemDefinition toggleBus;
private final IItemDefinition invertedToggleBus;
private final IItemDefinition storageBus;
private final IItemDefinition oreDictStorageBus;
private final IItemDefinition importBus;
private final IItemDefinition exportBus;
private final IItemDefinition iface;
@@ -70,7 +69,6 @@ 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;
@@ -79,7 +77,6 @@ public final class ApiParts implements IParts
private final IItemDefinition darkMonitor;
private final IItemDefinition interfaceTerminal;
private final IItemDefinition patternTerminal;
private final IItemDefinition expandedProcessingPatternTerminal;
private final IItemDefinition craftingTerminal;
private final IItemDefinition terminal;
private final IItemDefinition storageMonitor;
@@ -92,7 +89,9 @@ 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() )
@@ -113,7 +112,6 @@ public final class ApiParts implements IParts
this.toggleBus = new DamagedItemDefinition( "part.toggle_bus", itemPart.createPart( PartType.TOGGLE_BUS ) );
this.invertedToggleBus = new DamagedItemDefinition( "part.toggle_bus.inverted", itemPart.createPart( PartType.INVERTED_TOGGLE_BUS ) );
this.storageBus = new DamagedItemDefinition( "part.bus.storage", itemPart.createPart( PartType.STORAGE_BUS ) );
this.oreDictStorageBus = new DamagedItemDefinition( "part.bus.oredict_storage", itemPart.createPart( PartType.OREDICT_STORAGE_BUS ) );
this.importBus = new DamagedItemDefinition( "part.bus.import", itemPart.createPart( PartType.IMPORT_BUS ) );
this.exportBus = new DamagedItemDefinition( "part.bus.export", itemPart.createPart( PartType.EXPORT_BUS ) );
this.iface = new DamagedItemDefinition( "part.interface", itemPart.createPart( PartType.INTERFACE ) );
@@ -121,7 +119,8 @@ 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 ) );
@@ -131,7 +130,6 @@ 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 ) );
@@ -141,7 +139,6 @@ public final class ApiParts implements IParts
this.darkMonitor = new DamagedItemDefinition( "part.monitor.dark", itemPart.createPart( PartType.DARK_MONITOR ) );
this.interfaceTerminal = new DamagedItemDefinition( "part.terminal.interface", itemPart.createPart( PartType.INTERFACE_TERMINAL ) );
this.patternTerminal = new DamagedItemDefinition( "part.terminal.pattern", itemPart.createPart( PartType.PATTERN_TERMINAL ) );
this.expandedProcessingPatternTerminal = new DamagedItemDefinition( "part.terminal.expanded_processing_pattern", itemPart.createPart( PartType.EXPANDED_PROCESSING_PATTERN_TERMINAL ) );
this.craftingTerminal = new DamagedItemDefinition( "part.terminal.crafting", itemPart.createPart( PartType.CRAFTING_TERMINAL ) );
this.terminal = new DamagedItemDefinition( "part.terminal", itemPart.createPart( PartType.TERMINAL ) );
this.storageMonitor = new DamagedItemDefinition( "part.monitor.storage", itemPart.createPart( PartType.STORAGE_MONITOR ) );
@@ -248,12 +245,6 @@ public final class ApiParts implements IParts
return this.storageBus;
}
@Override
public IItemDefinition oreDictStorageBus()
{
return this.oreDictStorageBus;
}
@Override
public IItemDefinition importBus()
{
@@ -338,11 +329,6 @@ public final class ApiParts implements IParts
return this.p2PTunnelFE;
}
public IItemDefinition p2PTunnelGTEU()
{
return this.p2PTunnelGTEU;
}
@Override
public IItemDefinition p2PTunnelLight()
{
@@ -393,12 +379,6 @@ public final class ApiParts implements IParts
return this.patternTerminal;
}
@Override
public IItemDefinition expandedProcessingPatternTerminal()
{
return this.expandedProcessingPatternTerminal;
}
@Override
public IItemDefinition craftingTerminal()
{
@@ -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,7 +126,6 @@ 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 ),
@@ -164,6 +163,7 @@ 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,14 +19,13 @@
package appeng.core.features.registries;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
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;
@@ -68,25 +67,6 @@ 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
*/
@@ -147,12 +127,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
this.addNewAttunement( this.getModItem( "enderio", "itemitemconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.ITEM );
this.addNewAttunement( this.getModItem( "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
@@ -168,12 +148,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
this.addNewAttunement( this.getModItem( "enderio", "itemliquidconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.FLUID );
this.addNewAttunement( this.getModItem( "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() )
{
@@ -70,7 +70,6 @@ public enum GuiText
EnergyDrain,
StorageBus,
OreDictStorageBus,
StorageBusFluids,
Priority,
Security,
@@ -99,7 +98,6 @@ public enum GuiText
OCTunnel,
LightTunnel,
FETunnel,
GTEUTunnel,
PressureTunnel,
// spatial
@@ -31,10 +31,8 @@ public enum WailaText
DeviceMissingChannel,
P2PUnlinked,
P2P_INPUT_ONE_OUTPUT,
P2P_INPUT_MANY_OUTPUTS,
P2P_OUTPUT_ONE_INPUT,
P2P_OUTPUT_MANY_INPUTS,
P2PInputOneOutput,
P2PInputManyOutputs,
P2POutput,
Locked,
@@ -24,9 +24,34 @@ import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import appeng.core.sync.packets.*;
import io.netty.buffer.ByteBuf;
import appeng.core.sync.packets.PacketAssemblerAnimation;
import appeng.core.sync.packets.PacketClick;
import appeng.core.sync.packets.PacketCompassRequest;
import appeng.core.sync.packets.PacketCompassResponse;
import appeng.core.sync.packets.PacketCompressedNBT;
import appeng.core.sync.packets.PacketConfigButton;
import appeng.core.sync.packets.PacketCraftRequest;
import appeng.core.sync.packets.PacketFluidSlot;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketJEIRecipe;
import appeng.core.sync.packets.PacketLightning;
import appeng.core.sync.packets.PacketMEFluidInventoryUpdate;
import appeng.core.sync.packets.PacketMEInventoryUpdate;
import appeng.core.sync.packets.PacketMatterCannon;
import appeng.core.sync.packets.PacketMockExplosion;
import appeng.core.sync.packets.PacketPaintedEntity;
import appeng.core.sync.packets.PacketPartPlacement;
import appeng.core.sync.packets.PacketPatternSlot;
import appeng.core.sync.packets.PacketProgressBar;
import appeng.core.sync.packets.PacketSwapSlots;
import appeng.core.sync.packets.PacketSwitchGuis;
import appeng.core.sync.packets.PacketTargetFluidStack;
import appeng.core.sync.packets.PacketTargetItemStack;
import appeng.core.sync.packets.PacketTransitionEffect;
import appeng.core.sync.packets.PacketValueConfig;
public class AppEngPacketHandlerBase
{
@@ -82,10 +107,7 @@ public class AppEngPacketHandlerBase
PACKET_PAINTED_ENTITY( PacketPaintedEntity.class ),
PACKET_FLUID_TANK( PacketFluidSlot.class ),
PACKET_INFORM_PLAYER( PacketInformPlayer.class );
PACKET_FLUID_TANK( PacketFluidSlot.class );
private final Class<? extends AppEngPacket> packetClass;
private final Constructor<? extends AppEngPacket> packetConstructor;
+33 -7
View File
@@ -21,9 +21,6 @@ package appeng.core.sync;
import java.lang.reflect.Constructor;
import appeng.container.implementations.*;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
@@ -56,6 +53,39 @@ import appeng.client.gui.GuiNull;
import appeng.container.AEBaseContainer;
import appeng.container.ContainerNull;
import appeng.container.ContainerOpenContext;
import appeng.container.implementations.ContainerCellWorkbench;
import appeng.container.implementations.ContainerChest;
import appeng.container.implementations.ContainerCondenser;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.container.implementations.ContainerCraftConfirm;
import appeng.container.implementations.ContainerCraftingCPU;
import appeng.container.implementations.ContainerCraftingStatus;
import appeng.container.implementations.ContainerCraftingTerm;
import appeng.container.implementations.ContainerDrive;
import appeng.container.implementations.ContainerFormationPlane;
import appeng.container.implementations.ContainerGrinder;
import appeng.container.implementations.ContainerIOPort;
import appeng.container.implementations.ContainerInscriber;
import appeng.container.implementations.ContainerInterface;
import appeng.container.implementations.ContainerInterfaceTerminal;
import appeng.container.implementations.ContainerLevelEmitter;
import appeng.container.implementations.ContainerMAC;
import appeng.container.implementations.ContainerMEMonitorable;
import appeng.container.implementations.ContainerMEPortableCell;
import appeng.container.implementations.ContainerNetworkStatus;
import appeng.container.implementations.ContainerNetworkTool;
import appeng.container.implementations.ContainerPatternTerm;
import appeng.container.implementations.ContainerPriority;
import appeng.container.implementations.ContainerQNB;
import appeng.container.implementations.ContainerQuartzKnife;
import appeng.container.implementations.ContainerSecurityStation;
import appeng.container.implementations.ContainerSkyChest;
import appeng.container.implementations.ContainerSpatialIOPort;
import appeng.container.implementations.ContainerStorageBus;
import appeng.container.implementations.ContainerUpgradeable;
import appeng.container.implementations.ContainerVibrationChamber;
import appeng.container.implementations.ContainerWireless;
import appeng.container.implementations.ContainerWirelessTerm;
import appeng.fluids.container.ContainerFluidFormationPlane;
import appeng.fluids.container.ContainerFluidIO;
import appeng.fluids.container.ContainerFluidInterface;
@@ -141,8 +171,6 @@ public enum GuiBridge implements IGuiHandler
GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_OREDICTSTORAGEBUS( ContainerOreDictStorageBus.class, PartOreDicStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_STORAGEBUS_FLUID( ContainerFluidStorageBus.class, PartFluidStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
@@ -157,8 +185,6 @@ public enum GuiBridge implements IGuiHandler
GUI_PATTERN_TERMINAL( ContainerPatternTerm.class, PartPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL( ContainerExpandedProcessingPatternTerm.class, PartExpandedProcessingPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
GUI_FLUID_TERMINAL( ContainerFluidTerminal.class, ITerminalHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
// extends (Container/Gui) + Bus
@@ -1,89 +0,0 @@
package appeng.core.sync.packets;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.AppEng;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.util.item.AEItemStack;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.text.TextComponentString;
import java.io.IOException;
public class PacketInformPlayer extends AppEngPacket
{
private IAEItemStack actualItem = null;
private IAEItemStack reportedItem = null;
private final InfoType type;
public PacketInformPlayer( ByteBuf stream ) throws IOException
{
this.type = InfoType.values()[stream.readInt()];
if( type == InfoType.PARTIAL_ITEM_EXTRACTION )
{
this.reportedItem = AEItemStack.fromPacket( stream );
this.actualItem = AEItemStack.fromPacket( stream );
}
else if( type == InfoType.NO_ITEMS_EXTRACTED )
{
this.reportedItem = AEItemStack.fromPacket( stream );
}
}
public PacketInformPlayer( final IAEItemStack iaeItemStack ) throws IOException
{
this( iaeItemStack, null );
}
public PacketInformPlayer( IAEItemStack extra, IAEItemStack result ) throws IOException
{
this.reportedItem = extra;
this.actualItem = result;
if( actualItem == null )
{
this.type = InfoType.NO_ITEMS_EXTRACTED;
}
else
{
this.type = InfoType.PARTIAL_ITEM_EXTRACTION;
}
final ByteBuf data = Unpooled.buffer();
data.writeInt( this.getPacketID() );
data.writeInt( type.ordinal() );
reportedItem.writeToPacket( data );
if( actualItem != null )
{
actualItem.writeToPacket( data );
}
this.configureWrite( data );
}
@Override
public void clientPacketData( final INetworkInfo network, final AppEngPacket packet, final EntityPlayer player )
{
TextComponentString msg = null;
if( this.type == InfoType.PARTIAL_ITEM_EXTRACTION )
{
AppEng.proxy.getPlayers().get( 0 ).sendStatusMessage( new TextComponentString( "System reported " + reportedItem.getStackSize() + " " + reportedItem.getItem().getItemStackDisplayName( reportedItem.getDefinition() ) + " available but could only extract" + actualItem.getStackSize() ), false );
}
else if( this.type == InfoType.NO_ITEMS_EXTRACTED )
{
AppEng.proxy.getPlayers().get( 0 ).sendStatusMessage( new TextComponentString( "System reported " + reportedItem.getStackSize() + " " + reportedItem.getItem().getItemStackDisplayName( reportedItem.getDefinition() ) + " available but could not extract anything" ), false );
}
}
public enum InfoType
{
PARTIAL_ITEM_EXTRACTION,
NO_ITEMS_EXTRACTED
}
}
@@ -192,20 +192,7 @@ public class PacketInventoryAction extends AppEngPacket
}
else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM )
{
if( sender.openContainer instanceof ContainerFluidConfigurable )
{
if( this.slotItem != null )
{
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
if( aefs != null )
{
aefs.setStackSize( 1000 );
( (ContainerFluidConfigurable) sender.openContainer ).getFluidConfigInventory().setFluidInSlot( this.slot, aefs );
NetworkHandler.instance().sendToServer( new PacketFluidSlot( Collections.singletonMap( this.slot, aefs ) ) );
}
}
}
else if( this.slot < sender.openContainer.inventorySlots.size() && sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake )
if( sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake )
{
if( this.slotItem != null )
{
@@ -230,6 +217,20 @@ public class PacketInventoryAction extends AppEngPacket
AELog.debug( e );
}
}
if( sender.openContainer instanceof ContainerFluidConfigurable )
{
if( this.slotItem != null )
{
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
if( aefs != null )
{
aefs.setStackSize( 1000 );
( (ContainerFluidConfigurable) sender.openContainer ).getFluidConfigInventory().setFluidInSlot( this.slot, aefs );
NetworkHandler.instance().sendToServer( new PacketFluidSlot( Collections.singletonMap( this.slot, aefs ) ) );
}
}
}
}
else
{
@@ -23,13 +23,13 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Iterator;
import appeng.api.config.FuzzyMode;
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
import appeng.api.storage.data.IItemList;
import appeng.container.implementations.ContainerPatternTerm;
import gregtech.common.items.MetaTool;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -40,7 +40,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.items.IItemHandler;
import appeng.api.AEApi;
@@ -70,9 +69,8 @@ import appeng.util.prioritylist.IPartitionList;
public class PacketJEIRecipe extends AppEngPacket
{
private List<ItemStack[]> recipe;
private List<ItemStack> output;
static ItemStack[] emptyArray = {ItemStack.EMPTY};
private ItemStack[][] recipe;
private ItemStack[] output;
// automatic.
@@ -83,35 +81,28 @@ public class PacketJEIRecipe extends AppEngPacket
final NBTTagCompound comp = CompressedStreamTools.readCompressed( bytes );
if( comp != null )
{
this.recipe = new ArrayList<>();
for( int x = 0; x < comp.getKeySet().size(); x++ )
this.recipe = new ItemStack[9][];
for( int x = 0; x < this.recipe.length; x++ )
{
if( comp.hasKey( "#" + x ) )
final NBTTagList list = comp.getTagList( "#" + x, 10 );
if( list.tagCount() > 0 )
{
final NBTTagList list = comp.getTagList( "#" + x, 10 );
if( list.tagCount() > 0 )
this.recipe[x] = new ItemStack[list.tagCount()];
for( int y = 0; y < list.tagCount(); y++ )
{
this.recipe.add( new ItemStack[list.tagCount()] );
for( int y = 0; y < list.tagCount(); y++ )
{
this.recipe.get( x )[y] = new ItemStack( list.getCompoundTagAt( y ) );
}
}
else
{
this.recipe.add( emptyArray );
this.recipe[x][y] = new ItemStack( list.getCompoundTagAt( y ) );
}
}
}
if( comp.hasKey( "outputs" ) )
{
final NBTTagList outputList = comp.getTagList( "outputs", 10 );
this.output = new ArrayList<>();
for( int z = 0; z < outputList.tagCount(); z++ )
if ( comp.hasKey("outputs") ) {
final NBTTagList outputList = comp.getTagList("outputs", 10);
this.output = new ItemStack[3];
for( int x = 0; x < this.output.length; x++ )
{
this.output.add( new ItemStack( outputList.getCompoundTagAt( z ) ) );
if( outputList.tagCount() > 0 )
{
this.output[x] = new ItemStack(outputList.getCompoundTagAt( x ));
}
}
}
}
@@ -175,23 +166,15 @@ public class PacketJEIRecipe extends AppEngPacket
{
ItemStack currentItem = craftMatrix.getStackInSlot( x );
if( x >= this.recipe.size() )
{
currentItem = ItemStack.EMPTY;
}
// prepare slots
if( !currentItem.isEmpty() )
{
// already the correct item?
ItemStack newItem = this.canUseInSlot( x, currentItem );
if( !cct.useRealItems() && this.recipe.get( x ) != null )
{
if( this.recipe.get( x ).length > 0 )
{
currentItem.setCount( recipe.get( x )[0].getCount() );
}
if ( !cct.useRealItems() && this.recipe[x] != null ) {
if (this.recipe[x].length > 0 )
currentItem.setCount( recipe[x][0].getCount() );
}
// put away old item
@@ -210,12 +193,12 @@ public class PacketJEIRecipe extends AppEngPacket
}
}
if( currentItem.isEmpty() && recipe.size() > x && recipe.get( x ) != null )
if( currentItem.isEmpty() && this.recipe[x] != null )
{
// for each variant
for( int y = 0; y < this.recipe.get( x ).length && currentItem.isEmpty(); y++ )
for( int y = 0; y < this.recipe[x].length && currentItem.isEmpty(); y++ )
{
final IAEItemStack request = AEItemStack.fromItemStack( this.recipe.get( x )[y] );
final IAEItemStack request = AEItemStack.fromItemStack( this.recipe[x][y] );
if( request != null )
{
// try ae
@@ -229,7 +212,7 @@ public class PacketJEIRecipe extends AppEngPacket
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
if( out == null )
{
if( request.getItem().isDamageable() || Platform.isGTDamageableItem( request.getItem() ) )
if( request.getItem().isDamageable() || ( Platform.isModLoaded( "gregtech" ) && request.getItem() instanceof MetaTool ) )
{
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
for( IAEItemStack is : outList )
@@ -262,9 +245,9 @@ public class PacketJEIRecipe extends AppEngPacket
if( out != null )
{
if( !cct.useRealItems() )
if (!cct.useRealItems())
{
out.setStackSize( recipe.get( x )[y].getCount() );
out.setStackSize( recipe[x][y].getCount() );
}
currentItem = out.createItemStack();
}
@@ -277,20 +260,20 @@ public class PacketJEIRecipe extends AppEngPacket
if( cct.useRealItems() )
{
currentItem = ad.removeSimilarItems( 1, this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null );
currentItem = ad.removeSimilarItems(1, this.recipe[x][y],FuzzyMode.IGNORE_ALL, null );
}
else
{
currentItem = ad.simulateSimilarRemove( recipe.get( x )[y].getCount(), this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null );
currentItem = ad.simulateSimilarRemove(recipe[x][y].getCount(), this.recipe[x][y],FuzzyMode.IGNORE_ALL, null );
}
}
}
}
if( !cct.useRealItems() )
if (!cct.useRealItems())
{
if( currentItem.isEmpty() && recipe.size() > x && this.recipe.get( x ) != null )
if( currentItem.isEmpty() && this.recipe[x] != null )
{
currentItem = this.recipe.get( x )[0].copy();
currentItem = this.recipe[x][0].copy();
}
}
}
@@ -299,35 +282,29 @@ public class PacketJEIRecipe extends AppEngPacket
con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) );
if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) )
if( this.output != null && con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() )
{
IItemHandler outputSlots = cct.getInventoryByName( "output" );
for( int i = 0; i < outputSlots.getSlots(); ++i )
for( int i = 0; i < this.output.length; ++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 ) );
if( this.output[i] == null ) continue;
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output[i] );
}
}
}
}
/**
*
* @param slot
* @param is itemstack
* @param is itemstack
* @return is if it can be used, else EMPTY
*/
private ItemStack canUseInSlot( int slot, ItemStack is )
{
if( this.recipe.get( slot ) != null )
if( this.recipe[slot] != null )
{
for( ItemStack option : this.recipe.get( slot ) )
for( ItemStack option : this.recipe[slot] )
{
if( ItemStack.areItemStacksEqual( is, option ) )
{
@@ -24,8 +24,6 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import appeng.client.gui.implementations.GuiOreDictStorageBus;
import appeng.container.implementations.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -42,6 +40,17 @@ import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.client.gui.implementations.GuiCraftingCPU;
import appeng.container.AEBaseContainer;
import appeng.container.implementations.ContainerCellWorkbench;
import appeng.container.implementations.ContainerCraftConfirm;
import appeng.container.implementations.ContainerCraftingCPU;
import appeng.container.implementations.ContainerCraftingStatus;
import appeng.container.implementations.ContainerLevelEmitter;
import appeng.container.implementations.ContainerNetworkTool;
import appeng.container.implementations.ContainerPatternTerm;
import appeng.container.implementations.ContainerPriority;
import appeng.container.implementations.ContainerQuartzKnife;
import appeng.container.implementations.ContainerSecurityStation;
import appeng.container.implementations.ContainerStorageBus;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.fluids.container.ContainerFluidLevelEmitter;
@@ -157,109 +166,58 @@ public class PacketValueConfig extends AppEngPacket
final ContainerFluidLevelEmitter lvc = (ContainerFluidLevelEmitter) c;
lvc.setLevel( Long.parseLong( this.Value ), player );
}
else if( this.Name.startsWith( "PatternTerminal." ) )
else if( this.Name.startsWith( "PatternTerminal." ) && c instanceof ContainerPatternTerm )
{
if( c instanceof ContainerPatternTerm )
final ContainerPatternTerm cpt = (ContainerPatternTerm) c;
if( this.Name.equals( "PatternTerminal.CraftMode" ) )
{
final ContainerPatternTerm cpt = (ContainerPatternTerm) c;
if( this.Name.equals( "PatternTerminal.CraftMode" ) )
{
cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) );
cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) );
}
else if( this.Name.equals( "PatternTerminal.Encode" ) )
{
if (this.Value.equals( "2" )) {
cpt.encodeAndMoveToInventory();
}
else if( this.Name.equals( "PatternTerminal.Encode" ) )
else
{
if( this.Value.equals( "2" ) )
{
cpt.encodeAndMoveToInventory();
}
else
{
cpt.encode();
}
}
else if( this.Name.equals( "PatternTerminal.Clear" ) )
{
cpt.clear();
}
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
{
cpt.multiply( 2 );
}
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
{
cpt.multiply( 3 );
}
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
{
cpt.divide( 2 );
}
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
{
cpt.divide( 3 );
}
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
{
cpt.increase( 1 );
}
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
{
cpt.decrease( 1 );
}
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
{
cpt.maximizeCount();
}
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
{
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
cpt.encode();
}
}
else if( c instanceof ContainerExpandedProcessingPatternTerm )
else if( this.Name.equals( "PatternTerminal.Clear" ) )
{
final ContainerExpandedProcessingPatternTerm cept = (ContainerExpandedProcessingPatternTerm) c;
if( this.Name.equals( "PatternTerminal.Encode" ) )
{
if( this.Value.equals( "2" ) )
{
cept.encodeAndMoveToInventory();
}
else
{
cept.encode();
}
}
else if( this.Name.equals( "PatternTerminal.Clear" ) )
{
cept.clear();
}
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
{
cept.multiply( 2 );
}
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
{
cept.multiply( 3 );
}
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
{
cept.divide( 2 );
}
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
{
cept.divide( 3 );
}
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
{
cept.increase( 1 );
}
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
{
cept.decrease( 1 );
}
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
{
cept.maximizeCount();
}
cpt.clear();
}
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
{
cpt.multiply(2);
}
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
{
cpt.multiply(3);
}
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
{
cpt.divide(2);
}
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
{
cpt.divide(3);
}
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
{
cpt.increase(1);
}
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
{
cpt.decrease(1);
}
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
{
cpt.maximizeCount();
}
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
{
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
}
}
else if( this.Name.startsWith( "StorageBus." ) )
@@ -276,11 +234,6 @@ public class PacketValueConfig extends AppEngPacket
{
( (ContainerFluidStorageBus) c ).partition();
}
else if( c instanceof ContainerOreDictStorageBus )
{
( (ContainerOreDictStorageBus) c ).partition();
( (ContainerOreDictStorageBus) c ).sendRegex();
}
}
else if( this.Value.equals( "Clear" ) )
{
@@ -295,20 +248,6 @@ public class PacketValueConfig extends AppEngPacket
}
}
}
else if( this.Name.startsWith( "OreDictStorageBus" ) )
{
if( c instanceof ContainerOreDictStorageBus )
{
if( this.Name.equals( "OreDictStorageBus.save" ) )
{
( (ContainerOreDictStorageBus) c ).saveOreMatch( this.Value );
}
if( this.Name.equals( "OreDictStorageBus.getRegex" ) )
{
( (ContainerOreDictStorageBus) c ).sendRegex();
}
}
}
else if( this.Name.startsWith( "CellWorkbench." ) && c instanceof ContainerCellWorkbench )
{
final ContainerCellWorkbench ccw = (ContainerCellWorkbench) c;
@@ -385,14 +324,6 @@ public class PacketValueConfig extends AppEngPacket
( (GuiCraftingCPU) gs ).clearItems();
}
}
else if( this.Name.equals( "OreDictStorageBus.sendRegex" ) )
{
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if( gs instanceof GuiOreDictStorageBus )
{
( (GuiOreDictStorageBus) gs ).fillRegex( this.Value );
}
}
else if( c instanceof IConfigurableObject )
{
final IConfigManager cm = ( (IConfigurableObject) c ).getConfigManager();
+78 -94
View File
@@ -19,6 +19,15 @@
package appeng.crafting;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.networking.IGrid;
@@ -27,6 +36,7 @@ import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingCallback;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingJob;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IStorageGrid;
@@ -36,64 +46,56 @@ import appeng.api.storage.data.IItemList;
import appeng.api.util.DimensionalCoord;
import appeng.core.AELog;
import appeng.hooks.TickHandler;
import appeng.me.cache.GridStorageCache;
import com.google.common.base.Stopwatch;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
public class CraftingJob implements Runnable, ICraftingJob
{
private static final String LOG_CRAFTING_JOB = "CraftingJob (%s) issued by %s requesting [%s] using %s bytes took %s us";
private static final String LOG_CRAFTING_JOB = "CraftingJob (%s) issued by %s requesting [%s] using %s bytes took %s ms";
private static final String LOG_MACHINE_SOURCE_DETAILS = "Machine[object=%s, %s]";
private 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> neededForLoop = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final Object2ObjectOpenHashMap<CraftingTreeNode, IAEItemStack> reserved = new Object2ObjectOpenHashMap<>();
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
private final Object monitor = new Object();
private final Stopwatch tickSpreadingWatch = Stopwatch.createUnstarted();
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
private final IAEItemStack output;
private final IActionSource actionSrc;
private final ICraftingCallback callback;
private final Stopwatch watch = Stopwatch.createUnstarted();
private CraftingTreeNode tree;
private final IAEItemStack output;
private boolean simulate = false;
private MECraftingInventory availableCheck;
private long bytes = 0;
private final IActionSource actionSrc;
private final ICraftingCallback callback;
private boolean running = false;
private boolean done = false;
private int time;
private int incTime;
private World wrapWorld( final World w )
{
return w;
}
public CraftingJob( final World w, final IGrid grid, final IActionSource actionSrc, final IAEItemStack what, final ICraftingCallback callback )
{
this.world = w;
this.world = this.wrapWorld( w );
this.output = what.copy();
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 );
ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
final GridStorageCache sg = grid.getCache( IStorageGrid.class );
this.original = sg.getExtractableList( actionSrc );
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
this.setTree( this.getCraftingTree( cc, what ) );
this.availableCheck = null;
}
private CraftingTreeNode getCraftingTree( final ICraftingGrid cc, final IAEItemStack what )
{
return new CraftingTreeNode( cc, this, what, what.getStackSize(), null, -1 );
return new CraftingTreeNode( cc, this, what, null, -1, 0 );
}
void refund( final IAEItemStack o )
@@ -106,12 +108,12 @@ public class CraftingJob implements Runnable, ICraftingJob
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
}
IAEItemStack checkAvailable( final IAEItemStack available )
public void writeToNBT( final NBTTagCompound out )
{
return this.availableCheck.extractItems( available, Actionable.SIMULATE, this.actionSrc );
}
void addTask( IAEItemStack what, final long crafts )
void addTask( IAEItemStack what, final long crafts, final ICraftingPatternDetails details, final int depth )
{
if( crafts > 0 )
{
@@ -127,22 +129,6 @@ public class CraftingJob implements Runnable, ICraftingJob
this.missing.add( what );
}
public void reserve( CraftingTreeNode node, IAEItemStack stack )
{
this.checkUse( stack );
reserved.put( node, stack );
}
public IItemList<IAEItemStack> getNeededForLoop()
{
return neededForLoop;
}
public Object2ObjectOpenHashMap<CraftingTreeNode, IAEItemStack> getReserved()
{
return reserved;
}
@Override
public void run()
{
@@ -153,15 +139,13 @@ public class CraftingJob implements Runnable, ICraftingJob
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
this.handlePausing();
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.reserved.values().forEach( availableCheck::reserve );
this.reserved.values().forEach( craftingInventory::reserve );
craftingTreeWatch.start();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
craftingTreeWatch.stop();
this.getTree().dive( this );
for( final String s : this.opsAndMultiplier.keySet() )
@@ -170,14 +154,9 @@ public class CraftingJob implements Runnable, ICraftingJob
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
}
if( actionSrc.player().isPresent() )
{
this.logCraftingJob( "simulated, success", craftingTreeWatch );
}
else
{
this.logCraftingJob( "real, success", craftingTreeWatch );
}
this.logCraftingJob( "real", timer );
// if ( mode == Actionable.MODULATE )
// craftingInventory.moveItemsToStorage( storage );
}
catch( final CraftBranchFailure e )
{
@@ -185,32 +164,23 @@ public class CraftingJob implements Runnable, ICraftingJob
try
{
if( actionSrc.player().isPresent() )
final Stopwatch timer = Stopwatch.createStarted();
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
craftingInventory.ignore( this.output );
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
this.getTree().setSimulate();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
this.getTree().dive( this );
for( final String s : this.opsAndMultiplier.keySet() )
{
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
this.getTree().setSimulate();
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
this.reserved.values().forEach( availableCheck::reserve );
this.reserved.values().forEach( craftingInventory::reserve );
craftingTreeWatch.reset().start();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
craftingTreeWatch.stop();
this.getTree().dive( this );
for( final String s : this.opsAndMultiplier.keySet() )
{
final TwoIntegers ti = this.opsAndMultiplier.get( s );
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
}
this.logCraftingJob( "simulated, failed", craftingTreeWatch );
}
else
{
this.logCraftingJob( "real, failed", craftingTreeWatch );
final TwoIntegers ti = this.opsAndMultiplier.get( s );
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
}
this.logCraftingJob( "simulate", timer );
}
catch( final CraftBranchFailure e1 )
{
@@ -256,11 +226,10 @@ public class CraftingJob implements Runnable, ICraftingJob
this.incTime = 0;
synchronized ( this.monitor )
{
if( this.tickSpreadingWatch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
if( this.watch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
{
this.running = false;
this.craftingTreeWatch.stop();
this.tickSpreadingWatch.stop();
this.watch.stop();
this.monitor.notify();
}
@@ -276,13 +245,12 @@ 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++;
}
@@ -295,7 +263,7 @@ public class CraftingJob implements Runnable, ICraftingJob
this.availableCheck = null;
synchronized ( this.monitor )
synchronized( this.monitor )
{
this.running = false;
this.done = true;
@@ -343,7 +311,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;
@@ -355,11 +323,27 @@ public class CraftingJob implements Runnable, ICraftingJob
}
if( !this.actionSrc.player().isPresent() )
{
this.tickSpreadingWatch.reset();
this.tickSpreadingWatch.start();
this.watch.reset();
this.watch.start();
this.running = true;
AELog.craftingDebug( "main thread is now going to sleep" );
this.monitor.notify();
while ( this.running )
{
try
{
this.monitor.wait();
}
catch( final InterruptedException ignored )
{
}
}
AELog.craftingDebug( "main thread is now active" );
}
this.running = true;
}
return true;
@@ -385,7 +369,7 @@ public class CraftingJob implements Runnable, ICraftingJob
if( AELog.isCraftingLogEnabled() )
{
final String itemToOutput = this.output.toString();
final long elapsedTime = timer.elapsed( TimeUnit.MICROSECONDS );
final long elapsedTime = timer.elapsed( TimeUnit.MILLISECONDS );
final String actionSource;
if( this.actionSrc.player().isPresent() )
@@ -19,6 +19,15 @@
package appeng.crafting;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.google.common.collect.Lists;
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;
@@ -28,22 +37,9 @@ 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.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInformPlayer;
import appeng.me.cluster.implementations.CraftingCPUCluster;
import appeng.util.Platform;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Optional;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@Optional.Interface( iface = "gregtech.api.items.IToolItem", modid = "gregtech" )
public class CraftingTreeNode
{
@@ -58,20 +54,22 @@ public class CraftingTreeNode
private final IAEItemStack what;
// what are the crafting patterns for this?
private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<>();
private final boolean canEmit;
private CraftingTreeNode loopHead;
private int bytes = 0;
private boolean canEmit = false;
private long missing = 0;
private long howManyEmitted = 0;
private boolean exhausted = false;
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, long amount, final CraftingTreeProcess par, final int slot )
private boolean sim;
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth )
{
this.what = wat;
this.parent = par;
this.slot = slot;
this.world = job.getWorld();
this.job = job;
this.sim = false;
this.canEmit = cc.canEmitFor( this.what );
@@ -83,136 +81,108 @@ public class CraftingTreeNode
for( final ICraftingPatternDetails details : cc.getCraftingFor( this.what, this.parent == null ? null : this.parent.details, slot, this.world ) )// in
// order.
{
int times = 1;
for( IAEItemStack o : details.getCondensedOutputs() )
if( this.parent == null || this.parent.notRecursive( details ) )
{
if( what.equals( o ) )
{
times = (int) ( amount / o.getStackSize() + ( amount % o.getStackSize() != 0 ? 1 : 0 ) );
}
}
if( this.parent == null )
{
this.nodes.add( new CraftingTreeProcess( cc, job, details, times, this ) );
continue;
}
if( details == parent.details )
{
continue;
}
CraftingTreeNode recursive = recursiveNode( this );
if( recursive == null )
{
this.nodes.add( new CraftingTreeProcess( cc, job, details, times, this ) );
}
else
{
reserveForNode();
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
}
}
}
void reserveForNode()
boolean notRecursive( final ICraftingPatternDetails details )
{
if( this.equals( loopHead ) )
IAEItemStack[] o = details.getCondensedOutputs();
for( final IAEItemStack i : o )
{
return;
if( i.equals( this.what ) )
{
return false;
}
}
IAEItemStack available = job.checkAvailable( this.what );
if( available != null && available.getStackSize() >= this.what.getStackSize() )
o = details.getCondensedInputs();
for( final IAEItemStack i : o )
{
this.job.reserve( this, this.what.copy() );
if( i.equals( this.what ) )
{
return false;
}
}
else
if( this.parent == null )
{
parent.reserveForNode();
return true;
}
return this.parent.notRecursive( details );
}
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{
this.job.handlePausing();
if( this.canEmit )
{
final IAEItemStack wat = this.what.copy();
wat.setStackSize( l );
this.howManyEmitted = wat.getStackSize();
this.bytes += wat.getStackSize();
return wat;
}
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
IAEItemStack reserved = job.getReserved().get( this );
final List<IAEItemStack> thingsUsed = new ArrayList<>();
this.what.setStackSize( l );
IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
if( available != null )
{
Collection<IAEItemStack> itemList = new HashSet<>();
if( this.what.getItem().isDamageable() || Platform.isGTDamageableItem( this.what.getItem() ) )
if( !this.exhausted )
{
itemList.addAll( inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) );
final IAEItemStack is = this.job.checkUse( available );
if( this.parent.details.canSubstitute() )
if( is != null )
{
for( IAEItemStack is : inventoryList )
{
if( is.fuzzyComparison( this.what, FuzzyMode.IGNORE_ALL ) )
{
itemList.add( is );
}
}
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 ) );
}
}
else
{
itemList = Lists.newArrayList();
final IAEItemStack item = inventoryList.findPrecise( this.what );
if( item != null )
{
itemList.add( item );
}
if( this.parent.details.canSubstitute() )
{
for( IAEItemStack s : parent.details.getSubstituteInputs( this.slot ) )
{
if( s != null )
{
for( IAEItemStack ss : inventoryList.findFuzzy( s, FuzzyMode.IGNORE_ALL ) )
{
if( ss != null )
{
itemList.add( ss );
}
}
}
}
}
}
for( IAEItemStack fuzz : itemList )
{
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.getDefinition(), this.world ) )
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().setStackSize( 1 ).createItemStack(), this.world ) )
{
fuzz = fuzz.copy();
fuzz.setStackSize( l );
final IAEItemStack available;
if( reserved != null )
{
available = reserved;
}
else
{
available = inv.extractItems( fuzz, Actionable.MODULATE, src );
}
available = inv.extractItems( fuzz, Actionable.MODULATE, src );
if( available != null )
{
@@ -225,11 +195,6 @@ public class CraftingTreeNode
thingsUsed.add( is.copy() );
this.used.add( is );
}
else if( reserved != null )
{
thingsUsed.add( reserved.copy() );
this.used.add( reserved );
}
}
this.bytes += available.getStackSize();
@@ -243,49 +208,16 @@ public class CraftingTreeNode
}
}
}
else
if( this.canEmit )
{
final IAEItemStack available;
final IAEItemStack wat = this.what.copy();
wat.setStackSize( l );
if( parent == null && this.what.equals( job.getOutput() ) )
{
available = null;
}
else if( reserved != null )
{
available = reserved;
}
else
{
available = inv.extractItems( this.what, Actionable.MODULATE, src );
}
this.howManyEmitted = wat.getStackSize();
this.bytes += wat.getStackSize();
if( available != null )
{
if( !this.exhausted )
{
final IAEItemStack is = this.job.checkUse( available );
if( is != null )
{
thingsUsed.add( is.copy() );
this.used.add( is );
}
else if( reserved != null )
{
thingsUsed.add( reserved.copy() );
this.used.add( reserved );
}
}
this.bytes += available.getStackSize();
l -= available.getStackSize();
if( l == 0 )
{
return available;
}
}
return wat;
}
this.exhausted = true;
@@ -301,7 +233,8 @@ public class CraftingTreeNode
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
madeWhat.setStackSize( l );
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
if( available != null )
{
@@ -328,12 +261,10 @@ public class CraftingTreeNode
while ( pro.possible && l > 0 )
{
final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true );
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
pro.request( subInv, pro.getTimes( l, madeWhat.getStackSize() ), src );
pro.request( subInv, 1, src );
this.what.setStackSize( l );
final IAEItemStack available = subInv.extractItems( this.what, Actionable.MODULATE, src );
available = subInv.extractItems( this.what, Actionable.MODULATE, src );
if( available != null )
{
@@ -363,10 +294,10 @@ public class CraftingTreeNode
}
}
if( job.isSimulation() )
if( this.sim )
{
this.bytes += l;
this.missing += l;
this.bytes += l;
final IAEItemStack rv = this.what.copy();
rv.setStackSize( l );
return rv;
@@ -382,26 +313,6 @@ public class CraftingTreeNode
throw new CraftBranchFailure( this.what, l );
}
CraftingTreeNode recursiveNode( CraftingTreeNode node )
{
if( this.parent == null )
{
return null;
}
if( node != this )
{
if( node.what.equals( this.what ) )
{
if( node.what.getStackSize() == this.what.getStackSize() )
{
loopHead = this;
return node;
}
}
}
return this.parent.notRecursive( node );
}
void dive( final CraftingJob job )
{
if( this.missing > 0 )
@@ -427,6 +338,7 @@ public class CraftingTreeNode
void setSimulate()
{
this.sim = true;
this.missing = 0;
this.bytes = 0;
this.used.resetStatus();
@@ -448,21 +360,7 @@ public class CraftingTreeNode
{
if( src.player().isPresent() )
{
try
{
if( ex == null )
{
NetworkHandler.instance().sendTo( new PacketInformPlayer( i ), (EntityPlayerMP) src.player().get() );
}
else
{
NetworkHandler.instance().sendTo( new PacketInformPlayer( ex, i ), (EntityPlayerMP) src.player().get() );
}
}
catch( IOException e )
{
e.printStackTrace();
}
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + i.getStackSize() + " " + i.getDefinition().getItem().getItemStackDisplayName( i.getDefinition() ) + " available but could not extract anything" ), false );
}
throw new CraftBranchFailure( i, i.getStackSize() );
}
@@ -19,208 +19,240 @@
package appeng.crafting;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.inventory.InventoryCrafting;
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.config.FuzzyMode;
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;
import appeng.util.item.AEItemStack;
import com.google.common.collect.ImmutableCollection;
import it.unimi.dsi.fastutil.objects.Object2LongArrayMap;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
public class CraftingTreeProcess
{
final ICraftingPatternDetails details;
private final CraftingTreeNode parent;
private final CraftingJob job;
private final Object2LongArrayMap<CraftingTreeNode> nodes = new Object2LongArrayMap<>();
boolean possible = true;
private long crafts = 0;
private long bytes = 0;
private boolean hasContainerItem = false;
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, int times, final CraftingTreeNode craftingTreeNode )
private final CraftingTreeNode parent;
final ICraftingPatternDetails details;
private final CraftingJob job;
private final Map<CraftingTreeNode, Long> nodes = new HashMap<>();
private final int depth;
boolean possible = true;
private World world;
private long crafts = 0;
private boolean containerItems;
private boolean limitQty;
private boolean fullSimulation;
private long bytes = 0;
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, final CraftingTreeNode craftingTreeNode, final int depth )
{
this.parent = craftingTreeNode;
this.details = details;
this.job = job;
World world = job.getWorld();
this.depth = depth;
final World world = job.getWorld();
final IAEItemStack[] list = details.getInputs();
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
for( IAEItemStack part : details.getCondensedInputs() )
if( details.isCraftable() )
{
if( part == null )
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++ )
{
continue;
ic.setInventorySlotContents( x, is[x] == null ? ItemStack.EMPTY : is[x].createItemStack() );
}
for( int x = 0; x < list.length; x++ )
for( int x = 0; x < ic.getSizeInventory(); x++ )
{
final IAEItemStack comparePart = list[x];
if( part.equals( comparePart ) )
final ItemStack g = ic.getStackInSlot( x );
if( !g.isEmpty() && g.getCount() > 1 )
{
boolean isPartContainer = false;
if( part.getItem().hasContainerItem( part.getDefinition() ) )
this.fullSimulation = true;
}
}
for( final IAEItemStack part : details.getCondensedInputs() )
{
final ItemStack g = part.createItemStack();
boolean isAnInput = false;
for( final IAEItemStack a : details.getCondensedOutputs() )
{
if( !g.isEmpty() && a != null && a.equals( g ) )
{
part = list[x];
isPartContainer = true;
this.hasContainerItem = true;
isAnInput = true;
}
}
long wantedSize = isPartContainer ? part.getStackSize() : part.getStackSize() * times;
if( isAnInput )
{
this.limitQty = true;
}
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
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 )
{
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
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 ) )
{
if( subs.fuzzyComparison( part, FuzzyMode.IGNORE_ALL ) )
{
this.nodes.put( new CraftingTreeNode( cc, job, subs.copy(), wantedSize, this, x ), part.getStackSize() / times );
wantedSize = 0;
break;
}
// use the first slot...
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
break;
}
//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;
}
}
}
if( prioritizedIAE != null )
{
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), wantedSize, this, x ), part.getStackSize() / times );
wantedSize = 0;
break;
}
}
}
if( wantedSize > 0 )
{
part = part.copy().setStackSize( wantedSize );
// use the first slot...
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), wantedSize, this, x ), part.getStackSize() / times );
wantedSize = 0;
}
if( !isPartContainer && wantedSize == 0 )
{
break;
}
}
}
}
else
{
for( final IAEItemStack part : details.getCondensedInputs() )
{
final ItemStack g = part.createItemStack();
boolean isAnInput = false;
for( final IAEItemStack a : details.getCondensedOutputs() )
{
if( !g.isEmpty() && a != null && a.equals( g ) )
{
isAnInput = true;
}
}
if( isAnInput )
{
this.limitQty = true;
}
}
for( final IAEItemStack part : details.getCondensedInputs() )
{
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, -1, depth + 1 ), part.getStackSize() );
}
}
}
CraftingTreeNode notRecursive( CraftingTreeNode node )
boolean notRecursive( final ICraftingPatternDetails details )
{
if( parent == null )
{
return null;
}
return this.parent.recursiveNode( node );
return this.parent == null || this.parent.notRecursive( details );
}
long getTimes( final long remaining, final long stackSize )
{
if( hasContainerItem )
if( this.limitQty || this.fullSimulation )
{
return 1;
}
return ( remaining / stackSize ) + ( remaining % stackSize != 0 ? 1 : 0 );
}
void request( final MECraftingInventory inv, final long amountOfTimes, final IActionSource src ) throws CraftBranchFailure, InterruptedException
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{
this.job.handlePausing();
List<IAEItemStack> containerItems = null;
// request and remove inputs...
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
if( this.fullSimulation )
{
final IAEItemStack stack = entry.getKey().request( inv, details.isCraftable() && hasContainerItem ? 1 : entry.getValue() * amountOfTimes, src );
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
if( stack.equals( job.getOutput() ) )
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.entrySet() )
{
job.getNeededForLoop().add( stack.copy() );
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() );
}
if( details.isCraftable() && stack.getItem().hasContainerItem( stack.getDefinition() ) )
for( int x = 0; x < ic.getSizeInventory(); x++ )
{
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
final IAEItemStack o = AEItemStack.fromItemStack( is );
ItemStack is = ic.getStackInSlot( x );
is = Platform.getContainerItem( is );
final IAEItemStack o = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
if( o != null )
{
if( containerItems == null )
{
containerItems = new ArrayList<>();
}
this.bytes++;
o.setCachedItemStack( is );
containerItems.add( o );
inv.injectItems( o, Actionable.MODULATE, src );
}
if( containerItems != null )
}
}
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 )
{
for( IAEItemStack i : containerItems )
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
final IAEItemStack o = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
if( o != null )
{
inv.injectItems( i, Actionable.MODULATE, src );
this.bytes++;
inv.injectItems( o, Actionable.MODULATE, src );
}
}
}
}
// assume its possible.
// add crafting results..
for( final IAEItemStack out : this.details.getCondensedOutputs() )
{
final IAEItemStack o = out.copy();
o.setStackSize( o.getStackSize() * amountOfTimes );
o.setStackSize( o.getStackSize() * i );
inv.injectItems( o, Actionable.MODULATE, src );
}
this.crafts += amountOfTimes;
this.crafts += i;
}
void dive( final CraftingJob job )
{
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts );
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts, this.details, this.depth );
for( final CraftingTreeNode pro : this.nodes.keySet() )
{
entry.getKey().dive( job );
pro.dive( job );
}
job.addBytes( this.crafts * 8 + this.bytes );
job.addBytes( this.crafts + 8 + this.bytes );
}
IAEItemStack getAmountCrafted( IAEItemStack what2 )
@@ -254,9 +286,9 @@ public class CraftingTreeProcess
this.crafts = 0;
this.bytes = 0;
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
for( final CraftingTreeNode pro : this.nodes.keySet() )
{
entry.getKey().setSimulate();
pro.setSimulate();
}
}
@@ -264,9 +296,9 @@ public class CraftingTreeProcess
{
craftingCPUCluster.addCrafting( this.details, this.crafts );
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
for( final CraftingTreeNode pro : this.nodes.keySet() )
{
entry.getKey().setJob( storage, craftingCPUCluster, src );
pro.setJob( storage, craftingCPUCluster, src );
}
}
@@ -279,14 +311,9 @@ public class CraftingTreeProcess
plan.addRequestable( i );
}
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
for( final CraftingTreeNode pro : this.nodes.keySet() )
{
entry.getKey().getPlan( plan );
pro.getPlan( plan );
}
}
public void reserveForNode()
{
parent.reserveForNode();
}
}
@@ -28,14 +28,10 @@ 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.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInformPlayer;
import appeng.me.helpers.PlayerSource;
import appeng.util.inv.ItemListIgnoreCrafting;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.text.TextComponentString;
import java.io.IOException;
public class MECraftingInventory implements IMEInventory<IAEItemStack>
{
@@ -101,7 +97,8 @@ 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;
}
@@ -314,23 +311,17 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
{
if( src.player().isPresent() )
{
try
if( result == null )
{
if( result == null )
{
NetworkHandler.instance().sendTo( new PacketInformPlayer( extra ), (EntityPlayerMP) src.player().get() );
}
else
{
NetworkHandler.instance().sendTo( new PacketInformPlayer( extra, result ), (EntityPlayerMP) src.player().get() );
}
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could not extract anything" ), false );
}
catch( IOException e )
else
{
e.printStackTrace();
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could only extract " + result.getStackSize() ), false );
}
}
failed = true;
if( !src.player().isPresent() ) break;
}
}
}
@@ -361,6 +352,11 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
return true;
}
private void addMissing( final IAEItemStack extra )
{
this.missingCache.add( extra );
}
void ignore( final IAEItemStack what )
{
final IAEItemStack list = this.localCache.findPrecise( what );
@@ -369,18 +365,4 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
list.setStackSize( 0 );
}
}
void reserve( final IAEItemStack what )
{
final IAEItemStack list = this.localCache.findPrecise( what );
if( list != null )
{
list.decStackSize( what.getStackSize() );
}
}
private void addMissing( final IAEItemStack extra )
{
this.missingCache.add( extra );
}
}
@@ -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, 57, 16, 64 ) );
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 53, 16, 68 ) );
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
}
@@ -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 % 16;
int iconHeightRemainder = scaledHeight % this.getHeight();
if( iconHeightRemainder > 0 )
{
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, 16, iconHeightRemainder );
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, this.getWidth(), iconHeightRemainder );
}
for( int i = 0; i < scaledHeight / 16; i++ )
for( int i = 0; i < scaledHeight / this.getHeight(); i++ )
{
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, this.getWidth(), this.getHeight() );
}
}
}
@@ -113,7 +113,7 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
@Override
public int yPos()
{
return this.y - 4;
return this.y - 1;
}
@Override
@@ -125,7 +125,7 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
@Override
public int getHeight()
{
return this.height + 4;
return this.height + 1;
}
@Override
@@ -414,7 +414,7 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
}
}
if( notInserted == null || notInserted.getStackSize() == 0 )
if( notInserted == null )
{
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
@@ -91,10 +91,12 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
private int isWorking = -1;
private int priority;
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 boolean resetConfigCache = true;
private IMEMonitor<IAEFluidStack> configCachedHandler;
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 ) );
public DualityFluidInterface( final AENetworkProxy networkProxy, final IFluidInterfaceHost ih )
{
@@ -117,7 +119,15 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
public IUpgradeableHost getHost()
{
return this.iHost;
if( this.iHost instanceof IUpgradeableHost )
{
return this.iHost;
}
if( this.iHost instanceof IUpgradeableHost )
{
return this.iHost;
}
return null;
}
@Override
@@ -136,12 +146,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
{
if( this.hasConfig() )
{
if( resetConfigCache )
{
resetConfigCache = false;
configCachedHandler = new InterfaceInventory( this );
}
return (IMEMonitor<T>) configCachedHandler;
return (IMEMonitor<T>) new InterfaceInventory( this );
}
return (IMEMonitor<T>) this.fluids;
@@ -378,7 +383,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
{
changed = true;
}
else if( this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ).getStorageList().findPrecise( work ) != null )
else
{
final IAEFluidStack acquired = Platform.poweredExtraction( src, dest, work, this.interfaceRequestSource );
if( acquired != null )
@@ -445,13 +450,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
if( inventory == this.config )
{
boolean cfg = hasConfig();
this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
this.notifyNeighbors();
}
}
else if( inventory == this.tanks )
{
@@ -556,6 +555,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
InterfaceInventory( final DualityFluidInterface tileInterface )
{
super( tileInterface.tanks );
this.setActionSource( new MachineSource( tileInterface.iHost ) );
}
@Override
@@ -19,15 +19,16 @@
package appeng.fluids.parts;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.api.storage.data.IAEItemStack;
import appeng.me.GridAccessException;
import appeng.util.inv.ItemSlot;
import net.minecraft.item.ItemStack;
import appeng.parts.misc.PartStorageBus;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
@@ -44,6 +45,7 @@ import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IItemList;
import appeng.fluids.util.AEFluidStack;
import appeng.me.GridAccessException;
import appeng.me.helpers.IGridProxyable;
import appeng.me.storage.ITickingMonitor;
@@ -63,20 +65,17 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
private final IGridProxyable proxyable;
private final FluidHandlerAdapter.InventoryCache cache;
private StorageFilter mode;
private AccessRestriction access;
FluidHandlerAdapter( IFluidHandler fluidHandler, IGridProxyable proxy )
{
this.fluidHandler = fluidHandler;
this.proxyable = proxy;
if( this.proxyable instanceof PartFluidStorageBus )
if( this.proxyable instanceof PartStorageBus )
{
PartFluidStorageBus partFluidStorageBus = (PartFluidStorageBus) this.proxyable;
this.mode = ( (StorageFilter) partFluidStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
this.access = ( (AccessRestriction) partFluidStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode );
this.cache.update();
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode);
}
@Override
@@ -95,14 +94,11 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
if( type == Actionable.MODULATE )
{
IAEFluidStack added = input.copy().setStackSize( input.getStackSize() - remaining );
this.cache.currentlyCached.add( added );
this.postDifference( Collections.singletonList( added ) );
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
catch( GridAccessException ignore )
{
// meh
}
@@ -127,32 +123,25 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
return null;
}
IAEFluidStack gatheredAEFluidstack = AEFluidStack.fromFluidStack( gathered );
if( mode == Actionable.MODULATE )
{
IAEFluidStack cachedStack = this.cache.currentlyCached.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( gatheredAEFluidstack.getStackSize() );
this.postDifference( Collections.singletonList( gatheredAEFluidstack.copy().setStackSize( -gatheredAEFluidstack.getStackSize() ) ) );
}
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
catch( GridAccessException ignore )
{
// meh
}
}
return gatheredAEFluidstack;
return AEFluidStack.fromFluidStack( gathered );
}
@Override
public TickRateModulation onTick()
{
List<IAEFluidStack> changes = this.cache.update();
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
if( !changes.isEmpty() )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
@@ -213,9 +202,9 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
private static class InventoryCache
{
private IAEFluidStack[] cachedAeStacks = new IAEFluidStack[0];
private final IFluidHandler fluidHandler;
private final StorageFilter mode;
IItemList<IAEFluidStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
public InventoryCache( IFluidHandler fluidHandler, StorageFilter mode )
{
@@ -227,46 +216,102 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
{
final List<IAEFluidStack> changes = new ArrayList<>();
final IFluidTankProperties[] tankProperties = this.fluidHandler.getTankProperties();
final int slots = tankProperties.length;
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
for( IFluidTankProperties tankProperty : tankProperties )
// Make room for new slots
if( slots > this.cachedAeStacks.length )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain( 1, false ) == null )
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
}
for( int slot = 0; slot < slots; slot++ )
{
// Save the old stuff
final IAEFluidStack oldAEFS = this.cachedAeStacks[slot];
FluidStack newFS = tankProperties[slot].getContents();
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && newFS != null )
{
continue;
if( this.fluidHandler.drain( 1, false ) == null )
{
newFS = null;
}
}
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
this.handlePossibleSlotChanges( slot, oldAEFS, newFS, changes );
}
for ( final IAEFluidStack is : currentlyCached )
// Handle cases where the number of slots actually is lower now than before
if( slots < this.cachedAeStacks.length )
{
is.setStackSize( -is.getStackSize() );
}
for ( final IAEFluidStack is : currentlyOnStorage )
{
currentlyCached.add( is );
}
for ( final IAEFluidStack is : currentlyCached )
{
if( is.getStackSize() != 0 )
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
{
changes.add( is );
final IAEFluidStack aeStack = this.cachedAeStacks[slot];
if( aeStack != null )
{
final IAEFluidStack a = aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
}
}
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
}
currentlyCached = currentlyOnStorage;
return changes;
}
public IItemList<IAEFluidStack> getAvailableItems( IItemList<IAEFluidStack> out )
{
currentlyCached.iterator().forEachRemaining( out::add );
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
return out;
}
private void handlePossibleSlotChanges( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
{
if( oldAeFS != null && oldAeFS.getFluidStack().isFluidEqual( newFS ) )
{
this.handleStackSizeChanged( slot, oldAeFS, newFS, changes );
}
else
{
this.handleFluidChanged( slot, oldAeFS, newFS, changes );
}
}
private void handleStackSizeChanged( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
{
// Still the same fluid, but amount might have changed
final long diff = newFS.amount - oldAeFS.getStackSize();
if( diff != 0 )
{
final IAEFluidStack stack = oldAeFS.copy();
stack.setStackSize( newFS.amount );
this.cachedAeStacks[slot] = stack;
final IAEFluidStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
}
}
private void handleFluidChanged( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
{
// Completely different fluid
this.cachedAeStacks[slot] = AEFluidStack.fromFluidStack( newFS );
// If we had a stack previously in this slot, notify the network about its disappearance
if( oldAeFS != null )
{
oldAeFS.setStackSize( -oldAeFS.getStackSize() );
changes.add( oldAeFS );
}
// Notify the network about the new stack. Note that this is null if newFS was null
if( this.cachedAeStacks[slot] != null )
{
changes.add( this.cachedAeStacks[slot] );
}
}
}
}
@@ -178,9 +178,8 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
this.stateChanged();
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged changedChannels )
public void updateChannels( final MENetworkChannelsChanged changedChannels )
{
this.stateChanged();
}
@@ -205,7 +204,7 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
if( channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
handler.add( this.myHandler );
@@ -90,16 +90,14 @@ public class PartFluidInterface extends PartBasicState implements IGridTickable,
return this.duality;
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c )
public void stateChange( final MENetworkChannelsChanged c )
{
this.duality.notifyNeighbors();
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
public void stateChange( final MENetworkPowerStatusChange c )
{
this.duality.notifyNeighbors();
}
@@ -4,9 +4,7 @@ package appeng.fluids.parts;
import java.util.Random;
import appeng.api.storage.data.IItemList;
import appeng.fluids.helper.IConfigurableFluidInventory;
import appeng.me.cache.NetworkMonitor;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -36,6 +34,7 @@ import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.AECableType;
import appeng.api.util.AEPartLocation;
import appeng.api.util.IConfigManager;
@@ -128,25 +127,15 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
this.configureWatchers();
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange powerEvent )
public void channelChanged( final MENetworkChannelsChanged c )
{
if (this.getProxy().isActive())
{
onListUpdate();
}
this.updateState();
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c )
public void powerChanged( final MENetworkPowerStatusChange c )
{
if (this.getProxy().isActive())
{
onListUpdate();
}
this.updateState();
}
@@ -258,9 +247,10 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
if( myStack == null )
{
if( monitor instanceof NetworkMonitor )
this.lastReportedValue = 0;
for( final IAEFluidStack st : monitor.getStorageList() )
{
this.lastReportedValue = ( (NetworkMonitor<IAEFluidStack>) monitor ).getGridCurrentCount();
this.lastReportedValue += st.getStackSize();
}
}
else
File diff suppressed because it is too large Load Diff
+161 -189
View File
@@ -19,6 +19,41 @@
package appeng.helpers;
import java.util.*;
import javax.annotation.Nullable;
import appeng.api.definitions.IItemDefinition;
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
import appeng.util.*;
import appeng.util.inv.*;
import com.google.common.collect.ImmutableSet;
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
import gregtech.api.block.machines.BlockMachine;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.MetaTileEntityHolder;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.RangedWrapper;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
@@ -42,7 +77,11 @@ import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart;
import appeng.api.storage.*;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.IStorageMonitorableAccessor;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
@@ -64,51 +103,21 @@ import appeng.parts.automation.StackUpgradeInventory;
import appeng.parts.automation.UpgradeInventory;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.*;
import appeng.util.item.AEItemStack;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
import gregtech.api.block.machines.BlockMachine;
import gregtech.api.metatileentity.MetaTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.RangedWrapper;
import javax.annotation.Nullable;
import java.util.*;
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;
@@ -118,27 +127,30 @@ 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 final Accessor accessor = new Accessor();
private boolean hasConfig = false;
private int priority;
private List<ICraftingPatternDetails> craftingList = null;
private List<ItemStack> waitingToSend = null;
private IMEInventory<IAEItemStack> destination;
private int isWorking = -1;
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 boolean resetConfigCache = true;
private IMEMonitor<IAEItemStack> configCachedHandler;
private EnumMap<EnumFacing,List<ItemStack>> waitingToSendFacing = new EnumMap<>(EnumFacing.class);
private GTCEInventoryAdaptor GTad;
public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih )
{
this.gridProxy = networkProxy;
this.gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4 );
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4);
this.cm.registerSetting( Settings.BLOCK, YesNo.NO );
this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES );
@@ -153,11 +165,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.interfaceRequestSource = new InterfaceRequestSource( this.iHost );
}
private static boolean invIsCustomBlocking( BlockingInventoryAdaptor inv )
{
return ( inv.containsBlockingItems() );
}
@Override
public void saveChanges()
{
@@ -171,15 +178,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
return;
}
if( inv == this.config && ( !removed.isEmpty() || !added.isEmpty() ) )
if( inv == this.config )
{
boolean cfg = hasConfig();
this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
this.notifyNeighbors();
}
}
else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) )
{
@@ -238,12 +239,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 ) )
{
@@ -279,7 +280,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" );
for( EnumFacing s : EnumFacing.values() )
{
if( waitingListSided.hasKey( s.name() ) )
{
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
@@ -293,7 +293,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
}
}
this.craftingTracker.readFromNBT( data );
@@ -353,9 +352,8 @@ 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<>() );
@@ -412,6 +410,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
// :P
}
}
this.notifyNeighbors();
}
@@ -425,17 +424,15 @@ 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 )
@@ -446,49 +443,41 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if( !found )
{
removed = true;
i.remove();
}
}
}
boolean newPattern = false;
for( int x = 0; x < accountedFor.length; x++ )
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() ) );
}
catch( GridAccessException e )
catch( final GridAccessException e )
{
e.printStackTrace();
// :P
}
}
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;
}
}
@@ -599,7 +588,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private boolean hasItemsToSendFacing()
{
if( waitingToSendFacing != null )
if (waitingToSendFacing != null)
{
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{
@@ -619,13 +608,10 @@ 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 ) );
}
}
@@ -642,7 +628,8 @@ 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;
@@ -716,7 +703,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.pushItemsOut( this.iHost.getTargets() );
}
if( hasItemsToSendFacing() )
if (hasItemsToSendFacing())
{
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{
@@ -739,7 +726,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();
@@ -786,8 +773,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;
}
@@ -800,18 +787,17 @@ 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( result.getCount() );
whatToSend.setCount( whatToSend.getCount() - ( whatToSend.getCount() - result.getCount() ) );
}
else
{
@@ -852,7 +838,35 @@ 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( itemStack.getStackSize() < 0 )
if( this.craftingTracker.isBusy( x ) )
{
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
}
else if( itemStack.getStackSize() > 0 )
{
// make sure strange things didn't happen...
if( !adaptor.simulateAdd( itemStack.createItemStack() ).isEmpty() )
{
changed = true;
throw new GridAccessException();
}
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
if( acquired != null )
{
changed = true;
final ItemStack issue = adaptor.addItems( acquired.createItemStack() );
if( !issue.isEmpty() )
{
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
}
}
else
{
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
}
}
else if( itemStack.getStackSize() < 0 )
{
IAEItemStack toStore = itemStack.copy();
toStore.setStackSize( -toStore.getStackSize() );
@@ -890,51 +904,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
}
if( this.craftingTracker.isBusy( x ) )
{
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
}
else if( itemStack.getStackSize() > 0 )
{
// make sure strange things didn't happen...
ItemStack inputStack = itemStack.getCachedItemStack( itemStack.getStackSize() );
ItemStack remaining = adaptor.simulateAdd( inputStack );
if( !remaining.isEmpty() )
{
itemStack.setCachedItemStack( remaining );
changed = true;
throw new GridAccessException();
}
IAEItemStack storedStack = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findPrecise( itemStack );
if( storedStack != null )
{
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
if( acquired != null )
{
changed = true;
inputStack.setCount( Ints.saturatedCast( acquired.getStackSize() ) );
final ItemStack issue = adaptor.addItems( inputStack );
if( !issue.isEmpty() )
{
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
}
}
else if( storedStack.isCraftable() )
{
itemStack.setCachedItemStack( inputStack );
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
}
if( acquired == null )
{
itemStack.setCachedItemStack( inputStack );
}
}
}
// else wtf?
}
catch( final GridAccessException e )
@@ -962,7 +931,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null )
{
return this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(), this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
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;
}
}
catch( final GridAccessException e )
@@ -996,12 +975,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
if( this.hasConfig() )
{
if( resetConfigCache )
{
resetConfigCache = false;
configCachedHandler = new InterfaceInventory( this );
}
return (IMEMonitor<T>) configCachedHandler;
return (IMEMonitor<T>) new InterfaceInventory( this );
}
return (IMEMonitor<T>) this.items;
@@ -1102,7 +1076,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 )
{
return ( !inv.canRemoveAllExceptCircuits() );
}
@Override
@@ -1154,36 +1133,35 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null )
{
if( this.isBlocking() )
{
IPhantomTile phantomTE;
if( Loader.isModLoaded( "actuallyadditions" ) && te instanceof IPhantomTile )
IPhantomTile phantomTE = null;
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
{
phantomTE = ( (IPhantomTile) te );
if( phantomTE.hasBoundPosition() )
{
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) )
if( phantom instanceof MetaTileEntityHolder && isGTCEblocked( phantom, s ) )
{
if( isCustomInvBlocking( phantom, s ) )
{
visitedFaces.remove( s );
continue;
}
visitedFaces.remove( s );
continue;
}
}
}
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
{
if( isCustomInvBlocking( te, s ) )
if( isGTCEblocked( te, s ) )
{
visitedFaces.remove( s );
continue;
}
}
else if( invIsBlocked( ad ) )
{
visitedFaces.remove( s );
@@ -1232,42 +1210,38 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
for( final EnumFacing s : possibleDirections )
{
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
IPhantomTile phantomTE;
IPhantomTile phantomTE = null;
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( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) )
if( phantom instanceof MetaTileEntityHolder && !isGTCEblocked( phantom, s ) )
{
if( !isCustomInvBlocking( phantom, s ) )
{
allAreBusy = false;
break;
}
allAreBusy = false;
break;
}
}
}
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
{
if( !isCustomInvBlocking( te, s ) )
if( !isGTCEblocked( te, s ) )
{
allAreBusy = false;
break;
}
}
else
else if( !invIsBlocked( ad ) )
{
if( !invIsBlocked( ad ) )
{
allAreBusy = false;
break;
}
allAreBusy = false;
break;
}
}
}
@@ -1276,10 +1250,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return busy;
}
boolean isCustomInvBlocking( TileEntity te, EnumFacing s )
boolean isGTCEblocked(TileEntity te, EnumFacing s)
{
BlockingInventoryAdaptor blockingInventoryAdaptor = BlockingInventoryAdaptor.getAdaptor( te, s.getOpposite() );
return invIsCustomBlocking( blockingInventoryAdaptor );
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
return invIsBlockedGTCE( GTad );
}
private boolean sameGrid( final IGrid grid ) throws GridAccessException
@@ -1302,7 +1276,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
continue;
}
if( !ad.simulateAdd( is ).isEmpty() )
if( !ad.simulateAdd( is.copy() ).isEmpty() )
{
return false;
}
@@ -1339,13 +1313,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);
}
}
}
@@ -1475,9 +1449,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();
}
@@ -1593,7 +1567,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
private class InterfaceRequestContext implements Comparable<Integer>
{
@@ -1604,13 +1577,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
private class InterfaceInventory extends MEMonitorIInventory
{
public InterfaceInventory( final DualityInterface tileInterface )
{
super( new AdaptorItemHandler( tileInterface.storage ) );
this.setActionSource( new MachineSource( DualityInterface.this.iHost ) );
}
@Override
@@ -1642,7 +1615,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
private class Accessor implements IStorageMonitorableAccessor
{
@@ -24,7 +24,6 @@ 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;
@@ -84,70 +83,57 @@ 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 )
if( ais != null && d.simulateAdd( ais.createItemStack() ).isEmpty() )
{
ItemStack inputStack = ais.getCachedItemStack( ais.getStackSize() );
final Future<ICraftingJob> craftingJob = this.getJob( x );
ItemStack remaining = d.simulateAdd( inputStack );
if( remaining.isEmpty() )
if( this.getLink( x ) != null )
{
return false;
}
else if( craftingJob != null )
{
ais.setCachedItemStack( inputStack );
final Future<ICraftingJob> craftingJob = this.getJob( x );
if( this.getLink( x ) != null )
try
{
return false;
}
else if( craftingJob != null )
{
try
ICraftingJob job = null;
if( craftingJob.isDone() )
{
ICraftingJob job = null;
if( craftingJob.isDone() )
job = craftingJob.get();
}
if( job != null )
{
final ICraftingLink link = cg.submitJob( job, this.owner, null, false, mySrc );
this.setJob( x, null );
if( link != null )
{
job = craftingJob.get();
}
this.setLink( x, link );
if( job != null )
{
final ICraftingLink link = cg.submitJob( job, this.owner, null, false, mySrc );
this.setJob( x, null );
if( link != null )
{
this.setLink( x, link );
return true;
}
return true;
}
}
catch( final InterruptedException e )
{
// :P
}
catch( final ExecutionException e )
{
// :P
}
}
else
catch( final InterruptedException e )
{
if( this.getLink( x ) == null )
{
final IAEItemStack aisC = ais.copy();
aisC.setStackSize( itemToCraft );
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
}
// :P
}
catch( final ExecutionException e )
{
// :P
}
}
else
{
ais.setCachedItemStack( remaining );
if( this.getLink( x ) == null )
{
final IAEItemStack aisC = ais.copy();
aisC.setStackSize( itemToCraft );
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
}
}
}
return false;
@@ -1,133 +0,0 @@
package appeng.helpers;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.util.Platform;
import gregtech.api.items.metaitem.MetaItem;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.*;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.oredict.OreDictionary;
import java.util.*;
public class NonBlockingItems
{
public static Map<String, Object2ObjectOpenHashMap<Item, IntSet>> NON_BLOCKING_MAP = new HashMap<>();
public static NonBlockingItems INSTANCE = new NonBlockingItems();
private NonBlockingItems()
{
String[] strings = AEConfig.instance().getNonBlockingItems();
String[] modids = new String[0];
if( strings.length > 0 )
{
for( String s : strings )
{
if( s.startsWith( "[" ) && s.endsWith( "]" ) )
{
modids = s.substring( 1, s.length() - 1 ).split( "\\|" );
}
else
{
for( String modid : modids )
{
if( !Loader.isModLoaded( modid ) )
{
continue;
}
NON_BLOCKING_MAP.putIfAbsent( modid, new Object2ObjectOpenHashMap<>() );
String[] ModItemMeta = s.split( ":" );
if( ModItemMeta.length < 2 || ModItemMeta.length > 3 )
{
AELog.error( "Invalid non blocking item entry: " + s );
continue;
}
if( ModItemMeta[0].equals( "gregtech" ) && Platform.isModLoaded( "gregtech" ) )
{
boolean found = false;
for( MetaItem<?> metaItem : MetaItem.getMetaItems() )
{
MetaItem<?>.MetaValueItem metaItem2 = metaItem.getItem( ModItemMeta[1] );
if( metaItem.getItem( ModItemMeta[1] ) != null )
{
found = true;
ItemStack itemStack = metaItem2.getStackForm();
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
{
intSet.add( itemStack.getItemDamage() );
return intSet;
} );
}
else
{
ItemStack itemStack = GameRegistry.makeItemStack( ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt( ModItemMeta[2] ) : 0, 1, null );
if( !itemStack.isEmpty() )
{
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
{
intSet.add( itemStack.getItemDamage() );
return intSet;
} );
}
}
}
if( !found )
{
AELog.error( "Item not found on nonBlocking config: " + s );
}
}
else if( ModItemMeta[0].equals( "ore" ) )
{
OreDictionary.getOres( ModItemMeta[1] ).forEach( itemStack ->
{
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
{
intSet.add( itemStack.getItemDamage() );
return intSet;
} );
} );
}
else
{
ItemStack itemStack = GameRegistry.makeItemStack( ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt( ModItemMeta[2] ) : 0, 1, null );
if( !itemStack.isEmpty() )
{
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
{
intSet.add( itemStack.getItemDamage() );
return intSet;
} );
}
else
{
AELog.error( "Item not found on nonBlocking config: " + s );
}
}
}
}
}
}
}
public Map<String, Object2ObjectOpenHashMap<Item, IntSet>> getMap()
{
return NON_BLOCKING_MAP;
}
public void init()
{
}
}
+43 -67
View File
@@ -20,6 +20,7 @@ package appeng.helpers;
import java.util.*;
import java.util.stream.Collectors;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
@@ -37,26 +38,25 @@ import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.ContainerNull;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.features.AEFeature;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import net.minecraftforge.common.crafting.IShapedRecipe;
import net.minecraftforge.fml.common.Optional;
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
{
private static final int CRAFTING_GRID_DIMENSION = 3;
private static final int CRAFTING_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION;
public static final int PROCESSING_INPUT_HEIGHT = 4;
public static final int PROCESSING_INPUT_WIDTH = 4;
public static final int PROCESSING_INPUT_LIMIT = PROCESSING_INPUT_HEIGHT * PROCESSING_INPUT_WIDTH;
private static final int ALL_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION;
private static final int CRAFTING_OUTPUT_LIMIT = 1;
public static final int PROCESSING_OUTPUT_LIMIT = 6;
private static final int PROCESSING_OUTPUT_LIMIT = 3;
private final ItemStack patternItem;
private final InventoryCrafting crafting;
private final InventoryCrafting testFrame;
private final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 );
private final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 );
private final ItemStack correctOutput;
private final IRecipe standardRecipe;
private final IAEItemStack[] condensedInputs;
@@ -84,9 +84,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
final NBTTagList outTag = encodedValue.getTagList( "out", 10 );
this.isCrafting = encodedValue.getBoolean( "crafting" );
crafting = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
testFrame = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
this.canSubstitute = this.isCrafting && encodedValue.getBoolean( "substitute" );
this.patternItem = is;
this.pattern = AEItemStack.fromItemStack( is );
@@ -152,9 +149,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
}
final int outputLength = out.size();
this.inputs = in.toArray( new IAEItemStack[isCrafting ? CRAFTING_INPUT_LIMIT : PROCESSING_INPUT_LIMIT] );
this.outputs = out.toArray( new IAEItemStack[outputLength] );
this.substituteInputs = new HashMap<>( CRAFTING_INPUT_LIMIT );
this.inputs = in.toArray(new IAEItemStack[ALL_INPUT_LIMIT]);
this.outputs = out.toArray(new IAEItemStack[outputLength]);
this.substituteInputs = new HashMap<>(ALL_INPUT_LIMIT);
final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>();
@@ -248,7 +245,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
final TestStatus result = this.getStatus( slotIndex, i );
switch ( result )
switch( result )
{
case ACCEPT:
return true;
@@ -267,11 +264,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
this.testFrame.setInventorySlotContents( slotIndex, i );
// If we cannot substitute, the items must match exactly
if( ( !( i.getItem().isDamageable() || Platform.isGTDamageableItem( i.getItem() ) ) && !canSubstitute ) && slotIndex < inputs.length )
{
if( !inputs[slotIndex].isSameType( i ) )
{
this.markItemAs( slotIndex, i, TestStatus.DECLINE );
if (!canSubstitute && slotIndex < inputs.length) {
if (!inputs[slotIndex].isSameType(i)) {
this.markItemAs(slotIndex, i, TestStatus.DECLINE);
return false;
}
}
@@ -329,26 +324,23 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
}
@Override
public List<IAEItemStack> getSubstituteInputs( int slot )
{
if( this.inputs[slot] == null )
{
public List<IAEItemStack> getSubstituteInputs(int slot) {
if (this.inputs[slot] == null) {
return Collections.emptyList();
}
return this.substituteInputs.computeIfAbsent( slot, value -> {
ItemStack[] matchingStacks = getRecipeIngredient( slot ).getMatchingStacks();
List<IAEItemStack> itemList = new ArrayList<>( matchingStacks.length + 1 );
for( ItemStack matchingStack : matchingStacks )
{
itemList.add( AEItemStack.fromItemStack( matchingStack ) );
return this.substituteInputs.computeIfAbsent(slot, value -> {
ItemStack[] matchingStacks = getRecipeIngredient(slot).getMatchingStacks();
List<IAEItemStack> itemList = new ArrayList<>(matchingStacks.length + 1);
for (ItemStack matchingStack : matchingStacks) {
itemList.add(AEItemStack.fromItemStack(matchingStack));
}
// Ensure that the specific item put in by the user is at the beginning,
// so that it takes precedence over substitutions
itemList.add( 0, this.inputs[slot] );
itemList.add(0, this.inputs[slot]);
return itemList;
} );
});
}
/**
@@ -358,40 +350,31 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
* ingredient list will be condensed to the actual recipe's grid size. In addition, in our 3x3 grid, the user can
* shift the actual recipe input to the right and down.
*/
private Ingredient getRecipeIngredient( int slot )
{
private Ingredient getRecipeIngredient(int slot) {
if( standardRecipe instanceof IShapedRecipe )
{
if (standardRecipe instanceof IShapedRecipe ) {
IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe;
return getShapedRecipeIngredient( slot, shapedRecipe.getRecipeWidth() );
}
else
{
return getShapelessRecipeIngredient( slot );
return getShapedRecipeIngredient(slot, shapedRecipe.getRecipeWidth());
} else {
return getShapelessRecipeIngredient(slot);
}
}
private Ingredient getShapedRecipeIngredient( int slot, int recipeWidth )
{
private Ingredient getShapedRecipeIngredient(int slot, int recipeWidth) {
// Compute the offset of the user's input vs. crafting grid origin
// Which is >0 if they have empty rows above or to the left of their input
int topOffset = 0;
if( inputs[0] == null && inputs[1] == null && inputs[2] == null )
{
if (inputs[0] == null && inputs[1] == null && inputs[2] == null) {
topOffset++; // First row is fully empty
if( inputs[3] == null && inputs[4] == null && inputs[5] == null )
{
if (inputs[3] == null && inputs[4] == null && inputs[5] == null) {
topOffset++; // Second row is fully empty
}
}
int leftOffset = 0;
if( inputs[0] == null && inputs[3] == null && inputs[6] == null )
{
if (inputs[0] == null && inputs[3] == null && inputs[6] == null) {
leftOffset++; // First column is fully empty
if( inputs[1] == null && inputs[4] == null && inputs[7] == null )
{
if (inputs[1] == null && inputs[4] == null && inputs[7] == null) {
leftOffset++; // Second column is fully empty
}
}
@@ -405,37 +388,32 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
if( ingredientIndex < 0 || ingredientIndex > ingredients.size() )
{
if (ingredientIndex < 0 || ingredientIndex > ingredients.size()) {
return Ingredient.EMPTY;
}
return ingredients.get( ingredientIndex );
return ingredients.get(ingredientIndex);
}
private Ingredient getShapelessRecipeIngredient( int slot )
{
private Ingredient getShapelessRecipeIngredient(int slot) {
// We map the list of *filled* sparse inputs to the shapeless (ergo unordered)
// ingredients. While these do not actually correspond to each other,
// since both lists have the same length, the mapping is at least stable.
int ingredientIndex = 0;
for( int i = 0; i < slot; i++ )
{
if( inputs[i] != null )
{
for (int i = 0; i < slot; i++) {
if (inputs[i] != null) {
ingredientIndex++;
}
}
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
if( ingredientIndex < ingredients.size() )
{
return ingredients.get( ingredientIndex );
if (ingredientIndex < ingredients.size()) {
return ingredients.get(ingredientIndex);
}
return Ingredient.EMPTY;
}
@Override
public ItemStack getOutput( final InventoryCrafting craftingInv, final World w )
{
@@ -537,9 +515,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
private enum TestStatus
{
ACCEPT,
DECLINE,
TEST
ACCEPT, DECLINE, TEST
}
private static final class TestLookup
+10 -7
View File
@@ -190,11 +190,10 @@ 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 ) );
}
@@ -207,7 +206,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() )
@@ -239,7 +238,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 )
@@ -260,7 +259,7 @@ public class TickHandler
final Stopwatch sw = Stopwatch.createStarted();
IWorldCallable<?> c = null;
while ( ( c = queue.poll() ) != null )
while( ( c = queue.poll() ) != null )
{
try
{
@@ -276,11 +275,15 @@ 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,37 +30,35 @@ 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() );
}
},
GTCE( IntegrationSide.BOTH, "GregTech", "gregtech" ),
{
@Override
public IIntegrationModule createInstance()
{
return Integrations.setIc2( new IC2Module() );
}
},
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" )
{
@@ -0,0 +1,26 @@
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemSlot;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
{
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
{
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
{
// Attempt getting an IItemHandler for the given side via caps
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
if (itemHandler != null)
{
return new GTCEItemHandler(itemHandler);
}
}
return null;
}
public abstract boolean canRemoveAllExceptCircuits();
}
@@ -0,0 +1,58 @@
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemHandlerIterator;
import appeng.util.inv.ItemSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class GTCEItemHandler extends GTCEInventoryAdaptor
{
ArrayList<Integer> GTCElenses = new ArrayList<>(Arrays.asList(15085,15214,15092,15111,15113,15219,15218,15243,15244,15209,15117,15206,15216,15331,15212,15213,15154,15122,15157,15190,15247));
ArrayList<Integer> GTCEmolds = new ArrayList<>(Arrays.asList(32301,32303,32304,32305,32306,32307,32308,32309,32313,32314,32315,32317,32350,32351,32352,32353,32354,32355,32356,32358,32359,32360,32361,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373));
Item smallGearExtruderShape = Item.getByNameOrId("contenttweaker:smallgearextrudershape");
Item creativePortableTankMold = Item.getByNameOrId("contenttweaker:creativeportabletankmold");
protected final IItemHandler itemHandler;
public GTCEItemHandler(IItemHandler itemHandler)
{
this.itemHandler = itemHandler;
}
boolean isBlockableItem(ItemStack stack)
{
if ( stack.getItem() == Item.getByNameOrId("gregtech:meta_item_1") ) {
int metadata = stack.getItemDamage();
if ( metadata == 32766 || GTCElenses.contains(metadata) || GTCEmolds.contains(metadata)) {
return false;
}
}
if ( stack.getItem() == smallGearExtruderShape ) return false;
if ( stack.getItem() == creativePortableTankMold) return false;
return true;
}
@Override
public boolean canRemoveAllExceptCircuits()
{
int slots = this.itemHandler.getSlots();
for ( int slot = 0; slot < slots; slot++ ) {
ItemStack is = this.itemHandler.getStackInSlot(slot);
if ( is.isEmpty() || !isBlockableItem(is) ) continue;
return false;
}
return true;
}
@Override
public Iterator<ItemSlot> iterator()
{
return new ItemHandlerIterator( this.itemHandler );
}
}
@@ -26,7 +26,6 @@ import java.util.List;
import java.util.Optional;
import appeng.client.gui.AEGuiHandler;
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -91,13 +90,16 @@ public class JEIPlugin implements IModPlugin
this.registerDescriptions( definitions, registry );
// Allow recipe transfer from JEI to crafting and pattern terminal
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), VanillaRecipeCategoryUid.CRAFTING );
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerExpandedProcessingPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
registry.getRecipeTransferRegistry()
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ),
VanillaRecipeCategoryUid.CRAFTING );
registry.getRecipeTransferRegistry()
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ),
Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
aeGuiHandler = new AEGuiHandler();
registry.addAdvancedGuiHandlers( aeGuiHandler );
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler );
registry.addAdvancedGuiHandlers(aeGuiHandler);
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler);
}
private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
@@ -35,8 +35,6 @@ public enum TheOneProbeText
P2P_UNLINKED,
P2P_INPUT_ONE_OUTPUT,
P2P_INPUT_MANY_OUTPUTS,
P2P_OUTPUT_ONE_INPUT,
P2P_OUTPUT_MANY_INPUTS,
P2P_OUTPUT,
P2P_FREQUENCY,
@@ -57,11 +57,11 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
// The default state
int state = STATE_UNLINKED;
int outputCount = getOutputCount( tunnel );
int inputCount = getInputCount( tunnel );
int outputCount = 0;
if( !tunnel.isOutput() )
{
outputCount = getOutputCount( tunnel );
if( outputCount > 0 )
{
// Only set it to INPUT if we know there are any outputs
@@ -70,7 +70,8 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
}
else
{
if( inputCount > 0 )
final PartP2PTunnel input = tunnel.getInput();
if( input != null )
{
state = STATE_OUTPUT;
}
@@ -82,7 +83,7 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
probeInfo.text( TheOneProbeText.P2P_UNLINKED.getLocal() );
break;
case STATE_OUTPUT:
probeInfo.text( getInputText( inputCount ) );
probeInfo.text( TheOneProbeText.P2P_OUTPUT.getLocal() );
break;
case STATE_INPUT:
probeInfo.text( getOutputText( outputCount ) );
@@ -109,19 +110,6 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
}
}
private static int getInputCount( PartP2PTunnel tunnel )
{
try
{
return Iterators.size( tunnel.getInputs().iterator() );
}
catch( GridAccessException e )
{
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText( int outputs )
{
if( outputs <= 1 )
@@ -134,16 +122,4 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
}
}
private static String getInputText( int inputs )
{
if( inputs <= 1 )
{
return TheOneProbeText.P2P_OUTPUT_ONE_INPUT.getLocal();
}
else
{
return String.format( TheOneProbeText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs );
}
}
}
@@ -21,7 +21,6 @@ package appeng.integration.modules.waila.part;
import java.util.List;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import com.google.common.collect.Iterators;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -118,11 +117,11 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
// The default state
int state = STATE_UNLINKED;
int outputCount = getOutputCount( tunnel );
int inputCount = getInputCount( tunnel );
int outputCount = 0;
if( !tunnel.isOutput() )
{
outputCount = getOutputCount( tunnel );
if( outputCount > 0 )
{
// Only set it to INPUT if we know there are any outputs
@@ -131,7 +130,8 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
}
else
{
if( inputCount > 0 )
PartP2PTunnel input = tunnel.getInput();
if( input != null )
{
state = STATE_OUTPUT;
}
@@ -160,40 +160,15 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
}
}
private static int getInputCount( PartP2PTunnel tunnel )
{
try
{
return Iterators.size( tunnel.getInputs().iterator() );
}
catch( GridAccessException e )
{
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText( int outputs )
{
if( outputs <= 1 )
{
return WailaText.P2P_INPUT_ONE_OUTPUT.getLocal();
return WailaText.P2PInputOneOutput.getLocal();
}
else
{
return String.format( WailaText.P2P_INPUT_MANY_OUTPUTS.getLocal(), outputs );
}
}
private static String getInputText( int inputs )
{
if( inputs <= 1 )
{
return WailaText.P2P_OUTPUT_ONE_INPUT.getLocal();
}
else
{
return String.format( WailaText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs );
return String.format( WailaText.P2PInputManyOutputs.getLocal(), outputs );
}
}
@@ -19,7 +19,6 @@
package appeng.items.contents;
import appeng.api.networking.security.IActionSource;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -43,8 +42,6 @@ import appeng.me.helpers.MEMonitorHandler;
import appeng.util.ConfigManager;
import appeng.util.Platform;
import java.util.Collections;
public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implements IPortableCell, IInventorySlotAware
{
@@ -86,34 +83,6 @@ public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implement
return usePowerMultiplier.divide( this.ips.extractAEPower( this.target, amt, Actionable.MODULATE ) );
}
@Override
public IAEItemStack injectItems( IAEItemStack input, Actionable mode, IActionSource src )
{
final long size = input.getStackSize();
final IAEItemStack injected = super.injectItems( input, mode, src );
if( mode == Actionable.MODULATE && ( injected == null || injected.getStackSize() != size ) )
{
this.notifyListenersOfChange( Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( injected == null ? 0 : injected.getStackSize() ) ) ), null);
}
return injected;
}
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
final IAEItemStack extractable = super.extractItems( request, mode, src );
if( mode == Actionable.MODULATE && extractable != null )
{
this.notifyListenersOfChange( Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), null );
}
return extractable;
}
@Override
public <T extends IAEStack<T>> IMEMonitor<T> getInventory( IStorageChannel<T> channel )
{
+185 -149
View File
@@ -28,9 +28,6 @@ import java.util.List;
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;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
@@ -60,12 +57,33 @@ import appeng.parts.automation.PartFormationPlane;
import appeng.parts.automation.PartIdentityAnnihilationPlane;
import appeng.parts.automation.PartImportBus;
import appeng.parts.automation.PartLevelEmitter;
import appeng.parts.misc.PartCableAnchor;
import appeng.parts.misc.PartInterface;
import appeng.parts.misc.PartInvertedToggleBus;
import appeng.parts.misc.PartStorageBus;
import appeng.parts.misc.PartToggleBus;
import appeng.parts.networking.PartCableCovered;
import appeng.parts.networking.PartCableGlass;
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.parts.reporting.PartConversionMonitor;
import appeng.parts.reporting.PartCraftingTerminal;
import appeng.parts.reporting.PartDarkPanel;
import appeng.parts.reporting.PartInterfaceTerminal;
import appeng.parts.reporting.PartPanel;
import appeng.parts.reporting.PartPatternTerminal;
import appeng.parts.reporting.PartSemiDarkPanel;
import appeng.parts.reporting.PartStorageMonitor;
import appeng.parts.reporting.PartTerminal;
import appeng.util.Platform;
@@ -74,84 +92,96 @@ 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 ),
@@ -163,13 +193,14 @@ public enum PartType
MONITOR( 160, "monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartPanel.class, "itemIlluminatedPanel" ),
SEMI_DARK_MONITOR( 180, "semi_dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartSemiDarkPanel.class, "itemIlluminatedPanel" ),
SEMI_DARK_MONITOR( 180, "semi_dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet
.noneOf( IntegrationType.class ), PartSemiDarkPanel.class, "itemIlluminatedPanel" ),
DARK_MONITOR( 200, "dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartDarkPanel.class, "itemIlluminatedPanel" ),
STORAGE_BUS( 220, "storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartStorageBus.class ),
FLUID_STORAGE_BUS( 221, "fluid_storage_bus", EnumSet.of( AEFeature.FLUID_STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidStorageBus.class ),
OREDICT_STORAGE_BUS( 222, "oredict_storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartOreDicStorageBus.class ),
FLUID_STORAGE_BUS( 221, "fluid_storage_bus", EnumSet.of( AEFeature.FLUID_STORAGE_BUS ), EnumSet
.noneOf( IntegrationType.class ), PartFluidStorageBus.class ),
IMPORT_BUS( 240, "import_bus", EnumSet.of( AEFeature.IMPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartImportBus.class ),
@@ -180,109 +211,113 @@ public enum PartType
FLUID_EXPORT_BUS( 261, "fluid_export_bus", EnumSet.of( AEFeature.FLUID_EXPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidExportBus.class ),
LEVEL_EMITTER( 280, "level_emitter", EnumSet.of( AEFeature.LEVEL_EMITTER ), EnumSet.noneOf( IntegrationType.class ), PartLevelEmitter.class ),
FLUID_LEVEL_EMITTER( 281, "fluid_level_emitter", EnumSet.of( AEFeature.FLUID_LEVEL_EMITTER ), EnumSet.noneOf( IntegrationType.class ), PartFluidLevelEmitter.class ),
FLUID_LEVEL_EMITTER( 281, "fluid_level_emitter", EnumSet.of( AEFeature.FLUID_LEVEL_EMITTER ), EnumSet
.noneOf( IntegrationType.class ), PartFluidLevelEmitter.class ),
ANNIHILATION_PLANE( 300, "annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartAnnihilationPlane.class ),
ANNIHILATION_PLANE( 300, "annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE ), EnumSet
.noneOf( IntegrationType.class ), PartAnnihilationPlane.class ),
IDENTITY_ANNIHILATION_PLANE( 301, "identity_annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE, AEFeature.IDENTITY_ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartIdentityAnnihilationPlane.class ),
IDENTITY_ANNIHILATION_PLANE( 301, "identity_annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE, AEFeature.IDENTITY_ANNIHILATION_PLANE ), EnumSet
.noneOf( IntegrationType.class ), PartIdentityAnnihilationPlane.class ),
FLUID_ANNIHILATION_PLANE( 302, "fluid_annihilation_plane", EnumSet.of( AEFeature.FLUID_ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFluidAnnihilationPlane.class ),
FLUID_ANNIHILATION_PLANE( 302, "fluid_annihilation_plane", EnumSet.of( AEFeature.FLUID_ANNIHILATION_PLANE ), EnumSet
.noneOf( IntegrationType.class ), PartFluidAnnihilationPlane.class ),
FORMATION_PLANE( 320, "formation_plane", EnumSet.of( AEFeature.FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFormationPlane.class ),
FLUID_FORMATION_PLANE( 321, "fluid_formation_plane", EnumSet.of( AEFeature.FLUID_FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFluidFormationPlane.class ),
FLUID_FORMATION_PLANE( 321, "fluid_formation_plane", EnumSet.of( AEFeature.FLUID_FORMATION_PLANE ), EnumSet
.noneOf( IntegrationType.class ), PartFluidFormationPlane.class ),
PATTERN_TERMINAL( 340, "pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartPatternTerminal.class ),
EXPANDED_PROCESSING_PATTERN_TERMINAL( 341, "expanded_processing_pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartExpandedProcessingPatternTerminal.class ),
CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet
.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
TERMINAL( 380, "terminal", EnumSet.of( AEFeature.TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartTerminal.class ),
STORAGE_MONITOR( 400, "storage_monitor", EnumSet.of( AEFeature.STORAGE_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartStorageMonitor.class ),
CONVERSION_MONITOR( 420, "conversion_monitor", EnumSet.of( AEFeature.PART_CONVERSION_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartConversionMonitor.class ),
CONVERSION_MONITOR( 420, "conversion_monitor", EnumSet.of( AEFeature.PART_CONVERSION_MONITOR ), EnumSet
.noneOf( IntegrationType.class ), PartConversionMonitor.class ),
INTERFACE( 440, "interface", EnumSet.of( AEFeature.INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartInterface.class ),
FLUID_INTERFACE( 441, "fluid_interface", EnumSet.of( AEFeature.FLUID_INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartFluidInterface.class ),
P2P_TUNNEL_ME( 460, "p2p_tunnel_me", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ME ), EnumSet.noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_ME( 460, "p2p_tunnel_me", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ME ), EnumSet
.noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_REDSTONE( 461, "p2p_tunnel_redstone", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_REDSTONE ), EnumSet.noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_REDSTONE( 461, "p2p_tunnel_redstone", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_REDSTONE ), EnumSet
.noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_ITEMS( 462, "p2p_tunnel_items", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ITEMS ), EnumSet.noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_ITEMS( 462, "p2p_tunnel_items", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ITEMS ), EnumSet
.noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_FLUIDS( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet.noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_FLUIDS( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet
.noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_IC2( 465, "p2p_tunnel_ic2", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_EU ), EnumSet.of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_IC2( 465, "p2p_tunnel_ic2", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_EU ), EnumSet
.of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_LIGHT( 467, "p2p_tunnel_light", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIGHT ), EnumSet.noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
P2P_TUNNEL_LIGHT( 467, "p2p_tunnel_light", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIGHT ), EnumSet
.noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel )
{
@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";
}
},
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";
}
},
// 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 );
@@ -323,7 +358,8 @@ 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 )
{
+7 -1
View File
@@ -19,8 +19,12 @@
package appeng.me;
import java.util.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import appeng.api.AEApi;
import appeng.api.networking.IGrid;
@@ -216,7 +220,9 @@ 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;
}
+11 -15
View File
@@ -59,13 +59,12 @@ import appeng.me.cache.CraftingGridCache;
import appeng.me.pathfinding.IPathItem;
import appeng.util.IWorldCallable;
import appeng.util.ReadOnlyCollection;
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,6 +165,8 @@ public class GridNode implements IGridNode, IPathItem
{
final Object tracker = new Object();
CraftingGridCache.pauseRebuilds();
Deque<GridNode> nextRun = new ArrayDeque<>();
nextRun.add( this );
@@ -176,9 +177,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() );
}
@@ -194,7 +195,7 @@ public class GridNode implements IGridNode, IPathItem
}
else
{
while ( !nextRun.isEmpty() )
while( !nextRun.isEmpty() )
{
final Iterable<GridNode> thisRun = nextRun;
nextRun = new ArrayDeque<>();
@@ -205,6 +206,7 @@ public class GridNode implements IGridNode, IPathItem
}
}
}
CraftingGridCache.unpauseRebuilds();
}
@Override
@@ -266,7 +268,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 )
@@ -331,11 +333,7 @@ public class GridNode implements IGridNode, IPathItem
@Override
public void loadFromNBT( final String name, final NBTTagCompound nodeData )
{
if( this.myGrid != null )
{
throw new IllegalStateException( "Loading data after part of a grid, this is invalid." );
}
if( nodeData.hasKey( name, 10 ) )
if( this.myGrid == null )
{
final NBTTagCompound node = nodeData.getCompoundTag( name );
this.playerID = node.getInteger( "p" );
@@ -347,9 +345,7 @@ public class GridNode implements IGridNode, IPathItem
}
else
{
this.playerID = -1; // Unknown owner
setLastSecurityKey( -1 );
setGridStorage( null );
throw new IllegalStateException( "Loading data after part of a grid, this is invalid." );
}
}
@@ -375,7 +371,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
+61 -69
View File
@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -41,7 +42,10 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import it.unimi.dsi.fastutil.objects.*;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import net.minecraft.world.World;
import appeng.api.AEApi;
@@ -113,9 +117,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 boolean updatePatterns = false;
private static int pauseRebuilds = 0;
private static Set<CraftingGridCache> rebuildNeeded = new HashSet<>();
public CraftingGridCache( final IGrid grid )
{
@@ -140,14 +144,8 @@ 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 ) )
{
@@ -193,7 +191,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( machine instanceof ICraftingProvider )
{
this.craftingProviders.remove( machine );
this.updatePatterns = true;
this.updatePatterns();
}
}
@@ -227,7 +225,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( machine instanceof ICraftingProvider )
{
this.craftingProviders.add( (ICraftingProvider) machine );
this.updatePatterns = true;
this.updatePatterns();
}
}
@@ -248,21 +246,45 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
// nothing!
}
private void updatePatterns()
public static void pauseRebuilds()
{
this.updatePatterns = true;
pauseRebuilds++;
}
private void recalculateCraftingPatterns()
public static void unpauseRebuilds()
{
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>( this.craftableItems );
final Set<IAEItemStack> oldEmitableItems = new HashSet<>( this.emitableItems );
pauseRebuilds--;
if (pauseRebuilds == 0 && rebuildNeeded.size() > 0)
{
ImmutableSet<CraftingGridCache> needed = ImmutableSet.copyOf(rebuildNeeded);
rebuildNeeded.clear();
for ( CraftingGridCache cache: needed )
{
cache.updatePatterns();
}
}
}
private void updatePatterns()
{
// coalesce change events during a grid traversal to a single rebuild
if (pauseRebuilds != 0)
{
rebuildNeeded.add(this);
return;
}
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = this.craftableItems;
// erase list.
this.craftingMethods.clear();
this.craftableItems.clear();
this.emitableItems.clear();
// update the stuff that was in the list...
this.storageGrid.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), oldItems.keySet(),
new BaseActionSource() );
// re-create list..
for( final ICraftingProvider provider : this.craftingProviders )
{
@@ -297,55 +319,8 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
}
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() ) )
{
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.add( changedStack );
}
}
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j )
{
if( !oldItems.containsKey( ais ) )
{
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.add( changedStack );
}
}
for( final IAEItemStack st : oldEmitableItems )
{
if( !emitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.add( changedStack );
}
}
for( final IAEItemStack st : this.emitableItems )
{
if( !oldEmitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.add( changedStack );
}
}
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged, new BaseActionSource() );
this.storageGrid.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), this.craftableItems.keySet(),
new BaseActionSource() );
}
private void updateCPUClusters()
@@ -523,6 +498,22 @@ 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();
}
@@ -568,7 +559,8 @@ 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() );
@@ -647,7 +639,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 );
}
@@ -681,7 +673,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() )
+17 -56
View File
@@ -19,12 +19,13 @@
package appeng.me.cache;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.crafting.MECraftingInventory;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.IPriorityHost;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
@@ -54,8 +55,6 @@ 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
@@ -67,11 +66,8 @@ 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 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;
private Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
private Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
public GridStorageCache( final IGrid g )
{
@@ -85,8 +81,6 @@ public class GridStorageCache implements IStorageGrid
@Override
public void onUpdateTick()
{
this.localCache = null;
this.extractableItemPriorityMap.clear();
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.onTick() );
}
@@ -174,38 +168,17 @@ 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 ) )
if( this.inactiveCellProviders.contains( cc ) && !this.activeCellProviders.contains( cc ))
{
this.inactiveCellProviders.remove( cc );
this.activeCellProviders.add( cc );
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
this.storageMonitors.forEach( ( channel, monitor ) -> {
this.storageMonitors.forEach( ( channel, monitor ) ->
{
for( final IMEInventoryHandler<?> h : cc.getCellArray( channel ) )
{
tracker.postChanges( channel, 1, h, actionSrc );
@@ -225,7 +198,8 @@ 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 );
@@ -239,11 +213,6 @@ 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>();
@@ -278,9 +247,10 @@ public class GridStorageCache implements IStorageGrid
this.removeCellProvider( cc, tracker );
}
}
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
tracker.applyChanges();
localDepth--;
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.setForceUpdate( true ) );
}
private <T extends IAEStack<T>, C extends IStorageChannel<T>> void postChangesToNetwork( final C chan, final int upOrDown, final IItemList<T> availableItems, final IActionSource src )
@@ -311,12 +281,6 @@ public class GridStorageCache implements IStorageGrid
this.storageMonitors.get( chan ).postChange( true, (Iterable) input, src );
}
@Override
public void postCraftablesChanges( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src )
{
this.storageMonitors.get( chan ).updateCraftables( (Iterable) input, src );
}
@Override
public void registerCellProvider( final ICellProvider provider )
{
@@ -360,10 +324,7 @@ public class GridStorageCache implements IStorageGrid
public void applyChanges()
{
if( !this.list.isEmpty() )
{
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
}
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
}
}
+100 -139
View File
@@ -19,9 +19,20 @@
package appeng.me.cache;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.api.AEApi;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Queues;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.events.MENetworkStorageEvent;
@@ -30,26 +41,17 @@ import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.me.storage.ItemWatcher;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.*;
import java.util.Map.Entry;
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{
@Nonnull
private static final HashMap<IActionSource, LinkedList<NetworkMonitor<?>>> src2MonitorsMap = new HashMap<>();
private static final Set<IActionSource> nestingSources = new HashSet<>();
protected boolean wasNested = false;
protected boolean isNested = false;
private static final Deque<NetworkMonitor<?>> GLOBAL_DEPTH = Queues.newArrayDeque();
@Nonnull
private final GridStorageCache myGridCache;
@@ -61,9 +63,9 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
private boolean sendEvent = false;
private long gridItemCount;
private long gridFluidCount;
public boolean forceUpdate;
private boolean hasChanged = false;
@Nonnegative
private int localDepthSemaphore = 0;
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
{
@@ -88,7 +90,21 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
@Override
public T extractItems( final T request, final Actionable mode, final IActionSource src )
{
return this.getHandler().extractItems( request, mode, src );
if( mode == Actionable.SIMULATE )
{
return this.getHandler().extractItems( request, mode, src );
}
this.localDepthSemaphore++;
final T leftover = this.getHandler().extractItems( request, mode, src );
this.localDepthSemaphore--;
if( this.localDepthSemaphore == 0 )
{
this.monitorDifference( request.copy(), leftover, true, src );
}
return leftover;
}
@Override
@@ -121,42 +137,38 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return this.getHandler().getSlot();
}
public long getGridCurrentCount()
{
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
return gridItemCount;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
return gridFluidCount;
}
return 0;
}
public void incGridCurrentCount( long count )
{
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount += count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount += count;
}
}
@Nonnull
@Override
public IItemList<T> getStorageList()
{
if( hasChanged )
{
hasChanged = false;
this.cachedList.resetStatus();
return this.getAvailableItems( this.cachedList );
}
return this.cachedList;
}
@Override
public T injectItems( final T input, final Actionable mode, final IActionSource src )
{
return this.getHandler().injectItems( input, mode, src );
if( mode == Actionable.SIMULATE )
{
return this.getHandler().injectItems( input, mode, src );
}
this.localDepthSemaphore++;
final T leftover = this.getHandler().injectItems( input, mode, src );
this.localDepthSemaphore--;
if( this.localDepthSemaphore == 0 )
{
this.monitorDifference( input.copy(), leftover, false, src );
}
return leftover;
}
@Override
@@ -188,15 +200,36 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return this.listeners.entrySet().iterator();
}
private T monitorDifference( final IAEStack<T> original, final T leftOvers, final boolean extraction, final IActionSource src )
{
final T diff = original.copy();
if( extraction )
{
diff.setStackSize( leftOvers == null ? 0 : -leftOvers.getStackSize() );
}
else if( leftOvers != null )
{
diff.decStackSize( leftOvers.getStackSize() );
}
if( diff.getStackSize() != 0 )
{
this.postChangesToListeners( ImmutableList.of( diff ), src );
}
return leftOvers;
}
private void notifyListenersOfChange( final Iterable<T> diff, final IActionSource src )
{
this.hasChanged = true;
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
while( i.hasNext() )
{
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
if( receiver.isValid( o.getValue() ) )
{
receiver.postChange( this, diff, src );
@@ -208,57 +241,46 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
}
}
protected void updateCraftables( Iterable<T> input, IActionSource src )
private void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
{
for( final T changedItem : input )
{
if (changedItem.isCraftable()) {
this.cachedList.add( changedItem );
}
else
{
T i = this.cachedList.findPrecise( changedItem );
if (i != null)
i.setCraftable( false );
}
}
this.postChange( true, changes, src );
}
protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src )
{
src2MonitorsMap.putIfAbsent( src, new LinkedList<>() );
if( src2MonitorsMap.get( src ).contains( this ) )
if( this.localDepthSemaphore > 0 || GLOBAL_DEPTH.contains( this ) )
{
nestingSources.add( src );
return;
}
src2MonitorsMap.get( src ).add( this );
GLOBAL_DEPTH.push( this );
this.localDepthSemaphore++;
this.sendEvent = true;
for( final T change : changes )
this.notifyListenersOfChange( changes, src );
for( final T changedItem : changes )
{
//T change = changed;
if( !add && change != null )
T difference = changedItem;
if( !add && changedItem != null )
{
//change = changed.copy();
change.setStackSize( -change.getStackSize() );
difference = changedItem.copy();
difference.setStackSize( -changedItem.getStackSize() );
}
incGridCurrentCount( change.getStackSize() );
this.cachedList.addStorage( change );
if( this.myGridCache.getInterestManager().containsKey( change ) )
if( this.myGridCache.getInterestManager().containsKey( changedItem ) )
{
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( change );
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( changedItem );
if( !list.isEmpty() )
{
IAEStack<T> fullStack = this.getStorageList().findPrecise( change );
IAEStack<T> fullStack = this.getStorageList().findPrecise( changedItem );
if( fullStack == null )
{
fullStack = change.copy();
fullStack = changedItem.copy();
fullStack.setStackSize( 0 );
}
@@ -266,7 +288,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
for( final ItemWatcher iw : list )
{
iw.getHost().onStackChange( this.getStorageList(), fullStack, change, src, this.getChannel() );
iw.getHost().onStackChange( this.getStorageList(), fullStack, difference, src, this.getChannel() );
}
this.myGridCache.getInterestManager().disableTransactions();
@@ -274,78 +296,21 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
}
}
this.notifyListenersOfChange( changes, src );
final NetworkMonitor<?> last = GLOBAL_DEPTH.pop();
this.localDepthSemaphore--;
if( src2MonitorsMap.get( src ).getFirst() == this )
if( last != this )
{
boolean nested = nestingSources.contains( src );
src2MonitorsMap.get( src ).forEach( networkMonitor -> networkMonitor.isNested = nested );
src2MonitorsMap.get( src ).forEach( networkMonitor -> {
if( networkMonitor.isNested != networkMonitor.wasNested )
{
networkMonitor.wasNested = networkMonitor.isNested;
networkMonitor.setForceUpdate( true );
}
} );
src2MonitorsMap.remove( src );
nestingSources.remove( src );
throw new IllegalStateException( "Invalid Access to Networked Storage API detected." );
}
}
public void setForceUpdate( boolean forceUpdate )
{
this.forceUpdate = forceUpdate;
}
void forceUpdate()
{
forceUpdate = false;
this.cachedList.resetStatus();
this.getAvailableItems( this.cachedList );
long count = 0;
for( T stack : this.cachedList )
{
count += stack.getStackSize();
if( this.myGridCache.getInterestManager().containsKey( stack ) )
{
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( stack );
if( !list.isEmpty() )
{
IAEStack<T> fullStack = this.getStorageList().findPrecise( stack );
if( fullStack == null )
{
fullStack = stack.copy();
fullStack.setStackSize( 0 );
}
this.myGridCache.getInterestManager().enableTransactions();
for ( final ItemWatcher iw : list )
{
iw.getHost().onStackChange( this.getStorageList(), fullStack, stack, null, this.getChannel() );
}
this.myGridCache.getInterestManager().disableTransactions();
}
}
}
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount = count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount = count;
}
this.hasChanged = true;
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
while ( i.hasNext() )
while( i.hasNext() )
{
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
@@ -363,10 +328,6 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
void onTick()
{
if( forceUpdate )
{
forceUpdate();
}
if( this.sendEvent )
{
this.sendEvent = false;
+17 -56
View File
@@ -19,7 +19,7 @@
package appeng.me.cache;
import java.util.Collection;
import java.util.HashMap;
import java.util.Random;
import com.google.common.collect.LinkedHashMultimap;
@@ -46,7 +46,7 @@ public class P2PCache implements IGridCache
private static final TunnelCollection<PartP2PTunnel> NULL_COLLECTION = new TunnelCollection<PartP2PTunnel>( null, null );
private final IGrid myGrid;
private final Multimap<Short, PartP2PTunnel> inputs = LinkedHashMultimap.create();
private final HashMap<Short, PartP2PTunnel> inputs = new HashMap<>();
private final Multimap<Short, PartP2PTunnel> outputs = LinkedHashMultimap.create();
private final Random frequencyGenerator;
@@ -110,19 +110,10 @@ public class P2PCache implements IGridCache
}
else
{
this.inputs.remove( t.getFrequency(), t );
this.inputs.remove( t.getFrequency() );
}
if( this.inputs.get( t.getFrequency() ).isEmpty() )
{
this.inputs.removeAll( t.getFrequency() );
}
if( this.outputs.get( t.getFrequency() ).isEmpty() )
{
this.outputs.removeAll( t.getFrequency() );
}
this.updateTunnel( t.getFrequency(), t.isOutput(), false );
this.updateTunnel( t.getFrequency(), !t.isOutput(), false );
}
}
@@ -151,7 +142,7 @@ public class P2PCache implements IGridCache
this.inputs.put( t.getFrequency(), t );
}
this.updateTunnel( t.getFrequency(), t.isOutput(), false );
this.updateTunnel( t.getFrequency(), !t.isOutput(), false );
}
}
@@ -173,20 +164,6 @@ public class P2PCache implements IGridCache
}
public void removeTunnel( final PartP2PTunnel t, short freq )
{
this.outputs.remove( freq, t );
this.inputs.remove( freq, t );
if( this.inputs.get( t.getFrequency() ).isEmpty() )
{
this.inputs.removeAll( t.getFrequency() );
}
if( this.outputs.get( t.getFrequency() ).isEmpty() )
{
this.outputs.removeAll( t.getFrequency() );
}
}
private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange )
{
for( final PartP2PTunnel p : this.outputs.get( freq ) )
@@ -198,7 +175,8 @@ public class P2PCache implements IGridCache
p.onTunnelNetworkChange();
}
for( final PartP2PTunnel in : this.inputs.get( freq ) )
final PartP2PTunnel in = this.inputs.get( freq );
if( in != null )
{
if( configChange )
{
@@ -217,7 +195,7 @@ public class P2PCache implements IGridCache
if( this.inputs.containsValue( t ) )
{
this.inputs.remove( t.getFrequency(), t );
this.inputs.remove( t.getFrequency() );
}
t.setFrequency( newFrequency );
@@ -233,6 +211,7 @@ public class P2PCache implements IGridCache
// AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq );
this.updateTunnel( t.getFrequency(), t.isOutput(), true );
this.updateTunnel( t.getFrequency(), !t.isOutput(), true );
}
public short newFrequency()
@@ -257,43 +236,25 @@ public class P2PCache implements IGridCache
public TunnelCollection<PartP2PTunnel> getOutputs( final short freq, final Class<? extends PartP2PTunnel> c )
{
Collection<PartP2PTunnel> in = this.inputs.get( freq );
final PartP2PTunnel in = this.inputs.get( freq );
if( in == null )
{
return NULL_COLLECTION;
}
TunnelCollection<PartP2PTunnel> out;
for( PartP2PTunnel part : this.inputs.get( freq ) )
{
out = part.getCollection( this.outputs.get( freq ), c );
if( out != null )
{
return out;
}
}
return NULL_COLLECTION;
}
public TunnelCollection<PartP2PTunnel> getInputs( final short freq, final Class<? extends PartP2PTunnel> c )
{
Collection<PartP2PTunnel> out = this.outputs.get( freq );
final TunnelCollection<PartP2PTunnel> out = this.inputs.get( freq ).getCollection( this.outputs.get( freq ), c );
if( out == null )
{
return NULL_COLLECTION;
}
TunnelCollection<PartP2PTunnel> in;
for( PartP2PTunnel part : this.outputs.get( freq ) )
{
in = part.getCollection( this.inputs.get( freq ), c );
if( in != null )
{
return in;
}
}
return NULL_COLLECTION;
return out;
}
public PartP2PTunnel getInput( final short freq )
{
return this.inputs.get( freq );
}
}
+1
View File
@@ -138,6 +138,7 @@ public class TickManagerCache implements ITickManager
tt.addEntityCrashInfo( crashreportcategory );
throw new ReportedException( crashreport );
}
PartLevelEmitter.wipeCache();
}
private void addToQueue( final TickTracker tt )
@@ -19,6 +19,21 @@
package appeng.me.cluster.implementations;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import appeng.api.config.Upgrades;
import appeng.helpers.DualityInterface;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.FuzzyMode;
@@ -27,7 +42,14 @@ import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.*;
import appeng.api.networking.crafting.CraftingItemList;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingJob;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingMedium;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingRequester;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.events.MENetworkCraftingCpuChange;
import appeng.api.networking.security.IActionSource;
@@ -40,8 +62,11 @@ import appeng.api.storage.data.IItemList;
import appeng.api.util.WorldCoord;
import appeng.container.ContainerNull;
import appeng.core.AELog;
import appeng.crafting.*;
import appeng.helpers.PatternHelper;
import appeng.crafting.CraftBranchFailure;
import appeng.crafting.CraftingJob;
import appeng.crafting.CraftingLink;
import appeng.crafting.CraftingWatcher;
import appeng.crafting.MECraftingInventory;
import appeng.me.cache.CraftingGridCache;
import appeng.me.cluster.IAECluster;
import appeng.me.helpers.MachineSource;
@@ -49,17 +74,6 @@ import appeng.tile.crafting.TileCraftingMonitorTile;
import appeng.tile.crafting.TileCraftingTile;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
@@ -87,7 +101,6 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
private IAEItemStack finalOutput;
private boolean waiting = false;
private IItemList<IAEItemStack> waitingFor = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private IItemList<IAEItemStack> neededForLoop = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private long availableStorage = 0;
private MachineSource machineSrc = null;
private int accelerator = 0;
@@ -210,10 +223,13 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
public boolean canAccept( final IAEItemStack input )
{
if( input != null )
if( input instanceof IAEItemStack )
{
final IAEItemStack is = this.waitingFor.findPrecise( input );
return is != null && is.getStackSize() > 0;
if( is != null && is.getStackSize() > 0 )
{
return true;
}
}
return false;
}
@@ -222,8 +238,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
// also stop accepting items when the job is complete, i.e. to prevent re-insertion when pushing out
// items during storeItems
if( input == null || isComplete )
{
if (input == null || isComplete) {
return input;
}
@@ -287,28 +302,9 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
if( this.finalOutput.equals( what ) )
{
IAEItemStack isLoop = neededForLoop.findPrecise( finalOutput );
IAEItemStack leftover = what;
if( isLoop != null && isLoop.getStackSize() > 0 )
{
if( isLoop.getStackSize() >= what.getStackSize() )
{
leftover = this.inventory.injectItems( what.copy(), type, src );
isLoop.decStackSize( what.getStackSize() );
}
else
{
leftover = this.inventory.injectItems( what.copy().setStackSize( what.getStackSize() - isLoop.getStackSize() ), type, src );
isLoop.decStackSize( what.getStackSize() - isLoop.getStackSize() );
}
if( leftover == null )
{
return null;
}
}
this.finalOutput.decStackSize( leftover.getStackSize() );
this.finalOutput.decStackSize( what.getStackSize() );
if( this.myLastLink != null )
{
@@ -338,28 +334,9 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
if( this.finalOutput.equals( insert ) )
{
IAEItemStack isLoop = neededForLoop.findPrecise( finalOutput );
IAEItemStack leftover = input;
if( isLoop != null && isLoop.getStackSize() > 0 )
{
if( isLoop.getStackSize() >= insert.getStackSize() )
{
leftover = this.inventory.injectItems( insert.copy(), type, src );
isLoop.decStackSize( insert.getStackSize() );
}
else
{
leftover = this.inventory.injectItems( insert.copy().setStackSize( insert.getStackSize() - isLoop.getStackSize() ), type, src );
isLoop.decStackSize( insert.getStackSize() - isLoop.getStackSize() );
}
if( leftover == null )
{
return null;
}
}
this.finalOutput.decStackSize( leftover.getStackSize() );
this.finalOutput.decStackSize( insert.getStackSize() );
if( this.myLastLink != null )
{
@@ -397,7 +374,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();
@@ -517,14 +494,15 @@ 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() )
{
@@ -537,7 +515,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
// When substitutions are allowed, we have to keep track of which items we've reserved
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() )
@@ -546,9 +524,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 )
@@ -558,7 +536,8 @@ 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 )
{
@@ -585,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() );
@@ -695,7 +674,8 @@ 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];
@@ -711,7 +691,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();
@@ -727,12 +707,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();
@@ -762,88 +742,71 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
continue;
}
if( details.isCraftable() )
{
ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
}
else
{
ic = new InventoryCrafting( new ContainerNull(), PatternHelper.PROCESSING_INPUT_WIDTH, PatternHelper.PROCESSING_INPUT_HEIGHT );
}
ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
boolean found = false;
for( int x = 0; x < input.length; x++ )
{
if( input[x] != null )
{
for (int x = 0; x < input.length; x++) {
if (input[x] != null) {
found = false;
if( details.isCraftable() )
{
if (details.isCraftable()) {
final Collection<IAEItemStack> itemList;
if( details.canSubstitute() )
{
final List<IAEItemStack> substitutes = details.getSubstituteInputs( x );
itemList = new ArrayList<>( substitutes.size() );
if (details.canSubstitute()) {
final List<IAEItemStack> substitutes = details.getSubstituteInputs(x);
itemList = new ArrayList<>(substitutes.size());
for( IAEItemStack stack : substitutes )
{
itemList.addAll( this.inventory.getItemList().findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
for (IAEItemStack stack : substitutes) {
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;
}
}
@@ -927,7 +890,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 )
@@ -987,12 +950,10 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
try
{
this.waitingFor.resetStatus();
this.neededForLoop.resetStatus();
( (CraftingJob) job ).getTree().setJob( ci, this, src );
if( ci.commit( src ) )
{
this.finalOutput = job.getOutput();
this.neededForLoop = ( (CraftingJob) job ).getNeededForLoop();
this.waiting = false;
this.isComplete = false;
this.markDirty();
@@ -1043,7 +1004,8 @@ 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() )
{
@@ -1101,7 +1063,8 @@ 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 )
@@ -1128,7 +1091,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 )
@@ -1199,7 +1162,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
IAEItemStack is;
switch ( storage2 )
switch( storage2 )
{
case STORAGE:
is = this.inventory.getItemList().findPrecise( what );
@@ -123,4 +123,4 @@ public class GenericInterestManager<T>
this.iw = watcher;
}
}
}
}
@@ -28,6 +28,8 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableList;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.IActionSource;
@@ -83,7 +85,11 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
@Override
public T injectItems( final T input, final Actionable mode, final IActionSource src )
{
return this.getHandler().injectItems( input, mode, src );
if( mode == Actionable.SIMULATE )
{
return this.getHandler().injectItems( input, mode, src );
}
return this.monitorDifference( input.copy(), this.getHandler().injectItems( input, mode, src ), false, src );
}
protected IMEInventoryHandler<T> getHandler()
@@ -91,7 +97,28 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
return this.internalHandler;
}
public void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
private T monitorDifference( final T original, final T leftOvers, final boolean extraction, final IActionSource src )
{
final T diff = original.copy();
if( extraction )
{
diff.setStackSize( leftOvers == null ? 0 : -leftOvers.getStackSize() );
}
else if( leftOvers != null )
{
diff.decStackSize( leftOvers.getStackSize() );
}
if( diff.getStackSize() != 0 )
{
this.postChangesToListeners( ImmutableList.of( diff ), src );
}
return leftOvers;
}
protected void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
{
this.notifyListenersOfChange( changes, src );
}
@@ -123,7 +150,11 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
@Override
public T extractItems( final T request, final Actionable mode, final IActionSource src )
{
return this.getHandler().extractItems( request, mode, src );
if( mode == Actionable.SIMULATE )
{
return this.getHandler().extractItems( request, mode, src );
}
return this.monitorDifference( request.copy(), this.getHandler().extractItems( request, mode, src ), true, src );
}
@Override
@@ -19,7 +19,6 @@
package appeng.me.helpers;
import java.util.Objects;
import java.util.Optional;
import net.minecraft.entity.player.EntityPlayer;
@@ -56,24 +55,4 @@ public class MachineSource implements IActionSource
return Optional.empty();
}
@Override
public boolean equals( Object o )
{
if( this == o )
{
return true;
}
if( o == null || getClass() != o.getClass() )
{
return false;
}
MachineSource that = (MachineSource) o;
return via.equals( that.via );
}
@Override
public int hashCode()
{
return Objects.hash( via );
}
}
@@ -19,20 +19,15 @@
package appeng.me.storage;
import appeng.core.features.registries.cell.CreativeCellHandler;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.tile.storage.TileDrive;
import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.networking.security.IActionSource;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.data.IAEStack;
import java.util.Collections;
public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{
@@ -40,16 +35,14 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
private int oldStatus = 0;
private final ItemStack is;
private final ICellHandler handler;
private final TileDrive drive;
private IActionSource source;
private final IChestOrDrive cord;
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final TileDrive drive )
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final IChestOrDrive cod )
{
super( i, i.getChannel() );
this.is = is;
this.handler = han;
this.drive = drive;
this.source = new MachineSource( drive );
this.cord = cod;
}
public int getStatus()
@@ -62,58 +55,38 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{
final long size = input.getStackSize();
final T remainder = super.injectItems( input, type, src );
final T a = super.injectItems( input, type, src );
if( type == Actionable.MODULATE && ( remainder == null || remainder.getStackSize() != size ) )
if( type == Actionable.MODULATE && ( a == null || a.getStackSize() != size ) )
{
final int newStatus = this.getStatus();
if( newStatus != this.oldStatus )
{
this.drive.blinkCell( this.getSlot() );
this.cord.blinkCell( this.getSlot() );
this.oldStatus = newStatus;
}
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler))
{
try
{
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( remainder == null ? 0 : remainder.getStackSize() ) ) ), this.source );
} catch ( GridAccessException e )
{
e.printStackTrace();
}
}
}
return remainder;
return a;
}
@Override
public T extractItems( final T request, final Actionable type, final IActionSource src )
{
final T extractable = super.extractItems( request, type, src );
final T a = super.extractItems( request, type, src );
if( type == Actionable.MODULATE && extractable != null )
if( type == Actionable.MODULATE && a != null )
{
final int newStatus = this.getStatus();
if( newStatus != this.oldStatus )
{
this.drive.blinkCell( this.getSlot() );
this.cord.blinkCell( this.getSlot() );
this.oldStatus = newStatus;
}
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler ))
{
try
{
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), this.source );
} catch ( GridAccessException e )
{
e.printStackTrace();
}
}
}
return extractable;
return a;
}
}
@@ -19,11 +19,14 @@
package appeng.me.storage;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import appeng.fluids.util.AEFluidStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
@@ -45,14 +48,16 @@ import appeng.api.storage.data.IItemList;
public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor
{
private final IFluidHandler handler;
private IItemList<IAEFluidStack> cache = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
private final IItemList<IAEFluidStack> list = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedFluidStack> memory;
private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIFluidHandler( final IFluidHandler handler )
{
this.handler = handler;
this.memory = new ConcurrentSkipListMap<>();
}
@Override
@@ -77,6 +82,11 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return input.copy();
}
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( filled == input.getStackSize() )
{
return null;
@@ -84,15 +94,6 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
final IAEFluidStack o = input.copy();
o.setStackSize( input.getStackSize() - filled );
if( type == Actionable.MODULATE )
{
IAEFluidStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o;
}
@@ -106,18 +107,13 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return null;
}
final IAEFluidStack o = request.copy();
o.setStackSize( removed.amount );
if( type == Actionable.MODULATE )
{
IAEFluidStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
this.onTick();
}
final IAEFluidStack o = request.copy();
o.setStackSize( removed.amount );
return o;
}
@@ -130,51 +126,111 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public TickRateModulation onTick()
{
final List<IAEFluidStack> changes = new ArrayList<>();
this.list.resetStatus();
int high = 0;
boolean changed = false;
final List<IAEFluidStack> changes = new ArrayList<>();
final IFluidTankProperties[] tankProperties = this.handler.getTankProperties();
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
for( IFluidTankProperties tankProperty : tankProperties )
final IFluidTankProperties[] props = this.handler.getTankProperties();
for( int slot = 0; slot < this.handler.getTankProperties().length; ++slot )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.handler.drain( 1, false ) == null )
final CachedFluidStack old = this.memory.get( slot );
high = Math.max( high, slot );
final FluidStack newIS = !props[slot].canDrain() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? null : props[slot].getContents();
final FluidStack oldIS = old == null ? null : old.fluidStack;
if( isDifferent( newIS, oldIS ) )
{
continue;
final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
}
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
}
for( final IAEFluidStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEFluidStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEFluidStack is : cache )
{
if( is.getStackSize() != 0 )
else
{
changes.add( is );
final int newSize = newIS == null ? 0 : newIS.amount;
final int diff = newSize - ( oldIS == null ? 0 : oldIS.amount );
IAEFluidStack stack = null;
if( newIS != null )
{
stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IFluidStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
}
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
final IAEFluidStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
}
}
cache = currentlyOnStorage;
// detect dropped items; should fix non IISided Inventory Changes.
final NavigableMap<Integer, CachedFluidStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedFluidStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEFluidStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() )
{
this.postDifference( changes );
changed = true;
}
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private static boolean isDifferent( FluidStack a, FluidStack b )
{
if( a == b )
{
return false;
}
if( a == null || b == null )
{
return true;
}
return !a.getFluid().equals( b.getFluid() );
}
private void postDifference( final Iterable<IAEFluidStack> a )
{
if( a != null )
@@ -235,9 +291,9 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public IItemList<IAEFluidStack> getAvailableItems( final IItemList out )
{
for( final IAEFluidStack fs : cache )
for( final CachedFluidStack is : this.memory.values() )
{
out.addStorage( fs );
out.addStorage( is.aeStack );
}
return out;
@@ -246,7 +302,7 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public IItemList<IAEFluidStack> getStorageList()
{
return this.cache;
return this.list;
}
private StorageFilter getMode()
@@ -270,4 +326,24 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
this.mySource = mySource;
}
private static class CachedFluidStack
{
private final FluidStack fluidStack;
private final IAEFluidStack aeStack;
CachedFluidStack( final FluidStack is )
{
if( is == null )
{
this.fluidStack = null;
this.aeStack = null;
}
else
{
this.fluidStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createStack( is );
}
}
}
}
@@ -19,8 +19,12 @@
package appeng.me.storage;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import net.minecraft.item.ItemStack;
@@ -46,15 +50,16 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
{
private final InventoryAdaptor adaptor;
private IItemList<IAEItemStack> cache = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedItemStack> memory;
private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIInventory( final InventoryAdaptor adaptor )
{
this.adaptor = adaptor;
this.memory = new ConcurrentSkipListMap<>();
}
@Override
@@ -83,6 +88,11 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
out = this.adaptor.addItems( input.createItemStack() );
}
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( out.isEmpty() )
{
return null;
@@ -91,15 +101,6 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
// better then doing construction from scratch :3
final IAEItemStack o = input.copy();
o.setStackSize( out.getCount() );
if( type == Actionable.MODULATE )
{
IAEItemStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o;
}
@@ -128,12 +129,6 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
if( type == Actionable.MODULATE )
{
IAEItemStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
this.onTick();
}
@@ -149,52 +144,110 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public TickRateModulation onTick()
{
boolean changed = false;
final List<IAEItemStack> changes = new ArrayList<>();
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
for( final ItemSlot is : adaptor )
this.list.resetStatus();
int high = 0;
boolean changed = false;
for( final ItemSlot is : this.adaptor )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
final CachedItemStack old = this.memory.get( is.getSlot() );
high = Math.max( high, is.getSlot() );
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
final ItemStack oldIS = old == null ? ItemStack.EMPTY : old.itemStack;
if( this.isDifferent( newIS, oldIS ) )
{
continue;
final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
}
currentlyOnStorage.add( is.getAEItemStack() );
}
for( final IAEItemStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEItemStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEItemStack is : cache )
{
if( is.getStackSize() != 0 )
else
{
changes.add( is );
final int newSize = ( newIS.isEmpty() ? 0 : newIS.getCount() );
final int diff = newSize - ( oldIS.isEmpty() ? 0 : oldIS.getCount() );
final IAEItemStack stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IItemStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
final IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
}
}
cache = currentlyOnStorage;
// detect dropped items; should fix non IISided Inventory Changes.
final NavigableMap<Integer, CachedItemStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedItemStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEItemStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() )
{
this.postDifference( changes );
changed = true;
}
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private boolean isDifferent( final ItemStack a, final ItemStack b )
{
if( a == b && b.isEmpty() )
{
return false;
}
if( ( a.isEmpty() && !b.isEmpty() ) || ( !a.isEmpty() && b.isEmpty() ) )
{
return true;
}
return !Platform.itemComparisons().isSameItem( a, b );
}
private void postDifference( final Iterable<IAEItemStack> a )
{
// AELog.info( a.getItemStack().getUnlocalizedName() + " @ " + a.getStackSize() );
if( a != null )
{
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
@@ -253,9 +306,9 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
{
for( IAEItemStack is : cache )
for( final CachedItemStack is : this.memory.values() )
{
out.addStorage( is );
out.addStorage( is.aeStack );
}
return out;
@@ -264,7 +317,7 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public IItemList<IAEItemStack> getStorageList()
{
return this.cache;
return this.list;
}
private StorageFilter getMode()
@@ -288,4 +341,24 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
this.mySource = mySource;
}
private static class CachedItemStack
{
private final ItemStack itemStack;
private final IAEItemStack aeStack;
public CachedItemStack( final ItemStack is )
{
if( is.isEmpty() )
{
this.itemStack = ItemStack.EMPTY;
this.aeStack = null;
}
else
{
this.itemStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
}
}
}
}
@@ -90,13 +90,6 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
@Override
public void addListener( final IMEMonitorHandlerReceiver<T> l, final Object verificationToken )
{
if( this.listeners.size() == 0 )
{
if( this.monitor != null )
{
this.monitor.addListener( this, this.monitor );
}
}
this.listeners.put( l, verificationToken );
}
@@ -171,5 +164,4 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
{
this.changeSource = changeSource;
}
}
@@ -41,7 +41,7 @@ public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler
this.setInternal( i );
}
public IMEInventory<T> getInternal()
protected IMEInventory<T> getInternal()
{
return this.internal;
}
@@ -19,8 +19,6 @@
package appeng.me.storage;
import appeng.me.helpers.MEMonitorHandler;
import appeng.me.helpers.MachineSource;
import com.mojang.authlib.GameProfile;
import appeng.api.AEApi;
@@ -37,20 +35,16 @@ import appeng.api.storage.data.IItemList;
import appeng.me.GridAccessException;
import appeng.tile.misc.TileSecurityStation;
import java.util.Collections;
public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStack>
{
private final IItemList<IAEItemStack> storedItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final TileSecurityStation securityTile;
private final MachineSource src;
public SecurityStationInventory( final TileSecurityStation ts )
{
this.securityTile = ts;
this.src = new MachineSource( securityTile );
}
@Override
@@ -67,11 +61,6 @@ public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStac
return null;
}
if( securityTile.getProxy().isActive() )
{
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( input.copy() ), this.src );
}
this.getStoredItems().add( input );
this.securityTile.inventoryChanged();
return null;
@@ -112,11 +101,6 @@ public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStac
return output;
}
if( securityTile.getProxy().isActive() )
{
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( target.copy().setStackSize( -target.getStackSize() ) ), this.src );
}
target.setStackSize( 0 );
this.securityTile.inventoryChanged();
return output;
@@ -27,7 +27,6 @@ import net.minecraft.item.ItemStack;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
@@ -60,12 +59,6 @@ public abstract class PartBasicState extends AEBasePart implements IPowerChannel
this.getHost().markForUpdate();
}
@MENetworkEventSubscribe
public void bootingRender( final MENetworkBootingStatusChange bs )
{
this.getHost().markForUpdate();
}
@Override
public void writeToStream( final ByteBuf data ) throws IOException
{
@@ -22,7 +22,6 @@ 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;
@@ -71,6 +70,8 @@ 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
@@ -130,7 +131,10 @@ 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 );
@@ -146,17 +150,21 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
final IAEItemStack ais = this.getConfig().getAEStackInSlot( slotToExport );
if( ais == null || this.itemToSend <= 0 )
{
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;
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 )
@@ -180,7 +188,15 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( this.itemToSend == before && this.isCraftingEnabled() )
{
this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething;
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;
}
}
@@ -262,30 +278,11 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( energy.extractAEPower( power, mode, PowerMultiplier.CONFIG ) > power - 0.01 )
{
ItemStack inputStack = items.getCachedItemStack( items.getStackSize() );
ItemStack remaining;
if( mode == Actionable.SIMULATE )
if( mode == Actionable.MODULATE )
{
remaining = d.simulateAdd( inputStack );
items.setCachedItemStack( inputStack );
return AEItemStack.fromItemStack( d.addItems( items.createItemStack() ) );
}
else
{
remaining = d.addItems( inputStack );
if( !remaining.isEmpty() )
{
items.setCachedItemStack( remaining );
}
}
if( remaining == inputStack )
{
return items;
}
return AEItemStack.fromItemStack( remaining );
return AEItemStack.fromItemStack( d.simulateAdd( items.createItemStack() ) );
}
}
}
@@ -321,21 +318,11 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
private void pushItemIntoTarget( final InventoryAdaptor d, final IEnergyGrid energy, final IMEInventory<IAEItemStack> inv, IAEItemStack ais )
{
ItemStack inputStack = ais.getCachedItemStack( ais.getStackSize() );
final ItemStack is = ais.createItemStack();
is.setCount( (int) this.itemToSend );
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();
final ItemStack o = d.simulateAdd( is );
final long canFit = o.isEmpty() ? this.itemToSend : this.itemToSend - o.getCount();
if( canFit > 0 )
{
@@ -347,9 +334,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
{
this.itemToSend -= itemsToAdd.getStackSize();
inputStack.setCount( Ints.saturatedCast( itemsToAdd.getStackSize() ) );
final ItemStack failed = d.addItems( inputStack );
final ItemStack failed = d.addItems( itemsToAdd.createItemStack() );
if( !failed.isEmpty() )
{
ais.setStackSize( failed.getCount() );
@@ -187,9 +187,8 @@ public class PartFormationPlane extends PartAbstractFormationPlane<IAEItemStack>
this.stateChanged();
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged changedChannels )
public void updateChannels( final MENetworkChannelsChanged changedChannels )
{
this.stateChanged();
}
@@ -207,7 +206,7 @@ public class PartFormationPlane extends PartAbstractFormationPlane<IAEItemStack>
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
handler.add( this.myHandler );
@@ -19,9 +19,40 @@
package appeng.parts.automation;
import java.util.Random;
import appeng.me.Grid;
import appeng.me.GridNode;
import appeng.util.item.AEItemStack;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.networking.crafting.*;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingProvider;
import appeng.api.networking.crafting.ICraftingProviderHelper;
import appeng.api.networking.crafting.ICraftingWatcher;
import appeng.api.networking.crafting.ICraftingWatcherHost;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergyWatcher;
import appeng.api.networking.energy.IEnergyWatcherHost;
@@ -50,28 +81,10 @@ import appeng.core.sync.GuiBridge;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.cache.NetworkMonitor;
import appeng.parts.PartModel;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.item.OreHelper;
import appeng.util.item.OreReference;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import java.util.Optional;
import java.util.Random;
public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherHost, IStackWatcherHost, ICraftingWatcherHost, IMEMonitorHandlerReceiver<IAEItemStack>, ICraftingProvider
@@ -110,6 +123,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
private double centerX;
private double centerY;
private double centerZ;
static Object2LongMap<Grid> gridItemCount = new Object2LongOpenHashMap<>();
static Object2ObjectOpenHashMap<Grid, Object2LongMap<AEItemStack>> fuzzyAEItemStackCount = new Object2ObjectOpenHashMap<>();
static Object2ObjectOpenHashMap<Grid, Object2LongMap<AEItemStack>> preciseAEItemStackCount = new Object2ObjectOpenHashMap<>();
@Reflected
public PartLevelEmitter( final ItemStack is )
@@ -140,6 +156,12 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
}
}
@MENetworkEventSubscribe
public void powerChanged( final MENetworkPowerStatusChange c )
{
this.updateState();
}
private void updateState()
{
final boolean isOn = this.isLevelEmitterOn();
@@ -184,25 +206,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
return flipState ? this.reportingValue >= this.lastReportedValue + 1 : this.reportingValue < this.lastReportedValue + 1;
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange powerEvent )
public void channelChanged( final MENetworkChannelsChanged c )
{
if (this.getProxy().isActive())
{
onListUpdate();
}
this.updateState();
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c )
{
if (this.getProxy().isActive())
{
onListUpdate();
}
this.updateState();
}
@@ -317,29 +323,90 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
}
private void updateReportingValue( final IMEMonitor<IAEItemStack> monitor )
{
updateReportingValue( monitor,null );
}
private void updateReportingValue( final IMEMonitor<IAEItemStack> monitor, Iterable<IAEItemStack> change )
{
final IAEItemStack myStack = this.config.getAEStackInSlot( 0 );
if( myStack == null )
GridNode node = (GridNode) (this.getGridNode());
if( node != null )
{
if( monitor instanceof NetworkMonitor )
final Grid g = node.getInternalGrid();
if( myStack == null )
{
this.lastReportedValue = ( (NetworkMonitor<IAEItemStack>) monitor ).getGridCurrentCount();
if( change != null )
{
if( gridItemCount.containsKey( g ) )
{
change.forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
}
}
gridItemCount.computeIfAbsent( g, ( aLong ) -> {
this.lastReportedValue = 0;
monitor.getStorageList().forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
return ( lastReportedValue );
} );
this.lastReportedValue = gridItemCount.get( g );
}
}
else if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
else if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
if( change != null )
{
if( fuzzyAEItemStackCount.containsKey( g ) )
{
change.forEach( iaeItemStack -> {
if( iaeItemStack.sameOre( myStack ) ) lastReportedValue += iaeItemStack.getStackSize();
} );
}
}
this.lastReportedValue = 0;
monitor.getStorageList().findFuzzy( myStack, fzMode ).forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
}
else
{
this.lastReportedValue = 0;
IAEItemStack precise = monitor.getStorageList().findPrecise( myStack );
if( precise != null ) lastReportedValue = precise.getStackSize();
fuzzyAEItemStackCount.computeIfAbsent( g, ( grid -> new Object2LongOpenHashMap<>() ) );
fuzzyAEItemStackCount.get( g ).computeIfAbsent( (AEItemStack) myStack, ( aLong -> {
this.lastReportedValue = 0;
monitor.getStorageList().findFuzzy( myStack, fzMode ).forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
return ( lastReportedValue );
} ) );
this.lastReportedValue = fuzzyAEItemStackCount.get( g ).get( myStack );
if( this.lastReportedValue == 0 )
{
fuzzyAEItemStackCount.get( g ).remove( myStack );
fuzzyAEItemStackCount.trim();
}
}
else
{
if( change != null )
{
if( preciseAEItemStackCount.containsKey( g ) )
{
change.forEach( iaeItemStack -> {
if( iaeItemStack.isSameType( myStack ) ) lastReportedValue += iaeItemStack.getStackSize();
} );
}
}
preciseAEItemStackCount.computeIfAbsent( g, ( grid -> new Object2LongOpenHashMap<>() ) );
preciseAEItemStackCount.get( g ).computeIfAbsent( (AEItemStack) myStack, ( aLong -> {
this.lastReportedValue = 0;
IAEItemStack precise = monitor.getStorageList().findPrecise( myStack );
if( precise != null ) lastReportedValue = precise.getStackSize();
return ( lastReportedValue );
} ) );
this.lastReportedValue = preciseAEItemStackCount.get( g ).get( myStack );
if( this.lastReportedValue == 0 )
{
preciseAEItemStackCount.get( g ).remove( myStack );
preciseAEItemStackCount.trim();
}
}
}
this.updateState();
}
@@ -354,7 +421,8 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
@Override
public void onStackChange( final IItemList o, final IAEStack fullStack, final IAEStack diffStack, final IActionSource src, final IStorageChannel chan )
{
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this.getInstalledUpgrades( Upgrades.FUZZY ) == 0 )
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this
.getInstalledUpgrades( Upgrades.FUZZY ) == 0 )
{
this.lastReportedValue = fullStack.getStackSize();
this.updateState();
@@ -391,7 +459,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
@Override
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource actionSource )
{
this.updateReportingValue( (IMEMonitor<IAEItemStack>) monitor );
this.updateReportingValue( (IMEMonitor<IAEItemStack>) monitor, change );
}
@Override
@@ -484,7 +552,6 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
public void upgradesChanged()
{
this.configureWatchers();
this.updateState();
}
@Override
@@ -569,4 +636,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
}
}
public static void wipeCache(){
fuzzyAEItemStackCount.clear();
preciseAEItemStackCount.clear();
gridItemCount.clear();
}
}
@@ -19,8 +19,8 @@
package appeng.parts.misc;
import javax.annotation.Nullable;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
@@ -44,6 +44,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import java.util.*;
@@ -59,7 +60,8 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private final IGridProxyable proxyable;
private final InventoryCache cache;
private StorageFilter mode;
private AccessRestriction access;
private ItemStack stackCache = null;
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
{
@@ -69,41 +71,39 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
{
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
}
this.cache = new InventoryCache( this.itemHandler, this.mode );
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() );
@Nullable ItemStack currentCached = stackCache;
stackCache = null;
ItemStack remaining = inputStack;
int slotCount = this.itemHandler.getSlots();
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
ItemStack orgInput;
if( currentCached != null && iox.isSameType( currentCached ) )
{
remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE );
}
// Store the stack in the cache for next time.
if( type == Actionable.SIMULATE )
{
iox.setCachedItemStack( inputStack );
// Cache is suitable, just update the count
orgInput = currentCached;
currentCached.setCount( Ints.saturatedCast( iox.getStackSize() ) );
}
else
{
if( !remaining.isEmpty() )
{
iox.setCachedItemStack( remaining );
}
// We need a new stack :-(
orgInput = iox.createItemStack();
}
ItemStack remaining = ItemHandlerHelper.insertItem( this.itemHandler, orgInput, type == Actionable.SIMULATE );
// Store the stack in the cache for next time.
if (!remaining.isEmpty() && remaining != orgInput)
{
stackCache = remaining;
}
// At this point, we still have some items left...
if( remaining == inputStack )
if( remaining == orgInput )
{
// The stack remained unmodified, target inventory is full
return iox;
@@ -111,9 +111,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
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() );
@@ -122,6 +119,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
{
// meh
}
}
return AEItemStack.fromItemStack( remaining );
@@ -130,23 +128,23 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
int remainingSize = Ints.saturatedCast( request.getStackSize() );
int remainingSize = Ints.saturatedCast(request.getStackSize());
// Use this to gather the requested items
ItemStack gathered = ItemStack.EMPTY;
final boolean simulate = ( mode == Actionable.SIMULATE );
for( int i = 0; i < this.itemHandler.getSlots(); i++ )
{
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
if( !request.isSameType( stackInInventorySlot ) )
if (!request.isSameType(stackInInventorySlot))
{
continue;
}
ItemStack extracted;
int stackSizeCurrentSlot = stackInInventorySlot.getCount();
int remainingCurrentSlot = Math.min( remainingSize, stackSizeCurrentSlot );
@@ -155,36 +153,24 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
do
{
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
if( !extracted.isEmpty() )
{
// In order to guard against broken IItemHandler implementations, we'll try to guess if the returned
// stack (especially in simulate mode) is the same that was returned by getStackInSlot. This is
// obviously not a precise science, but it would catch the previous Forge bug:
// https://github.com/MinecraftForge/MinecraftForge/pull/6580
if( extracted == stackInInventorySlot )
{
extracted = extracted.copy();
}
if( extracted.getCount() > remainingCurrentSlot )
{
// 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 );
extracted.setCount( remainingCurrentSlot );
}
// Heuristic for simulation: looping in case of simulations is pointless, since the state of the
// underlying inventory does not change after a simulated extraction. To still support inventories
// that report stacks that are larger than maxStackSize, we use this heuristic
if( simulate && extracted.getCount() == extracted.getMaxStackSize() && remainingCurrentSlot > extracted.getMaxStackSize() )
{
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 );
}
// We're just gonna use the first stack we get our hands on as the template for the rest.
// In case some stupid itemhandler (aka forge) returns an internal state we have to do a second
// expensive copy again.
if( gathered.isEmpty() )
{
gathered = extracted;
gathered = extracted.copy();
}
else
{
@@ -192,9 +178,11 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
}
remainingCurrentSlot -= extracted.getCount();
}
} while ( !simulate && !extracted.isEmpty() && remainingCurrentSlot > 0 );
} while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
// Done?
if( remainingSize <= 0 )
{
break;
@@ -203,15 +191,8 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
if( !gathered.isEmpty() )
{
IAEItemStack gatheredAEItemStack = AEItemStack.fromItemStack( gathered );
if( mode == Actionable.MODULATE )
{
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( gatheredAEItemStack.getStackSize() );
this.postDifference( Collections.singletonList( gatheredAEItemStack.copy().setStackSize( -gatheredAEItemStack.getStackSize() ) ) );
}
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
@@ -222,7 +203,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
}
}
return gatheredAEItemStack;
return AEItemStack.fromItemStack( gathered );
}
return null;
@@ -232,7 +213,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
public TickRateModulation onTick()
{
List<IAEItemStack> changes = this.cache.update();
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
if( !changes.isEmpty() )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
@@ -293,9 +274,9 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private static class InventoryCache implements Iterable<ItemSlot>
{
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
private final IItemHandler itemHandler;
private final StorageFilter mode;
IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
public InventoryCache( IItemHandler itemHandler, StorageFilter mode )
{
@@ -305,7 +286,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
{
currentlyCached.iterator().forEachRemaining( out::add );
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
return out;
}
@@ -317,41 +298,93 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
public List<IAEItemStack> update()
{
final List<IAEItemStack> changes = new ArrayList<>();
final int slots = this.itemHandler.getSlots();
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
// Make room for new slots
if( slots > this.cachedAeStacks.length )
{
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
}
for( final ItemSlot is : this )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
// Save the old stuff
final IAEItemStack oldAeIS = this.cachedAeStacks[is.getSlot()];
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
this.handlePossibleSlotChanges( is.getSlot(), oldAeIS, newIS, changes );
}
// Handle cases where the number of slots actually is lower now than before
if( slots < this.cachedAeStacks.length )
{
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
{
continue;
final IAEItemStack aeStack = this.cachedAeStacks[slot];
if( aeStack != null )
{
final IAEItemStack a = aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
}
}
currentlyOnStorage.add( is.getAEItemStack() );
}
for( final IAEItemStack is : currentlyCached )
{
is.setStackSize( -is.getStackSize() );
// Reduce the cache size
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
}
for( final IAEItemStack is : currentlyOnStorage )
{
currentlyCached.add( is );
}
for( final IAEItemStack is : currentlyCached )
{
if( is.getStackSize() != 0 )
{
changes.add( is );
}
}
currentlyCached = currentlyOnStorage;
return changes;
}
private void handlePossibleSlotChanges( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
{
if( oldAeIS != null && oldAeIS.isSameType( newIS ) )
{
this.handleStackSizeChanged( slot, oldAeIS, newIS, changes );
}
else
{
this.handleItemChanged( slot, oldAeIS, newIS, changes );
}
}
private void handleStackSizeChanged( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
{
// Still the same item, but amount might have changed
final long diff = newIS.getCount() - oldAeIS.getStackSize();
if( diff != 0 )
{
final IAEItemStack stack = oldAeIS.copy();
stack.setStackSize( newIS.getCount() );
this.cachedAeStacks[slot] = stack;
final IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
}
}
private void handleItemChanged( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
{
// Completely different item
this.cachedAeStacks[slot] = AEItemStack.fromItemStack( newIS );
// If we had a stack previously in this slot, notify the network about its disappearance
if( oldAeIS != null )
{
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
changes.add( oldAeIS );
}
// Notify the network about the new stack. Note that this is null if newIS was null
if( this.cachedAeStacks[slot] != null )
{
changes.add( this.cachedAeStacks[slot] );
}
}
@Override
public Iterator<ItemSlot> iterator()
{
@@ -2,9 +2,7 @@ package appeng.parts.misc;
import javax.annotation.Nullable;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.ticking.TickRateModulation;
@@ -26,6 +24,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.item.ItemStack;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -35,225 +34,281 @@ 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;
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();
}
private ItemStack stackCache;
@Override
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{
// Try to reuse the cached stack
ItemStack inputStack = iox.getCachedItemStack( iox.getStackSize() );
ItemRepositoryAdapter( IItemRepository itemRepository, IGridProxyable proxy )
{
this.itemRepository = itemRepository;
this.proxyable = proxy;
this.cache = new InventoryCache( this.itemRepository );
}
ItemStack remaining;
@Override
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{
// Try to reuse the cached stack
@Nullable ItemStack currentCached = stackCache;
stackCache = null;
remaining = this.itemRepository.insertItem( inputStack, type == Actionable.SIMULATE );
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 );
// Store the stack in the cache for next time.
if( type == Actionable.SIMULATE )
{
iox.setCachedItemStack( inputStack );
}
else
{
if( !remaining.isEmpty() )
{
iox.setCachedItemStack( remaining );
}
}
// Store the stack in the cache for next time.
if (!remaining.isEmpty() && remaining != orgInput)
{
stackCache = remaining;
}
// At this point, we still have some items left...
if( remaining == inputStack )
{
// The stack remained unmodified, target inventory is full
return iox;
}
// At this point, we still have some items left...
if( remaining == orgInput )
{
// 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 )
{
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() )
{
if( mode == Actionable.MODULATE )
{
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
}
}
return AEItemStack.fromItemStack( extracted );
}
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() )
{
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 IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
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 )
{
Arrays.stream( this.cachedAeStacks ).forEach( 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 );
List<IAEItemStack> out = this.iItemRepository.getAllItems().stream().map( s -> AEItemStack.fromItemStack( s.itemPrototype ).setStackSize( s.count ) ).collect( Collectors.toList() );
for( final IAEItemStack is : currentlyCached )
{
is.setStackSize( -is.getStackSize() );
}
final int size = out.size();
for( final IAEItemStack is : currentlyOnStorage )
{
currentlyCached.add( is );
}
// Make room for new slots
if( size > this.cachedAeStacks.length )
{
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, size );
}
for( final IAEItemStack is : currentlyCached )
{
if( is.getStackSize() != 0 )
{
changes.add( is );
}
}
for( int x = 0; x < size; x++ )
{
// Save the old stuff
final IAEItemStack oldAeIS = this.cachedAeStacks[x];
final IAEItemStack newIS = out.get( x );
currentlyCached = currentlyOnStorage;
this.handlePossibleSlotChanges( x, oldAeIS, newIS, changes );
}
return changes;
}
// Handle cases where the number of slots actually is lower now than before
if( size < this.cachedAeStacks.length )
{
for( int x = 0; x < this.cachedAeStacks.length; x++ )
{
final IAEItemStack aeStack = this.cachedAeStacks[x];
}
if( aeStack != null )
{
final IAEItemStack a = aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
}
}
// Reduce the cache size
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, size );
}
return changes;
}
private void handlePossibleSlotChanges( int slot, IAEItemStack oldAeIS, IAEItemStack newIS, List<IAEItemStack> changes )
{
if( oldAeIS != null && oldAeIS.isSameType( newIS ) )
{
this.handleStackSizeChanged( slot, oldAeIS, newIS, changes );
}
else
{
this.handleItemChanged( slot, oldAeIS, newIS, changes );
}
}
private void handleStackSizeChanged( int slot, IAEItemStack oldAeIS, IAEItemStack newIS, List<IAEItemStack> changes )
{
// Still the same item, but amount might have changed
final long diff = newIS.getStackSize() - oldAeIS.getStackSize();
if( diff != 0 )
{
final IAEItemStack stack = oldAeIS.copy();
stack.setStackSize( newIS.getStackSize() );
this.cachedAeStacks[slot] = stack;
final IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
}
}
private void handleItemChanged( int slot, IAEItemStack oldAeIS, IAEItemStack newIS, List<IAEItemStack> changes )
{
// Completely different item
this.cachedAeStacks[slot] = newIS ;
// If we had a stack previously in this slot, notify the network about its disappearance
if( oldAeIS != null )
{
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
changes.add( oldAeIS );
}
// Notify the network about the new stack. Note that this is null if newIS was null
if( this.cachedAeStacks[slot] != null )
{
changes.add( this.cachedAeStacks[slot] );
}
}
}
}
@@ -95,16 +95,14 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto
super( is );
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c )
public void stateChange( final MENetworkChannelsChanged c )
{
this.duality.notifyNeighbors();
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
public void stateChange( final MENetworkPowerStatusChange c )
{
this.duality.notifyNeighbors();
}
@@ -1,225 +0,0 @@
package appeng.parts.misc;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.ITickManager;
import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.AppEng;
import appeng.core.sync.GuiBridge;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.cache.GridStorageCache;
import appeng.me.storage.ITickingMonitor;
import appeng.me.storage.MEInventoryHandler;
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;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
public class PartOreDicStorageBus extends PartStorageBus
{
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/oredict_storage_bus_base" );
@PartModels
public static final IPartModel MODELS_OFF = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_off" ) );
@PartModels
public static final IPartModel MODELS_ON = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_on" ) );
@PartModels
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_has_channel" ) );
public String oreExp = "";
OreDictPriorityList<IAEItemStack> priorityList;
public PartOreDicStorageBus( ItemStack is )
{
super( is );
}
@Override
public void readFromNBT( NBTTagCompound data )
{
super.readFromNBT( data );
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", getOreExp() );
}
@Override
public boolean onPartActivate( final EntityPlayer player, final EnumHand hand, final Vec3d pos )
{
if( Platform.isServer() )
{
Platform.openGUI( player, this.getHost().getTile(), this.getSide(), GuiBridge.GUI_OREDICTSTORAGEBUS );
}
return true;
}
@Override
public GuiBridge getGuiBridge()
{
return GuiBridge.GUI_OREDICTSTORAGEBUS;
}
@Override
public MEInventoryHandler<IAEItemStack> getInternalHandler()
{
if( this.cached )
{
return this.handler;
}
final boolean wasSleeping = this.monitor == null;
this.cached = true;
final TileEntity self = this.getHost().getTile();
final TileEntity target = self.getWorld().getTileEntity( self.getPos().offset( this.getSide().getFacing() ) );
final int newHandlerHash = this.createHandlerHash( target );
if( newHandlerHash != 0 && newHandlerHash == this.handlerHash )
{
return this.handler;
}
this.handlerHash = newHandlerHash;
this.handler = null;
if( this.monitor != null )
{
( (IBaseMonitor<IAEItemStack>) monitor ).removeListener( this );
}
this.monitor = null;
if( target != null )
{
IMEInventory<IAEItemStack> inv = this.getInventoryWrapper( target );
if( inv instanceof ITickingMonitor )
{
this.monitor = (ITickingMonitor) inv;
this.monitor.setActionSource( mySrc );
this.monitor.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv != null )
{
this.handler = new MEInventoryHandler<>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
this.handler.setBaseAccess( (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS ) );
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
this.handler.setPriority( this.priority );
this.handler.setPartitionList( this.getPriorityList() );
if( inv instanceof IBaseMonitor )
{
if( ( (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS ) ).hasPermission( AccessRestriction.READ ) )
{
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
}
}
}
}
// update sleep state...
if( wasSleeping != ( this.monitor == null ) )
{
try
{
final ITickManager tm = this.getProxy().getTick();
if( this.monitor == null )
{
tm.sleepDevice( this.getProxy().getNode() );
}
else
{
tm.wakeDevice( this.getProxy().getNode() );
}
}
catch( final GridAccessException e )
{
// :(
}
}
try
{
// force grid to update handlers...
( (GridStorageCache) this.getProxy().getGrid().getCache( IStorageGrid.class ) ).cellUpdate( null );
}
catch( final GridAccessException e )
{
// :3
}
return this.handler;
}
private IPartitionList<IAEItemStack> getPriorityList()
{
if( priorityList == null )
{
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp );
}
return priorityList;
}
public String getOreExp()
{
if( this.oreExp == null )
{
return "";
}
return oreExp;
}
public void saveOreMatch( String oreMatch )
{
if( !this.oreExp.equals( oreMatch ) )
{
this.oreExp = oreMatch;
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp );
if( this.handler != null )
{
handler.setPartitionList( this.priorityList );
}
this.getHost().markForSave();
}
}
@Override
public IPartModel getStaticModels()
{
if( this.isActive() && this.isPowered() )
{
return MODELS_HAS_CHANNEL;
}
else if( this.isPowered() )
{
return MODELS_ON;
}
else
{
return MODELS_OFF;
}
}
}
@@ -0,0 +1,216 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2018, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.parts.misc;
import java.util.Collections;
import java.util.List;
import appeng.fluids.parts.PartFluidInterface;
import appeng.fluids.tile.TileFluidInterface;
import appeng.tile.networking.TileCableBus;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import appeng.api.AEApi;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.storage.ICellContainer;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.util.AECableType;
import appeng.api.util.IConfigManager;
import appeng.helpers.IPriorityHost;
import appeng.me.GridAccessException;
import appeng.parts.automation.PartUpgradeable;
/**
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public abstract class PartSharedStorageBus extends PartUpgradeable implements IGridTickable, ICellContainer, IPriorityHost
{
private boolean wasActive = false;
private int priority = 0;
public PartSharedStorageBus( ItemStack is )
{
super( is );
}
protected void updateStatus()
{
final boolean currentActive = this.getProxy().isActive();
if( this.wasActive != currentActive )
{
this.wasActive = currentActive;
try
{
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
this.getHost().markForUpdate();
}
catch( final GridAccessException ignore )
{
// :P
}
}
}
@MENetworkEventSubscribe
public void updateChannels( final MENetworkChannelsChanged changedChannels )
{
this.updateStatus();
}
/**
* Helper method to get this parts storage channel
*
* @return Storage channel
*/
public IStorageChannel getStorageChannel()
{
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
}
protected abstract void resetCache();
protected abstract void resetCache( boolean fullReset );
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
return Collections.emptyList();
}
@Override
public void blinkCell( int slot )
{
}
@Override
public void saveChanges( ICellInventory<?> cellInventory )
{
}
@Override
public int getPriority()
{
return this.priority;
}
@Override
public void setPriority( final int newValue )
{
this.priority = newValue;
this.getHost().markForSave();
this.resetCache( true );
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
{
this.updateStatus();
}
@Override
public void upgradesChanged()
{
super.upgradesChanged();
this.resetCache( true );
}
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
this.resetCache( true );
this.getHost().markForSave();
}
@Override
public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor )
{
final TileEntity te = w.getTileEntity( neighbor );
// In case the TE was destroyed, we have to do a full reset immediately.
if( te instanceof TileCableBus )
{
if( ( (TileCableBus) te ).getPart( this.getSide().getOpposite() ) instanceof PartFluidInterface )
{
this.resetCache( true );
this.resetCache();
}
}
if( te == null || te instanceof TileFluidInterface )
{
this.resetCache( true );
this.resetCache();
}
else
{
this.resetCache( false );
}
}
@Override
public void readFromNBT( final NBTTagCompound data )
{
super.readFromNBT( data );
this.priority = data.getInteger( "priority" );
}
@Override
public void writeToNBT( final NBTTagCompound data )
{
super.writeToNBT( data );
data.setInteger( "priority", this.priority );
}
@Override
public void getBoxes( final IPartCollisionHelper bch )
{
bch.addBox( 3, 3, 15, 13, 13, 16 );
bch.addBox( 2, 2, 14, 14, 14, 15 );
bch.addBox( 5, 5, 12, 11, 11, 14 );
}
@Override
protected int getUpgradeSlots()
{
return 5;
}
@Override
public float getCableConnectionLength( AECableType cable )
{
return 4;
}
}
@@ -19,51 +19,14 @@
package appeng.parts.misc;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.ITickManager;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartModel;
import appeng.api.storage.*;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.AECableType;
import appeng.api.util.IConfigManager;
import appeng.capabilities.Capabilities;
import appeng.core.AppEng;
import appeng.core.settings.TickRates;
import appeng.core.sync.GuiBridge;
import appeng.helpers.IPriorityHost;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.cache.GridStorageCache;
import appeng.me.helpers.MachineSource;
import appeng.me.storage.ITickingMonitor;
import appeng.me.storage.MEInventoryHandler;
import appeng.parts.PartModel;
import appeng.parts.automation.PartUpgradeable;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.misc.TileInterface;
import appeng.tile.networking.TileCableBus;
import appeng.util.ConfigManager;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.prioritylist.FuzzyPriorityList;
import appeng.util.prioritylist.PrecisePriorityList;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@@ -80,33 +43,88 @@ import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.FuzzyMode;
import appeng.api.config.IncludeExclude;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.api.config.Upgrades;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.ITickManager;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartModel;
import appeng.api.storage.ICellContainer;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.IStorageMonitorableAccessor;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.AECableType;
import appeng.api.util.AEPartLocation;
import appeng.api.util.IConfigManager;
import appeng.capabilities.Capabilities;
import appeng.core.AppEng;
import appeng.core.settings.TickRates;
import appeng.core.sync.GuiBridge;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.IPriorityHost;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.me.storage.ITickingMonitor;
import appeng.me.storage.MEInventoryHandler;
import appeng.me.storage.MEMonitorIInventory;
import appeng.parts.PartModel;
import appeng.parts.automation.PartUpgradeable;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.prioritylist.FuzzyPriorityList;
import appeng.util.prioritylist.PrecisePriorityList;
public class PartStorageBus extends PartUpgradeable implements IGridTickable, ICellContainer, IMEMonitorHandlerReceiver<IAEItemStack>, IPriorityHost
{
@CapabilityInject(IItemRepository.class)
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY = null;
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_base" );
@PartModels
public static final IPartModel MODELS_OFF = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_off" ) );
@PartModels
public static final IPartModel MODELS_ON = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_on" ) );
@PartModels
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_has_channel" ) );
@CapabilityInject( IItemRepository.class )
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY = null;
protected final IActionSource mySrc;
protected final AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 );
protected int priority = 0;
protected boolean cached = false;
protected ITickingMonitor monitor = null;
protected MEInventoryHandler<IAEItemStack> handler = null;
protected int handlerHash = 0;
private final IActionSource mySrc;
private final AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 );
private int priority = 0;
private boolean cached = false;
private ITickingMonitor monitor = null;
private MEInventoryHandler<IAEItemStack> handler = null;
private int handlerHash = 0;
private boolean wasActive = false;
private byte resetCacheLogic = 0;
private boolean accessChanged;
private boolean readOncePass;
@Reflected
public PartStorageBus( final ItemStack is )
@@ -143,9 +161,8 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged changedChannels )
public void updateChannels( final MENetworkChannelsChanged changedChannels )
{
this.updateStatus();
}
@@ -159,10 +176,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( settingName.name().equals( "ACCESS" ) )
{
this.accessChanged = true;
}
this.resetCache( true );
this.getHost().markForSave();
}
@@ -191,7 +204,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
super.readFromNBT( data );
this.Config.readFromNBT( data, "config" );
this.priority = data.getInteger( "priority" );
this.accessChanged = false;
}
@Override
@@ -215,7 +227,9 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
private void resetCache( final boolean fullReset )
{
if( this.getHost() == null || this.getHost().getTile() == null || this.getHost().getTile().getWorld() == null || this.getHost().getTile().getWorld().isRemote )
if( this.getHost() == null || this.getHost().getTile() == null || this.getHost().getTile().getWorld() == null || this.getHost()
.getTile()
.getWorld().isRemote )
{
return;
}
@@ -224,7 +238,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
{
this.resetCacheLogic = 2;
}
else if( this.resetCacheLogic < 2 )
else if( resetCacheLogic < 2 )
{
this.resetCacheLogic = 1;
}
@@ -248,29 +262,14 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
@Override
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource source )
{
if( this.getProxy().isActive() )
if( source == this.mySrc || source.machine().map( machine -> machine == this ).orElse( false ) )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
if( readOncePass )
{
readOncePass = false;
try
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, mySrc );
}
catch( final GridAccessException e )
{
// :(
}
return;
}
if( !currentAccess.hasPermission( AccessRestriction.READ ) )
{
return;
}
try
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, source );
if( this.getProxy().isActive() )
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, this.mySrc );
}
}
catch( final GridAccessException e )
{
@@ -303,34 +302,17 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
// In case the TE was destroyed, we have to do a full reset immediately.
if( te instanceof TileCableBus )
{
IPart iPart = ( (TileCableBus) te ).getPart( this.getSide().getOpposite() );
if( iPart == null )
if( ( (TileCableBus) te ).getPart( this.getSide().getOpposite() ) instanceof PartInterface )
{
this.resetCache( true );
this.resetCache();
}
else if( iPart instanceof PartInterface )
{
if( createHandlerHash( te ) != handlerHash )
{
this.resetCache( true );
this.resetCache();
}
}
}
else if( te == null )
if( te == null || te instanceof TileInterface )
{
this.resetCache( true );
this.resetCache();
}
else if( te instanceof TileInterface )
{
if( createHandlerHash( te ) != handlerHash )
{
this.resetCache( true );
this.resetCache();
}
}
else
{
this.resetCache( false );
@@ -381,28 +363,11 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
final boolean fullReset = this.resetCacheLogic == 2;
this.resetCacheLogic = 0;
final MEInventoryHandler<IAEItemStack> in = this.getInternalHandler();
final IMEInventory<IAEItemStack> in = this.getInternalHandler();
IItemList<IAEItemStack> before = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
if( in != null )
{
if( accessChanged )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
AccessRestriction oldAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getOldSetting( Settings.ACCESS );
if( oldAccess.hasPermission( AccessRestriction.READ ) && !currentAccess.hasPermission( AccessRestriction.READ ) )
{
readOncePass = true;
}
in.setBaseAccess( oldAccess );
before = in.getAvailableItems( before );
in.setBaseAccess( currentAccess );
accessChanged = false;
}
else
{
before = in.getAvailableItems( before );
}
before = in.getAvailableItems( before );
}
this.cached = false;
@@ -411,12 +376,11 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
this.handlerHash = 0;
}
final MEInventoryHandler<IAEItemStack> out = this.getInternalHandler();
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
final IMEInventory<IAEItemStack> out = this.getInternalHandler();
if( in != out )
{
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
if( out != null )
{
after = out.getAvailableItems( after );
@@ -425,7 +389,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
}
IMEInventory<IAEItemStack> getInventoryWrapper( TileEntity target )
private IMEInventory<IAEItemStack> getInventoryWrapper( TileEntity target )
{
EnumFacing targetSide = this.getSide().getFacing().getOpposite();
@@ -449,7 +413,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
// Check via cap for IItemRepository
if( ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ) )
if (ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ))
{
IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide );
if( handlerRepo != null )
@@ -468,7 +432,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
int createHandlerHash( TileEntity target )
private int createHandlerHash( TileEntity target )
{
if( target == null )
{
@@ -479,15 +443,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
if( target.hasCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide ) )
{
IStorageMonitorableAccessor accessor = target.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide );
if( accessor != null )
{
IStorageMonitorable inventory = accessor.getInventory( this.mySrc );
if( inventory != null )
{
return Objects.hash( target, inventory.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
}
return Objects.hash( target, target.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide ) );
}
@@ -522,25 +477,29 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
this.handlerHash = newHandlerHash;
this.handler = null;
if( this.monitor != null )
{
( (IBaseMonitor<IAEItemStack>) monitor ).removeListener( this );
}
this.monitor = null;
if( target != null )
{
IMEInventory<IAEItemStack> inv = this.getInventoryWrapper( target );
if( inv instanceof MEMonitorIInventory )
{
final MEMonitorIInventory h = (MEMonitorIInventory) inv;
h.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv instanceof ITickingMonitor )
{
this.monitor = (ITickingMonitor) inv;
this.monitor.setActionSource( mySrc );
this.monitor.setActionSource( new MachineSource( this ) );
this.monitor.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv != null )
{
this.handler = new MEInventoryHandler<>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
this.checkInterfaceVsStorageBus( target, this.getSide().getOpposite() );
this.handler = new MEInventoryHandler<IAEItemStack>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
this.handler.setBaseAccess( (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS ) );
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
@@ -560,19 +519,18 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
this.handler.setPartitionList( new FuzzyPriorityList<>( priorityList, (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ) ) );
this.handler
.setPartitionList( new FuzzyPriorityList<IAEItemStack>( priorityList, (FuzzyMode) this.getConfigManager()
.getSetting( Settings.FUZZY_MODE ) ) );
}
else
{
this.handler.setPartitionList( new PrecisePriorityList<>( priorityList ) );
this.handler.setPartitionList( new PrecisePriorityList<IAEItemStack>( priorityList ) );
}
if( inv instanceof IBaseMonitor )
{
if( ( (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS ) ).hasPermission( AccessRestriction.READ ) )
{
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
}
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
}
}
}
@@ -601,7 +559,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
try
{
// force grid to update handlers...
( (GridStorageCache) this.getProxy().getGrid().getCache( IStorageGrid.class ) ).cellUpdate( null );
(( GridStorageCache ) this.getProxy().getGrid().getCache( IStorageGrid.class )).cellUpdate( null );
}
catch( final GridAccessException e )
{
@@ -611,12 +569,38 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
return this.handler;
}
private void checkInterfaceVsStorageBus( final TileEntity target, final AEPartLocation side )
{
IInterfaceHost achievement = null;
if( target instanceof IInterfaceHost )
{
achievement = (IInterfaceHost) target;
}
if( target instanceof IPartHost )
{
final Object part = ( (IPartHost) target ).getPart( side );
if( part instanceof IInterfaceHost )
{
achievement = (IInterfaceHost) part;
}
}
if( achievement != null && achievement.getActionableNode() != null )
{
// Platform.addStat( achievement.getActionableNode().getPlayerID(), Achievements.Recursive.getAchievement()
// );
// Platform.addStat( getActionableNode().getPlayerID(), Achievements.Recursive.getAchievement() );
}
}
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
final IMEInventoryHandler<IAEItemStack> out = this.getInternalHandler();
final IMEInventoryHandler<IAEItemStack> out = this.getProxy().isActive() ? this.getInternalHandler() : null;
if( out != null )
{
return Collections.singletonList( out );
@@ -83,19 +83,10 @@ public class PartP2PFluids extends PartP2PTunnel<PartP2PFluids> implements IFlui
if( this.isOutput() )
{
try
final PartP2PFluids in = this.getInput();
if( in != null )
{
for( PartP2PFluids in : this.getInputs() )
{
if( in != null )
{
in.onTunnelNetworkChange();
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
in.onTunnelNetworkChange();
}
}
}
@@ -133,21 +124,13 @@ public class PartP2PFluids extends PartP2PTunnel<PartP2PFluids> implements IFlui
{
if( !this.isOutput() )
{
try
final PartP2PFluids tun = this.getInput();
if( tun != null )
{
for( PartP2PFluids tun : this.getInputs() )
{
if( tun != null )
{
return ACTIVE_TANK;
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
return ACTIVE_TANK;
}
}
return INACTIVE_TANK;
}
@@ -1,308 +0,0 @@
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;
}
}
}
@@ -33,6 +33,10 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.EmptyHandler;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
@@ -70,22 +74,10 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor )
{
this.cachedInv = null;
try
final PartP2PItems input = this.getInput();
if( input != null && this.isOutput() )
{
if( this.isOutput() )
{
for( PartP2PItems input : this.getInputs() )
{
if( input != null )
{
input.onTunnelNetworkChange();
}
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
input.onTunnelNetworkChange();
}
}
@@ -170,6 +162,51 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
return wasReq ? TickRateModulation.FASTER : TickRateModulation.SLOWER;
}
@MENetworkEventSubscribe
public void changeStateA( final MENetworkBootingStatusChange bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@MENetworkEventSubscribe
public void changeStateB( final MENetworkChannelsChanged bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@MENetworkEventSubscribe
public void changeStateC( final MENetworkPowerStatusChange bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@Override
public void onTunnelNetworkChange()
{
@@ -185,19 +222,10 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
}
else
{
try
final PartP2PItems input = this.getInput();
if( input != null )
{
for( PartP2PItems input : this.getInputs() )
{
if( input != null )
{
input.getHost().notifyNeighbors();
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
input.getHost().notifyNeighbors();
}
}
}
@@ -32,6 +32,8 @@ import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
@@ -60,6 +62,20 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
super( is );
}
@Override
public void chanRender( final MENetworkChannelsChanged c )
{
this.onTunnelNetworkChange();
super.chanRender( c );
}
@Override
public void powerRender( final MENetworkPowerStatusChange c )
{
this.onTunnelNetworkChange();
super.powerRender( c );
}
@Override
public void writeToStream( final ByteBuf data ) throws IOException
{
@@ -99,17 +115,9 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
this.lastValue = newLevel;
try
{
int light = 0;
for( PartP2PLight src : this.getInputs() )
{
if( src != null && src.getProxy().isActive() )
{
light = Math.max( light, src.lastValue );
}
}
for( final PartP2PLight out : this.getOutputs() )
{
out.setLightLevel( light );
out.setLightLevel( this.lastValue );
}
}
catch( final GridAccessException e )
@@ -188,22 +196,14 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
{
if( this.isOutput() )
{
try
final PartP2PLight src = this.getInput();
if( src != null && src.getProxy().isActive() )
{
int light = 0;
for( PartP2PLight src : this.getInputs() )
{
if( src != null && src.getProxy().isActive() )
{
light = Math.max( light, src.lastValue );
}
}
this.setLightLevel( light );
this.getHost().markForUpdate();
this.setLightLevel( src.lastValue );
}
catch( GridAccessException e )
else
{
e.printStackTrace();
this.getHost().markForUpdate();
}
}
else
@@ -31,6 +31,10 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.parts.IPartModel;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
@@ -56,25 +60,20 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
super( is );
}
@MENetworkEventSubscribe
public void changeStateA( final MENetworkBootingStatusChange bs )
{
this.setNetworkReady();
}
private void setNetworkReady()
{
if( this.isOutput() )
{
try
final PartP2PRedstone in = this.getInput();
if( in != null )
{
int power = 0;
for( PartP2PRedstone in : this.getInputs() )
{
if( in != null )
{
power = Math.max( power, in.power );
}
}
this.putInput( power );
}
catch( GridAccessException e )
{
e.printStackTrace();
this.putInput( in.power );
}
}
}
@@ -87,20 +86,12 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
}
this.recursive = true;
if( this.isOutput() )
if( this.isOutput() && this.getProxy().isActive() )
{
if( this.getProxy().isActive() )
final int newPower = (Integer) o;
if( this.power != newPower )
{
final int newPower = (Integer) o;
if( this.power != newPower )
{
this.power = newPower;
this.notifyNeighbors();
}
}
else
{
this.power = 0;
this.power = newPower;
this.notifyNeighbors();
}
}
@@ -120,6 +111,18 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
}
}
@MENetworkEventSubscribe
public void changeStateB( final MENetworkChannelsChanged bs )
{
this.setNetworkReady();
}
@MENetworkEventSubscribe
public void changeStateC( final MENetworkPowerStatusChange bs )
{
this.setNetworkReady();
}
@Override
public void readFromNBT( final NBTTagCompound tag )
{
@@ -164,22 +167,7 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
this.power = b.getWeakPower( state, this.getTile().getWorld(), target, srcSide );
this.power = Math.max( this.power, b.getWeakPower( state, this.getTile().getWorld(), target, srcSide ) );
int powerOut = this.power;
try
{
for( PartP2PRedstone in : this.getInputs() )
{
if( in != null )
{
powerOut = Math.max( in.power, powerOut );
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.sendToOutput( powerOut );
this.sendToOutput( this.power );
}
else
{
+29 -117
View File
@@ -24,10 +24,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
@@ -57,7 +53,6 @@ import appeng.me.cache.P2PCache;
import appeng.me.cache.helpers.TunnelCollection;
import appeng.parts.PartBasicState;
import appeng.util.Platform;
import org.lwjgl.input.Keyboard;
public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicState
@@ -82,13 +77,26 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
return null;
}
public TunnelCollection<T> getInputs() throws GridAccessException
public T getInput()
{
if( this.getProxy().isActive() && this.getFrequency() != 0 )
if( this.getFrequency() == 0 )
{
return (TunnelCollection<T>) this.getProxy().getP2P().getInputs( this.getFrequency(), this.getClass() );
return null;
}
return new TunnelCollection( new ArrayList(), this.getClass() );
try
{
final PartP2PTunnel tunnel = this.getProxy().getP2P().getInput( this.getFrequency() );
if( this.getClass().isInstance( tunnel ) )
{
return (T) tunnel;
}
}
catch( final GridAccessException e )
{
// :P
}
return null;
}
public TunnelCollection<T> getOutputs() throws GridAccessException
@@ -157,30 +165,6 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
data.writeShort( this.getFrequency() );
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c )
{
this.onTunnelNetworkChange();
super.chanRender( c );
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
{
this.onTunnelNetworkChange();
super.powerRender( c );
}
@Override
@MENetworkEventSubscribe
public void bootingRender( final MENetworkBootingStatusChange bs )
{
this.onTunnelNetworkChange();
super.bootingRender( bs );
}
@Override
public float getCableConnectionLength( AECableType cable )
{
@@ -206,13 +190,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
return false;
}
boolean pasteAsOutput = true;
ItemStack is = player.getHeldItem( hand );
if( is.isEmpty() )
{
pasteAsOutput = false;
is = player.getHeldItemOffhand();
}
final ItemStack is = player.getHeldItem( hand );
// UniqueIdentifier id = GameRegistry.findUniqueIdentifierFor( is.getItem() );
// AELog.info( "ID:" + id.toString() + " : " + is.getItemDamage() );
@@ -233,29 +211,14 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final IPart testPart = ( (IPartItem) newType.getItem() ).createPartFromItemStack( newType );
if( testPart instanceof PartP2PTunnel )
{
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), true );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir );
if( newBus instanceof PartP2PTunnel )
{
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
if( pasteAsOutput )
{
newTunnel.setOutput( true );
}
newTunnel.setOutput( true );
try
{
@@ -283,7 +246,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 );
@@ -293,10 +256,6 @@ 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;
@@ -336,17 +295,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final boolean oldOutput = this.isOutput();
final short myFreq = this.getFrequency();
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), false );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir );
@@ -354,6 +303,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
{
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( oldOutput );
newTunnel.onTunnelNetworkChange();
try
{
@@ -364,10 +314,9 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
{
// :P
}
newTunnel.onTunnelNetworkChange();
}
Platform.notifyBlocksOfNeighbors( this.getTile().getWorld(), this.getTile().getPos() );
return true;
}
}
@@ -401,38 +350,9 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
if( needsNewFrequency )
{
newFreq = this.getProxy().getP2P().newFrequency();
final ItemStack newType = this.getHost().getPart( this.getSide() ).getItemStack( PartItemStack.WRENCH );
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), false );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir );
if( newBus instanceof PartP2PTunnel )
{
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( false );
newTunnel.getProxy().getP2P().updateFreq( newTunnel, newFreq );
newTunnel.onTunnelNetworkChange();
}
}
else
{
this.getProxy().getP2P().updateFreq( this, newFreq );
this.onTunnelNetworkChange();
}
Platform.notifyBlocksOfNeighbors( this.getTile().getWorld(), this.getTile().getPos() );
this.getProxy().getP2P().updateFreq( this, newFreq );
}
catch( final GridAccessException e )
{
@@ -445,21 +365,12 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final String type = p2pItem.getUnlocalizedName();
p2pItem.writeToNBT( data );
if( needsNewFrequency )
{
data.setShort( "freq", newFreq );
}
else
{
data.setShort( "freq", this.getFrequency() );
}
data.setShort( "freq", this.getFrequency() );
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(),
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(),
};
data.setIntArray( "colorCode", colorCode );
@@ -484,6 +395,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
public void onTunnelNetworkChange()
{
}
protected void queueTunnelDrain( final PowerUnits unit, final double f )
@@ -21,14 +21,10 @@ package appeng.parts.reporting;
import java.io.IOException;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IItemList;
import appeng.fluids.util.AEFluidStack;
import appeng.util.item.AEStack;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.GlStateManager;
@@ -47,6 +43,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import appeng.api.AEApi;
import appeng.api.implementations.parts.IPartStorageMonitor;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IStackWatcher;
import appeng.api.networking.storage.IStackWatcherHost;
import appeng.api.parts.IPartModel;
@@ -55,6 +52,7 @@ import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.client.render.TesrRenderHelper;
import appeng.core.localization.PlayerMessages;
import appeng.helpers.Reflected;
@@ -82,7 +80,6 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
private IAEItemStack configuredItem;
private IAEFluidStack configuredFluid;
private long configuredAmount;
private String lastHumanReadableText;
private boolean isLocked;
private IStackWatcher myWatcher;
@@ -223,7 +220,7 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
}
else if( fluidInTank.amount > 0 )
{
this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank ).setStackSize( 0 );
this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank );
this.configuredItem = null;
}
@@ -307,31 +304,30 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
private <T extends IAEStack<T>> void updateReportingValue ( final IMEMonitor<T> monitor )
{
if( this.configuredItem != null)
{
final IAEItemStack result = (IAEItemStack) monitor.getStorageList().findPrecise( (T) this.configuredItem );
if( result == null )
{
this.configuredAmount = 0;
this.configuredItem.setStackSize( 0 );
}
else
{
this.configuredAmount = result.getStackSize();
this.configuredItem.setStackSize( result.getStackSize() );
}
this.configuredItem.setStackSize( this.configuredAmount );
}
else if( this.configuredFluid != null)
{
final IAEFluidStack result = (IAEFluidStack) monitor.getStorageList().findPrecise( (T) this.configuredFluid );
if( result == null )
{
this.configuredAmount = 0;
this.configuredFluid.setStackSize( 0 );
}
else
{
this.configuredAmount = result.getStackSize();
this.configuredFluid.setStackSize( result.getStackSize() );
}
this.configuredFluid.setStackSize( this.configuredAmount );
}
}
@@ -396,38 +392,49 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
this.configureWatchers();
}
@MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange ev )
{
if( this.getProxy().isPowered() )
{
this.configureWatchers();
}
}
@MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c )
{
if( this.getProxy().isPowered() )
{
this.configureWatchers();
}
}
@Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
public void onStackChange( final IItemList o, final IAEStack fullStack, final IAEStack diffStack, final IActionSource src, final IStorageChannel chan )
{
this.configuredAmount = fullStack.getStackSize();
if( this.configuredItem != null )
{
this.configuredItem.setStackSize( this.configuredAmount );
if( fullStack == null )
{
this.configuredItem.setStackSize( 0 );
}
else
{
this.configuredItem.setStackSize( fullStack.getStackSize() );
}
final long stackSize = this.configuredItem.getStackSize();
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize );
if( !humanReadableText.equals( this.lastHumanReadableText ) )
{
this.lastHumanReadableText = humanReadableText;
this.getHost().markForUpdate();
}
}
else if( this.configuredFluid != null )
{
this.configuredFluid.setStackSize( this.configuredAmount );
if( fullStack == null )
{
this.configuredFluid.setStackSize( 0 );
}
else
{
this.configuredFluid.setStackSize( fullStack.getStackSize() );
}
final long stackSize = this.configuredFluid.getStackSize() / 1000;
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
if( !humanReadableText.equals( this.lastHumanReadableText ) )
{
this.lastHumanReadableText = humanReadableText;
this.getHost().markForUpdate();
}
}
this.getHost().markForUpdate();
}
@Override
@@ -137,10 +137,14 @@ public class PartConversionMonitor extends AbstractPartMonitor
{
this.insertItem( player, hand, false );
}
}
//If its a fluid container, grab its fluidstack. if its empty pass its itemstack;
if (eq.isEmpty()){
return super.onPartActivate( player, hand, pos );
}
if( fluidInTank != null && fluidInTank.amount > 0 )
{
if( getDisplayed() instanceof IAEItemStack || getDisplayed() == null )
@@ -151,14 +155,20 @@ public class PartConversionMonitor extends AbstractPartMonitor
{
this.drainFluidContainer( player, hand );
}
else
{
else {
return super.onPartActivate( player, hand, pos );
}
}
else if( this.getDisplayed() != null && this.getDisplayed().equals( player.getHeldItem( hand ) ) )
else
{
this.insertItem( player, hand, false );
if( getDisplayed() instanceof IAEFluidStack || getDisplayed() == null )
{
return super.onPartActivate( player, hand, pos );
}
if( ( (IAEItemStack) this.getDisplayed() ).equals( eq ) )
{
this.insertItem( player, hand, false );
}
}
return super.onPartActivate( player, hand, pos );
}
@@ -181,6 +191,7 @@ public class PartConversionMonitor extends AbstractPartMonitor
return false;
}
ItemStack eq = player.getHeldItem( hand );
if( this.getDisplayed() != null && this.getDisplayed() instanceof IAEItemStack )
{
this.extractItem( player, ( (IAEItemStack) this.getDisplayed() ).getDefinition().getMaxStackSize() );
@@ -270,7 +281,7 @@ public class PartConversionMonitor extends AbstractPartMonitor
{
if (!(this.getDisplayed() instanceof IAEItemStack))
return;
final IAEItemStack input = (IAEItemStack) this.getDisplayed().copy();
final IAEItemStack input = (IAEItemStack) this.getDisplayed();
if( input != null )
{
try

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