Compare commits

..

4 Commits

Author SHA1 Message Date
Salomão d58a5f0307 fix advancements 2021-04-01 02:13:11 -03:00
Salomão 4c4214754a Merge branch 'fastutils' into AE2-Omnifactory 2021-03-31 21:09:03 -03:00
Salomão 011b3a4b94 backport 0bdc408e950fe787277d1e48be61ebf928127429 2021-03-31 20:53:26 -03:00
Salomão ca7ce33f34 testes 2021-03-31 18:14:16 -03:00
130 changed files with 2696 additions and 4149 deletions
-58
View File
@@ -1,58 +0,0 @@
Changes so far :
Design changes/breakages:
- Interfaces no longer spill items of one pattern on other faces
- Interfaces now push patterns in round-robin (Interfaces, then sides)
Fixes:
- Fix gregtech machines appearing with 'unnamed' or 'draconium lens' on the interface terminal on specific situations.
- Add memorycard support for fluid interfaces, import/export/storage busses and level emitters ( this fix was upstreamed to AE2 for MC 1.16)
- Storage busses now hide/show inaccessible items as configured.
- 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:
- Added @talchas fixes for insane channelless AE networks.
- Implemented StorageDrawers slotless itemrepository.
- Removed CraftedEvent calls (really bad lag with craftweaker versions before CraftTweaker2-1.12-4.1.20.626)
- 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:
- added highlight interface button to interface terminal ("?" button on the left of the interface slots)
- 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)
- 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 )
- Encoded patterns stack up to 64 ( holding shift and clicking the encode arrow will transfer the encoded pattern to the player inventory)
- 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)
HOTKEYS:
- Implemented mousetweaks API. AE2 custom keybinds now work. (Try right clicking and use the scroll-wheel on the terminals)
- Holding SHIFT and scrolling UP and DOWN will increase the items set on the configured slots of Interfaces and Pattern Terminal (Processing mode)
+1 -1
View File
@@ -3,7 +3,7 @@ aechannel=stable
aebuild=7
aegroup=appeng
aebasename=appliedenergistics2
trousers=omni-fixes-v46aa
trousers=omni-fixes-v21b
#########################################################
# Versions #
+14 -7
View File
@@ -19,6 +19,11 @@
repositories {
mavenLocal()
maven {
name = "storagedrawers"
url = "https://dl.bintray.com/jaquadro/dev/"
}
maven {
name "Mobius"
url "http://mobiusstrip.eu/maven"
@@ -34,11 +39,6 @@ repositories {
url "http://maven.mcmoddev.com"
}
maven {
name "Ellpeck"
url "https://maven.ellpeck.de"
}
maven {
name = "IC2 repo"
url = "http://maven.ic2.player.to"
@@ -59,6 +59,11 @@ repositories {
url "http://maven.k-4u.nl/"
}
maven { // Hwyla
name 'tehnut'
url "http://tehnut.info/maven"
}
maven { // CraftTweaker
name 'jared maven'
url "http://maven.blamejared.com/"
@@ -80,7 +85,8 @@ configurations {
}
dependencies {
compileOnly "gregtechce:gregtech:1.12.2:1.15.1.735"
compileOnly "com.jaquadro.minecraft.storagedrawers:StorageDrawers:1.12.2-5.4.2:api"
compileOnly "gregtechce:gregtech:1.12.2:1.12.0.662"
// installable runtime dependencies
mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
@@ -97,10 +103,11 @@ dependencies {
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
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"
// at runtime, use the full JEI jar
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
runtime "com.jaquadro.minecraft.storagedrawers:StorageDrawers:1.12.2-5.4.2"
runtime "com.jaquadro.minecraft.chameleon:Chameleon:1.12-4.1.3"
// unit test dependencies
testCompile "junit:junit:4.12"
+31 -11
View File
@@ -23,18 +23,38 @@
package appeng.api.config;
public enum FuzzyMode {
/**
* Matches any item from undamaged to including 0% durability, but not negative durability (where item damage
* exceeds maxdamage).
*/
IGNORE_ALL(-1),
/**
* Matches items that have less than 100% durability (that is, at least 1 damage point) if a damaged item is used as
* the filter, or undamaged items otherwise.
*/
PERCENT_99(0),
/**
* If an item with less than 75% durability is used as the filter, items with less than 75% durability are matched.
* Otherwise items with 75% durability or more are matched.
*/
PERCENT_75(25),
/**
* If an item with less than 50% durability is used as the filter, items with less than 50% durability are matched.
* Otherwise items with 50% durability or more are matched.
*/
PERCENT_50(50),
/**
* If an item with less than 25% durability is used as the filter, items with less than 50% durability are matched.
* Otherwise items with 25% durability or more are matched.
*/
PERCENT_25(75);
public enum FuzzyMode
{
// Note that percentage damaged, is the inverse of percentage durability.
IGNORE_ALL( -1 ),
PERCENT_99( 0 ),
PERCENT_75( 25 ),
PERCENT_50( 50 ),
PERCENT_25( 75 );
public final float breakPoint;
public final float percentage;
public final float breakPoint;
/**
* Note this is percentage "damaged". It's the inverse of percentage durability.
*/
public final float percentage;
FuzzyMode( final float p )
{
+1 -2
View File
@@ -46,8 +46,7 @@ public enum Upgrades
*/
FUZZY( 1 ),
SPEED( 1 ),
INVERTER( 1 ),
PATTERN_EXPANSION(1);
INVERTER( 1 );
private final int tier;
private final Map<ItemStack, Integer> supportedMax = new HashMap<>();
@@ -89,8 +89,6 @@ public interface IMaterials
IItemDefinition cardCapacity();
IItemDefinition cardPatternExpansion();
IItemDefinition cardFuzzy();
IItemDefinition cardInverter();
@@ -31,9 +31,6 @@ import net.minecraft.world.World;
import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.storage.data.IAEItemStack;
import java.util.Collections;
import java.util.List;
/**
* do not implement provided by {@link ICraftingPatternItem}
@@ -87,11 +84,6 @@ public interface ICraftingPatternDetails
*/
boolean canSubstitute();
default List<IAEItemStack> getSubstituteInputs( int slot )
{
return Collections.emptyList();
}
/**
* Allow using this INSTANCE of the pattern details to preform the crafting action with performance enhancements.
*
@@ -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
@@ -114,8 +114,8 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
ItemStack getDefinition();
/**
* Compare this AE item stack to another item stack, but ignores
* the amount. It checks the item type, NBT and damage values.
* Compare this AE item stack to another item stack, but ignores the amount. It checks the item type, NBT and damage
* values.
*
* @param is An item stack
*/
@@ -23,27 +23,24 @@
package appeng.api.storage.data;
import java.io.IOException;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import appeng.api.config.FuzzyMode;
import appeng.api.storage.IStorageChannel;
public interface IAEStack<T extends IAEStack<T>>
{
public interface IAEStack<T extends IAEStack<T>> {
/**
* add two stacks together
*
* @param is added item
*/
void add( T is );
void add(T is);
/**
* number of items in the stack.
@@ -57,7 +54,7 @@ public interface IAEStack<T extends IAEStack<T>>
*
* @param stackSize , ItemStack.stackSize = N
*/
T setStackSize( long stackSize );
T setStackSize(long stackSize);
/**
* Same as getStackSize, but for requestable items. ( LP )
@@ -71,7 +68,7 @@ public interface IAEStack<T extends IAEStack<T>>
*
* @return basically itemStack.stackSize = N but for setStackSize items.
*/
T setCountRequestable( long countRequestable );
T setCountRequestable(long countRequestable);
/**
* true, if the item can be crafted.
@@ -85,7 +82,7 @@ public interface IAEStack<T extends IAEStack<T>>
*
* @param isCraftable can item be crafted
*/
T setCraftable( boolean isCraftable );
T setCraftable(boolean isCraftable);
/**
* clears, requestable, craftable, and stack sizes.
@@ -104,33 +101,33 @@ public interface IAEStack<T extends IAEStack<T>>
*
* @param i additional stack size
*/
void incStackSize( long i );
void incStackSize(long i);
/**
* removes some from the stack size.
*/
void decStackSize( long i );
void decStackSize(long i);
/**
* adds items to the requestable
*
* @param i increased amount of requested items
*/
void incCountRequestable( long i );
void incCountRequestable(long i);
/**
* removes items from the requestable
*
* @param i decreased amount of requested items
*/
void decCountRequestable( long i );
void decCountRequestable(long i);
/**
* write to a NBTTagCompound.
* write to a CompoundNBT.
*
* @param i to be written data
*/
void writeToNBT( NBTTagCompound i );
void writeToNBT( NBTTagCompound i);
/**
* Compare stacks using precise logic.
@@ -146,17 +143,18 @@ public interface IAEStack<T extends IAEStack<T>>
* @return true if they are the same.
*/
@Override
boolean equals( Object obj );
boolean equals(Object obj);
/**
* Compare the same subtype of {@link IAEStack} with another using a fuzzy comparison.
* Compare the same subtype of {@link IAEStack} with another using a fuzzy
* comparison.
*
* @param other The stack to compare.
* @param mode Which {@link FuzzyMode} should be used.
* @param mode Which {@link FuzzyMode} should be used.
*
* @return true if two stacks are equal based on AE Fuzzy Comparison.
*/
boolean fuzzyComparison( T other, FuzzyMode mode );
boolean fuzzyComparison(T other, FuzzyMode mode);
/**
* Slower for disk saving, but smaller/more efficient for packets.
@@ -165,7 +163,7 @@ public interface IAEStack<T extends IAEStack<T>>
*
* @throws IOException
*/
void writeToPacket( ByteBuf data ) throws IOException;
void writeToPacket( ByteBuf data) throws IOException;
/**
* Clone the Item / Fluid Stack
@@ -182,17 +180,7 @@ public interface IAEStack<T extends IAEStack<T>>
T empty();
/**
* @return true if the stack is a {@link IAEItemStack}
*/
boolean isItem();
/**
* @return true if the stack is a {@link IAEFluidStack}
*/
boolean isFluid();
/**
* @return ITEM or FLUID
* @return The {@link IStorageChannel} backing this stack.
*/
IStorageChannel<T> getChannel();
@@ -202,4 +190,4 @@ public interface IAEStack<T extends IAEStack<T>>
* @return itemstack
*/
ItemStack asItemStackRepresentation();
}
}
@@ -1,143 +0,0 @@
package com.jaquadro.minecraft.storagedrawers.api.capabilities;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import javax.annotation.Nonnull;
import java.util.function.Predicate;
/**
* An interface for treating an inventory as a slotless, central repository of items.
*
* For all operations that accept a predicate, if a predicate is supplied, a stored ItemStack must pass the predicate
* in order to be considered for the given operation.
*
* An IItemRepository implementation MAY relax or eliminate its own internal tests when a predicate is supplied. If
* the predicate is derived from DefaultPredicate, then the implementation MUST apply any tests it would have applied
* had no predicate been provided at all, in addition to testing the predicate itself.
*/
public interface IItemRepository
{
/**
* Gets a list of all items in the inventory. The same item may appear multiple times with varying counts.
* @return A list of zero or more items in the inventory.
*/
@Nonnull
NonNullList<ItemRecord> getAllItems ();
/**
* Inserts an ItemStack into the inventory and returns the remainder.
*
* @param stack ItemStack to insert.
* @param simulate If true, the insertion is only simulated
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return The remaining ItemStack that was not inserted. If the entire stack was accepted, returns
* ItemStack.EMPTY instead.
*/
@Nonnull
ItemStack insertItem (@Nonnull ItemStack stack, boolean simulate, Predicate<ItemStack> predicate);
@Nonnull
default ItemStack insertItem (@Nonnull ItemStack stack, boolean simulate) {
return insertItem(stack, simulate, null);
}
/**
* Tries to extract the given ItemStack from the inventory. The returned value will be a matching ItemStack
* with a stack size equal to or less than amount, or the empty ItemStack if the item could not be found at all.
* The returned stack size may exceed the ItemStack's getMaxStackSize() value.
* @param stack The item to extract. The stack size is ignored.
* @param amount Amount to extract (may be greater than the stacks max limit)
* @param simulate If true, the extraction is only simulated
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return ItemStack extracted from the inventory, or ItemStack.EMPTY if nothing could be extracted.
*/
@Nonnull
ItemStack extractItem (@Nonnull ItemStack stack, int amount, boolean simulate, Predicate<ItemStack> predicate);
@Nonnull
default ItemStack extractItem (@Nonnull ItemStack stack, int amount, boolean simulate) {
return extractItem(stack, amount, simulate, null);
}
/**
* Gets the number of items matching the given ItemStack stored by the inventory.
* @param stack ItemStack to query.
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return The number of stored matching items. A value of Integer.MAX_VALUE may indicate an infinite item source.
*/
default int getStoredItemCount (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
ItemStack amount = extractItem(stack, Integer.MAX_VALUE, true, predicate);
return amount.getCount();
}
default int getStoredItemCount (@Nonnull ItemStack stack) {
return getStoredItemCount(stack, null);
}
/**
* Gets the number items matching the given ItemStack that additionally still be stored by the inventory.
* Remaining capacity may include space that is internally empty or unassigned to any given item.
*
* @param stack ItemStack to query.
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return The available remaining space for matching items.
*/
default int getRemainingItemCapacity (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
stack = stack.copy();
stack.setCount(Integer.MAX_VALUE);
ItemStack remainder = insertItem(stack, true, predicate);
return Integer.MAX_VALUE - remainder.getCount();
}
default int getRemainingItemCapacity (@Nonnull ItemStack stack) {
return getRemainingItemCapacity(stack, null);
}
/**
* Gets the total inventory capacity for items matching the given ItemStack.
* Total capacity may include space that is internally empty or unassigned to any given item.
*
* @param stack ItemStack to query.
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return The total capacity for matching items.
*/
default int getItemCapacity (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
long capacity = getStoredItemCount(stack, predicate) + getRemainingItemCapacity(stack, predicate);
if (capacity > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
return (int)capacity;
}
default int getItemCapacity (@Nonnull ItemStack stack) {
return getItemCapacity(stack, null);
}
/**
* An item record representing an item and the amount stored.
*
* The ItemStack held by itemPrototype always reports a stack size of 1.
* IT IS IMPORTANT THAT YOU NEVER MODIFY itemPrototype.
*/
class ItemRecord
{
@Nonnull
public final ItemStack itemPrototype;
public final int count;
public ItemRecord (@Nonnull ItemStack itemPrototype, int count) {
this.itemPrototype = itemPrototype;
this.count = count;
}
}
/**
* A variant of the standard Predicate interface that when passed to IItemRepository functions, will ask the
* internal default predicate to be tested in addition to the custom predicate. An IItemRepository function
* may choose to enforce its own predicate regardless.
*/
interface DefaultPredicate<T> extends Predicate<T> { }
}
+4 -27
View File
@@ -25,11 +25,8 @@ import java.util.EnumMap;
import java.util.List;
import java.util.Random;
import appeng.client.gui.AEBaseGui;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.helpers.HighlighterHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
@@ -39,7 +36,10 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.*;
import net.minecraftforge.client.event.MouseEvent;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.MinecraftForge;
@@ -75,7 +75,6 @@ import appeng.hooks.TickHandler;
import appeng.hooks.TickHandler.PlayerColor;
import appeng.server.ServerHelper;
import appeng.util.Platform;
import org.lwjgl.input.Mouse;
public class ClientHelper extends ServerHelper
@@ -316,28 +315,6 @@ public class ClientHelper extends ServerHelper
Minecraft.getMinecraft().effectRenderer.addEffect( fx );
}
@SubscribeEvent
public void MouseClickEvent( final GuiScreenEvent.MouseInputEvent.Pre me )
{
final Minecraft mc = Minecraft.getMinecraft();
if( mc.currentScreen instanceof IJEIGhostIngredients )
{
AEBaseGui gui = ( (AEBaseGui) mc.currentScreen );
Object ingredient = gui.getBookmarkedIngredient();
if( ingredient != null )
{
if( GuiScreen.isShiftKeyDown() )
{
me.setCanceled( true );
}
else if( Mouse.isButtonDown( 0 ) )
{
me.setCanceled( true );
}
}
}
}
@SubscribeEvent
public void wheelEvent( final MouseEvent me )
{
+59 -150
View File
@@ -19,7 +19,6 @@
package appeng.client.gui;
import java.awt.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.ParseException;
@@ -32,16 +31,13 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import appeng.container.slot.*;
import appeng.tile.inventory.AppEngInternalInventory;
import com.google.common.base.Joiner;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.Gui;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.items.IItemHandler;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
@@ -75,7 +71,17 @@ import appeng.client.me.SlotDisconnected;
import appeng.client.me.SlotME;
import appeng.client.render.StackSizeRenderer;
import appeng.container.AEBaseContainer;
import appeng.container.slot.AppEngCraftingSlot;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.AppEngSlot.hasCalculatedValidness;
import appeng.container.slot.IOptionalSlot;
import appeng.container.slot.SlotCraftingTerm;
import appeng.container.slot.SlotDisabled;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotInaccessible;
import appeng.container.slot.SlotOutput;
import appeng.container.slot.SlotPatternTerm;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
@@ -86,9 +92,6 @@ import appeng.fluids.container.slots.IMEFluidSlot;
import appeng.helpers.InventoryAction;
import yalter.mousetweaks.api.IMTModGuiContainer2;
import static appeng.integration.modules.jei.JEIPlugin.aeGuiHandler;
import static appeng.integration.modules.jei.JEIPlugin.runtime;
@Optional.Interface( iface = "yalter.mousetweaks.api.IMTModGuiContainer2", modid = "mousetweaks" )
public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContainer2
@@ -103,28 +106,6 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
private Stopwatch dbl_clickTimer = Stopwatch.createStarted();
private ItemStack dbl_whichItem = ItemStack.EMPTY;
private Slot bl_clicked;
private Stopwatch lastClicked = Stopwatch.createStarted();
private List<IGhostIngredientHandler.Target<Object>> hoveredIngredientTargets = new ArrayList<>();
private Object bookmarkedIngredient;
private boolean isDraggingJeiGhostItem;
public void setJeiGhostItem( boolean jeiGhostItem )
{
isJeiGhostItem = jeiGhostItem;
}
private boolean isJeiGhostItem;
public Object getBookmarkedIngredient()
{
return bookmarkedIngredient;
}
public List<GuiCustomSlot> getGuiSlots()
{
return guiSlots;
}
protected final List<GuiCustomSlot> guiSlots = new ArrayList<>();
public AEBaseGui( final Container container )
@@ -207,65 +188,6 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
this.drawTooltip( (ITooltip) c, mouseX, mouseY );
}
}
GlStateManager.enableDepth();
bookmarkedJEIghostItem(mouseX,mouseY);
GlStateManager.disableDepth();
}
void bookmarkedJEIghostItem(final int mouseX, final int mouseY) {
if (!isJeiGhostItem)
{
bookmarkedIngredient = runtime.getBookmarkOverlay().getIngredientUnderMouse();
}
if( bookmarkedIngredient != null )
{
hoveredIngredientTargets = aeGuiHandler.getTargets( this, bookmarkedIngredient, false );
ItemStack dragItem = ItemStack.EMPTY;
if( hoveredIngredientTargets.size() > 0 )
{
if( isShiftKeyDown() && Mouse.isButtonDown( 0 ) && this.lastClicked.elapsed( TimeUnit.MILLISECONDS ) > 200 )
{
this.lastClicked = Stopwatch.createStarted();
aeGuiHandler.getTargets( this, bookmarkedIngredient, true );
}
else if( Mouse.isButtonDown( 0 ) && this.lastClicked.elapsed( TimeUnit.MILLISECONDS ) > 200 )
{
this.lastClicked = Stopwatch.createStarted();
if( bookmarkedIngredient instanceof ItemStack )
{
dragItem = ( (ItemStack) bookmarkedIngredient );
}
else if( bookmarkedIngredient instanceof FluidStack )
{
dragItem = FluidUtil.getFilledBucket( ( (FluidStack) bookmarkedIngredient ) );
}
mc.player.inventory.setItemStack( dragItem.copy() );
this.isJeiGhostItem = true;
}
drawTargets( mouseX, mouseY );
}
}
}
private void drawTargets(int mouseX, int mouseY) {
GlStateManager.disableLighting();
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{
Rectangle area = target.getArea();
Color color;
if( area.contains( mouseX, mouseY ) )
{
color = new Color( 76, 201, 25, 128 );
}
else
{
color = new Color( 19, 201, 10, 64 );
}
Gui.drawRect( area.x, area.y, area.x + area.width, area.y + area.height, color.getRGB() );
}
GlStateManager.color( 1f, 1f, 1f, 1f );
GlStateManager.enableDepth();
}
protected void drawGuiSlot( GuiCustomSlot slot, int mouseX, int mouseY, float partialTicks )
@@ -398,6 +320,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{
slot.drawBackground( ox, oy );
}
}
@Override
@@ -464,13 +387,29 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{
if( !itemstack.isEmpty() )
{
Set<IItemHandler> visitedInterfaces = new HashSet<>();
for( final Slot dr : this.drag_click )
{
if( slot.getStack().isEmpty() )
IItemHandler interfaceHandler = ( (SlotDisconnected) slot ).getSlot().getInventory();
if (visitedInterfaces.contains( interfaceHandler )) break;
visitedInterfaces.add( interfaceHandler );
boolean canInsert = true;
for( int s = 0; s < interfaceHandler.getSlots(); s++ )
{
InventoryAction action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
final PacketInventoryAction p = new PacketInventoryAction( action, dr.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance().sendToServer( p );
if( ItemStack.areItemStacksEqual( interfaceHandler.getStackInSlot( s ), itemstack ) )
{
canInsert = false;
break;
}
}
if( canInsert )
{
if( slot.getStack().isEmpty() )
{
InventoryAction action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
final PacketInventoryAction p = new PacketInventoryAction( action, dr.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance().sendToServer( p );
}
}
}
}
@@ -506,56 +445,18 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{
final EntityPlayer player = Minecraft.getMinecraft().player;
if( this.isJeiGhostItem && isDraggingJeiGhostItem)
if( slot instanceof SlotFake )
{
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{
Rectangle area = target.getArea();
final int x = Mouse.getEventX() * this.width / this.mc.displayWidth;
final int y = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1;
if( area.contains( x, y ) )
{
target.accept( bookmarkedIngredient );
break;
}
}
this.isJeiGhostItem = false;
this.isDraggingJeiGhostItem = false;
ItemStack dragItem = ItemStack.EMPTY;
if( runtime.getBookmarkOverlay().getIngredientUnderMouse() != null )
{
bookmarkedJEIghostItem( Mouse.getX(), this.mc.displayHeight - Mouse.getY() );
if( bookmarkedIngredient instanceof ItemStack )
{
dragItem = ( (ItemStack) bookmarkedIngredient );
}
else if( bookmarkedIngredient instanceof FluidStack )
{
dragItem = FluidUtil.getFilledBucket( ( (FluidStack) bookmarkedIngredient ) );
}
mc.player.inventory.setItemStack( dragItem.copy() );
this.isJeiGhostItem = true;
}
else
{
mc.player.inventory.setItemStack( dragItem );
}
}
else if( slot instanceof SlotFake )
{
final InventoryAction action;
action = mouseButton == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
final InventoryAction action = mouseButton == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
if( this.drag_click.size() > 1 )
{
return;
}
PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, 0 );
final PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, 0 );
NetworkHandler.instance().sendToServer( p );
return;
}
@@ -637,12 +538,23 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
case PICKUP: // pickup / set-down.
if( slot.getStack().isEmpty() && !player.inventory.getItemStack().isEmpty() )
{
action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
}
if( !slot.getStack().isEmpty() && player.inventory.getItemStack().getCount() <= 1 )
{
action = InventoryAction.PICKUP_OR_SET_DOWN;
boolean canInsert = true;
IItemHandler interfaceHandler = ( (SlotDisconnected) slot ).getSlot().getInventory();
for( int s = 0; s < interfaceHandler.getSlots(); s++ )
{
if( ItemStack.areItemStacksEqual( interfaceHandler.getStackInSlot( s ), player.inventory.getItemStack() ) )
{
canInsert = false;
break;
}
}
if( canInsert )
{
action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
}
break;
}
if( !slot.getStack().isEmpty() && player.inventory.getItemStack().getCount() <= 1 ) action = InventoryAction.PICKUP_OR_SET_DOWN;
break;
case QUICK_MOVE:
action = ( mouseButton == 1 ) ? InventoryAction.PICKUP_SINGLE : InventoryAction.SHIFT_CLICK;
@@ -675,13 +587,14 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
InventoryAction action = null;
IAEItemStack stack = null;
switch ( clickType )
switch( clickType )
{
case PICKUP: // pickup / set-down.
action = ( mouseButton == 1 ) ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
stack = ( (SlotME) slot ).getAEStack();
if( stack != null && action == InventoryAction.PICKUP_OR_SET_DOWN && stack.getStackSize() == 0 && player.inventory.getItemStack().isEmpty() )
if( stack != null && action == InventoryAction.PICKUP_OR_SET_DOWN && stack.getStackSize() == 0 && player.inventory.getItemStack()
.isEmpty() )
{
action = InventoryAction.AUTO_CRAFT;
}
@@ -748,7 +661,9 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
final List<Slot> slots = this.getInventorySlots();
for( final Slot inventorySlot : slots )
{
if( inventorySlot != null && inventorySlot.canTakeStack( this.mc.player ) && inventorySlot.getHasStack() && inventorySlot.isSameInventory( slot ) && Container.canAddItemToSlot( inventorySlot, this.dbl_whichItem, true ) )
if( inventorySlot != null && inventorySlot.canTakeStack(
this.mc.player ) && inventorySlot.getHasStack() && inventorySlot.isSameInventory( slot ) && Container.canAddItemToSlot(
inventorySlot, this.dbl_whichItem, true ) )
{
this.handleMouseClick( inventorySlot, inventorySlot.slotNumber, 0, ClickType.QUICK_MOVE );
}
@@ -759,11 +674,6 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
this.disableShiftClick = false;
}
if (clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem) {
this.isDraggingJeiGhostItem = true;
return;
}
super.handleMouseClick( slot, slotIdx, mouseButton, clickType );
}
@@ -1191,5 +1101,4 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{
return false;
}
}
@@ -2,23 +2,26 @@ package appeng.client.gui;
import javax.annotation.Nullable;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.implementations.*;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.SlotFake;
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
import appeng.client.gui.implementations.GuiCraftAmount;
import appeng.client.gui.implementations.GuiCraftConfirm;
import appeng.client.gui.implementations.GuiCraftingCPU;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.container.implementations.ContainerCraftAmount;
import mezz.jei.api.gui.IAdvancedGuiHandler;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiScreen;
import org.lwjgl.input.Mouse;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngredientHandler<AEBaseGui>
public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>
{
@Override
public Class<AEBaseGui> getGuiContainerClass()
{
@@ -36,8 +39,8 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
@Override
public Object getIngredientUnderMouse( AEBaseGui guiContainer, int mouseX, int mouseY )
{
List<IAEItemStack> visual;
int guiSlotIdx;
List<IAEItemStack> visual = new ArrayList<>();
int guiSlotIdx = 0;
Object result = null;
if( guiContainer instanceof GuiCraftConfirm )
{
@@ -91,54 +94,4 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
if( guiSloty > ( rows - 1 ) || mouseY < guitop + yo ) return -1;
return ( guiSloty * 3 ) + guiSlotx + ( currentScroll * 3 );
}
@Override
public <I> List<Target<I>> getTargets( AEBaseGui gui, I ingredient, boolean doStart )
{
ArrayList<Target<I>> targets = new ArrayList<>();
if( gui instanceof IJEIGhostIngredients )
{
IJEIGhostIngredients g = (IJEIGhostIngredients) gui;
List<Target<?>> phantomTargets = g.getPhantomTargets( ingredient );
targets.addAll( (List<Target<I>>) (Object) phantomTargets );
}
if( doStart && GuiScreen.isShiftKeyDown() && Mouse.isButtonDown( 0 ) )
{
if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm )
{
IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui );
for( Target<I> target : targets )
{
if( ghostGui.getFakeSlotTargetMap().get( target ) instanceof SlotFake )
{
if( ( (SlotFake) ghostGui.getFakeSlotTargetMap().get( target ) ).getStack().isEmpty() )
{
target.accept( ingredient );
break;
}
}
else if( ghostGui.getFakeSlotTargetMap().get( target ) instanceof GuiFluidSlot )
{
if( ( (GuiFluidSlot) ghostGui.getFakeSlotTargetMap().get( target ) ).getFluidStack() == null )
{
target.accept( ingredient );
break;
}
}
}
}
}
return targets;
}
@Override
public void onComplete(){
}
@Override
public boolean shouldHighlightTargets()
{
return true;
}
}
@@ -50,7 +50,7 @@ public class GuiInterface extends GuiUpgradeable
public GuiInterface( final InventoryPlayer inventoryPlayer, final IInterfaceHost te )
{
super( new ContainerInterface( inventoryPlayer, te ) );
this.ySize = 256;
this.ySize = 211;
}
@Override
@@ -62,7 +62,8 @@ public class GuiInterface extends GuiUpgradeable
this.BlockMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO );
this.buttonList.add( this.BlockMode );
this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal() );
this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal
.getLocal(), GuiText.InterfaceTerminalHint.getLocal() );
this.buttonList.add( this.interfaceMode );
}
@@ -85,20 +86,13 @@ public class GuiInterface extends GuiUpgradeable
this.fontRenderer.drawString( GuiText.StoredItems.getLocal(), 8, 6 + 60 + 7, 4210752 );
this.fontRenderer.drawString( GuiText.Patterns.getLocal(), 8, 6 + 73 + 7, 4210752 );
this.fontRenderer.drawString( GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752 );
}
@Override
protected String getBackground()
{
int upgrades = ( (ContainerInterface) this.cvb ).getPatternUpgrades();
if( upgrades == 0 )
{
return "guis/newinterface.png";
}
else
{
return "guis/newinterface" + upgrades + ".png";
}
return "guis/interface.png";
}
@Override
@@ -123,5 +117,4 @@ public class GuiInterface extends GuiUpgradeable
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.BlockMode.getSetting(), backwards ) );
}
}
}
@@ -24,13 +24,7 @@ import java.util.*;
import appeng.api.config.ActionItems;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.core.worlddata.IWorldPlayerMapping;
import appeng.helpers.DualityInterface;
import appeng.parts.misc.PartInterface;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.misc.TileInterface;
import appeng.util.BlockPosUtils;
import com.google.common.collect.HashMultimap;
@@ -55,8 +49,6 @@ import appeng.util.Platform;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.DimensionManager;
import org.lwjgl.input.Mouse;
import static appeng.client.render.BlockPosHighlighter.hilightBlock;
@@ -74,10 +66,8 @@ public class GuiInterfaceTerminal extends AEBaseGui
private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create();
private final HashMap<ClientDCInternalInv,BlockPos> blockPosHashMap = new HashMap<>();
private final HashMap<GuiButton,ClientDCInternalInv> guiButtonHashMap = new HashMap<>();
private final Map<ClientDCInternalInv,Integer> numUpgradesMap = new HashMap<>();
private final ArrayList<String> names = new ArrayList<>();
private final ArrayList<Object> lines = new ArrayList<>();
private final Set<Object> matchedStacks = new HashSet<>();
private final Map<String, Set<Object>> cachedSearches = new WeakHashMap<>();
@@ -87,7 +77,6 @@ public class GuiInterfaceTerminal extends AEBaseGui
private PartInterfaceTerminal partInterfaceTerminal;
private GuiButton guiButtonHide;
private GuiButton guiButtonNextAssembler;
private HashMap<ClientDCInternalInv,Integer> dimHashMap = new HashMap<>();
public GuiInterfaceTerminal( final InventoryPlayer inventoryPlayer, final PartInterfaceTerminal te )
{
@@ -97,7 +86,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
final GuiScrollbar scrollbar = new GuiScrollbar();
this.setScrollBar( scrollbar );
this.xSize = 208;
this.ySize = 255;
this.ySize = 256;
}
@Override
@@ -134,6 +123,14 @@ public class GuiInterfaceTerminal extends AEBaseGui
super.onGuiClosed();
}
@Override
protected boolean isPointInRegion( int rectX, int rectY, int rectWidth, int rectHeight, int pointX, int pointY )
{
if( searchFieldInputs.isMouseIn( pointX, pointY ) ) drawTooltip( pointX - guiLeft - offsetX, pointY - guiTop , "Inputs OR names" );
else if( searchFieldOutputs.isMouseIn( pointX, pointY ) ) drawTooltip( pointX - guiLeft - offsetX, pointY - guiTop, "Outputs OR names" );
return super.isPointInRegion( rectX, rectY, rectWidth, rectHeight, pointX, pointY );
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
@@ -142,43 +139,34 @@ public class GuiInterfaceTerminal extends AEBaseGui
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.InterfaceTerminal.getLocal() ), 8, 6, 4210752 );
this.fontRenderer.drawString( GuiText.inventory.getLocal(), this.offsetX + 2, this.ySize - 96 + 3, 4210752 );
final int currentScroll = this.getScrollBar().getCurrentScroll();
final int ex = this.getScrollBar().getCurrentScroll();
this.guiButtonNextAssembler = new GuiImgButton( guiLeft + 123, guiTop + 25, Settings.ACTIONS, ActionItems.FREE_MOLECULAR_SLOT_SHORTCUT );
this.guiButtonNextAssembler = new GuiImgButton(guiLeft + 123, guiTop + 25,Settings.ACTIONS, ActionItems.FREE_MOLECULAR_SLOT_SHORTCUT);
this.buttonList.add( guiButtonNextAssembler );
guiButtonHide = new GuiImgButton( guiLeft + 141, guiTop + 25, Settings.ACTIONS, this.partInterfaceTerminal.onlyInterfacesWithFreeSlots ? ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF : ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON );
guiButtonHide = new GuiImgButton( guiLeft + 141, guiTop + 25,Settings.ACTIONS, this.partInterfaceTerminal.onlyInterfacesWithFreeSlots ?
ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF :
ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON);
this.buttonList.add( guiButtonHide );
this.inventorySlots.inventorySlots.removeIf( slot -> slot instanceof SlotDisconnected );
int offset = 52;
int linesDraw = 0;
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && currentScroll + x < this.lines.size(); x++ )
int offset = 51;
for( int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
{
final Object lineObj = this.lines.get( currentScroll + x );
final Object lineObj = this.lines.get( ex + x );
if( lineObj instanceof ClientDCInternalInv )
{
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
GuiButton guiButton = new GuiImgButton( guiLeft + 4, guiTop + offset, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE );
guiButtonHashMap.put( guiButton, inv );
this.buttonList.add( guiButton );
int extraLines = numUpgradesMap.get( inv );
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE ; ++row )
for( int z = 0; z < inv.getInventory().getSlots(); z++ )
{
for( int z = 0; z < 9 ; z++ )
{
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z + ( row * 9 ), ( z * 18 + 22 ), offset ) );
if( this.matchedStacks.contains( inv.getInventory().getStackInSlot( z + ( row * 9 ) ) ) )
{
drawRect( z * 18 + 22, offset, z * 18 + 22 + 16, offset + 16, 0x2A00FF00 );
}
}
linesDraw++;
offset += 18;
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z, z * 18 + 22, 1 + offset ) );
}
GuiButton guiButton = new GuiImgButton(guiLeft + 4, guiTop + offset + 1, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE);
guiButtonHashMap.put( guiButton , inv);
this.buttonList.add( guiButton );
}
else if( lineObj instanceof String )
{
@@ -189,19 +177,15 @@ public class GuiInterfaceTerminal extends AEBaseGui
name = name + " (" + rows + ')';
}
while ( name.length() > 2 && this.fontRenderer.getStringWidth( name ) > 155 )
while( name.length() > 2 && this.fontRenderer.getStringWidth( name ) > 155 )
{
name = name.substring( 0, name.length() - 1 );
}
this.fontRenderer.drawString( name, this.offsetX + 2, 5 + offset, 4210752 );
linesDraw++;
offset += 18;
this.fontRenderer.drawString( name, this.offsetX + 2, 6 + offset, 4210752 );
}
offset += 18;
}
if( searchFieldInputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Inputs OR names" );
else if( searchFieldOutputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Outputs OR names" );
}
@Override
@@ -233,21 +217,8 @@ public class GuiInterfaceTerminal extends AEBaseGui
{
BlockPos blockPos = blockPosHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
BlockPos blockPos2 = mc.player.getPosition();
int playerDim = mc.world.provider.getDimension();
int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
if( playerDim != interfaceDim )
{
try {
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
} catch(Exception e){
mc.player.sendStatusMessage( new TextComponentString( "Interface is located in another dimension and cannot be highlighted" ), false );
}
}
else
{
hilightBlock( blockPos, System.currentTimeMillis() + 500 * BlockPosUtils.getDistance( blockPos, blockPos2 ), playerDim );
mc.player.sendStatusMessage( new TextComponentString( "The interface is now highlighted at " + "X: " + blockPos.getX() + " Y: " + blockPos.getY() + " Z: " + blockPos.getZ() ), false );
}
hilightBlock( blockPos, System.currentTimeMillis() + 500 * BlockPosUtils.getDistance(blockPos, blockPos2) );
mc.player.sendStatusMessage( new TextComponentString( "The interface is now highlighted at " + "X: " + blockPos.getX() + " Y: " + blockPos.getY() + " Z: " + blockPos.getZ() ), false );
mc.player.closeScreen();
}
@@ -281,28 +252,19 @@ public class GuiInterfaceTerminal extends AEBaseGui
int offset = 51;
final int ex = this.getScrollBar().getCurrentScroll();
int linesDraw = 0;
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
for( int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
{
final Object lineObj = this.lines.get( ex + x );
if( lineObj instanceof ClientDCInternalInv )
{
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
GlStateManager.color( 1, 1, 1, 1 );
final int width = 9 * 18;
int extraLines = numUpgradesMap.get( lineObj );
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE; ++row )
{
this.drawTexturedModalRect( offsetX + 20, offsetY + offset , 20, 173, width, 18 );
offset += 18;
linesDraw++;
}
}
else {
offset += 18;
linesDraw++;
final int width = inv.getInventory().getSlots() * 18;
this.drawTexturedModalRect( offsetX + 20, offsetY + offset, 20, 173, width, 18 );
}
offset += 18;
}
if( this.searchFieldInputs != null )
@@ -362,8 +324,6 @@ public class GuiInterfaceTerminal extends AEBaseGui
final NBTTagCompound invData = in.getCompoundTag( key );
final ClientDCInternalInv current = this.getById( id, invData.getLong( "sortBy" ), invData.getString( "un" ) );
blockPosHashMap.put( current, NBTUtil.getPosFromTag( invData.getCompoundTag( "pos" )) );
dimHashMap.put( current, invData.getInteger( "dim" ));
numUpgradesMap.put( current, invData.getInteger("numUpgrades"));
for( int x = 0; x < current.getInventory().getSlots(); x++ )
{
@@ -398,7 +358,6 @@ public class GuiInterfaceTerminal extends AEBaseGui
{
this.byName.clear();
this.buttonList.clear();
this.matchedStacks.clear();
final String searchFieldInputs = this.searchFieldInputs.getText().toLowerCase();
final String searchFieldOutputs = this.searchFieldOutputs.getText().toLowerCase();
@@ -417,41 +376,37 @@ public class GuiInterfaceTerminal extends AEBaseGui
// Shortcut to skip any filter if search term is ""/empty
boolean found = (searchFieldInputs.isEmpty() && searchFieldOutputs.isEmpty() && !partInterfaceTerminal.onlyInterfacesWithFreeSlots);
boolean interfaceHasFreeSlots = false;
// Search if the current inventory holds a pattern containing the search term.
if( !found )
{
int slot = 0;
for( final ItemStack itemStack : entry.getInventory() )
{
if (slot > 8 + numUpgradesMap.get(entry) * 9) {
if( !searchFieldInputs.isEmpty() && !searchFieldOutputs.isEmpty() )
found = ( this.itemStackMatchesSearchTerm( itemStack, searchFieldInputs, 0 ) || this.itemStackMatchesSearchTerm( itemStack, searchFieldOutputs, 1 ) );
else if( !searchFieldInputs.isEmpty() )
found = ( this.itemStackMatchesSearchTerm( itemStack, searchFieldInputs, 0 ) );
else if( !searchFieldOutputs.isEmpty() )
found = ( this.itemStackMatchesSearchTerm( itemStack, searchFieldOutputs, 1 ) );
if( found )
{
break;
}
if( !searchFieldInputs.isEmpty() && !searchFieldOutputs.isEmpty() ) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0) || this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
found = true;
matchedStacks.add(itemStack);
}
}
else if( !searchFieldInputs.isEmpty() ) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0)) {
found = true;
matchedStacks.add(itemStack);
}
}
else if( !searchFieldOutputs.isEmpty() ) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
found = true;
matchedStacks.add(itemStack);
}
}
// If only Interfaces with empty slots should be shown, check that here
if(itemStack.isEmpty())
}
}
// If only Interfaces with empty slots should be shown, check that here
boolean interfaceHasFreeSlots = false;
if (partInterfaceTerminal.onlyInterfacesWithFreeSlots) {
for( final ItemStack itemStack : entry.getInventory() )
{
if(itemStack.isEmpty()){
interfaceHasFreeSlots = true;
slot++;
break;
}
}
}
// if found, filter skipped or machine name matching the search term, add it
if( found || (entry.getName().toLowerCase().contains( searchFieldInputs ) && entry.getName().toLowerCase().contains( searchFieldOutputs )))
{
@@ -490,7 +445,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
this.lines.addAll( clientInventories );
}
this.getScrollBar().setRange( 0, this.lines.size() - 1, 1 );
this.getScrollBar().setRange( 0, this.lines.size() - LINES_ON_PAGE, 2 );
}
private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm,int pass )
@@ -580,7 +535,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
if( o == null )
{
this.byId.put( id, o = new ClientDCInternalInv( DualityInterface.NUMBER_OF_PATTERN_SLOTS, id, sortBy, string ) );
this.byId.put( id, o = new ClientDCInternalInv( 9, id, sortBy, string ) );
this.refreshList = true;
}
@@ -19,21 +19,11 @@
package appeng.client.gui.implementations;
import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.List;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.SlotFake;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import mezz.jei.api.gui.IGhostIngredientHandler.Target;
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 appeng.api.config.ActionItems;
@@ -50,7 +40,7 @@ import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketValueConfig;
public class GuiPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
public class GuiPatternTerm extends GuiMEMonitorable
{
private static final String BACKGROUND_CRAFTING_MODE = "guis/pattern.png";
@@ -77,7 +67,6 @@ public class GuiPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredi
private GuiImgButton divThreeBtn;
private GuiImgButton minusOneBtn;
private GuiImgButton maxCountBtn;
public Map<Target<?>,Object> mapTargetSlot = new HashMap<>();
public GuiPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
@@ -285,52 +274,4 @@ public class GuiPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredi
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
}
@Override
public List<Target<?>> getPhantomTargets(Object ingredient) {
if (!(ingredient instanceof ItemStack )) {
return Collections.emptyList();
}
List<Target<?>> targets = new ArrayList<>();
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotFake )
{
ItemStack itemStack = (ItemStack) ingredient;
Target<Object> target = new 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<Target<?>, Object> getFakeSlotTargetMap()
{
return mapTargetSlot;
}
}
@@ -19,24 +19,8 @@
package appeng.client.gui.implementations;
import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.List;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.IJEITargetSlot;
import appeng.container.slot.SlotFake;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
import appeng.fluids.util.AEFluidStack;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import mezz.jei.api.gui.IGhostIngredientHandler.Target;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.*;
import org.lwjgl.input.Mouse;
import net.minecraft.client.gui.GuiButton;
@@ -59,9 +43,9 @@ import appeng.parts.automation.PartExportBus;
import appeng.parts.automation.PartImportBus;
public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
public class GuiUpgradeable extends AEBaseGui
{
private final Map<Target<?>,Object> mapTargetSlot = new HashMap<>();
protected final ContainerUpgradeable cvb;
protected final IUpgradeableHost bc;
@@ -216,111 +200,4 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.schedulingMode.getSetting(), backwards ) );
}
}
@Override
public List<Target<?>> getPhantomTargets(Object ingredient)
{
mapTargetSlot.clear();
FluidStack fluidStack = null;
ItemStack itemStack = ItemStack.EMPTY;
if( ingredient instanceof ItemStack )
{
itemStack = (ItemStack) ingredient;
fluidStack = FluidUtil.getFluidContained( itemStack );
}
else if( ingredient instanceof FluidStack )
{
fluidStack = (FluidStack) ingredient;
}
if( !( ingredient instanceof ItemStack ) && !( ingredient instanceof FluidStack ) )
return Collections.emptyList();
List<Target<?>> targets = new ArrayList<>();
List<IJEITargetSlot> slots = new ArrayList<>();
if( this.inventorySlots.inventorySlots.size() > 0 )
{
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotFake && ( !itemStack.isEmpty() || this instanceof GuiCellWorkbench && fluidStack != null ) )
{
slots.add( (IJEITargetSlot) slot );
}
}
}
if( this.getGuiSlots().size() > 0 )
{
for( GuiCustomSlot slot : this.getGuiSlots() )
{
if( slot instanceof GuiFluidSlot && fluidStack != null )
{
slots.add( (IJEITargetSlot) slot );
}
}
}
for( Object slot : slots )
{
ItemStack finalItemStack = itemStack;
FluidStack finalFluidStack = fluidStack;
Target<Object> targetItem = new Target<Object>()
{
@Override
public Rectangle getArea()
{
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
{
return new Rectangle( getGuiLeft() + ( (SlotFake) slot ).xPos, getGuiTop() + ( (SlotFake) slot ).yPos, 16, 16 );
}
else if( slot instanceof GuiFluidSlot && ( (GuiFluidSlot) slot ).isSlotEnabled() )
{
return new Rectangle( getGuiLeft() + ( (GuiFluidSlot) slot ).xPos(), getGuiTop() + ( (GuiFluidSlot) slot ).yPos(), 16, 16 );
}
return new Rectangle();
}
@Override
public void accept( Object ingredient )
{
PacketInventoryAction p = null;
try
{
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
{
if( finalItemStack.isEmpty() && finalFluidStack != null )
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( FluidUtil.getFilledBucket( finalFluidStack ) ) );
}
else if( !finalItemStack.isEmpty() )
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( finalItemStack ) );
}
}
else
{
if( finalFluidStack == null ) return;
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( AEFluidStack.fromFluidStack( finalFluidStack ).asItemStackRepresentation() ) );
}
NetworkHandler.instance().sendToServer( p );
}
catch( IOException e )
{
e.printStackTrace();
}
}
};
targets.add( targetItem );
mapTargetSlot.putIfAbsent( targetItem, slot );
}
return targets;
}
@Override
public Map<Target<?>, Object> getFakeSlotTargetMap()
{
return mapTargetSlot;
}
}
@@ -10,9 +10,9 @@ import net.minecraft.item.ItemStack;
public abstract class GuiCustomSlot extends Gui implements ITooltip
{
protected final int x;
protected final int y;
protected final int id;
private final int x;
private final int y;
private final int id;
public GuiCustomSlot( final int id, final int x, final int y )
{
@@ -8,14 +8,9 @@ public class BlockPosHighlighter
private static BlockPos hilightedBlock;
private static long expireHilight;
private static int dimension;
public static void hilightBlock( BlockPos c, long expireHilight, int dimension ) {
public static void hilightBlock( BlockPos c, long expireHilight ) {
hilightedBlock = c;
BlockPosHighlighter.expireHilight = expireHilight;
BlockPosHighlighter.dimension = dimension;
}
public static BlockPos getHilightedBlock() {
@@ -26,9 +21,5 @@ public class BlockPosHighlighter
return expireHilight;
}
public static int getDimension()
{
return dimension;
}
}
@@ -19,21 +19,17 @@
package appeng.client.render;
import appeng.api.storage.data.IAEFluidStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.IWideReadableNumberConverter;
import appeng.util.ReadableNumberConverter;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
/**
@@ -123,49 +119,6 @@ public class TesrRenderHelper
}
}
public static void renderFluid2d( FluidStack fluidStack, float scale )
{
if( fluidStack != null )
{
GlStateManager.pushMatrix();
int color = fluidStack.getFluid().getColor( fluidStack );
float r = ( color >> 16 & 255 ) / 255.0f;
float g = ( color >> 8 & 255 ) / 255.0f;
float b = ( color & 255 ) / 255.0f;
TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( fluidStack.getFluid().getStill( fluidStack ).toString() );
GlStateManager.enableBlend();
GlStateManager.blendFunc( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA );
GlStateManager.disableAlpha();
GlStateManager.disableLighting();
Minecraft.getMinecraft().getTextureManager().bindTexture( TextureMap.LOCATION_BLOCKS_TEXTURE );
Tessellator tess = Tessellator.getInstance();
BufferBuilder buf = tess.getBuffer();
float width = 0.4f;
float height = 0.4f;
float alpha = 1.0f;
float z = 0.0001f;
float x = -0.20f;
float y = -0.25f;
buf.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
double uMin = sprite.getInterpolatedU( 16D - width * 16D ), uMax = sprite.getInterpolatedU( width * 16D );
double vMin = sprite.getMinV(), vMax = sprite.getInterpolatedV( height * 16D );
buf.pos( x, y, z ).tex( uMin, vMin ).color( r, g, b, alpha ).endVertex();
buf.pos( x, y + height, z ).tex( uMin, vMax ).color( r, g, b, alpha ).endVertex();
buf.pos( x + width, y + height, z ).tex( uMax, vMax ).color( r, g, b, alpha ).endVertex();
buf.pos( x + width, y, z ).tex( uMax, vMin ).color( r, g, b, alpha ).endVertex();
tess.draw();
GlStateManager.enableLighting();
GlStateManager.enableAlpha();
GlStateManager.disableBlend();
GlStateManager.color( 1F, 1F, 1F, 1F );
GlStateManager.popMatrix();
}
}
/**
* Render an item in 2D and the given text below it.
*
@@ -190,23 +143,4 @@ public class TesrRenderHelper
}
public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing )
{
final FluidStack renderStack = fluidStack.getFluidStack();
TesrRenderHelper.renderFluid2d( renderStack, scale );
final long stackSize = fluidStack.getStackSize() / 1000;
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
// Render the item count
final FontRenderer fr = Minecraft.getMinecraft().fontRenderer;
final int width = fr.getStringWidth( renderedStackSize );
GlStateManager.translate( 0.0f, spacing, 0 );
GlStateManager.scale( 1.0f / 62.0f, 1.0f / 62.0f, 1.0f / 62.0f );
GlStateManager.translate( -0.5f * width, 0.0f, 0.5f );
fr.drawString( renderedStackSize, 0, 0, 0 );
}
}
@@ -159,58 +159,56 @@ public class ContainerCraftingCPU extends AEBaseContainer implements IMEMonitorH
@Override
public void detectAndSendChanges()
{
if( Platform.isServer() && this.getMonitor() != null )
if( Platform.isServer() && this.getMonitor() != null && !this.list.isEmpty() )
{
if( this.getEstimatedTime() >= 0 )
try
{
final long elapsedTime = this.getMonitor().getElapsedTime();
final double remainingItems = this.getMonitor().getRemainingItemCount();
final double startItems = this.getMonitor().getStartItemCount();
final long eta = (long) ( elapsedTime / Math.max( 1d, ( startItems - remainingItems ) ) * remainingItems );
this.setEstimatedTime( eta );
}
if( !this.list.isEmpty() )
{
try
if( this.getEstimatedTime() >= 0 )
{
final PacketMEInventoryUpdate a = new PacketMEInventoryUpdate( (byte) 0 );
final PacketMEInventoryUpdate b = new PacketMEInventoryUpdate( (byte) 1 );
final PacketMEInventoryUpdate c = new PacketMEInventoryUpdate( (byte) 2 );
final long elapsedTime = this.getMonitor().getElapsedTime();
final double remainingItems = this.getMonitor().getRemainingItemCount();
final double startItems = this.getMonitor().getStartItemCount();
final long eta = (long) ( elapsedTime / Math.max( 1d, ( startItems - remainingItems ) ) * remainingItems );
this.setEstimatedTime( eta );
}
for( final IAEItemStack out : this.list )
final PacketMEInventoryUpdate a = new PacketMEInventoryUpdate( (byte) 0 );
final PacketMEInventoryUpdate b = new PacketMEInventoryUpdate( (byte) 1 );
final PacketMEInventoryUpdate c = new PacketMEInventoryUpdate( (byte) 2 );
for( final IAEItemStack out : this.list )
{
a.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.STORAGE ) );
b.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.ACTIVE ) );
c.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.PENDING ) );
}
this.list.resetStatus();
for( final Object g : this.listeners )
{
if( g instanceof EntityPlayer )
{
a.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.STORAGE ) );
b.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.ACTIVE ) );
c.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.PENDING ) );
}
this.list.resetStatus();
for( final Object g : this.listeners )
{
if( g instanceof EntityPlayer )
if( !a.isEmpty() )
{
if( !a.isEmpty() )
{
NetworkHandler.instance().sendTo( a, (EntityPlayerMP) g );
}
NetworkHandler.instance().sendTo( a, (EntityPlayerMP) g );
}
if( !b.isEmpty() )
{
NetworkHandler.instance().sendTo( b, (EntityPlayerMP) g );
}
if( !b.isEmpty() )
{
NetworkHandler.instance().sendTo( b, (EntityPlayerMP) g );
}
if( !c.isEmpty() )
{
NetworkHandler.instance().sendTo( c, (EntityPlayerMP) g );
}
if( !c.isEmpty() )
{
NetworkHandler.instance().sendTo( c, (EntityPlayerMP) g );
}
}
}
catch( final IOException e )
{
// :P
}
}
catch( final IOException e )
{
// :P
}
}
super.detectAndSendChanges();
@@ -19,9 +19,6 @@
package appeng.container.implementations;
import appeng.api.config.Upgrades;
import appeng.container.slot.*;
import appeng.util.Platform;
import net.minecraft.entity.player.InventoryPlayer;
import appeng.api.config.SecurityPermissions;
@@ -29,11 +26,14 @@ import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.api.util.IConfigManager;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotNormal;
import appeng.container.slot.SlotRestrictedInput;
import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost;
public class ContainerInterface extends ContainerUpgradeable implements IOptionalSlotHost
public class ContainerInterface extends ContainerUpgradeable
{
private final DualityInterface myDuality;
@@ -44,22 +44,16 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
@GuiSync( 4 )
public YesNo iTermMode = YesNo.YES;
@GuiSync( 7 )
public int patternExpansions = 0;
public ContainerInterface( final InventoryPlayer ip, final IInterfaceHost te )
{
super( ip, te.getInterfaceDuality().getHost() );
this.myDuality = te.getInterfaceDuality();
for (int row = 0 ; row < 4 ; ++row)
for( int x = 0; x < DualityInterface.NUMBER_OF_PATTERN_SLOTS; x++ )
{
for( int x = 0; x < 9; x++ )
{
this.addSlotToContainer( new OptionalSlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, this.myDuality
.getPatterns(), this, x + row * 9, 8 + 18 * x, 97 + ( 18 * row ), row, this.getInventoryPlayer() ).setStackLimit( 1 ) );
}
this.addSlotToContainer( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, this.myDuality
.getPatterns(), x, 8 + 18 * x, 90 + 7, this.getInventoryPlayer() ).setStackLimit( 1 ) );
}
for( int x = 0; x < DualityInterface.NUMBER_OF_CONFIG_SLOTS; x++ )
@@ -76,7 +70,7 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
@Override
protected int getHeight()
{
return 256;
return 211;
}
@Override
@@ -88,35 +82,16 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
@Override
public int availableUpgrades()
{
return 4;
}
@Override
public boolean isSlotEnabled( final int idx )
{
return myDuality.getInstalledUpgrades(Upgrades.PATTERN_EXPANSION) >= idx;
return 1;
}
@Override
public void detectAndSendChanges()
{
this.verifyPermissions( SecurityPermissions.BUILD, false );
if (patternExpansions != getPatternUpgrades())
{
patternExpansions = getPatternUpgrades();
this.myDuality.dropExcessPatterns();
}
super.detectAndSendChanges();
}
@Override
public void onUpdate( final String field, final Object oldValue, final Object newValue ) {
super.onUpdate(field, oldValue, newValue);
if ( Platform.isClient() && field.equals("patternExpansions"))
this.myDuality.dropExcessPatterns();
}
@Override
protected void loadSettingsFromHost( final IConfigManager cm )
{
@@ -143,9 +118,4 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
{
this.iTermMode = iTermMode;
}
public int getPatternUpgrades()
{
return this.myDuality.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION );
}
}
@@ -24,7 +24,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import appeng.api.config.Upgrades;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
@@ -216,48 +215,35 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
final IItemHandler theSlot = new WrapperFilteredItemHandler( new WrapperRangeItemHandler( inv.server, slot, slot + 1 ), new PatternSlotFilter() );
final InventoryAdaptor interfaceSlot = new AdaptorItemHandler( theSlot );
IItemHandler interfaceHandler = inv.server;
boolean canInsert = true;
switch ( action )
switch( action )
{
case PICKUP_OR_SET_DOWN:
if( hasItemInHand )
{
for( int s = 0; s < interfaceHandler.getSlots(); s++ )
ItemStack inSlot = theSlot.getStackInSlot( 0 );
if( inSlot.isEmpty() )
{
if( Platform.itemComparisons().isSameItem( interfaceHandler.getStackInSlot( s ), player.inventory.getItemStack() ) )
{
canInsert = false;
break;
}
player.inventory.setItemStack( interfaceSlot.addItems( player.inventory.getItemStack() ) );
}
if( canInsert )
else
{
ItemStack inSlot = theSlot.getStackInSlot( 0 );
if( inSlot.isEmpty() )
inSlot = inSlot.copy();
final ItemStack inHand = player.inventory.getItemStack().copy();
ItemHandlerUtil.setStackInSlot( theSlot, 0, ItemStack.EMPTY );
player.inventory.setItemStack( ItemStack.EMPTY );
player.inventory.setItemStack( interfaceSlot.addItems( inHand.copy() ) );
if( player.inventory.getItemStack().isEmpty() )
{
player.inventory.setItemStack( interfaceSlot.addItems( player.inventory.getItemStack() ) );
player.inventory.setItemStack( inSlot );
}
else
{
inSlot = inSlot.copy();
final ItemStack inHand = player.inventory.getItemStack().copy();
ItemHandlerUtil.setStackInSlot( theSlot, 0, ItemStack.EMPTY );
player.inventory.setItemStack( ItemStack.EMPTY );
player.inventory.setItemStack( interfaceSlot.addItems( inHand.copy() ) );
if( player.inventory.getItemStack().isEmpty() )
{
player.inventory.setItemStack( inSlot );
}
else
{
player.inventory.setItemStack( inHand );
ItemHandlerUtil.setStackInSlot( theSlot, 0, inSlot );
}
player.inventory.setItemStack( inHand );
ItemHandlerUtil.setStackInSlot( theSlot, 0, inSlot );
}
}
}
@@ -268,27 +254,17 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
break;
case SPLIT_OR_PLACE_SINGLE:
if( hasItemInHand )
{
for( int s = 0; s < interfaceHandler.getSlots(); s++ )
ItemStack extra = playerHand.removeItems( 1, ItemStack.EMPTY, null );
if( !extra.isEmpty() && !interfaceSlot.containsItems())
{
if( Platform.itemComparisons().isSameItem( interfaceHandler.getStackInSlot( s ), player.inventory.getItemStack() ) )
{
canInsert = false;
break;
}
extra = interfaceSlot.addItems( extra );
}
if( canInsert )
if( !extra.isEmpty() )
{
ItemStack extra = playerHand.removeItems( 1, ItemStack.EMPTY, null );
if( !extra.isEmpty() && !interfaceSlot.containsItems() )
{
extra = interfaceSlot.addItems( extra );
}
if( !extra.isEmpty() )
{
playerHand.addItems( extra );
}
playerHand.addItems( extra );
}
}
else if( !is.isEmpty() )
@@ -404,9 +380,7 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
{
tag.setLong( "sortBy", inv.sortBy );
tag.setString( "un", inv.unlocalizedName );
tag.setTag( "pos", NBTUtil.createPosTag( inv.pos ) );
tag.setInteger( "dim", inv.dim );
tag.setInteger( "numUpgrades", inv.numUpgrades );
tag.setTag("pos", NBTUtil.createPosTag( inv.pos ) );
}
for( int x = 0; x < length; x++ )
@@ -438,8 +412,6 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
private final IItemHandler client;
private final IItemHandler server;
private final BlockPos pos;
private final int dim;
private final int numUpgrades;
public InvTracker( final DualityInterface dual, final IItemHandler patterns, final String unlocalizedName )
{
@@ -448,8 +420,6 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
this.unlocalizedName = unlocalizedName;
this.sortBy = dual.getSortValue();
this.pos = dual.getLocation().getPos();
this.dim = dual.getLocation().getWorld().provider.getDimension();
this.numUpgrades = dual.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION);
}
}
@@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import appeng.container.slot.*;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
@@ -52,6 +51,12 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.container.ContainerNull;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.IOptionalSlotHost;
import appeng.container.slot.OptionalSlotFake;
import appeng.container.slot.SlotFakeCraftingMatrix;
import appeng.container.slot.SlotPatternOutputs;
import appeng.container.slot.SlotPatternTerm;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.sync.packets.PacketPatternSlot;
import appeng.helpers.IContainerCraftingPacket;
import appeng.items.storage.ItemViewCell;
@@ -127,28 +132,6 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
this.updateOrderOfOutputSlots();
}
@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.getPatternTerminal().getInventoryByName( "pattern" );
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
clickSlot.putStack( remainder );
}
}
return super.transferStackInSlot( p, idx );
}
private void updateOrderOfOutputSlots()
{
if( !this.isCraftingMode() )
@@ -1,18 +0,0 @@
package appeng.container.interfaces;
import mezz.jei.api.gui.IGhostIngredientHandler.Target;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public interface IJEIGhostIngredients
{
List<Target<?>> getPhantomTargets( Object ingredient );
default Map<Target<?>, Object> getFakeSlotTargetMap(){
return new HashMap<>();
}
}
@@ -157,7 +157,7 @@ public class AppEngSlot extends Slot
{
if( this.isSlotEnabled() )
{
return !this.itemHandler.extractItem( this.index, Integer.MAX_VALUE, true ).isEmpty();
return !this.itemHandler.extractItem( this.index, 1, true ).isEmpty();
}
return false;
}
@@ -1,4 +0,0 @@
package appeng.container.slot;
public interface IJEITargetSlot {
}
@@ -24,7 +24,7 @@ import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
public class SlotFake extends AppEngSlot implements IJEITargetSlot
public class SlotFake extends AppEngSlot
{
public SlotFake( final IItemHandler inv, final int idx, final int x, final int y )
@@ -363,8 +363,6 @@ final class Registration
// Interface
Upgrades.CRAFTING.registerItem( parts.iface(), 1 );
Upgrades.CRAFTING.registerItem( blocks.iface(), 1 );
Upgrades.PATTERN_EXPANSION.registerItem( parts.iface(), 3 );
Upgrades.PATTERN_EXPANSION.registerItem( blocks.iface(), 3 );
// IO Port!
Upgrades.SPEED.registerItem( blocks.iOPort(), 3 );
@@ -175,7 +175,7 @@ public class ApiStorage implements IStorageHelper
@Override
public int transferFactor()
{
return 1000;
return 125;
}
@Override
@@ -86,7 +86,6 @@ public final class ApiMaterials implements IMaterials
private final IItemDefinition cardRedstone;
private final IItemDefinition cardSpeed;
private final IItemDefinition cardCapacity;
private final IItemDefinition cardPatternExpansion;
private final IItemDefinition cardFuzzy;
private final IItemDefinition cardInverter;
private final IItemDefinition cardCrafting;
@@ -205,7 +204,6 @@ public final class ApiMaterials implements IMaterials
this.cardRedstone = new DamagedItemDefinition( "material.card.redstone", materials.createMaterial( MaterialType.CARD_REDSTONE ) );
this.cardSpeed = new DamagedItemDefinition( "material.card.acceleration", materials.createMaterial( MaterialType.CARD_SPEED ) );
this.cardCapacity = new DamagedItemDefinition( "material.card.capacity", materials.createMaterial( MaterialType.CARD_CAPACITY ) );
this.cardPatternExpansion = new DamagedItemDefinition( "material.card.pattern.expansion", materials.createMaterial(MaterialType.CARD_PATTERN_EXPANSION) );
this.cardFuzzy = new DamagedItemDefinition( "material.card.fuzzy", materials.createMaterial( MaterialType.CARD_FUZZY ) );
this.cardInverter = new DamagedItemDefinition( "material.card.inverter", materials.createMaterial( MaterialType.CARD_INVERTER ) );
this.cardCrafting = new DamagedItemDefinition( "material.card.crafting", materials.createMaterial( MaterialType.CARD_CRAFTING ) );
@@ -426,9 +424,6 @@ public final class ApiMaterials implements IMaterials
return this.cardCapacity;
}
@Override
public IItemDefinition cardPatternExpansion(){ return this.cardPatternExpansion;}
@Override
public IItemDefinition cardFuzzy()
{
@@ -164,6 +164,7 @@ public enum AEFeature
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." ),
INSANE_BLOCKING_MODE( "InsaneBlockingMode", Constants.CATEGORY_CRAFTING_FEATURES, "Use the default AE2 blocking mode that doesn't work on any machines" ),
BASIC_CARDS( "BasicCards", Constants.CATEGORY_UPGRADES ),
ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ),
@@ -20,16 +20,7 @@ package appeng.core.sync.packets;
import java.io.IOException;
import java.util.Collections;
import appeng.api.storage.data.IAEFluidStack;
import appeng.container.slot.IJEITargetSlot;
import appeng.container.slot.SlotFake;
import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler;
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
import appeng.fluids.container.ContainerFluidConfigurable;
import appeng.fluids.util.AEFluidStack;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -49,7 +40,6 @@ import appeng.core.sync.network.INetworkInfo;
import appeng.helpers.InventoryAction;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import net.minecraftforge.fluids.FluidStack;
public class PacketInventoryAction extends AppEngPacket
@@ -67,7 +57,6 @@ public class PacketInventoryAction extends AppEngPacket
this.slot = stream.readInt();
this.id = stream.readLong();
final boolean hasItem = stream.readBoolean();
if( hasItem )
{
this.slotItem = AEItemStack.fromPacket( stream );
@@ -81,6 +70,7 @@ public class PacketInventoryAction extends AppEngPacket
// api
public PacketInventoryAction( final InventoryAction action, final int slot, final IAEItemStack slotItem ) throws IOException
{
if( Platform.isClient() )
{
throw new IllegalStateException( "invalid packet, client cannot post inv actions with stacks." );
@@ -111,36 +101,6 @@ public class PacketInventoryAction extends AppEngPacket
this.configureWrite( data );
}
public PacketInventoryAction(final InventoryAction action, final IJEITargetSlot slot, final IAEItemStack slotItem ) throws IOException
{
this.action = action;
if (slot instanceof SlotFake)
this.slot = ((SlotFake) slot).slotNumber;
else this.slot = ((GuiFluidSlot) slot).getId();
this.id = 0;
this.slotItem = slotItem;
final ByteBuf data = Unpooled.buffer();
data.writeInt( this.getPacketID() );
data.writeInt( action.ordinal() );
data.writeInt( this.slot );
data.writeLong( this.id );
if( slotItem == null )
{
data.writeBoolean( false );
}
else
{
data.writeBoolean( true );
slotItem.writeToPacket( data );
}
this.configureWrite( data );
}
// api
public PacketInventoryAction( final InventoryAction action, final int slot, final long id )
{
@@ -190,48 +150,6 @@ public class PacketInventoryAction extends AppEngPacket
}
}
}
else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM )
{
if( sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake )
{
if( this.slotItem != null )
{
sender.openContainer.inventorySlots.get( this.slot ).putStack( this.slotItem.createItemStack() );
if( sender.openContainer.inventorySlots.get( this.slot ).getStack().isEmpty() )
{
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
if( aefs != null )
{
FluidStack fluid = aefs.getFluidStack();
sender.openContainer.inventorySlots.get( this.slot ).putStack( AEFluidStack.fromFluidStack( fluid ).asItemStackRepresentation() );
}
}
}
else sender.openContainer.inventorySlots.get( this.slot ).putStack( ItemStack.EMPTY );
try
{
NetworkHandler.instance().sendTo( new PacketInventoryAction( InventoryAction.UPDATE_HAND, 0, AEItemStack.fromItemStack( ItemStack.EMPTY ) ), sender );
}
catch( final IOException e )
{
AELog.debug( e );
}
}
if( sender.openContainer instanceof ContainerFluidConfigurable )
{
if( 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
{
baseContainer.doAction( sender, this.action, this.slot, this.id );
@@ -29,7 +29,6 @@ import java.util.Iterator;
import appeng.api.config.FuzzyMode;
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;
@@ -212,21 +211,23 @@ public class PacketJEIRecipe extends AppEngPacket
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
if( out == null )
{
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 );
IAEItemStack mostDamaged = null;
for( IAEItemStack is : outList )
{
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
for( IAEItemStack is : outList )
if( !is.isCraftable() && is.getItem().isDamageable() )
{
if( is.getDefinition().getMetadata() == request.getDefinition().getMetadata() )
if( mostDamaged == null || mostDamaged.getItemDamage() < is.getItemDamage() )
{
out = Platform.poweredExtraction( energy, storage, is.copy().setStackSize( 1 ), cct.getActionSource() );
}
if( out != null )
{
break;
mostDamaged = is;
}
}
}
if( mostDamaged != null )
{
mostDamaged.setStackSize( 1 );
out = Platform.poweredExtraction( energy, storage, mostDamaged, cct.getActionSource() );
}
}
}
else
@@ -245,10 +246,7 @@ public class PacketJEIRecipe extends AppEngPacket
if( out != null )
{
if (!cct.useRealItems())
{
out.setStackSize( recipe[x][y].getCount() );
}
out.setStackSize( recipe[x][y].getCount() );
currentItem = out.createItemStack();
}
}
@@ -287,7 +285,6 @@ public class PacketJEIRecipe extends AppEngPacket
IItemHandler outputSlots = cct.getInventoryByName( "output" );
for( int i = 0; i < this.output.length; ++i )
{
if( this.output[i] == null ) continue;
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output[i] );
}
}
@@ -306,7 +303,7 @@ public class PacketJEIRecipe extends AppEngPacket
{
for( ItemStack option : this.recipe[slot] )
{
if( ItemStack.areItemStacksEqual( is, option ) )
if( is.isItemEqual( option ) )
{
return is;
}
@@ -19,7 +19,6 @@
package appeng.core.sync.packets;
import appeng.fluids.container.ContainerFluidInterface;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -91,9 +90,5 @@ public class PacketTargetFluidStack extends AppEngPacket
{
( (ContainerFluidTerminal) player.openContainer ).setTargetStack( this.stack );
}
else if( player.openContainer instanceof ContainerFluidInterface )
{
( (ContainerFluidInterface) player.openContainer ).setTargetStack( this.stack );
}
}
}
+3 -56
View File
@@ -59,7 +59,6 @@ public class CraftingJob implements Runnable, ICraftingJob
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
private final Object monitor = new Object();
private final Stopwatch watch = Stopwatch.createUnstarted();
private CraftingTreeNode tree;
private final IAEItemStack output;
private boolean simulate = false;
@@ -67,10 +66,7 @@ public class CraftingJob implements Runnable, ICraftingJob
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 )
{
@@ -137,7 +133,6 @@ public class CraftingJob implements Runnable, ICraftingJob
try
{
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
this.handlePausing();
final Stopwatch timer = Stopwatch.createStarted();
@@ -219,41 +214,6 @@ public class CraftingJob implements Runnable, ICraftingJob
this.finish();
}
void handlePausing() throws InterruptedException
{
if( !this.actionSrc.player().isPresent() && this.incTime > 100 )
{
this.incTime = 0;
synchronized ( this.monitor )
{
if( this.watch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
{
this.running = false;
this.watch.stop();
this.monitor.notify();
}
if( !this.running )
{
AELog.craftingDebug( "crafting job will now sleep" );
while ( !this.running )
{
this.monitor.wait();
}
AELog.craftingDebug( "crafting job now active" );
}
}
if( Thread.interrupted() )
{
throw new InterruptedException();
}
}
this.incTime++;
}
private void finish()
{
if( this.callback != null )
@@ -265,7 +225,6 @@ public class CraftingJob implements Runnable, ICraftingJob
synchronized( this.monitor )
{
this.running = false;
this.done = true;
this.monitor.notify();
}
@@ -311,25 +270,13 @@ public class CraftingJob implements Runnable, ICraftingJob
/**
* @return true if this needs more simulation
*/
public boolean simulateFor(final int milli)
public boolean simulateFor()
{
this.time = milli;
synchronized ( this.monitor )
{
if( this.done )
{
synchronized( this.monitor ) {
if ( this.done ) {
return false;
}
if( !this.actionSrc.player().isPresent() )
{
this.watch.reset();
this.watch.start();
this.monitor.notify();
}
this.running = true;
}
return true;
}
@@ -119,7 +119,7 @@ public class CraftingTreeNode
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{
this.job.handlePausing();
final List<IAEItemStack> thingsUsed = new ArrayList<>();
this.what.setStackSize( l );
@@ -130,12 +130,7 @@ public class CraftingTreeNode
if( this.parent.details.canSubstitute() )
{
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs(this.slot);
itemList = new ArrayList<>(substitutes.size());
for (IAEItemStack stack : substitutes) {
itemList.addAll(inventoryList.findFuzzy(stack, FuzzyMode.IGNORE_ALL));
}
itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL );
}
else
{
@@ -185,7 +185,7 @@ public class CraftingTreeProcess
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{
this.job.handlePausing();
if( this.fullSimulation )
{
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
@@ -28,9 +28,7 @@ import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.me.helpers.PlayerSource;
import appeng.util.inv.ItemListIgnoreCrafting;
import net.minecraft.util.text.TextComponentString;
public class MECraftingInventory implements IMEInventory<IAEItemStack>
@@ -309,15 +307,8 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
if( result == null || result.getStackSize() != extra.getStackSize() )
{
if( src.player().isPresent() )
{
if( result == null )
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could not extract anything" ), false );
else
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could only extract " + result.getStackSize() ), false );
}
failed = true;
if( !src.player().isPresent() ) break;
break;
}
}
}
@@ -21,9 +21,6 @@ package appeng.fluids.client.gui;
import java.io.IOException;
import appeng.api.util.IConfigManager;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.util.IConfigManagerHost;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
@@ -41,12 +38,11 @@ import appeng.fluids.helper.IFluidInterfaceHost;
import appeng.fluids.util.IAEFluidTank;
public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerHost
public class GuiFluidInterface extends GuiUpgradeable
{
public final static int ID_BUTTON_TANK = 222;
private final IFluidInterfaceHost host;
private final ContainerFluidInterface container;
private GuiTabButton priority;
public GuiFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
@@ -54,8 +50,6 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH
super( new ContainerFluidInterface( ip, te ) );
this.ySize = 231;
this.host = te;
( this.container = (ContainerFluidInterface) this.inventorySlots ).setGui( this );
}
@Override
@@ -68,7 +62,9 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH
for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i )
{
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 53, 16, 68 ) );
final GuiFluidTank guiTank = new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, this.getGuiLeft() + 35 + 18 * i, this
.getGuiTop() + 53, 16, 68 );
this.buttonList.add( guiTank );
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
}
@@ -108,33 +104,9 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH
}
}
@Override
protected void mouseClicked( int xCoord, int yCoord, int btn ) throws IOException
{
for( GuiCustomSlot slot : this.guiSlots )
{
if( slot instanceof GuiFluidTank )
{
if( this.isPointInRegion( slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord ) && slot.canClick( this.mc.player ) )
{
this.container.setTargetStack( ( (GuiFluidTank) slot ).getFluidStack() );
slot.slotClicked( this.mc.player.inventory.getItemStack(), btn );
return;
}
}
}
super.mouseClicked( xCoord, yCoord, btn );
}
@Override
protected boolean drawUpgrades()
{
return false;
}
@Override
public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue )
{
}
}
@@ -90,13 +90,6 @@ public class GuiFluidLevelEmitter extends GuiUpgradeable
this.level.drawTextBox();
}
@Override
public void drawFG( int offsetX, int offsetY, int mouseX, int mouseY )
{
if( isPointInRegion( 24, 43,89,this.fontRenderer.FONT_HEIGHT,mouseX,mouseY ) ) drawTooltip( mouseX - guiLeft - 7, mouseY - guiTop + 25, "Amount in millibuckets" );
super.drawFG( offsetX, offsetY, mouseX, mouseY );
}
@Override
protected boolean drawUpgrades()
{
@@ -4,7 +4,6 @@ package appeng.fluids.client.gui.widgets;
import java.util.Collections;
import appeng.container.slot.IJEITargetSlot;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@@ -24,7 +23,7 @@ import appeng.fluids.util.AEFluidStack;
import appeng.fluids.util.IAEFluidTank;
public class GuiFluidSlot extends GuiCustomSlot implements IJEITargetSlot
public class GuiFluidSlot extends GuiCustomSlot
{
private final IAEFluidTank fluids;
private final int slot;
@@ -19,50 +19,42 @@
package appeng.fluids.client.gui.widgets;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.helpers.InventoryAction;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.util.AEColor;
import appeng.client.gui.widgets.ITooltip;
import appeng.fluids.util.IAEFluidTank;
@SideOnly( Side.CLIENT )
public class GuiFluidTank extends GuiCustomSlot implements ITooltip
public class GuiFluidTank extends GuiButton implements ITooltip
{
private final IAEFluidTank tank;
private final int slot;
private final int width;
private final int height;
public GuiFluidTank( IAEFluidTank tank, int slot, int id, int x, int y, int w, int h )
{
super( id, x, y );
super( id, x, y, w, h, "" );
this.tank = tank;
this.slot = slot;
this.width = w;
this.height = h;
}
@Override
public void drawContent( Minecraft mc, int mouseX, int mouseY, float partialTicks )
public void drawButton( final Minecraft mc, final int mouseX, final int mouseY, final float partialTicks )
{
final IAEFluidStack fs = this.getFluidStack();
if( fs != null )
if( this.visible )
{
GlStateManager.disableBlend();
GlStateManager.disableLighting();
//drawRect( this.x, this.y, this.x + this.width, this.y + this.height, AEColor.GRAY.blackVariant | 0xFF000000 );
drawRect( this.x, this.y, this.x + this.width, this.y + this.height, AEColor.GRAY.blackVariant | 0xFF000000 );
final IAEFluidStack fluid = this.tank.getFluidInSlot( this.slot );
if( fluid != null && fluid.getStackSize() > 0 )
@@ -77,16 +69,17 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite( fluid.getFluid().getStill().toString() );
final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) );
int iconHeightRemainder = scaledHeight % this.getHeight();
int iconHeightRemainder = scaledHeight % 16;
if( iconHeightRemainder > 0 )
{
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, this.getWidth(), iconHeightRemainder );
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder, sprite, 16, iconHeightRemainder );
}
for( int i = 0; i < scaledHeight / this.getHeight(); i++ )
for( int i = 0; i < scaledHeight / 16; i++ )
{
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, this.getWidth(), this.getHeight() );
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
}
}
}
}
@@ -107,25 +100,25 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
@Override
public int xPos()
{
return this.x - 1;
return this.x - 2;
}
@Override
public int yPos()
{
return this.y - 1;
return this.y - 2;
}
@Override
public int getWidth()
{
return this.width;
return this.width + 4;
}
@Override
public int getHeight()
{
return this.height + 1;
return this.height + 4;
}
@Override
@@ -134,24 +127,4 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
return true;
}
public IAEFluidStack getFluidStack()
{
return this.tank.getFluidInSlot( this.slot );
}
@Override
public void slotClicked( ItemStack clickStack, final int mouseButton )
{
if( getFluidStack() != null )
{
NetworkHandler.instance().sendToServer( new PacketInventoryAction( InventoryAction.FILL_ITEM, slot, 0 ) );
}
else
{
NetworkHandler.instance().sendToServer( new PacketInventoryAction( InventoryAction.EMPTY_ITEM, slot, 0 ) );
}
}
}
@@ -19,17 +19,9 @@
package appeng.fluids.container;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.Map;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketTargetFluidStack;
import appeng.fluids.util.AEFluidStack;
import appeng.helpers.InventoryAction;
import appeng.util.IConfigManagerHost;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IContainerListener;
@@ -41,19 +33,12 @@ import appeng.fluids.helper.FluidSyncHelper;
import appeng.fluids.helper.IFluidInterfaceHost;
import appeng.fluids.util.IAEFluidTank;
import appeng.util.Platform;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
public class ContainerFluidInterface extends ContainerFluidConfigurable implements IConfigManagerHost
public class ContainerFluidInterface extends ContainerFluidConfigurable
{
private final DualityFluidInterface myDuality;
private final FluidSyncHelper tankSync;
private IConfigManagerHost gui;
// Holds the fluid the client wishes to extract, or null for insert
private IAEFluidStack clientRequestedTargetFluid = null;
public ContainerFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
{
@@ -75,15 +60,6 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable implemen
return this.myDuality.getConfig();
}
@Override
public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue )
{
if( this.getGui() != null )
{
this.getGui().updateSetting( manager, settingName, newValue );
}
}
@Override
public void detectAndSendChanges()
{
@@ -121,126 +97,6 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable implemen
this.tankSync.readPacket( fluids );
}
private IConfigManagerHost getGui()
{
return this.gui;
}
public void setGui( @Nonnull final IConfigManagerHost gui )
{
this.gui = gui;
}
public void doAction( EntityPlayerMP player, InventoryAction action, int slot, long id )
{
if( action != InventoryAction.FILL_ITEM && action != InventoryAction.EMPTY_ITEM )
{
super.doAction( player, action, slot, id );
return;
}
final ItemStack held = player.inventory.getItemStack();
ItemStack heldCopy = held.copy();
heldCopy.setCount( 1 );
IFluidHandlerItem fh = FluidUtil.getFluidHandler( heldCopy );
if( fh == null )
{
// only fluid handlers items
return;
}
if( action == InventoryAction.FILL_ITEM && this.clientRequestedTargetFluid != null )
{
final IAEFluidStack stack = this.clientRequestedTargetFluid.copy();
// Check how much we can store in the item
stack.setStackSize( Integer.MAX_VALUE );
int amountAllowed = fh.fill( stack.getFluidStack(), false );
int heldAmount = held.getCount();
for( int i = 0; i < heldAmount; i++ )
{
ItemStack copiedFluidContainer = held.copy();
copiedFluidContainer.setCount( 1 );
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
FluidStack extractableFluid = this.myDuality.getTanks().drain( stack.setStackSize( amountAllowed ).getFluidStack(), false );
if( extractableFluid == null || extractableFluid.amount == 0 )
{
break;
}
int fillableAmount = fh.fill( extractableFluid, false );
if( fillableAmount > 0 )
{
FluidStack extractedFluid = this.myDuality.getTanks().drain( extractableFluid, true );
fh.fill( extractedFluid, true );
}
if( held.getCount() == 1 )
{
player.inventory.setItemStack( fh.getContainer() );
}
else
{
player.inventory.getItemStack().shrink( 1 );
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
player.dropItem( fh.getContainer(), false );
}
}
}
}
else if( action == InventoryAction.EMPTY_ITEM )
{
int heldAmount = held.getCount();
for( int i = 0; i < heldAmount; i++ )
{
ItemStack copiedFluidContainer = held.copy();
copiedFluidContainer.setCount( 1 );
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
FluidStack drainable = fh.drain( this.myDuality.getTanks().getTankProperties()[slot].getCapacity(), false );
if( drainable != null )
{
fh.drain( drainable, true );
this.myDuality.getTanks().fill( drainable, true );
}
if( held.getCount() == 1 )
{
player.inventory.setItemStack( fh.getContainer() );
}
else
{
player.inventory.getItemStack().shrink( 1 );
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
player.dropItem( fh.getContainer(), false );
}
}
}
}
this.updateHeld( player );
}
public void setTargetStack( final IAEFluidStack stack )
{
if( Platform.isClient() )
{
if( stack == null && this.clientRequestedTargetFluid == null )
{
return;
}
if( stack != null && this.clientRequestedTargetFluid != null && stack.getFluidStack().isFluidEqual( this.clientRequestedTargetFluid.getFluidStack() ) )
{
return;
}
NetworkHandler.instance().sendToServer( new PacketTargetFluidStack( (AEFluidStack) stack ) );
}
this.clientRequestedTargetFluid = stack == null ? null : stack.copy();
}
@Override
protected boolean supportCapacity()
{
@@ -24,9 +24,6 @@ import java.nio.BufferOverflowException;
import javax.annotation.Nonnull;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.SlotPlayerHotBar;
import appeng.container.slot.SlotPlayerInv;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
@@ -73,7 +70,6 @@ import appeng.me.helpers.ChannelPowerSrc;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
import net.minecraftforge.items.IItemHandler;
/**
@@ -346,89 +342,6 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
}
}
@Override
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
{
if( Platform.isClient() )
{
return ItemStack.EMPTY;
}
EntityPlayerMP player = (EntityPlayerMP) p;
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();
ItemStack copy = itemStack.copy();
copy.setCount( 1 );
IFluidHandlerItem fh = FluidUtil.getFluidHandler( copy );
if( fh == null )
{
// only fluid handlers items
return ItemStack.EMPTY;
}
int heldAmount = itemStack.getCount();
for( int i = 0; i < heldAmount; i++ )
{
copy = itemStack.copy();
copy.setCount( 1 );
fh = FluidUtil.getFluidHandler( copy );
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
if( extract == null || extract.amount < 1 )
{
return ItemStack.EMPTY;
}
// Check if we can push into the system
final IAEFluidStack notStorable = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource(), Actionable.SIMULATE );
if( notStorable != null && notStorable.getStackSize() > 0 )
{
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
final FluidStack storable = fh.drain( toStore, false );
if( storable == null || storable.amount == 0 )
{
return ItemStack.EMPTY;
}
else
{
extract.amount = storable.amount;
}
}
// Actually drain
final FluidStack drained = fh.drain( extract, true );
extract.amount = drained.amount;
final IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource() );
if( notInserted != null && notInserted.getStackSize() > 0 )
{
IAEFluidStack spill = this.monitor.injectItems( notInserted, Actionable.MODULATE, this.getActionSource() );
if( spill != null && spill.getStackSize() > 0 )
{
fh.fill( spill.getFluidStack(), true );
}
}
if( notInserted == null )
{
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
player.dropItem( fh.getContainer(), false );
}
clickSlot.decrStackSize( 1 );
}
}
this.detectAndSendChanges();
return ItemStack.EMPTY;
}
return super.transferStackInSlot( p, idx );
}
@Override
public void doAction( EntityPlayerMP player, InventoryAction action, int slot, long id )
{
@@ -439,9 +352,13 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
}
final ItemStack held = player.inventory.getItemStack();
ItemStack heldCopy = held.copy();
heldCopy.setCount( 1 );
IFluidHandlerItem fh = FluidUtil.getFluidHandler( heldCopy );
if( held.getCount() != 1 )
{
// only support stacksize 1 for now
return;
}
final IFluidHandlerItem fh = FluidUtil.getFluidHandler( held );
if( fh == null )
{
// only fluid handlers items
@@ -455,122 +372,84 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
// Check how much we can store in the item
stack.setStackSize( Integer.MAX_VALUE );
int amountAllowed = fh.fill( stack.getFluidStack(), false );
int heldAmount = held.getCount();
for( int i = 0; i < heldAmount; i++ )
stack.setStackSize( amountAllowed );
// Check if we can pull out of the system
final IAEFluidStack canPull = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack, this.getActionSource(), Actionable.SIMULATE );
if( canPull == null || canPull.getStackSize() < 1 )
{
ItemStack copiedFluidContainer = held.copy();
copiedFluidContainer.setCount( 1 );
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
// Check if we can pull out of the system
final IAEFluidStack canPull = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack.setStackSize( amountAllowed ), this.getActionSource(), Actionable.SIMULATE );
if( canPull == null || canPull.getStackSize() < 1 )
{
return;
}
// How much could fit into the container
final int canFill = fh.fill( canPull.getFluidStack(), false );
if( canFill == 0 )
{
return;
}
// Now actually pull out of the system
final IAEFluidStack pulled = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack.setStackSize( canFill ), this.getActionSource() );
if( pulled == null || pulled.getStackSize() < 1 )
{
// Something went wrong
AELog.error( "Unable to pull fluid out of the ME system even though the simulation said yes " );
return;
}
// Actually fill
final int used = fh.fill( pulled.getFluidStack(), true );
if( used != canFill )
{
AELog.error( "Fluid item [%s] reported a different possible amount than it actually accepted.", held.getDisplayName() );
}
if( held.getCount() == 1 )
{
player.inventory.setItemStack( fh.getContainer() );
}
else
{
player.inventory.getItemStack().shrink( 1 );
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
player.dropItem( fh.getContainer(), false );
}
}
return;
}
this.updateHeld( player );
// How much could fit into the container
final int canFill = fh.fill( canPull.getFluidStack(), false );
if( canFill == 0 )
{
return;
}
// Now actually pull out of the system
stack.setStackSize( canFill );
final IAEFluidStack pulled = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack, this.getActionSource() );
if( pulled == null || pulled.getStackSize() < 1 )
{
// Something went wrong
AELog.error( "Unable to pull fluid out of the ME system even though the simulation said yes " );
return;
}
// Actually fill
final int used = fh.fill( pulled.getFluidStack(), true );
if( used != canFill )
{
AELog.error( "Fluid item [%s] reported a different possible amount than it actually accepted.", held.getDisplayName() );
}
player.inventory.setItemStack( fh.getContainer() );
this.updateHeld( player );
}
else if( action == InventoryAction.EMPTY_ITEM )
{
int heldAmount = held.getCount();
for( int i = 0; i < heldAmount; i++ )
// See how much we can drain from the item
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
if( extract == null || extract.amount < 1 )
{
ItemStack copiedFluidContainer = held.copy();
copiedFluidContainer.setCount( 1 );
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
return;
}
// See how much we can drain from the item
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
if( extract == null || extract.amount < 1 )
// Check if we can push into the system
final IAEFluidStack notStorable = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ),
this.getActionSource(), Actionable.SIMULATE );
if( notStorable != null && notStorable.getStackSize() > 0 )
{
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
final FluidStack storable = fh.drain( toStore, false );
if( storable == null || storable.amount == 0 )
{
return;
}
// Check if we can push into the system
final IAEFluidStack notStorable = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource(), Actionable.SIMULATE );
if( notStorable != null && notStorable.getStackSize() > 0 )
{
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
final FluidStack storable = fh.drain( toStore, false );
if( storable == null || storable.amount == 0 )
{
return;
}
else
{
extract.amount = storable.amount;
}
}
// Actually drain
final FluidStack drained = fh.drain( extract, true );
extract.amount = drained.amount;
final IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource() );
if( notInserted != null && notInserted.getStackSize() > 0 )
{
IAEFluidStack spill = this.monitor.injectItems( notInserted, Actionable.MODULATE, this.getActionSource() );
if( spill != null && spill.getStackSize() > 0 )
{
fh.fill( spill.getFluidStack(), true );
}
}
if( held.getCount() == 1 )
{
player.inventory.setItemStack( fh.getContainer() );
}
else
{
player.inventory.getItemStack().shrink( 1 );
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
player.dropItem( fh.getContainer(), false );
}
extract.amount = storable.amount;
}
}
// Actually drain
final FluidStack drained = fh.drain( extract, true );
extract.amount = drained.amount;
final IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ),
this.getActionSource() );
if( notInserted != null && notInserted.getStackSize() > 0 )
{
AELog.error( "Fluid item [%s] reported a different possible amount to drain than it actually provided.", held.getDisplayName() );
}
player.inventory.setItemStack( fh.getContainer() );
this.updateHeld( player );
}
}
@@ -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;
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 )
{
@@ -144,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;
@@ -453,12 +450,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
if( inventory == this.config )
{
boolean cfg = hasConfig();
this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
}
}
else if( inventory == this.tanks )
{
@@ -563,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] );
}
}
}
}
@@ -204,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 );
@@ -4,10 +4,7 @@ package appeng.fluids.parts;
import java.util.Random;
import appeng.api.networking.events.MENetworkChannelChanged;
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;
@@ -37,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;
@@ -116,9 +114,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
@Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
{
if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && diffStack.equals( this.config.getFluidInSlot( 0 ) ) )
if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && fullStack.equals( this.config.getFluidInSlot( 0 ) ) )
{
this.lastReportedValue += diffStack.getStackSize();
this.lastReportedValue = fullStack.getStackSize();
this.updateState();
}
}
@@ -130,22 +128,14 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
}
@MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange powerEvent )
public void channelChanged( final MENetworkChannelsChanged c )
{
if (this.getProxy().isActive())
{
onListUpdate();
}
this.updateState();
}
@MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c )
public void powerChanged( final MENetworkPowerStatusChange c )
{
if (this.getProxy().isActive())
{
onListUpdate();
}
this.updateState();
}
@@ -257,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
@@ -26,7 +26,6 @@ import java.util.Objects;
import javax.annotation.Nonnull;
import appeng.fluids.helper.IConfigurableFluidInventory;
import appeng.util.ConfigManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -168,28 +167,11 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
final boolean fullReset = this.resetCacheLogic == 2;
this.resetCacheLogic = 0;
final MEInventoryHandler<IAEFluidStack> in = this.getInternalHandler();
final IMEInventory<IAEFluidStack> in = this.getInternalHandler();
IItemList<IAEFluidStack> before = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
boolean denyRead = false;
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 ) )
{
denyRead = 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;
@@ -198,17 +180,15 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
this.handlerHash = 0;
}
final MEInventoryHandler<IAEFluidStack> out = this.getInternalHandler();
final IMEInventory<IAEFluidStack> out = this.getInternalHandler();
if( in != out || denyRead )
if( in != out )
{
IItemList<IAEFluidStack> after = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
if( out != null && !denyRead )
if( out != null )
{
after = out.getAvailableItems( after );
}
Platform.postListChanges( before, after, this, this.source );
}
}
@@ -227,7 +207,7 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
{
this.resetCacheLogic = 2;
}
else if( this.resetCacheLogic < 2 )
else
{
this.resetCacheLogic = 1;
}
@@ -284,19 +264,13 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
@Override
public void postChange( final IBaseMonitor<IAEFluidStack> monitor, final Iterable<IAEFluidStack> change, final IActionSource source )
{
if( this.source.machine().map( machine -> machine == this ).orElse( false ) && monitor != null )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
if( !currentAccess.hasPermission( AccessRestriction.READ ) )
{
return;
}
}
try
{
if( this.getProxy().isActive() )
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ), change, this.source );
this.getProxy()
.getStorage()
.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ), change, this.source );
}
}
catch( final GridAccessException e )
@@ -326,10 +300,6 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
this.handlerHash = newHandlerHash;
this.handler = null;
if( this.monitor != null )
{
( (IBaseMonitor<IAEFluidStack>) monitor ).removeListener( this );
}
this.monitor = null;
if( target != null )
{
@@ -338,7 +308,6 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
{
this.monitor = (ITickingMonitor) inv;
this.monitor.setActionSource( new MachineSource( this ) );
this.monitor.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv != null )
@@ -445,7 +414,7 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
{
if( channel == this.getStorageChannel() )
{
final IMEInventoryHandler<IAEFluidStack> out = this.getInternalHandler();
final IMEInventoryHandler<IAEFluidStack> out = this.getProxy().isActive() ? this.getInternalHandler() : null;
if( out != null )
{
return Collections.singletonList( out );
@@ -32,6 +32,7 @@ import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
@@ -216,18 +217,6 @@ public final class AEFluidStack extends AEStack<IAEFluidStack> implements IAEFlu
return dup;
}
@Override
public boolean isItem()
{
return false;
}
@Override
public boolean isFluid()
{
return true;
}
@Override
public IStorageChannel<IAEFluidStack> getChannel()
{
@@ -318,17 +307,17 @@ public final class AEFluidStack extends AEStack<IAEFluidStack> implements IAEFlu
}
@Override
public void writeToPacket( final ByteBuf buffer ) throws IOException
public void writeToPacket( final ByteBuf i ) throws IOException
{
final byte mask = (byte) ( ( this.getType( this.getStackSize() ) << 2 ) | ( this
.getType( this.getCountRequestable() ) << 4 ) | ( (byte) ( this.isCraftable() ? 1 : 0 ) << 6 ) | ( this.hasTagCompound() ? 1 : 0 ) << 7 );
buffer.writeByte( mask );
i.writeByte( mask );
this.writeToStream( buffer );
this.writeToStream( i );
this.putPacketValue( buffer, this.getStackSize() );
this.putPacketValue( buffer, this.getCountRequestable() );
this.putPacketValue( i, this.getStackSize() );
this.putPacketValue( i, this.getCountRequestable() );
}
private void writeToStream( final ByteBuf buffer ) throws IOException
@@ -19,19 +19,22 @@
package appeng.helpers;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
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.init.Items;
@@ -90,6 +93,8 @@ import appeng.api.util.AEPartLocation;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IConfigManager;
import appeng.capabilities.Capabilities;
import appeng.core.AEConfig;
import appeng.core.features.AEFeature;
import appeng.core.settings.TickRates;
import appeng.me.GridAccessException;
import appeng.me.helpers.AENetworkProxy;
@@ -101,6 +106,10 @@ import appeng.parts.automation.StackUpgradeInventory;
import appeng.parts.automation.UpgradeInventory;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.inv.AdaptorItemHandler;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.IInventoryDestination;
import appeng.util.inv.InvOperation;
import appeng.util.item.AEItemStack;
import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
@@ -112,7 +121,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
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;
public static final int NUMBER_OF_PATTERN_SLOTS = 9;
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
private final IAEItemStack[] requireWork = { null, null, null, null, null, null, null, null, null };
@@ -139,18 +148,14 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
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 GTCEInventoryAdaptor GTad;
private boolean resetConfigCache = true;
private IMEMonitor<IAEItemStack> configCachedHandler;
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, 1 );
this.cm.registerSetting( Settings.BLOCK, YesNo.NO );
this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES );
@@ -178,14 +183,10 @@ 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;
}
}
else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) )
{
@@ -241,27 +242,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
data.setTag( "waitingToSend", waitingToSend );
NBTTagCompound sidedWaitList = new NBTTagCompound();
if (this.waitingToSendFacing != null)
{
for( EnumFacing s : this.iHost.getTargets() )
{
NBTTagList waitingListSided = new NBTTagList();
if (this.waitingToSendFacing.containsKey( s ))
{
for( final ItemStack is : this.waitingToSendFacing.get( s ) )
{
final NBTTagCompound item = new NBTTagCompound();
is.writeToNBT( item );
waitingListSided.appendTag( item );
}
sidedWaitList.setTag( s.name(), waitingListSided );
}
}
}
data.setTag( "sidedWaitList", sidedWaitList );
}
public void readFromNBT( final NBTTagCompound data )
@@ -281,44 +261,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
this.waitingToSendFacing = null;
final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" );
for( EnumFacing s : EnumFacing.values() )
if( waitingListSided.hasKey( s.name() ) )
{
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
for( int x = 0; x < w.tagCount(); x++ )
{
final NBTTagCompound c = w.getCompoundTagAt( x );
if( c != null )
{
final ItemStack is = new ItemStack( c );
this.addToSendListFacing( is, EnumFacing.getFront( s.getIndex() ) );
}
}
}
this.craftingTracker.readFromNBT( data );
// fix upgrade slot size mismatch
NBTTagCompound up = data.getCompoundTag( "upgrades" );
if( up.hasKey( "Size" ) && up.getInteger( "Size" ) != this.upgrades.getSlots() )
{
up.setInteger( "Size", this.upgrades.getSlots() );
this.upgrades.writeToNBT( up, "upgrades" );
}
this.upgrades.readFromNBT( data, "upgrades" );
this.config.readFromNBT( data, "config" );
NBTTagCompound pa = data.getCompoundTag( "patterns" );
if( pa.hasKey( "Size" ) && pa.getInteger( "Size" ) != this.patterns.getSlots() )
{
pa.setInteger( "Size", this.patterns.getSlots() );
this.upgrades.writeToNBT( pa, "patterns" );
}
this.patterns.readFromNBT( data, "patterns" );
this.storage.readFromNBT( data, "storage" );
this.priority = data.getInteger( "priority" );
@@ -351,30 +296,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
private void addToSendListFacing( final ItemStack is, EnumFacing f )
{
if( is.isEmpty() )
{
return;
}
if (this.waitingToSendFacing == null){
this.waitingToSendFacing = new EnumMap<>(EnumFacing.class);
}
this.waitingToSendFacing.computeIfAbsent( f, k -> new ArrayList<>() );
this.waitingToSendFacing.get( f ).add( is );
try
{
this.gridProxy.getTick().wakeDevice( this.gridProxy.getNode() );
}
catch( final GridAccessException e )
{
// :P
}
}
private void readConfig()
{
this.hasConfig = false;
@@ -421,8 +342,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private void updateCraftingList()
{
final Boolean[] accountedFor = new Boolean[this.patterns.getSlots()];
Arrays.fill( accountedFor, false );
final Boolean[] accountedFor = { false, false, false, false, false, false, false, false, false }; // 9...
assert ( accountedFor.length == this.patterns.getSlots() );
if( !this.gridProxy.isReady() )
{
@@ -437,7 +359,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
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 )
@@ -453,7 +375,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
for( int x = 0; x < accountedFor.length ; x++ )
for( int x = 0; x < accountedFor.length; x++ )
{
if( !accountedFor[x] )
{
@@ -471,22 +393,24 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
private boolean hasWorkToDo() {
if (hasItemsToSend()){
private boolean hasWorkToDo()
{
if( this.hasItemsToSend() )
{
return true;
}
if(hasItemsToSendFacing()){
return true;
}
for (final IAEItemStack requiredWork : this.requireWork) {
if (requiredWork != null) {
return true;
else
{
for( final IAEItemStack requiredWork : this.requireWork )
{
if( requiredWork != null )
{
return true;
}
}
return false;
}
return false;
}
private void updatePlan( final int slot )
@@ -591,45 +515,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return this.waitingToSend != null && !this.waitingToSend.isEmpty();
}
private boolean hasItemsToSendFacing()
{
if (waitingToSendFacing != null)
{
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{
if( !waitingToSendFacing.get( enumFacing ).isEmpty() )
{
return true;
}
}
}
return false;
}
public void dropExcessPatterns()
{
IItemHandler patterns = getPatterns();
List<ItemStack> dropList = new ArrayList<>();
for( int invSlot = 0; invSlot < patterns.getSlots(); invSlot++ )
{
if( invSlot > 8 + this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) * 9 )
{
ItemStack is = patterns.getStackInSlot( invSlot );
if( is.isEmpty() ) continue;
dropList.add( patterns.extractItem( invSlot, Integer.MAX_VALUE, false ) );
}
}
if( dropList.size() > 0 )
{
World world = this.getLocation().getWorld();
BlockPos blockPos = this.getLocation().getPos();
Platform.spawnDrops( world, blockPos, dropList );
}
this.gridProxy.setIdlePowerUsage( Math.pow( 4, ( this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) ) ) );
}
@Override
public boolean canInsert( final ItemStack stack )
{
@@ -701,21 +586,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return TickRateModulation.SLEEP;
}
//Previous version might have items saved in this list
//recover them
if( this.hasItemsToSend() )
{
this.pushItemsOut( this.iHost.getTargets() );
}
if (hasItemsToSendFacing())
{
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{
this.pushItemsOut( enumFacing );
}
}
final boolean couldDoWork = this.updateStorage();
return this.hasWorkToDo() ? ( couldDoWork ? TickRateModulation.URGENT : TickRateModulation.SLOWER ) : TickRateModulation.SLEEP;
}
@@ -776,47 +651,6 @@ 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())) {
return;
}
final TileEntity tile = this.iHost.getTileEntity();
final World w = tile.getWorld();
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
if( te == null )
{
return;
}
final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator();
while ( i.hasNext() )
{
ItemStack whatToSend = i.next();
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null )
{
final ItemStack result = ad.addItems( whatToSend );
if( !result.isEmpty() )
{
whatToSend.setCount( whatToSend.getCount() - ( whatToSend.getCount() - result.getCount() ) );
}
else
{
i.remove();
}
}
}
if( this.waitingToSendFacing.get( s ).isEmpty() )
{
this.waitingToSendFacing.remove( s );
}
}
private boolean updateStorage()
{
boolean didSomething = false;
@@ -980,12 +814,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;
@@ -1084,9 +913,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
};
}
private boolean invIsBlocked( InventoryAdaptor inv )
private static boolean invIsBlocked( InventoryAdaptor inv )
{
return (inv.containsItems());
if( AEConfig.instance().isFeatureEnabled( AEFeature.INSANE_BLOCKING_MODE ) )
{
return !inv.simulateRemove( 1, ItemStack.EMPTY, null ).isEmpty();
}
else return inv.containsItems();
}
private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv )
@@ -1097,7 +930,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
@Override
public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table )
{
if( this.hasItemsToSend() || this.hasItemsToSendFacing() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
if( this.hasItemsToSend() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
{
return false;
}
@@ -1105,12 +938,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final TileEntity tile = this.iHost.getTileEntity();
final World w = tile.getWorld();
if( this.visitedFaces.isEmpty() )
{
this.visitedFaces = this.iHost.getTargets();
}
for( final EnumFacing s : visitedFaces )
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
for( final EnumFacing s : possibleDirections )
{
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
if( te instanceof IInterfaceHost )
@@ -1119,7 +948,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
if( ( (IInterfaceHost) te ).getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
{
visitedFaces.remove( s );
continue;
}
}
@@ -1134,7 +962,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final ICraftingMachine cm = (ICraftingMachine) te;
if( cm.acceptsPlans() )
{
visitedFaces.remove( s );
if( cm.pushPattern( patternDetails, table, s.getOpposite() ) )
{
return true;
@@ -1148,67 +975,53 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
if( this.isBlocking() )
{
IPhantomTile phantomTE = null;
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
{
phantomTE = ( (IPhantomTile) te );
if( phantomTE.hasBoundPosition() )
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( invIsBlockedGTCE( GTad ) )
{
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
if( phantom instanceof MetaTileEntityHolder && isGTCEblocked( phantom, s ) )
{
visitedFaces.remove( s );
continue;
}
}
}
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
{
if( isGTCEblocked( te, s ) )
{
visitedFaces.remove( s );
continue;
}
}
else if( invIsBlocked( ad ) )
else
{
visitedFaces.remove( s );
continue;
if( invIsBlocked( ad ) )
{
continue;
}
}
}
if( this.acceptsItems( ad, table ) )
{
visitedFaces.remove( s );
for( int x = 0; x < table.getSizeInventory(); x++ )
{
final ItemStack is = table.getStackInSlot( x );
if( !is.isEmpty() )
{
addToSendListFacing( is, s );
final ItemStack added = ad.addItems( is );
this.addToSendList( added );
}
}
pushItemsOut( s );
this.pushItemsOut( possibleDirections );
return true;
}
}
visitedFaces.remove( s );
}
return false;
}
@Override
public boolean isBusy()
{
boolean busy = false;
if( this.hasItemsToSend() || hasItemsToSendFacing() )
if( this.hasItemsToSend() )
{
return true;
}
boolean busy = false;
if( this.isBlocking() )
{
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
@@ -1220,38 +1033,27 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
for( final EnumFacing s : possibleDirections )
{
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
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( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
{
phantomTE = ( (IPhantomTile) te );
if( phantomTE.hasBoundPosition() )
{
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
if( phantom instanceof MetaTileEntityHolder && !isGTCEblocked( phantom, s ) )
{
allAreBusy = false;
break;
}
}
}
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
{
if( !isGTCEblocked( te, s ) )
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( !invIsBlockedGTCE( GTad ) )
{
allAreBusy = false;
break;
}
}
else if( !invIsBlocked( ad ) )
else
{
allAreBusy = false;
break;
if( !invIsBlocked( ad ) )
{
allAreBusy = false;
break;
}
}
}
}
@@ -1260,12 +1062,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return busy;
}
boolean isGTCEblocked(TileEntity te, EnumFacing s)
{
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
return invIsBlockedGTCE( GTad );
}
private boolean sameGrid( final IGrid grid ) throws GridAccessException
{
return grid == this.gridProxy.getGrid();
@@ -1321,20 +1117,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
if( this.waitingToSendFacing != null )
{
for (List<ItemStack> itemList : waitingToSendFacing.values())
{
for (final ItemStack is : itemList)
{
if (!is.isEmpty())
{
drops.add(is);
}
}
}
}
for( final ItemStack is : this.upgrades )
{
if( !is.isEmpty() )
@@ -1593,6 +1375,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
public InterfaceInventory( final DualityInterface tileInterface )
{
super( new AdaptorItemHandler( tileInterface.storage ) );
this.setActionSource( new MachineSource( DualityInterface.this.iHost ) );
}
@Override
@@ -26,11 +26,10 @@ public class HighlighterHandler
return;
}
Minecraft mc = Minecraft.getMinecraft();
int dimension = mc.world.provider.getDimension();
long time = System.currentTimeMillis();
if (time > BlockPosHighlighter.getExpireHilight() || dimension != BlockPosHighlighter.getDimension()) {
BlockPosHighlighter.hilightBlock(null, -1, BlockPosHighlighter.getDimension() );
if (time > BlockPosHighlighter.getExpireHilight()) {
BlockPosHighlighter.hilightBlock(null, -1);
return;
}
@@ -62,7 +61,6 @@ public class HighlighterHandler
tessellator.draw();
GlStateManager.enableTexture2D();
GlStateManager.enableDepth();
GlStateManager.popMatrix();
}
@@ -43,6 +43,5 @@ public enum InventoryAction
ROLL_UP,
ROLL_DOWN,
AUTO_CRAFT,
PLACE_SINGLE,
PLACE_JEI_GHOST_ITEM
PLACE_SINGLE
}
+46 -114
View File
@@ -19,18 +19,21 @@
package appeng.helpers;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.NonNullList;
import net.minecraft.world.World;
import appeng.api.AEApi;
@@ -43,17 +46,11 @@ import appeng.core.AELog;
import appeng.core.features.AEFeature;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import net.minecraftforge.common.crafting.IShapedRecipe;
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
{
private static final int CRAFTING_GRID_DIMENSION = 3;
private static final int ALL_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION;
private static final int CRAFTING_OUTPUT_LIMIT = 1;
private static final int PROCESSING_OUTPUT_LIMIT = 3;
private final ItemStack patternItem;
private final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 );
private final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 );
@@ -63,7 +60,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
private final IAEItemStack[] condensedOutputs;
private final IAEItemStack[] inputs;
private final IAEItemStack[] outputs;
private final Map<Integer, List<IAEItemStack>> substituteInputs;
private final boolean isCrafting;
private final boolean canSubstitute;
private final Set<TestLookup> failCache = new HashSet<>();
@@ -147,11 +143,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
}
}
}
final int outputLength = out.size();
this.inputs = in.toArray(new IAEItemStack[ALL_INPUT_LIMIT]);
this.outputs = out.toArray(new IAEItemStack[outputLength]);
this.substituteInputs = new HashMap<>(ALL_INPUT_LIMIT);
this.outputs = out.toArray( new IAEItemStack[out.size()] );
this.inputs = in.toArray( new IAEItemStack[in.size()] );
final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>();
@@ -263,14 +257,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
this.testFrame.setInventorySlotContents( slotIndex, i );
// If we cannot substitute, the items must match exactly
if (!canSubstitute && slotIndex < inputs.length) {
if (!inputs[slotIndex].isSameType(i)) {
this.markItemAs(slotIndex, i, TestStatus.DECLINE);
return false;
}
}
if( this.standardRecipe.matches( this.testFrame, w ) )
{
final ItemStack testOutput = this.standardRecipe.getCraftingResult( this.testFrame );
@@ -282,6 +268,25 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
return true;
}
}
else if( AEConfig.instance().isFeatureEnabled( AEFeature.CRAFTING_MANAGER_FALLBACK ) )
{
final ItemStack testOutput = CraftingManager.findMatchingResult( this.testFrame, w );
if( Platform.itemComparisons().isSameItem( this.correctOutput, testOutput ) )
{
this.testFrame.setInventorySlotContents( slotIndex, this.crafting.getStackInSlot( slotIndex ) );
this.markItemAs( slotIndex, i, TestStatus.ACCEPT );
if( AELog.isCraftingDebugLogEnabled() )
{
this.warnAboutCraftingManager( true );
}
return true;
}
this.warnAboutCraftingManager( false );
}
this.markItemAs( slotIndex, i, TestStatus.DECLINE );
return false;
@@ -323,97 +328,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
return this.canSubstitute;
}
@Override
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));
}
// 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]);
return itemList;
});
}
/**
* Gets the {@link Ingredient} from the actual used recipe for a given slot-index into {@link #getInputs()}.
* <p/>
* Conversion is needed for two reasons: our sparse ingredients are always organized in a 3x3 grid, while Vanilla's
* 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) {
if (standardRecipe instanceof IShapedRecipe ) {
IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe;
return getShapedRecipeIngredient(slot, shapedRecipe.getRecipeWidth());
} else {
return getShapelessRecipeIngredient(slot);
}
}
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) {
topOffset++; // First row is fully empty
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) {
leftOffset++; // First column is fully empty
if (inputs[1] == null && inputs[4] == null && inputs[7] == null) {
leftOffset++; // Second column is fully empty
}
}
// Compute the x,y of the slot, as-if the recipe was anchored to 0,0
int slotX = slot % CRAFTING_GRID_DIMENSION - leftOffset;
int slotY = slot / CRAFTING_GRID_DIMENSION - topOffset;
// Compute the index into the recipe's ingredient list now
int ingredientIndex = slotY * recipeWidth + slotX;
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
if (ingredientIndex < 0 || ingredientIndex > ingredients.size()) {
return Ingredient.EMPTY;
}
return ingredients.get(ingredientIndex);
}
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) {
ingredientIndex++;
}
}
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
if (ingredientIndex < ingredients.size()) {
return ingredients.get(ingredientIndex);
}
return Ingredient.EMPTY;
}
@Override
public ItemStack getOutput( final InventoryCrafting craftingInv, final World w )
{
@@ -492,6 +406,24 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
return this.pattern.hashCode();
}
private void warnAboutCraftingManager( boolean foundAlternative )
{
final String foundAlternativeRecipe = foundAlternative ? "Found alternative recipe." : "NOT FOUND, please report.";
final StringJoiner joinActualInputs = new StringJoiner( ", " );
for( int j = 0; j < this.testFrame.getSizeInventory(); j++ )
{
final ItemStack stack = this.testFrame.getStackInSlot( j );
if( !stack.isEmpty() )
{
joinActualInputs.add( stack.toString() );
}
}
AELog.warn( "Using CraftingManager fallback: Recipe <%s> for output <%s> rejected inputs [%s]. %s",
this.standardRecipe.getRegistryName(), this.standardRecipe.getRecipeOutput(), joinActualInputs, foundAlternativeRecipe );
}
@Override
public boolean equals( final Object obj )
{
+12 -7
View File
@@ -187,15 +187,20 @@ public class TickHandler
if( ev.type == Type.WORLD && ev.phase == Phase.END )
{
final WorldTickEvent wte = (WorldTickEvent) ev;
synchronized ( this.craftingJobs )
synchronized( this.craftingJobs )
{
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
if (!jobSet.isEmpty()) {
final int jobSize = jobSet.size();
final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000;
final int simTime = Math.max(1, microSecondsPerTick / jobSize);
jobSet.removeIf( cj -> !cj.simulateFor( simTime ) );
if( !jobSet.isEmpty() )
{
final Iterator<CraftingJob> i = jobSet.iterator();
while( i.hasNext() )
{
final CraftingJob cj = i.next();
if( !cj.simulateFor() )
{
i.remove();
}
}
}
}
}
@@ -1,26 +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();
}
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemSlot;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
{
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
{
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
{
// Attempt getting an IItemHandler for the given side via caps
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
if (itemHandler != null)
{
return new GTCEItemHandler(itemHandler);
}
}
return null;
}
public abstract boolean canRemoveAllExceptCircuits();
}
@@ -1,58 +1,57 @@
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 );
}
}
package appeng.integration.modules.gregtech;
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 null;
}
}
@@ -19,8 +19,6 @@
package appeng.integration.modules.jei;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -29,11 +27,14 @@ import appeng.client.gui.AEGuiHandler;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import mezz.jei.api.*;
import mezz.jei.config.Constants;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import mezz.jei.api.IJeiRuntime;
import mezz.jei.api.IModPlugin;
import mezz.jei.api.IModRegistry;
import mezz.jei.api.ISubtypeRegistry;
import mezz.jei.api.recipe.IRecipeCategoryRegistration;
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
@@ -56,9 +57,6 @@ import appeng.items.parts.ItemFacade;
@mezz.jei.api.JEIPlugin
public class JEIPlugin implements IModPlugin
{
public static IJeiRuntime runtime;
public static AEGuiHandler aeGuiHandler;
@Override
public void registerItemSubtypes( ISubtypeRegistry subtypeRegistry )
{
@@ -97,9 +95,8 @@ public class JEIPlugin implements IModPlugin
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ),
Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
aeGuiHandler = new AEGuiHandler();
AEGuiHandler aeGuiHandler = new AEGuiHandler();
registry.addAdvancedGuiHandlers(aeGuiHandler);
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler);
}
private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
@@ -222,6 +219,5 @@ public class JEIPlugin implements IModPlugin
{
JEIModule jeiModule = (JEIModule) Integrations.jei();
jeiModule.setJei( new JeiRuntimeAdapter( jeiRuntime ) );
runtime = jeiRuntime;
}
}
@@ -27,7 +27,6 @@ import java.util.Map;
import javax.annotation.Nullable;
import appeng.container.implementations.ContainerPatternTerm;
import appeng.core.sync.packets.PacketValueConfig;
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
import mezz.jei.transfer.RecipeTransferErrorInternal;
import mezz.jei.transfer.RecipeTransferErrorTooltip;
@@ -74,7 +73,24 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
{
final String recipeType = recipeLayout.getRecipeCategory().getUid();
if (recipeType.equals( VanillaRecipeCategoryUid.INFORMATION) || recipeType.equals(VanillaRecipeCategoryUid.FUEL))
if (!recipeType.equals( VanillaRecipeCategoryUid.INFORMATION) && !recipeType.equals(VanillaRecipeCategoryUid.FUEL))
{
if( container instanceof ContainerPatternTerm )
{
if( !( (ContainerPatternTerm) container ).isCraftingMode() )
{
if( recipeType.equals( VanillaRecipeCategoryUid.CRAFTING ) )
{
return new RecipeTransferErrorTooltip( I18n.format( "gui.appliedenergistics2.CraftingPattern" ) );
}
}
else if( !recipeType.equals( VanillaRecipeCategoryUid.CRAFTING ) )
{
return new RecipeTransferErrorTooltip( I18n.format( "gui.appliedenergistics2.ProcessingPattern" ) );
}
}
}
else
{
return RecipeTransferErrorInternal.INSTANCE;
}
@@ -84,30 +100,6 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
return null;
}
if( container instanceof ContainerPatternTerm )
{
try
{
if( !( (ContainerPatternTerm) container ).isCraftingMode() )
{
if( recipeType.equals( VanillaRecipeCategoryUid.CRAFTING ) )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", "1" ) );
}
}
else if( !recipeType.equals( VanillaRecipeCategoryUid.CRAFTING ) )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", "0" ) );
}
}
catch( IOException e )
{
e.printStackTrace();
}
}
Map<Integer, ? extends IGuiIngredient<ItemStack>> ingredients = recipeLayout.getItemStacks().getGuiIngredients();
final NBTTagCompound recipe = new NBTTagCompound();
@@ -147,12 +139,8 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
}
// prefer pure crystals.
for ( ItemStack stack : ingredient.getAllIngredients() )
for( ItemStack stack : ingredient.getAllIngredients() )
{
if( stack == null )
{
continue;
}
if( Platform.isRecipePrioritized( stack ) )
{
list.add( 0, stack );
@@ -163,7 +151,7 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
}
}
for ( final ItemStack is : list )
for( final ItemStack is : list )
{
final NBTTagCompound tag = new NBTTagCompound();
is.writeToNBT( tag );
@@ -164,8 +164,6 @@ public final class ItemMaterial extends AEBaseItem implements IStorageComponent,
return Upgrades.INVERTER;
case CARD_CRAFTING:
return Upgrades.CRAFTING;
case CARD_PATTERN_EXPANSION:
return Upgrades.PATTERN_EXPANSION;
default:
return null;
}
@@ -118,10 +118,7 @@ public enum MaterialType
FLUID_CELL1K_PART( 54, "material_fluid_cell1k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
FLUID_CELL4K_PART( 55, "material_fluid_cell4k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
FLUID_CELL16K_PART( 56, "material_fluid_cell16k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
FLUID_CELL64K_PART( 57, "material_fluid_cell64k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
CARD_PATTERN_EXPANSION( 58, "material_card_pattern_expansion", EnumSet.of( AEFeature.ADVANCED_CARDS ) );
FLUID_CELL64K_PART( 57, "material_fluid_cell64k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) );
private final Set<AEFeature> features;
private final ModelResourceLocation model;
+2 -2
View File
@@ -633,10 +633,10 @@ public class GridNode implements IGridNode, IPathItem
this.usedChannels = 0;
}
final int idx = this.connections.indexOf( (IGridConnection) fast );
final int idx = this.connections.indexOf( fast );
if( idx > 0 )
{
this.connections.remove( (IGridConnection) fast );
this.connections.remove( fast );
this.connections.add( 0, (IGridConnection) fast );
}
}
+16 -61
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,6 @@ 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 net.minecraft.world.World;
import appeng.api.AEApi;
@@ -105,8 +105,8 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
private final Set<ICraftingProvider> craftingProviders = new HashSet<>();
private final Map<IGridNode, ICraftingWatcher> craftingWatchers = new HashMap<>();
private final IGrid grid;
private final Object2ObjectMap<ICraftingPatternDetails, List<ICraftingMedium>> craftingMethods = new Object2ObjectOpenHashMap<>();
private final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftableItems = new Object2ObjectOpenHashMap<>();
private final Map<ICraftingPatternDetails, List<ICraftingMedium>> craftingMethods = new HashMap<>();
private final Map<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftableItems = new HashMap<>();
private final Set<IAEItemStack> emitableItems = new HashSet<>();
private final Map<String, CraftingLinkNexus> craftingLinks = new HashMap<>();
private final Multimap<IAEStack, CraftingWatcher> interests = HashMultimap.create();
@@ -160,11 +160,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
{
if( machine instanceof ICraftingWatcherHost )
{
final ICraftingWatcher craftingWatcher = this.craftingWatchers.get( gridNode );
final ICraftingWatcher craftingWatcher = this.craftingWatchers.get( machine );
if( craftingWatcher != null )
{
craftingWatcher.reset();
this.craftingWatchers.remove( gridNode );
this.craftingWatchers.remove( machine );
}
}
@@ -270,21 +270,24 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
return;
}
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>(this.craftableItems);
final Set<IAEItemStack> oldEmitableItems = new HashSet<>(this.emitableItems);
final Map<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 )
{
provider.provideCrafting( this );
}
final Object2ObjectMap<IAEItemStack, ObjectSet<ICraftingPatternDetails>> tmpCraft = new Object2ObjectOpenHashMap<>();
final Map<IAEItemStack, Set<ICraftingPatternDetails>> tmpCraft = new HashMap<>();
// new craftables!
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
@@ -295,11 +298,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
out.reset();
out.setCraftable( true );
ObjectSet<ICraftingPatternDetails> methods = tmpCraft.get( out );
Set<ICraftingPatternDetails> methods = tmpCraft.get( out );
if( methods == null )
{
tmpCraft.put( out, methods = new ObjectRBTreeSet<>( COMPARATOR ) );
tmpCraft.put( out, methods = new TreeSet<>( COMPARATOR ) );
}
methods.add( details );
@@ -307,56 +310,12 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
}
// make them immutable
for( final Entry<IAEItemStack, ObjectSet<ICraftingPatternDetails>> e : tmpCraft.entrySet() )
for( final Entry<IAEItemStack, Set<ICraftingPatternDetails>> e : tmpCraft.entrySet() )
{
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
}
Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftablesChanged = new Object2ObjectArrayMap<>();
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.put( changedStack, ais.getValue() );
}
}
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.put( changedStack, ais.getValue() );
}
}
for( final IAEItemStack st : oldEmitableItems )
{
if( !emitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.put( changedStack, null );
}
}
for( final IAEItemStack st : this.emitableItems )
{
if( !oldEmitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.put( changedStack, null );
}
}
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged.keySet(),
this.storageGrid.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), this.craftableItems.keySet(),
new BaseActionSource() );
}
@@ -676,11 +635,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
public boolean hasCpu( final ICraftingCPU cpu )
{
if (cpu instanceof CraftingCPUCluster)
{
return this.craftingCPUClusters.contains( (CraftingCPUCluster) cpu );
}
return false;
return this.craftingCPUClusters.contains( cpu );
}
public GenericInterestManager<CraftingWatcher> getInterestManager()
+27 -156
View File
@@ -30,7 +30,6 @@ import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;
@@ -64,7 +63,7 @@ import appeng.me.energy.EnergyWatcher;
public class EnergyGridCache implements IEnergyGrid
{
private static final double MAX_BUFFER_STORAGE = 800;
private static final double MAX_BUFFER_STORAGE = 200;
private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(),
o1.getProviderStoredEnergy() );
@@ -77,24 +76,9 @@ public class EnergyGridCache implements IEnergyGrid
};
private final NavigableSet<EnergyThreshold> interests = Sets.newTreeSet();
// Should only be modified from the add/remove methods below to guard against
// concurrent modifications
private final double averageLength = 40.0;
private final Set<IAEPowerStorage> providers = new LinkedHashSet<>();
// Used to track whether an extraction is currently in progress, to fail fast
// when something externally
// modifies the energy grid.
private boolean ongoingExtractOperation = false;
// Should only be modified from the add/remove methods below to guard against
// concurrent modifications
private final Set<IAEPowerStorage> requesters = new LinkedHashSet<>();
// Used to track whether an injection is currently in progress, to fail fast
// when something externally
// modifies the energy grid.
private boolean ongoingInjectOperation = false;
private final Multiset<IEnergyGridProvider> energyGridProviders = HashMultiset.create();
private final IGrid myGrid;
private final HashMap<IGridNode, IEnergyWatcher> watchers = new HashMap<>();
@@ -126,10 +110,6 @@ public class EnergyGridCache implements IEnergyGrid
private double lastStoredPower = -1;
private final GridPowerStorage localStorage = new GridPowerStorage();
private Set<IAEPowerStorage> providerToRemove = new HashSet<>();
private Set<IAEPowerStorage> requesterToRemove = new HashSet<>();
private Set<IAEPowerStorage> providersToAdd = new HashSet<>();
private Set<IAEPowerStorage> requesterToAdd = new HashSet<>();
public EnergyGridCache( final IGrid g )
{
@@ -163,32 +143,18 @@ public class EnergyGridCache implements IEnergyGrid
{
if( ev.storage.isAEPublicPowerStorage() )
{
switch ( ev.type )
switch( ev.type )
{
case PROVIDE_POWER:
if( ev.storage.getPowerFlow() != AccessRestriction.WRITE )
{
if( !ongoingExtractOperation )
{
addProvider( ev.storage );
}
else
{
this.providersToAdd.add( ev.storage );
}
this.providers.add( ev.storage );
}
break;
case REQUEST_POWER:
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
{
if( !ongoingInjectOperation )
{
addRequester( ev.storage );
}
else
{
this.requesterToAdd.add( ev.storage );
}
this.requesters.add( ev.storage );
}
break;
}
@@ -335,55 +301,22 @@ public class EnergyGridCache implements IEnergyGrid
{
double extractedPower = 0;
this.providers.addAll( providersToAdd );
providersToAdd.clear();
final Iterator<IAEPowerStorage> it = this.providers.iterator();
ongoingExtractOperation = true;
boolean ls = false;
try
while( extractedPower < amt && it.hasNext() )
{
while ( extractedPower < amt && it.hasNext() )
{
final IAEPowerStorage node = it.next();
final IAEPowerStorage node = it.next();
if( node == localStorage && mode == Actionable.MODULATE )
{
ls = true;
continue;
}
final double req = amt - extractedPower;
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower;
if( newPower < req && mode == Actionable.MODULATE )
{
it.remove();
}
}
} finally
{
ongoingExtractOperation = false;
}
if( ls && extractedPower < amt )
{
final double req = amt - extractedPower;
final double newPower = localStorage.extractAEPower( req, mode, PowerMultiplier.ONE );
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower;
if( newPower < req )
if( newPower < req && mode == Actionable.MODULATE )
{
providers.remove( localStorage );
it.remove();
}
}
providers.removeIf( p -> providerToRemove.contains( p ) );
this.providerToRemove.clear();
final double result = Math.min( extractedPower, amt );
if( mode == Actionable.MODULATE )
@@ -405,33 +338,19 @@ public class EnergyGridCache implements IEnergyGrid
{
final double originalAmount = amt;
this.requesters.addAll( requesterToAdd );
requesterToAdd.clear();
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
ongoingInjectOperation = true;
try
while( amt > 0 && it.hasNext() )
{
while ( amt > 0 && it.hasNext() )
final IAEPowerStorage node = it.next();
amt = node.injectAEPower( amt, mode );
if( amt > 0 && mode == Actionable.MODULATE )
{
final IAEPowerStorage node = it.next();
amt = node.injectAEPower( amt, mode );
if( amt > 0 && mode == Actionable.MODULATE )
{
it.remove();
}
it.remove();
}
} finally
{
ongoingInjectOperation = false;
}
requesters.removeIf( r -> requesterToRemove.contains( r ) );
this.requesterToRemove.clear();
final double overflow = Math.max( 0.0, amt );
if( mode == Actionable.MODULATE )
@@ -448,7 +367,7 @@ public class EnergyGridCache implements IEnergyGrid
double required = 0;
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
while ( required < maxRequired && it.hasNext() )
while( required < maxRequired && it.hasNext() )
{
final IAEPowerStorage node = it.next();
if( node.getPowerFlow() != AccessRestriction.READ )
@@ -509,7 +428,11 @@ public class EnergyGridCache implements IEnergyGrid
@Override
public double getStoredPower()
{
this.refreshPower();
if( this.availableTicksSinceUpdate > 90 )
{
this.refreshPower();
}
return Math.max( 0.0, this.globalAvailablePower );
}
@@ -582,22 +505,9 @@ public class EnergyGridCache implements IEnergyGrid
this.globalMaxPower -= ps.getAEMaxPower();
this.globalAvailablePower -= ps.getAECurrentPower();
}
if( !ongoingExtractOperation )
{
removeProvider( ps );
}
else
{
this.providerToRemove.add( ps );
}
if( !ongoingInjectOperation )
{
removeRequester( ps );
}
else
{
this.requesterToRemove.add( ps );
}
this.providers.remove( ps );
this.requesters.remove( ps );
}
}
@@ -613,31 +523,6 @@ public class EnergyGridCache implements IEnergyGrid
}
}
private void addRequester(IAEPowerStorage requester) {
Preconditions.checkState(!ongoingInjectOperation,
"Cannot modify energy requesters while energy is being injected.");
this.requesters.add(requester);
}
private void removeRequester(IAEPowerStorage requester) {
Preconditions.checkState(!ongoingInjectOperation,
"Cannot modify energy requesters while energy is being injected.");
this.requesters.remove(requester);
}
private void addProvider(IAEPowerStorage provider) {
Preconditions.checkState(!ongoingExtractOperation,
"Cannot modify energy providers while energy is being extracted.");
this.providers.add(provider);
}
private void removeProvider(IAEPowerStorage provider) {
Preconditions.checkState(!ongoingExtractOperation,
"Cannot modify energy providers while energy is being extracted.");
this.providers.remove(provider);
}
@Override
public void addNode( final IGridNode node, final IGridHost machine )
{
@@ -669,26 +554,12 @@ public class EnergyGridCache implements IEnergyGrid
if( current > 0 && ps.getPowerFlow() != AccessRestriction.WRITE )
{
this.globalAvailablePower += current;
if( !ongoingExtractOperation )
{
addProvider( ps );
}
else
{
this.providersToAdd.add( ps );
}
this.providers.add( ps );
}
if( current < max && ps.getPowerFlow() != AccessRestriction.READ )
{
if( !ongoingInjectOperation )
{
addRequester( ps );
}
else
{
this.requesterToAdd.add( ps );
}
this.requesters.add( ps );
}
}
}
@@ -815,4 +686,4 @@ public class EnergyGridCache implements IEnergyGrid
}
}
}
}
}
+4 -14
View File
@@ -101,17 +101,14 @@ public class GridStorageCache implements IStorageGrid
if( machine instanceof IStackWatcherHost )
{
final IStackWatcher myWatcher = this.watchers.get( node );
final IStackWatcher myWatcher = this.watchers.get( machine );
if( myWatcher != null )
{
myWatcher.reset();
this.watchers.remove( node );
this.watchers.remove( machine );
}
}
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
}
@Override
@@ -140,9 +137,6 @@ public class GridStorageCache implements IStorageGrid
this.watchers.put( node, iw );
swh.updateWatcher( iw );
}
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
}
@Override
@@ -254,6 +248,8 @@ public class GridStorageCache implements IStorageGrid
}
}
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
tracker.applyChanges();
}
@@ -285,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 )
{
+87 -95
View File
@@ -19,10 +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;
@@ -31,19 +41,9 @@ 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 com.google.common.collect.Queues;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.Map.Entry;
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
@@ -58,21 +58,19 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
@Nonnull
private final IItemList<T> cachedList;
@Nonnull
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
private final Map<IMEMonitorHandlerReceiver<T>, Object> listeners;
private boolean sendEvent = false;
private boolean forceUpdate = false;
private boolean hasChanged = false;
@Nonnegative
private int localDepthSemaphore = 0;
private long gridItemCount;
private long gridFluidCount;
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
{
this.myGridCache = cache;
this.myChannel = chan;
this.cachedList = chan.createList();
this.listeners = new Object2ObjectOpenHashMap<>();
this.listeners = new HashMap<>();
}
@Override
@@ -90,7 +88,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
@@ -123,57 +135,15 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return this.getHandler().getSlot();
}
public long getGridCurrentCount()
{
if( forceUpdate )
{
getStorageList();
}
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( forceUpdate )
if( hasChanged )
{
forceUpdate = false;
hasChanged = false;
this.cachedList.resetStatus();
this.getAvailableItems( this.cachedList );
long count = 0;
for (T stack : this.cachedList) {
count += stack.getStackSize();
}
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount = count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount = count;
}
return this.getAvailableItems( this.cachedList );
}
return this.cachedList;
@@ -182,7 +152,21 @@ public class NetworkMonitor<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 );
}
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
@@ -214,8 +198,30 @@ 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() )
@@ -233,20 +239,9 @@ 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 )
@@ -256,34 +251,34 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return;
}
this.localDepthSemaphore++;
GLOBAL_DEPTH.push( this );
this.localDepthSemaphore++;
this.sendEvent = true;
for( final T changed : 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.add( 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 );
}
@@ -291,7 +286,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();
@@ -299,8 +294,6 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
}
}
this.notifyListenersOfChange( changes, src );
final NetworkMonitor<?> last = GLOBAL_DEPTH.pop();
this.localDepthSemaphore--;
@@ -312,10 +305,10 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
void forceUpdate()
{
this.forceUpdate = true;
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();
@@ -338,6 +331,5 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
this.sendEvent = false;
this.myGridCache.getGrid().postEvent( new MENetworkStorageEvent( this, this.myChannel ) );
}
}
}
+1 -1
View File
@@ -314,7 +314,7 @@ public class PathGridCache implements IPathingGrid
int depth = 0;
for( final IGridNode nodes : this.requireChannels )
{
if( !this.semiOpen.contains( (IPathItem) nodes ) )
if( !this.semiOpen.contains( nodes ) )
{
final IGridBlock gb = nodes.getGridBlock();
final EnumSet<GridFlags> flags = gb.getFlags();
+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,13 +19,14 @@
package appeng.me.cluster.implementations;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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;
@@ -33,6 +34,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
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;
@@ -90,7 +93,6 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
private final List<TileCraftingTile> storage = new ArrayList<>();
private final List<TileCraftingMonitorTile> status = new ArrayList<>();
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final Map<ICraftingPatternDetails, Queue<ICraftingMedium>> visitedMediums = new HashMap<>();
private ICraftingLink myLastLink;
private String myName = "";
private boolean isDestroyed = false;
@@ -236,9 +238,8 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
public IAEItemStack injectItems( final IAEItemStack input, final Actionable type, final IActionSource src )
{
// 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 instanceof IAEItemStack ) )
{
return input;
}
@@ -296,7 +297,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
is.decStackSize( what.getStackSize() );
this.updateRemainingItemCount( what );
this.updateElapsedTime( what );
this.markDirty();
this.postCraftingStatusChange( what.copy().setStackSize( -what.getStackSize() ) );
@@ -435,11 +436,6 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
AELog.crafting( LOG_MARK_AS_COMPLETE, logStack );
}
// Waiting for can potentially contain items at this point, if the user has a 64xplank->64xbutton processing
// recipe for example, but only requested 1xbutton. We just ignore the rest since it will be dumped
// back into the network inventory regardless. For this to work it's important that injectItems in this CPU
// does not accept any further items if isComplete is true.
this.waitingFor.resetStatus();
this.remainingItemCount = 0;
this.startItemCount = 0;
this.lastTime = 0;
@@ -494,87 +490,22 @@ 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() )
for( IAEItemStack g : condensedInputs )
{
// Processing patterns are relatively easy
for ( IAEItemStack input : condensedInputs )
{
final IAEItemStack ais = this.inventory.extractItems( input.copy(), Actionable.SIMULATE,
this.machineSrc );
if( ais == null || ais.getStackSize() < input.getStackSize() )
{
return false;
}
}
}
else if( details.canSubstitute() )
{
// 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++ )
{
List<IAEItemStack> substitutes = details.getSubstituteInputs( i );
if( substitutes.isEmpty() )
{
continue;
}
boolean found = false;
for ( IAEItemStack substitute : substitutes )
{
for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( substitute, FuzzyMode.IGNORE_ALL ) )
{
int alreadyConsumed = consumedCount.getOrDefault( fuzz, 0 );
if( fuzz.getStackSize() - alreadyConsumed <= 0 )
{
continue; // Already fully consumed by a previous slot of this recipe
}
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 );
if( ais != null && ais.getStackSize() > 0 )
{
// Mark 1 of the stack as consumed
consumedCount.merge( fuzz, 1, Integer::sum );
found = true;
break;
}
}
if( found )
{
break;
}
}
if( !found )
{
return false;
}
}
}
else
{
// 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 )
if( details.isCraftable() )
{
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() );
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE, this.machineSrc );
if( ais != null && ais.getStackSize() >= g.getStackSize() )
if (ais != null && ais.getStackSize() == g.getStackSize())
{
found = true;
break;
@@ -591,7 +522,15 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
return false;
}
}
else
{
final IAEItemStack ais = this.inventory.extractItems( g.copy(), Actionable.SIMULATE, this.machineSrc );
if (ais == null || ais.getStackSize() < g.getStackSize())
{
return false;
}
}
}
return true;
@@ -707,22 +646,14 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
InventoryCrafting ic = null;
if (!visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty())
for( final ICraftingMedium m : cc.getMediums( e.getKey() ) )
{
visitedMediums.put( details, new ArrayDeque<>( cc.getMediums( details ).stream().filter( Objects::nonNull ).collect( Collectors.toList()) ) );
}
while (!visitedMediums.get( details ).isEmpty())
{
ICraftingMedium m = visitedMediums.get( details ).poll();
if( e.getValue().value <= 0 )
{
continue;
}
if( m != null && !m.isBusy() )
if( !m.isBusy() )
{
if( ic == null )
{
@@ -746,67 +677,71 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
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() )
{
itemList = this.inventory.getItemList().findFuzzy( input[x], FuzzyMode.IGNORE_ALL );
}
else
{
itemList = new ArrayList<>( 1 );
for (IAEItemStack stack : substitutes) {
itemList.addAll(this.inventory.getItemList().findFuzzy(stack,
FuzzyMode.IGNORE_ALL));
}
} 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;
}
}
@@ -890,7 +825,6 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
private void storeItems()
{
Preconditions.checkState(isComplete, "CPU should be complete to prevent re-insertion when dumping items");
final IGrid g = this.getGrid();
if( g == null )
@@ -901,24 +835,23 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
final IStorageGrid sg = g.getCache( IStorageGrid.class );
final IMEInventory<IAEItemStack> ii = sg.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
IItemList<IAEItemStack> itemList = this.inventory.getItemList();
for( IAEItemStack is : itemList )
for( IAEItemStack is : this.inventory.getItemList() )
{
this.postChange( is, this.machineSrc );
IAEItemStack remainder = ii.injectItems( is.copy(), Actionable.MODULATE, this.machineSrc );
is = this.inventory.extractItems( is.copy(), Actionable.MODULATE, this.machineSrc );
// The network was unable to receive all of the items, i.e. no or not enough storage space left
if( remainder != null )
if( is != null )
{
is.setStackSize( remainder.getStackSize() );
this.postChange( is, this.machineSrc );
is = ii.injectItems( is, Actionable.MODULATE, this.machineSrc );
}
else
if( is != null )
{
is.reset();
this.inventory.injectItems( is, Actionable.MODULATE, this.machineSrc );
}
}
if( itemList.isEmpty() )
if( this.inventory.getItemList().isEmpty() )
{
this.inventory = new MECraftingInventory();
}
@@ -1003,13 +936,14 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
@Override
public boolean isBusy()
{
final Iterator<Entry<ICraftingPatternDetails, TaskProgress>> i = this.tasks.entrySet().iterator();
this.tasks.entrySet().removeIf(
taskProgressEntry -> taskProgressEntry.getValue().value <= 0 );
if( !this.waitingFor.isEmpty() || !this.tasks.isEmpty() )
while( i.hasNext() )
{
this.updateElapsedTime();
if( i.next().getValue().value <= 0 )
{
i.remove();
}
}
return !this.tasks.isEmpty() || !this.waitingFor.isEmpty();
@@ -1401,16 +1335,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
this.remainingItemCount = itemCount;
}
private void updateRemainingItemCount( final IAEItemStack is )
{
this.remainingItemCount = this.getRemainingItemCount() - is.getStackSize();
}
private void updateElapsedTime()
private void updateElapsedTime( final IAEItemStack is )
{
final long nextStartTime = System.nanoTime();
this.elapsedTime = this.getElapsedTime() + nextStartTime - this.lastTime;
this.lastTime = nextStartTime;
this.remainingItemCount = this.getRemainingItemCount() - is.getStackSize();
}
public long getElapsedTime()
@@ -23,11 +23,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import appeng.api.config.FuzzyMode;
import appeng.api.storage.data.IAEStack;
import appeng.util.item.AEItemStack;
import com.google.common.collect.Multimap;
import appeng.api.storage.data.IAEStack;
public class GenericInterestManager<T>
{
@@ -102,30 +101,12 @@ public class GenericInterestManager<T>
public boolean containsKey( final IAEStack stack )
{
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
{
return this.container.keySet().stream().filter( s -> s.isItem() )
.anyMatch( s -> s.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) );
}
return this.container.containsKey( stack );
}
public Collection<T> get( final IAEStack stack )
{
Collection<T> watchers = new ArrayList<>();
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
{
this.container.keySet().stream().filter( s -> s.isItem() )
.filter( k -> k.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
.forEach( key ->
watchers.addAll( this.container.get( key ) )
);
}
else
{
return this.container.get( stack );
}
return watchers;
return this.container.get( stack );
}
private class SavedTransactions
@@ -151,7 +151,7 @@ public abstract class AbstractCellInventory<T extends IAEStack<T>> implements IC
}
// clean any old crusty stuff...
for( ; x >= oldStoredItems && x < this.maxItemTypes; x++ )
for( ; x < oldStoredItems && x < this.maxItemTypes; x++ )
{
this.tagCompound.removeTag( ITEM_SLOT_KEYS[x] );
this.tagCompound.removeTag( ITEM_SLOT_COUNT_KEYS[x] );
@@ -277,7 +277,6 @@ public class BasicCellInventory<T extends IAEStack<T>> extends AbstractCellInven
}
t.setStackSize( stackSize );
t.setCraftable( false );
if( stackSize > 0 )
{
@@ -19,10 +19,6 @@
package appeng.me.storage;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.tile.storage.TileDrive;
import com.google.common.collect.ImmutableList;
import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable;
@@ -40,7 +36,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
private final ItemStack is;
private final ICellHandler handler;
private final IChestOrDrive cord;
private IActionSource source;
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final IChestOrDrive cod )
{
@@ -48,7 +43,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
this.is = is;
this.handler = han;
this.cord = cod;
this.source = new MachineSource( cod );
}
public int getStatus()
@@ -72,14 +66,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
this.cord.blinkCell( this.getSlot() );
this.oldStatus = newStatus;
}
try
{
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( input.copy().setStackSize( input.getStackSize() - ( a == null ? 0 : a.getStackSize() ) ) ), this.source );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
return a;
@@ -99,15 +85,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
this.cord.blinkCell( this.getSlot() );
this.oldStatus = newStatus;
}
try
{
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( request.copy().setStackSize( -a.getStackSize() ) ), this.source );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
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()
@@ -72,7 +72,7 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
final IItemList<T> after = this.getInternal() == null ? this.getWrappedChannel().createList() : this.getInternal()
.getAvailableItems( new ItemListIgnoreCrafting( this.getWrappedChannel().createList() ) );
if( this.monitor != null && this.listeners.size() > 0 )
if( this.monitor != null )
{
this.monitor.addListener( this, this.monitor );
}
@@ -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 );
}
@@ -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;
}
@@ -180,10 +180,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
}
else
{
if( inv.getStorageList().findPrecise( ais ) != null )
{
this.pushItemIntoTarget( destination, energy, inv, ais );
}
this.pushItemIntoTarget( destination, energy, inv, ais );
}
if( this.itemToSend == before && this.isCraftingEnabled() )
@@ -206,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 );
@@ -218,12 +218,6 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
private boolean importStuff( final InventoryAdaptor myAdaptor, final IAEItemStack whatToImport, final IMEMonitor<IAEItemStack> inv, final IEnergySource energy, final FuzzyMode fzMode )
{
final int toSend = this.calculateMaximumAmountToImport( myAdaptor, whatToImport, inv, fzMode );
if( toSend == 0 )
{
return true;
}
final ItemStack newItems;
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
@@ -283,26 +277,17 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
final ItemStack simResult;
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, null );
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, this );
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
}
else
{
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, null );
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, this );
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
}
if( simResult.isEmpty() )
{
return 0;
}
if( itemAmountNotStorable != null )
{
if( simResult.getCount() == itemAmountNotStorable.getStackSize() )
{
return 0;
}
return (int) Math.min( simResult.getCount() - itemAmountNotStorable.getStackSize(), toSend );
}
@@ -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,23 +206,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
return flipState ? this.reportingValue >= this.lastReportedValue + 1 : this.reportingValue < this.lastReportedValue + 1;
}
@MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange powerEvent )
{
if (this.getProxy().isActive())
{
onListUpdate();
}
this.updateState();
}
@MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c )
{
if (this.getProxy().isActive())
{
onListUpdate();
}
this.updateState();
}
@@ -288,37 +296,24 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
try
{
if( myStack == null )
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 || myStack == null )
{
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).addListener( this, this.getProxy().getGrid() );
this.getProxy()
.getStorage()
.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
.addListener( this,
this.getProxy().getGrid() );
}
else
{
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).removeListener( this );
if( this.myWatcher != null )
{
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
Optional<OreReference> ores = OreHelper.INSTANCE.getOre( myStack.getDefinition() );
if( ores.isPresent() )
{
for( IAEItemStack iaeItemStack : ores.get().getAEEquivalents() )
{
this.myWatcher.add( iaeItemStack );
}
}
else
{
this.myWatcher.add( myStack );
}
}
else
{
this.myWatcher.add( myStack );
}
this.myWatcher.add( myStack );
}
}
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
catch( final GridAccessException e )
@@ -328,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();
}
@@ -363,23 +419,12 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
}
@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 )
{
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this
.getInstalledUpgrades( Upgrades.FUZZY ) == 0 )
{
IAEItemStack myStack = this.config.getAEStackInSlot( 0 );
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
if( Platform.itemComparisons().isFuzzyEqualItem( myStack.getDefinition(), ( (IAEItemStack) diffStack ).getDefinition(), fzMode ) )
{
this.lastReportedValue += diffStack.getStackSize();
}
}
else if( diffStack.equals( myStack ) )
{
this.lastReportedValue += diffStack.getStackSize();
}
this.lastReportedValue = fullStack.getStackSize();
this.updateState();
}
}
@@ -414,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
@@ -507,7 +552,6 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
public void upgradesChanged()
{
this.configureWatchers();
this.updateState();
}
@Override
@@ -592,4 +636,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
}
}
public static void wipeCache(){
fuzzyAEItemStackCount.clear();
preciseAEItemStackCount.clear();
gridItemCount.clear();
}
}
@@ -19,20 +19,10 @@
package appeng.parts.automation;
import javax.annotation.Nonnull;
import appeng.api.AEApi;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.Api;
import appeng.helpers.DualityInterface;
import appeng.util.inv.ItemHandlerIterator;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Items;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import appeng.api.config.Upgrades;
@@ -43,9 +33,6 @@ import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.InvOperation;
import appeng.util.inv.filter.IAEItemFilter;
import java.util.ArrayList;
import java.util.List;
public abstract class UpgradeInventory extends AppEngInternalInventory implements IAEAppEngInventory
{
@@ -58,7 +45,6 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
private int capacityUpgrades = 0;
private int inverterUpgrades = 0;
private int craftingUpgrades = 0;
private int patternExpansionUpgrades = 0;
public UpgradeInventory( final IAEAppEngInventory parent, final int s )
{
@@ -95,8 +81,6 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
return this.inverterUpgrades;
case CRAFTING:
return this.craftingUpgrades;
case PATTERN_EXPANSION:
return this.patternExpansionUpgrades;
default:
return 0;
}
@@ -107,7 +91,7 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
private void updateUpgradeInfo()
{
this.cached = true;
this.patternExpansionUpgrades = this.inverterUpgrades = this.capacityUpgrades = this.redstoneUpgrades = this.speedUpgrades = this.fuzzyUpgrades = this.craftingUpgrades = 0;
this.inverterUpgrades = this.capacityUpgrades = this.redstoneUpgrades = this.speedUpgrades = this.fuzzyUpgrades = this.craftingUpgrades = 0;
for( final ItemStack is : this )
{
@@ -137,9 +121,6 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
case CRAFTING:
this.craftingUpgrades++;
break;
case PATTERN_EXPANSION:
this.patternExpansionUpgrades++;
break;
default:
break;
}
@@ -151,7 +132,6 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
this.speedUpgrades = Math.min( this.speedUpgrades, this.getMaxInstalled( Upgrades.SPEED ) );
this.inverterUpgrades = Math.min( this.inverterUpgrades, this.getMaxInstalled( Upgrades.INVERTER ) );
this.craftingUpgrades = Math.min( this.craftingUpgrades, this.getMaxInstalled( Upgrades.CRAFTING ) );
this.patternExpansionUpgrades = Math.min( this.patternExpansionUpgrades, this.getMaxInstalled( Upgrades.PATTERN_EXPANSION ) );
}
@Override
@@ -180,13 +160,6 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
}
}
@Nonnull
@Override
public ItemStack extractItem( int slot, int amount, boolean simulate )
{
return super.extractItem( slot, amount, simulate );
}
private class UpgradeInvFilter implements IAEItemFilter
{
@@ -19,12 +19,20 @@
package appeng.parts.misc;
import javax.annotation.Nullable;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
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.Settings;
import appeng.api.config.StorageFilter;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.ticking.TickRateModulation;
@@ -37,16 +45,8 @@ import appeng.core.AELog;
import appeng.me.GridAccessException;
import appeng.me.helpers.IGridProxyable;
import appeng.me.storage.ITickingMonitor;
import appeng.util.inv.ItemHandlerIterator;
import appeng.util.inv.ItemSlot;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import com.google.common.primitives.Ints;
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 java.util.*;
/**
@@ -54,15 +54,12 @@ import java.util.*;
*/
class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
{
private final Object2ObjectMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new Object2ObjectOpenHashMap<>();
private final Map<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private IActionSource mySource;
private final IItemHandler itemHandler;
private final IGridProxyable proxyable;
private final InventoryCache cache;
private StorageFilter mode;
private AccessRestriction access;
private ItemStack stackCache = null;
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
{
@@ -72,45 +69,23 @@ 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
@Nullable ItemStack currentCached = stackCache;
stackCache = null;
ItemStack orgInput;
int slotCount = this.itemHandler.getSlots();
if( currentCached != null && iox.isSameType( currentCached ) )
{
// Cache is suitable, just update the count
orgInput = currentCached;
currentCached.setCount( Ints.saturatedCast( iox.getStackSize() ) );
}
else
{
// We need a new stack :-(
orgInput = iox.createItemStack();
}
ItemStack orgInput = iox.createItemStack();
ItemStack remaining = orgInput;
int slotCount = this.itemHandler.getSlots();
boolean simulate = ( type == Actionable.SIMULATE );
// This uses a brute force approach and tries to jam it in every slot the inventory exposes.
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
{
remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE );
}
// Store the stack in the cache for next time.
if( !remaining.isEmpty() && remaining != orgInput )
{
stackCache = remaining;
remaining = this.itemHandler.insertItem( i, remaining, simulate );
}
// At this point, we still have some items left...
@@ -122,9 +97,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() );
@@ -141,17 +113,20 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
int remainingSize = Ints.saturatedCast( request.getStackSize() );
ItemStack requestedItemStack = request.createItemStack();
int remainingSize = requestedItemStack.getCount();
// 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++ )
for( int i = 0; i < this.itemHandler.getSlots(); i++ )
{
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
if( !request.isSameType( stackInInventorySlot ) )
if( !Platform.itemComparisons().isSameItem( stackInInventorySlot, requestedItemStack ) )
{
continue;
}
@@ -165,9 +140,16 @@ 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...
@@ -177,12 +159,17 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
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.
// Heuristic for simulation: looping in case of simulations is pointless, since the state of the
// underlying inventory does not change after a simulated extraction. To still support inventories
// that report stacks that are larger than maxStackSize, we use this heuristic
if (simulate && extracted.getCount() == extracted.getMaxStackSize()
&& remainingCurrentSlot > extracted.getMaxStackSize()) {
extracted.setCount(remainingCurrentSlot);
}
if( gathered.isEmpty() )
{
gathered = extracted.copy();
gathered = extracted;
}
else
{
@@ -190,7 +177,8 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
}
remainingCurrentSlot -= extracted.getCount();
}
} while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
}
while( !simulate && !extracted.isEmpty() && remainingCurrentSlot > 0 );
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
@@ -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;
@@ -276,7 +257,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private void postDifference( Iterable<IAEItemStack> a )
{
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
while ( i.hasNext() )
while( i.hasNext() )
{
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
@@ -291,11 +272,11 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
}
}
private static class InventoryCache implements Iterable<ItemSlot>
private static class InventoryCache
{
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,58 +286,106 @@ 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;
}
private StorageFilter getMode()
{
return this.mode;
}
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();
for( final ItemSlot is : this )
// Make room for new slots
if( slots > this.cachedAeStacks.length )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
}
for( int slot = 0; slot < slots; slot++ )
{
// Save the old stuff
final IAEItemStack oldAeIS = this.cachedAeStacks[slot];
ItemStack newIS = this.itemHandler.getStackInSlot( slot );
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !newIS.isEmpty() )
{
continue;
if( this.itemHandler.extractItem( slot, 1, true ).isEmpty() )
{
newIS = ItemStack.EMPTY;
}
}
currentlyOnStorage.add( is.getAEItemStack() );
this.handlePossibleSlotChanges( slot, oldAeIS, newIS, changes );
}
for ( final IAEItemStack 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 IAEItemStack is : currentlyOnStorage )
{
currentlyCached.add( is );
}
for ( final IAEItemStack is : currentlyCached )
{
if( is.getStackSize() != 0 )
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
{
changes.add( is );
}
}
final IAEItemStack aeStack = this.cachedAeStacks[slot];
currentlyCached = currentlyOnStorage;
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, slots );
}
return changes;
}
@Override
public Iterator<ItemSlot> iterator()
private void handlePossibleSlotChanges( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
{
return new ItemHandlerIterator( this.itemHandler );
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] );
}
}
}
}
@@ -1,32 +1,37 @@
package appeng.parts.misc;
import javax.annotation.Nullable;
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 java.util.function.Predicate;
import java.util.stream.Collectors;
import appeng.api.storage.IStorageChannel;
import appeng.core.AELog;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
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;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEMonitorHandlerReceiver;
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.AELog;
import appeng.me.GridAccessException;
import appeng.me.helpers.IGridProxyable;
import appeng.me.storage.ITickingMonitor;
import appeng.util.item.AEItemStack;
import com.google.common.primitives.Ints;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.item.ItemStack;
import java.util.*;
import javax.annotation.Nonnull;
/**
* Wraps an Item Repository in such a way that it can be used as an IMEInventory for items.
@@ -35,54 +40,29 @@ import java.util.*;
class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
{
private final Object2ObjectMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new Object2ObjectOpenHashMap<>();
private final Map<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private IActionSource mySource;
private final IItemRepository itemRepository;
private final IGridProxyable proxyable;
private final InventoryCache cache;
private AccessRestriction access;
private ItemStack stackCache;
ItemRepositoryAdapter( IItemRepository itemRepository, IGridProxyable proxy )
{
this.itemRepository = itemRepository;
this.proxyable = proxy;
this.cache = new InventoryCache( this.itemRepository );
if( this.proxyable instanceof PartStorageBus )
{
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
}
this.cache.update();
}
@Override
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{
// Try to reuse the cached stack
@Nullable ItemStack currentCached = stackCache;
stackCache = null;
ItemStack orgInput = iox.createItemStack();
ItemStack remaining = orgInput;
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 );
boolean simulate = ( type == Actionable.SIMULATE );
// Store the stack in the cache for next time.
if( !remaining.isEmpty() && remaining != orgInput )
{
stackCache = remaining;
}
remaining = this.itemRepository.insertItem( remaining, simulate );
// At this point, we still have some items left...
if( remaining == orgInput )
@@ -93,9 +73,6 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
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() );
@@ -113,11 +90,13 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
int remainingSize = Ints.saturatedCast( request.getStackSize() );
ItemStack requestedItemStack = request.createItemStack();
int remainingSize = requestedItemStack.getCount();
final boolean simulate = ( mode == Actionable.SIMULATE );
ItemStack extracted = this.itemRepository.extractItem( request.getDefinition(), remainingSize, simulate );
ItemStack extracted;
extracted = this.itemRepository.extractItem( requestedItemStack, remainingSize, simulate );
if( extracted.getCount() > remainingSize )
{
@@ -130,15 +109,8 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
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() );
@@ -148,8 +120,10 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
// meh
}
}
return extractedAEItemStack;
return AEItemStack.fromItemStack( extracted );
}
return null;
}
@@ -180,7 +154,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
private void postDifference( Iterable<IAEItemStack> a )
{
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
while ( i.hasNext() )
while( i.hasNext() )
{
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
@@ -198,15 +172,17 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
@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;
List<IAEItemStack> changes = this.cache.update();
if( !changes.isEmpty() )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
}
else
{
return TickRateModulation.SLOWER;
}
}
}
@@ -218,7 +194,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
private static class InventoryCache
{
private IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
private final IItemRepository iItemRepository;
public InventoryCache( IItemRepository iItemRepository )
@@ -228,7 +204,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
{
currentlyCached.iterator().forEachRemaining( out::add );
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
return out;
}
@@ -236,31 +212,94 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
{
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 )
final int size = out.size();
// Make room for new slots
if( size > this.cachedAeStacks.length )
{
is.setStackSize( -is.getStackSize() );
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, size );
}
for ( final IAEItemStack is : currentlyOnStorage )
for( int x = 0; x < size; x++ )
{
currentlyCached.add( is );
// Save the old stuff
final IAEItemStack oldAeIS = this.cachedAeStacks[x];
final IAEItemStack newIS = out.get( x );
this.handlePossibleSlotChanges( x, oldAeIS, newIS, changes );
}
for ( final IAEItemStack is : currentlyCached )
// Handle cases where the number of slots actually is lower now than before
if( size < this.cachedAeStacks.length )
{
if( is.getStackSize() != 0 )
for( int x = 0; x < this.cachedAeStacks.length; x++ )
{
changes.add( is );
}
}
final IAEItemStack aeStack = this.cachedAeStacks[x];
currentlyCached = currentlyOnStorage;
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] );
}
}
}
}
@@ -22,14 +22,8 @@ package appeng.parts.misc;
import java.util.Collections;
import java.util.List;
import appeng.api.config.AccessRestriction;
import appeng.fluids.parts.PartFluidInterface;
import appeng.fluids.tile.TileFluidInterface;
import appeng.tile.misc.TileInterface;
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;
@@ -61,7 +55,6 @@ public abstract class PartSharedStorageBus extends PartUpgradeable implements IG
{
private boolean wasActive = false;
private int priority = 0;
protected boolean accessChanged;
public PartSharedStorageBus( ItemStack is )
{
@@ -153,10 +146,6 @@ public abstract class PartSharedStorageBus extends PartUpgradeable implements IG
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( settingName instanceof AccessRestriction )
{
this.accessChanged = true;
}
this.resetCache( true );
this.getHost().markForSave();
}
@@ -166,27 +155,7 @@ public abstract class PartSharedStorageBus extends PartUpgradeable implements IG
{
if( pos.offset( this.getSide().getFacing() ).equals( 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 );
}
this.resetCache( false );
}
}
@@ -23,12 +23,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import appeng.fluids.parts.FluidHandlerAdapter;
import appeng.me.storage.MEPassThrough;
import appeng.parts.AEBasePart;
import appeng.tile.misc.TileInterface;
import appeng.tile.networking.TileCableBus;
import appeng.util.ConfigManager;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@@ -127,7 +121,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
private int handlerHash = 0;
private boolean wasActive = false;
private byte resetCacheLogic = 0;
private boolean accessChanged;
@Reflected
public PartStorageBus( final ItemStack is )
@@ -179,10 +172,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( settingName instanceof AccessRestriction )
{
this.accessChanged = true;
}
this.resetCache( true );
this.getHost().markForSave();
}
@@ -245,7 +234,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
{
this.resetCacheLogic = 2;
}
else if( this.resetCacheLogic < 2 )
else
{
this.resetCacheLogic = 1;
}
@@ -269,19 +258,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.mySrc.machine().map( machine -> machine == this ).orElse( false ) && monitor != null )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
if( !currentAccess.hasPermission( AccessRestriction.READ ) )
{
return;
}
}
try
{
if( this.getProxy().isActive() )
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, this.mySrc );
this.getProxy()
.getStorage()
.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change,
this.mySrc );
}
}
catch( final GridAccessException e )
@@ -309,19 +293,10 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
{
if( pos.offset( this.getSide().getFacing() ).equals( 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 PartInterface )
{
this.resetCache( true );
this.resetCache();
}
}
if( te == null || te instanceof TileInterface )
if( te == null )
{
this.resetCache( true );
this.resetCache();
@@ -376,28 +351,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();
boolean denyRead = false;
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 ) )
{
denyRead = 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;
@@ -406,19 +364,16 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
this.handlerHash = 0;
}
final MEInventoryHandler<IAEItemStack> out = this.getInternalHandler();
final IMEInventory<IAEItemStack> out = this.getInternalHandler();
if( in != out || denyRead )
if( in != out )
{
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
if( out != null && !denyRead )
if( out != null )
{
after = out.getAvailableItems( after );
}
Platform.postListChanges( before, after, this, this.mySrc );
}
}
@@ -446,13 +401,10 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
// Check via cap for IItemRepository
if (ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ))
IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide );
if( handlerRepo != null )
{
IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide );
if( handlerRepo != null )
{
return new ItemRepositoryAdapter( handlerRepo, this );
}
return new ItemRepositoryAdapter( handlerRepo, this );
}
// Check via cap for IItemHandler
IItemHandler handlerExt = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide );
@@ -479,6 +431,13 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
return Objects.hash( target, target.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide ) );
}
final IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide );
if( handlerRepo != null )
{
return Objects.hash( target, handlerRepo, handlerRepo.getAllItems().size() );
}
final IItemHandler itemHandler = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide );
if( itemHandler != null )
@@ -510,15 +469,17 @@ 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;
@@ -631,7 +592,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
{
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 );
@@ -19,12 +19,11 @@
package appeng.parts.p2p;
import java.util.*;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.me.cache.helpers.TunnelCollection;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.capabilities.Capability;
@@ -43,7 +42,6 @@ public class PartP2PFEPower extends PartP2PTunnel<PartP2PFEPower>
private static final IEnergyStorage NULL_ENERGY_STORAGE = new NullEnergyStorage();
private final IEnergyStorage inputHandler = new InputEnergyStorage();
private final IEnergyStorage outputHandler = new OutputEnergyStorage();
private final Queue<PartP2PFEPower> outputs = new ArrayDeque<>();
public PartP2PFEPower( ItemStack is )
{
@@ -110,8 +108,6 @@ public class PartP2PFEPower extends PartP2PTunnel<PartP2PFEPower>
private class InputEnergyStorage implements IEnergyStorage
{
private boolean iteratingOutputs;
@Override
public int extractEnergy( int maxExtract, boolean simulate )
{
@@ -135,14 +131,8 @@ public class PartP2PFEPower extends PartP2PTunnel<PartP2PFEPower>
final int amountPerOutput = maxReceive / outputTunnels;
int overflow = amountPerOutput == 0 ? maxReceive : maxReceive % amountPerOutput;
if (outputs.isEmpty())
for( PartP2PFEPower target : PartP2PFEPower.this.getOutputs() )
{
for ( PartP2PFEPower o : PartP2PFEPower.this.getOutputs())
outputs.add( o );
}
while ( !outputs.isEmpty() ) {
PartP2PFEPower target = outputs.poll();
final IEnergyStorage output = target.getAttachedEnergyStorage();
final int toSend = amountPerOutput + overflow;
final int received = output.receiveEnergy( toSend, simulate );
@@ -350,25 +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 );
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.onTunnelNetworkChange();
newTunnel.getProxy().getP2P().updateFreq( newTunnel, newFreq );
}
}
else
{
this.getProxy().getP2P().updateFreq( this, newFreq );
}
this.getProxy().getP2P().updateFreq( this, newFreq );
}
catch( final GridAccessException e )
{
@@ -381,17 +365,10 @@ 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[]{
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(),
};
@@ -21,14 +21,6 @@ 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 io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.GlStateManager;
@@ -39,14 +31,12 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fml.relauncher.Side;
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 +45,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;
@@ -79,10 +70,7 @@ import appeng.util.item.AEItemStack;
public abstract class AbstractPartMonitor extends AbstractPartDisplay implements IPartStorageMonitor, IStackWatcherHost
{
private static final IWideReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
private IAEItemStack configuredItem;
private IAEFluidStack configuredFluid;
private long configuredAmount;
private String lastHumanReadableText;
private boolean isLocked;
private IStackWatcher myWatcher;
@@ -102,9 +90,6 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
final NBTTagCompound myItem = data.getCompoundTag( "configuredItem" );
this.configuredItem = AEItemStack.fromNBT( myItem );
final NBTTagCompound myFluid = data.getCompoundTag( "configuredFluid" );
this.configuredFluid = AEFluidStack.fromNBT( myFluid );
}
@Override
@@ -119,15 +104,8 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
{
this.configuredItem.writeToNBT( myItem );
}
final NBTTagCompound myFluid = new NBTTagCompound();
if( this.configuredFluid != null )
{
this.configuredFluid.writeToNBT( myFluid );
}
data.setTag( "configuredItem", myItem );
data.setTag( "configuredFluid", myFluid );
}
@Override
@@ -136,17 +114,11 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
super.writeToStream( data );
data.writeBoolean( this.isLocked );
//is configured
data.writeBoolean( this.configuredItem != null);
data.writeBoolean( this.configuredFluid != null);
data.writeBoolean( this.configuredItem != null );
if( this.configuredItem != null )
{
this.configuredItem.writeToPacket( data );
}
else if( this.configuredFluid != null )
{
this.configuredFluid.writeToPacket( data );
}
}
@Override
@@ -159,22 +131,14 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
this.isLocked = isLocked;
final boolean isItem = data.readBoolean();
final boolean isFluid = data.readBoolean();
if( isItem )
final boolean val = data.readBoolean();
if( val )
{
this.configuredItem = AEItemStack.fromPacket( data );
this.configuredFluid = null;
}
else if( isFluid )
{
this.configuredFluid = AEFluidStack.fromPacket( data );
this.configuredItem = null;
}
else
{
this.configuredItem = null;
this.configuredFluid = null;
}
return needRedraw;
@@ -201,32 +165,7 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
if( !this.isLocked )
{
final ItemStack eq = player.getHeldItem( hand );
FluidStack fluidInTank = null;
if( eq.hasCapability( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null ) )
{
IFluidHandlerItem fluidHandlerItem = ( eq.getCapability( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null ) );
fluidInTank = fluidHandlerItem.drain( Integer.MAX_VALUE, false );
}
if( fluidInTank == null )
{
this.configuredFluid = null;
if( !eq.isEmpty() )
{
this.configuredItem = AEItemStack.fromItemStack( eq ).setStackSize( 0 );
}
else
{
this.configuredItem = null;
}
}
else if( fluidInTank.amount > 0 )
{
this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank ).setStackSize( 0 );
this.configuredItem = null;
}
this.configuredItem = AEItemStack.fromItemStack( eq );
this.configureWatchers();
this.getHost().markForSave();
this.getHost().markForUpdate();
@@ -288,16 +227,6 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
this.updateReportingValue(
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
else if ( this.configuredFluid != null )
{
if( this.myWatcher != null )
{
this.myWatcher.add( this.configuredFluid );
}
this.updateReportingValue(
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
}
}
catch( final GridAccessException e )
{
@@ -305,33 +234,19 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
}
}
private <T extends IAEStack<T>> void updateReportingValue ( final IMEMonitor<T> monitor )
private void updateReportingValue( final IMEMonitor<IAEItemStack> itemInventory )
{
if( this.configuredItem != null)
if( this.configuredItem != null )
{
final IAEItemStack result = (IAEItemStack) monitor.getStorageList().findPrecise( (T) this.configuredItem );
final IAEItemStack result = itemInventory.getStorageList().findPrecise( 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;
}
else
{
this.configuredAmount = result.getStackSize();
}
this.configuredFluid.setStackSize( this.configuredAmount );
}
}
@@ -345,7 +260,7 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
return;
}
IAEStack<?> ais = this.getDisplayed();
final IAEItemStack ais = this.getDisplayed();
if( ais == null )
{
@@ -359,10 +274,8 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
TesrRenderHelper.moveToFace( facing );
TesrRenderHelper.rotateToFace( facing, this.getSpin() );
if (ais instanceof IAEItemStack)
TesrRenderHelper.renderItem2dWithAmount( (IAEItemStack) ais, 0.8f, 0.17f );
if (ais instanceof IAEFluidStack)
TesrRenderHelper.renderFluid2dWithAmount( (IAEFluidStack) ais, 0.8f, 0.17f );
TesrRenderHelper.renderItem2dWithAmount( ais, 0.8f, 0.17f );
GlStateManager.popMatrix();
}
@@ -374,13 +287,9 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
}
@Override
public IAEStack<?> getDisplayed()
public IAEItemStack getDisplayed()
{
if (this.configuredItem != null)
return this.configuredItem;
else if (this.configuredFluid != null)
return this.configuredFluid;
return null;
}
@Override
@@ -396,38 +305,29 @@ 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 = this.configuredAmount + diffStack.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 );
}
this.getHost().markForUpdate();
}
@Override
@@ -19,31 +19,15 @@
package appeng.parts.reporting;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import appeng.api.config.Actionable;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEStack;
import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.fluids.util.AEFluidStack;
import appeng.helpers.InventoryAction;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
@@ -108,13 +92,6 @@ public class PartConversionMonitor extends AbstractPartMonitor
}
final ItemStack eq = player.getHeldItem( hand );
FluidStack fluidInTank = null;
if( eq.hasCapability( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null ) )
{
IFluidHandlerItem fluidHandlerItem = ( eq.getCapability( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null ) );
fluidInTank = fluidHandlerItem.drain( Integer.MAX_VALUE, false );
}
if( this.isLocked() )
{
if( eq.isEmpty() )
@@ -126,41 +103,21 @@ public class PartConversionMonitor extends AbstractPartMonitor
// wrench it
return super.onPartActivate( player, hand, pos );
}
else if( fluidInTank != null && fluidInTank.amount > 0 )
{
if( this.getDisplayed() != null && getDisplayed().equals( AEFluidStack.fromFluidStack( fluidInTank ) ) )
{
this.drainFluidContainer( player, hand );
}
}
else
{
this.insertItem( player, hand, false );
}
}
//If its a fluid container, grab its fluidstack. if its empty pass its itemstack;
if( fluidInTank != null && fluidInTank.amount > 0 )
{
if( getDisplayed() instanceof IAEItemStack || getDisplayed() == null )
{
return super.onPartActivate( player, hand, pos );
}
if( ( (IAEFluidStack) this.getDisplayed() ).equals( AEFluidStack.fromFluidStack( fluidInTank ) ) )
{
this.drainFluidContainer( player, hand );
}
else
{
return super.onPartActivate( player, hand, pos );
}
}
else if( this.getDisplayed() != null && this.getDisplayed().equals( player.getHeldItem( hand ) ) )
else if( this.getDisplayed() != null && this.getDisplayed().equals( eq ) )
{
this.insertItem( player, hand, false );
}
return super.onPartActivate( player, hand, pos );
else
{
return super.onPartActivate( player, hand, pos );
}
return true;
}
@Override
@@ -181,13 +138,9 @@ public class PartConversionMonitor extends AbstractPartMonitor
return false;
}
if( this.getDisplayed() != null && this.getDisplayed() instanceof IAEItemStack )
if( this.getDisplayed() != null )
{
this.extractItem( player, ( (IAEItemStack) this.getDisplayed() ).getDefinition().getMaxStackSize() );
}
else if( this.getDisplayed() != null && this.getDisplayed() instanceof IAEFluidStack )
{
this.fillFluidContainer( player,hand );
this.extractItem( player, this.getDisplayed().getDefinition().getMaxStackSize() );
}
return true;
@@ -230,9 +183,9 @@ public class PartConversionMonitor extends AbstractPartMonitor
if( allItems )
{
if( this.getDisplayed() != null && this.getDisplayed() instanceof IAEItemStack)
if( this.getDisplayed() != null )
{
final IAEItemStack input = (IAEItemStack) this.getDisplayed().copy();
final IAEItemStack input = this.getDisplayed().copy();
IItemHandler inv = new PlayerMainInvWrapper( player.inventory );
for( int x = 0; x < inv.getSlots(); x++ )
@@ -268,9 +221,7 @@ public class PartConversionMonitor extends AbstractPartMonitor
private void extractItem( final EntityPlayer player, int count )
{
if (!(this.getDisplayed() instanceof IAEItemStack))
return;
final IAEItemStack input = (IAEItemStack) this.getDisplayed().copy();
final IAEItemStack input = this.getDisplayed();
if( input != null )
{
try
@@ -314,141 +265,6 @@ public class PartConversionMonitor extends AbstractPartMonitor
}
}
private void drainFluidContainer( final EntityPlayer player, final EnumHand hand ) {
try
{
final ItemStack held = player.getHeldItem( hand );
if( held.getCount() != 1 )
{
// only support stacksize 1 for now
return;
}
final IFluidHandlerItem fh = FluidUtil.getFluidHandler( held );
if( fh == null )
{
// only fluid handlers items
return;
}
// See how much we can drain from the item
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
if( extract == null || extract.amount < 1 )
{
return;
}
// Check if we can push into the system
final IEnergySource energy = this.getProxy().getEnergy();
final IMEMonitor<IAEFluidStack> cell = this.getProxy()
.getStorage()
.getInventory(
AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
final IAEFluidStack notStorable = Platform.poweredInsert( energy, cell, AEFluidStack.fromFluidStack( extract ), new PlayerSource( player, this ), Actionable.SIMULATE );
if( notStorable != null && notStorable.getStackSize() > 0 )
{
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
final FluidStack storable = fh.drain( toStore, false );
if( storable == null || storable.amount == 0 )
{
return;
}
else
{
extract.amount = storable.amount;
}
}
// Actually drain
final FluidStack drained = fh.drain( extract, true );
extract.amount = drained.amount;
final IAEFluidStack notInserted = Platform.poweredInsert( energy, cell, AEFluidStack.fromFluidStack( extract ), new PlayerSource( player, this ) );
if( notInserted != null && notInserted.getStackSize() > 0 )
{
AELog.error( "Fluid item [%s] reported a different possible amount to drain than it actually provided.", held.getDisplayName() );
}
player.setHeldItem( hand, fh.getContainer() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
private void fillFluidContainer( final EntityPlayer player, final EnumHand hand )
{
try
{
final ItemStack held = player.getHeldItem( hand );
if( held.getCount() != 1 )
{
// only support stacksize 1 for now
return;
}
final IFluidHandlerItem fh = FluidUtil.getFluidHandler( held );
if( fh == null )
{
// only fluid handlers items
return;
}
final IAEFluidStack stack = (IAEFluidStack) this.getDisplayed().copy();
// Check how much we can store in the item
stack.setStackSize( Integer.MAX_VALUE );
int amountAllowed = fh.fill( stack.getFluidStack(), false );
stack.setStackSize( amountAllowed );
// Check if we can pull out of the system
final IEnergySource energy = this.getProxy().getEnergy();
final IMEMonitor<IAEFluidStack> cell = this.getProxy()
.getStorage()
.getInventory(
AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
final IAEFluidStack canPull = Platform.poweredExtraction( energy, cell, stack, new PlayerSource( player, this ), Actionable.SIMULATE );
if( canPull == null || canPull.getStackSize() < 1 )
{
return;
}
// How much could fit into the container
final int canFill = fh.fill( canPull.getFluidStack(), false );
if( canFill == 0 )
{
return;
}
// Now actually pull out of the system
stack.setStackSize( canFill );
final IAEFluidStack pulled = Platform.poweredExtraction( energy, cell, stack, new PlayerSource( player, this ) );
if( pulled == null || pulled.getStackSize() < 1 )
{
// Something went wrong
AELog.error( "Unable to pull fluid out of the ME system even though the simulation said yes " );
return;
}
// Actually fill
final int used = fh.fill( pulled.getFluidStack(), true );
if( used != canFill )
{
AELog.error( "Fluid item [%s] reported a different possible amount than it actually accepted.", held.getDisplayName() );
}
player.setHeldItem( hand, fh.getContainer() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
@Override
public IPartModel getStaticModels()
{
@@ -206,7 +206,7 @@ public class AppEngInternalInventory extends ItemStackHandler implements Iterabl
this.enableClientEvents = enableClientEvents;
}
public IAEAppEngInventory getTileEntity()
private IAEAppEngInventory getTileEntity()
{
return this.te;
}
@@ -164,7 +164,6 @@ public class TileInterface extends AENetworkInvTile implements IGridTickable, II
super.onReady();
this.duality.initialize();
this.getProxy().setIdlePowerUsage( Math.pow( 4, ( this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) ) ) );
}
@Override
@@ -494,14 +494,12 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
try
{
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
if( this.getProxy().isActive() )
{
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
catch( final GridAccessException ignored )
{
}
// update the neighbors
@@ -556,10 +554,14 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
this.updateHandler();
if( this.cellHandler != null && this.cellHandler.getChannel() == channel )
if( this.getProxy().isActive() )
{
return Collections.singletonList( this.cellHandler );
this.updateHandler();
if( this.cellHandler != null && this.cellHandler.getChannel() == channel )
{
return Collections.singletonList( this.cellHandler );
}
}
return Collections.emptyList();
}
@@ -690,16 +692,21 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
@Override
public void postChange( final IBaseMonitor<T> monitor, final Iterable<T> change, final IActionSource source )
{
try
if( source == TileChest.this.mySrc || source.machine().map( machine -> machine == TileChest.this ).orElse( false ) )
{
if( TileChest.this.getProxy().isActive() )
try
{
TileChest.this.getProxy().getStorage().postAlterationOfStoredItems( this.chan, change, TileChest.this.mySrc );
if( TileChest.this.getProxy().isActive() )
{
TileChest.this.getProxy().getStorage().postAlterationOfStoredItems( this.chan, change, TileChest.this.mySrc );
}
}
catch( final GridAccessException e )
{
// :(
}
} catch ( final GridAccessException e )
{
// :(
}
TileChest.this.blinkCell( 0 );
}
@@ -264,11 +264,9 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
try
{
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
if( this.getProxy().isActive() )
{
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
catch( final GridAccessException ignored )
{
@@ -336,8 +334,13 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
this.updateState();
return this.inventoryHandlers.get( channel );
if( this.getProxy().isActive() )
{
this.updateState();
return this.inventoryHandlers.get( channel );
}
return Collections.emptyList();
}
@Override
@@ -418,16 +418,13 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
if( possible > 0 )
{
IAEStack injectable = s.copy();
possible = Math.min( possible, itemsToMove );
injectable.setStackSize( possible );
s.setStackSize( possible );
final IAEStack extracted = src.extractItems( injectable, Actionable.MODULATE, this.mySrc );
final IAEStack extracted = src.extractItems( s, Actionable.MODULATE, this.mySrc );
if( extracted != null )
{
possible = extracted.getStackSize();
extracted.setCraftable( false );
final IAEStack failed = Platform.poweredInsert( energy, destination, extracted, this.mySrc );
if( failed != null )
@@ -502,9 +499,8 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
final IAEStack test = myList.getFirstItem();
if( test != null )
{
IAEStack testCopy = test.copy();
testCopy.setStackSize( 1 );
return src.injectItems( testCopy, Actionable.SIMULATE, this.mySrc ) != null;
test.setStackSize( 1 );
return src.injectItems( test, Actionable.SIMULATE, this.mySrc ) != null;
}
return false;
}
@@ -36,7 +36,6 @@ public final class ConfigManager implements IConfigManager
{
private final Map<Settings, Enum<?>> settings = new EnumMap<>( Settings.class );
private final IConfigManagerHost target;
private Map<Settings, Enum<?>> oldSettings = new EnumMap<>( Settings.class );
public ConfigManager( final IConfigManagerHost tile )
{
@@ -73,15 +72,10 @@ public final class ConfigManager implements IConfigManager
{
final Enum<?> oldValue = this.getSetting( settingName );
this.settings.put( settingName, newValue );
this.oldSettings.put( settingName, oldValue );
this.target.updateSetting( this, settingName, newValue );
return oldValue;
}
public Enum<?> getOldSetting(final Settings settingName){
return this.oldSettings.get( settingName );
}
/**
* save all settings using config manager.
*
@@ -47,7 +47,7 @@ public abstract class InventoryAdaptor implements Iterable<ItemSlot>
{
if( te != null )
{
if( ITEM_REPOSITORY_CAPABILITY != null && te.hasCapability( ITEM_REPOSITORY_CAPABILITY, d ) )
if( te.hasCapability( ITEM_REPOSITORY_CAPABILITY, d ) )
{
IItemRepository itemRepository = te.getCapability( ITEM_REPOSITORY_CAPABILITY, d );
if (itemRepository != null){

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