Compare commits
243 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d1c502b41 | |||
| 63653c1833 | |||
| 6cadfbdcdc | |||
| d054c6ab91 | |||
| 234b1c5dc6 | |||
| 8cc29734a2 | |||
| 1e9e8d2639 | |||
| 19c6e2ff2d | |||
| 4f25c1551b | |||
| 3b94e9420d | |||
| f30f334a23 | |||
| 706e577dab | |||
| ccc8486571 | |||
| 3e8440644e | |||
| 50f4e08b64 | |||
| cfa9fa2843 | |||
| 47f819e021 | |||
| 6d151bb890 | |||
| 3305270a71 | |||
| f824bfd2e1 | |||
| 036f4e1c5b | |||
| 146d3f5628 | |||
| 9c821cb015 | |||
| 3a83c99b1f | |||
| 447c6debab | |||
| 50470ae3cf | |||
| 993be652c9 | |||
| b3bfbd0b58 | |||
| 49b3dc8b60 | |||
| 71ffcfb839 | |||
| 73f76a6654 | |||
| 645de1d868 | |||
| 8f40478695 | |||
| 056fcc3818 | |||
| 0ed0eb9d5f | |||
| 3ddc846648 | |||
| f98f6ef852 | |||
| 4192d721a0 | |||
| a0f3ef9d86 | |||
| 6b29288de6 | |||
| 285fc6314c | |||
| 50fd83e96b | |||
| cc51138a6a | |||
| 918df0bf7f | |||
| c852199901 | |||
| fd95d3de47 | |||
| c3dd6dabe1 | |||
| b0e81ac2d1 | |||
| 30f4cdf545 | |||
| ee9441474e | |||
| 8846202270 | |||
| 17a900ae9a | |||
| 66bc243b41 | |||
| a2bda8f449 | |||
| a2c2a4df0f | |||
| b4e237244a | |||
| b541ad8d18 | |||
| 64f29a7dba | |||
| 6d25b7ef3c | |||
| c3a608ef59 | |||
| af1f5c34d2 | |||
| f5378e060e | |||
| 47407acc42 | |||
| d7f3428824 | |||
| 63e339b88b | |||
| 98761809fd | |||
| 8cb013b686 | |||
| f2fe376982 | |||
| 603452de1f | |||
| 40bd96d21c | |||
| a14d160a07 | |||
| df28a5520f | |||
| 0d096944cc | |||
| 963d3414d8 | |||
| 4414451f5e | |||
| e0ddb92b81 | |||
| 6f551ad67f | |||
| fd3349614d | |||
| 903f211044 | |||
| 78e1e26a11 | |||
| 2a6de11597 | |||
| cd2b53af85 | |||
| 1c5565491a | |||
| 311cc5c6f6 | |||
| 41796449ed | |||
| 9eef9d3840 | |||
| 13afa6908a | |||
| 103438f805 | |||
| eaa01f7648 | |||
| e81fb09599 | |||
| 94d73aec7c | |||
| b51af43dba | |||
| 85dc8ae7c1 | |||
| c34176f392 | |||
| 76fe2175a0 | |||
| c5d33ed892 | |||
| b423d99879 | |||
| 81156b411d | |||
| 6be1660d41 | |||
| 304f394497 | |||
| 50f21125c8 | |||
| 30b85bd239 | |||
| 9ce00d338f | |||
| 11f5b71089 | |||
| e7da72163b | |||
| 6d7c65dd70 | |||
| 5e21101619 | |||
| 3db8d0185f | |||
| 2f5ecfe638 | |||
| 75843e802d | |||
| e41b6943aa | |||
| 92347ad2f5 | |||
| 517bd77df7 | |||
| 19f928a9a5 | |||
| 73251a0fe5 | |||
| 9335daff7d | |||
| cc5377d53b | |||
| 059f20d801 | |||
| d229570495 | |||
| c284748b6c | |||
| 880a9c8821 | |||
| c68c02ef3b | |||
| 89c4d2736c | |||
| 01778794e5 | |||
| 8f2a06e457 | |||
| 2d71b75019 | |||
| 9f09cd04d4 | |||
| b041fae0d5 | |||
| c466a0e00e | |||
| 618e9390c6 | |||
| 9a71bfb0f0 | |||
| 9680123906 | |||
| 87730894e9 | |||
| 71c944daea | |||
| e96b4a698a | |||
| 1d5465a4b8 | |||
| 09cbfe96d6 | |||
| cbdad7c58e | |||
| 6be96956a9 | |||
| e376e002e9 | |||
| 0b9df31d4e | |||
| cef6dbf0d7 | |||
| e4af7b1947 | |||
| 6eadb8f861 | |||
| b6b6a83563 | |||
| 32ab4c6af4 | |||
| fda8c87410 | |||
| 389e060707 | |||
| 0942a90ef4 | |||
| 8cef06512a | |||
| 8e4658be20 | |||
| 0bd2bd6b5a | |||
| db2c4c4325 | |||
| ac793ee847 | |||
| 6404f26cca | |||
| ced6ad865c | |||
| 24750f00b1 | |||
| df08ce0513 | |||
| f9c274fb48 | |||
| 3582582e3f | |||
| 6de48f8541 | |||
| 5a2c2d06d3 | |||
| 98d3cafdfd | |||
| 904de49543 | |||
| b0772bf94c | |||
| aa5d5e3623 | |||
| 42f4ef2855 | |||
| 3eb2582f29 | |||
| 307f86ded8 | |||
| 56f57e18a5 | |||
| eab695b692 | |||
| 0fb393820b | |||
| 01fe5c7a8b | |||
| 8468b47443 | |||
| 6cb583c918 | |||
| d69395a117 | |||
| 59effe8131 | |||
| 6f42876963 | |||
| 08952b48dd | |||
| e3c9c4ce65 | |||
| 7b91da58c0 | |||
| 26c06bca15 | |||
| 4458bd28ab | |||
| df3f00d978 | |||
| 18ae994ee4 | |||
| 47888b5546 | |||
| e18593feb5 | |||
| af4c3de55e | |||
| bea29331a3 | |||
| 9b9579b358 | |||
| 52da4f9528 | |||
| 50aac2c768 | |||
| 33946438bd | |||
| 9372cb2f14 | |||
| 00037ace77 | |||
| e13af643ba | |||
| ffcfd809d8 | |||
| 7c10a6b883 | |||
| c2bddc30c4 | |||
| 024655f84d | |||
| 589e48ac01 | |||
| 43d3a2c1c0 | |||
| c432fa7200 | |||
| cc744ab8b9 | |||
| 8fe4229a8e | |||
| 3f86884965 | |||
| 1319ec79c9 | |||
| 31a3afc18b | |||
| 9d6026635d | |||
| 39038ac935 | |||
| 4f627b234c | |||
| 6180c188e6 | |||
| 7ada6d18ee | |||
| f493767243 | |||
| ba4cdbcb85 | |||
| f3877aa1ec | |||
| 366b31b3aa | |||
| 533fb5c34b | |||
| 62d1d904c6 | |||
| 03fb43db16 | |||
| 9576bec855 | |||
| b5da6730a1 | |||
| 039bab4811 | |||
| 4b5bdf9893 | |||
| 3c3c23712d | |||
| af91c04ea1 | |||
| 0240a5d76a | |||
| 0c0aafba2f | |||
| b541025738 | |||
| 62f842d4ef | |||
| fc154d8568 | |||
| 4641e48529 | |||
| 0fae87afc7 | |||
| ee1b6bb0d7 | |||
| 36ca8b9f0a | |||
| 9c94c7342b | |||
| 399d67b42c | |||
| 10761a1e9d | |||
| d1ddf53d99 | |||
| f776b4d548 | |||
| 41180792e1 | |||
| 2269c05d98 | |||
| 63616e5730 |
+58
@@ -0,0 +1,58 @@
|
||||
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
@@ -57,7 +57,7 @@ tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
version = aeversion + "-" + aechannel + "-" + aebuild + " " + trousers
|
||||
version = aeversion + "-" + aechannel + "-" + aebuild + "-" + extended + "-" + extendedversion
|
||||
group = aegroup
|
||||
archivesBaseName = aebasename
|
||||
|
||||
|
||||
+3
-5
@@ -3,20 +3,18 @@ aechannel=stable
|
||||
aebuild=7
|
||||
aegroup=appeng
|
||||
aebasename=appliedenergistics2
|
||||
trousers=omni-fixes-v21b
|
||||
|
||||
extended=extended_life
|
||||
extendedversion=v52b
|
||||
#########################################################
|
||||
# Versions #
|
||||
#########################################################
|
||||
minecraft_version=1.12.2
|
||||
mcp_mappings=snapshot_20171003
|
||||
forge_version=14.23.5.2847
|
||||
|
||||
#########################################################
|
||||
# Installable #
|
||||
#########################################################
|
||||
hwyla_version=1.8.26-B41_1.12.2
|
||||
|
||||
#########################################################
|
||||
# Provided APIs #
|
||||
#########################################################
|
||||
@@ -28,7 +26,7 @@ cofhcore_version=1.12.2-4.5.2.19
|
||||
crafttweaker_version=4.1.8.9
|
||||
inventorytweaks_version=1.63
|
||||
ctm_version=MC1.12.2-0.3.1.16
|
||||
|
||||
forestry_version=5.8.2.387
|
||||
#########################################################
|
||||
# Deployment #
|
||||
#########################################################
|
||||
|
||||
@@ -19,11 +19,6 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
|
||||
maven {
|
||||
name = "storagedrawers"
|
||||
url = "https://dl.bintray.com/jaquadro/dev/"
|
||||
}
|
||||
|
||||
maven {
|
||||
name "Mobius"
|
||||
url "http://mobiusstrip.eu/maven"
|
||||
@@ -36,7 +31,12 @@ repositories {
|
||||
|
||||
maven {
|
||||
name = "Tesla repo"
|
||||
url "http://maven.mcmoddev.com"
|
||||
url "https://maven.mcmoddev.com"
|
||||
}
|
||||
|
||||
maven {
|
||||
name "Ellpeck"
|
||||
url "https://maven.ellpeck.de"
|
||||
}
|
||||
|
||||
maven {
|
||||
@@ -59,12 +59,7 @@ repositories {
|
||||
url "http://maven.k-4u.nl/"
|
||||
}
|
||||
|
||||
maven { // Hwyla
|
||||
name 'tehnut'
|
||||
url "http://tehnut.info/maven"
|
||||
}
|
||||
|
||||
maven { // CraftTweaker
|
||||
maven { // CraftTweaker
|
||||
name 'jared maven'
|
||||
url "http://maven.blamejared.com/"
|
||||
}
|
||||
@@ -75,9 +70,9 @@ repositories {
|
||||
//}
|
||||
|
||||
maven {
|
||||
name = "CurseForge"
|
||||
url = "https://minecraft.curseforge.com/api/maven/"
|
||||
}
|
||||
name = "CurseForge"
|
||||
url = "https://minecraft.curseforge.com/api/maven/"
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
@@ -85,9 +80,7 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly "com.jaquadro.minecraft.storagedrawers:StorageDrawers:1.12.2-5.4.2:api"
|
||||
compileOnly "gregtechce:gregtech:1.12.2:1.12.0.662"
|
||||
|
||||
deobfCompile "gregtechce:gregtech:1.12.2:1.15.1.735"
|
||||
// installable runtime dependencies
|
||||
mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
|
||||
mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev"
|
||||
@@ -101,13 +94,14 @@ dependencies {
|
||||
compileOnly "mcjty.theoneprobe:TheOneProbe-1.12:${top_version}:api"
|
||||
compileOnly "cofh:CoFHCore:${cofhcore_version}:deobf"
|
||||
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
|
||||
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
|
||||
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
|
||||
compileOnly "team.chisel.ctm:CTM:${ctm_version}"
|
||||
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
|
||||
deobfCompile "net.sengir.forestry:forestry_${minecraft_version}:$forestry_version"
|
||||
|
||||
|
||||
// at runtime, use the full JEI jar
|
||||
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
|
||||
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"
|
||||
|
||||
@@ -28,7 +28,8 @@ public enum PowerUnits
|
||||
{
|
||||
AE( "gui.appliedenergistics2.units.appliedenergstics" ), // Native Units - AE Energy
|
||||
EU( "gui.appliedenergistics2.units.ic2" ), // IndustrialCraft 2 - Energy Units
|
||||
RF( "gui.appliedenergistics2.units.rf" ); // RF - Redstone Flux
|
||||
RF( "gui.appliedenergistics2.units.rf" ), // RF - Redstone Flux
|
||||
GTEU( "gui.appliedenergistics2.units.gteu" ); // RF - Redstone Flux
|
||||
|
||||
/**
|
||||
* unlocalized name for the power unit.
|
||||
@@ -46,14 +47,13 @@ public enum PowerUnits
|
||||
|
||||
/**
|
||||
* do power conversion using AE's conversion rates.
|
||||
*
|
||||
* <p>
|
||||
* Example: PowerUnits.EU.convertTo( PowerUnits.AE, 32 );
|
||||
*
|
||||
* <p>
|
||||
* will normally returns 64, as it will convert the EU, to AE with AE's power settings.
|
||||
*
|
||||
* @param target target power unit
|
||||
* @param value value
|
||||
*
|
||||
* @param value value
|
||||
* @return value converted to target units, from this units.
|
||||
*/
|
||||
public double convertTo( final PowerUnits target, final double value )
|
||||
|
||||
@@ -29,6 +29,7 @@ public enum TunnelType
|
||||
ME, // Network Tunnel
|
||||
IC2_POWER, // EU Tunnel
|
||||
FE_POWER, // Forge Energy tunnel
|
||||
GTEU_POWER, // Forge Energy tunnel
|
||||
REDSTONE, // Redstone Tunnel
|
||||
FLUID, // Fluid Tunnel
|
||||
ITEM, // Item Tunnel
|
||||
|
||||
@@ -46,7 +46,8 @@ public enum Upgrades
|
||||
*/
|
||||
FUZZY( 1 ),
|
||||
SPEED( 1 ),
|
||||
INVERTER( 1 );
|
||||
INVERTER( 1 ),
|
||||
PATTERN_EXPANSION(1);
|
||||
|
||||
private final int tier;
|
||||
private final Map<ItemStack, Integer> supportedMax = new HashMap<>();
|
||||
|
||||
@@ -89,6 +89,8 @@ public interface IMaterials
|
||||
|
||||
IItemDefinition cardCapacity();
|
||||
|
||||
IItemDefinition cardPatternExpansion();
|
||||
|
||||
IItemDefinition cardFuzzy();
|
||||
|
||||
IItemDefinition cardInverter();
|
||||
|
||||
@@ -58,6 +58,8 @@ public interface IParts
|
||||
|
||||
IItemDefinition storageBus();
|
||||
|
||||
IItemDefinition oreDictStorageBus();
|
||||
|
||||
IItemDefinition importBus();
|
||||
|
||||
IItemDefinition exportBus();
|
||||
@@ -86,6 +88,8 @@ public interface IParts
|
||||
|
||||
IItemDefinition p2PTunnelFE();
|
||||
|
||||
IItemDefinition p2PTunnelGTEU();
|
||||
|
||||
IItemDefinition p2PTunnelLight();
|
||||
|
||||
// IItemDefinition p2PTunnelOpenComputers();
|
||||
@@ -102,6 +106,8 @@ public interface IParts
|
||||
|
||||
IItemDefinition patternTerminal();
|
||||
|
||||
IItemDefinition expandedProcessingPatternTerminal();
|
||||
|
||||
IItemDefinition craftingTerminal();
|
||||
|
||||
IItemDefinition terminal();
|
||||
|
||||
@@ -31,6 +31,9 @@ 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}
|
||||
@@ -84,6 +87,11 @@ 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,10 +44,7 @@ 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,6 +51,7 @@ 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
|
||||
|
||||
@@ -112,4 +112,17 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
|
||||
* @return definition stack
|
||||
*/
|
||||
ItemStack getDefinition();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
boolean equals( ItemStack is );
|
||||
|
||||
ItemStack getCachedItemStack( long stackSize );
|
||||
|
||||
void setCachedItemStack( ItemStack is );
|
||||
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
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> { }
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
|
||||
@Override
|
||||
protected IProperty[] getAEStates()
|
||||
{
|
||||
return new IProperty[] { POWERED };
|
||||
return new IProperty[]{POWERED};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,4 +108,14 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
|
||||
|
||||
return super.onBlockActivated( w, pos, state, p, hand, side, hitX, hitY, hitZ );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborChange( IBlockAccess world, BlockPos pos, BlockPos neighbor )
|
||||
{
|
||||
final TileMolecularAssembler tg = this.getTileEntity( world, pos );
|
||||
if( tg != null )
|
||||
{
|
||||
tg.updateNeighbors( world, pos, neighbor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package appeng.capabilities;
|
||||
|
||||
|
||||
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
|
||||
import gregtech.api.capability.IEnergyContainer;
|
||||
import net.darkhax.tesla.api.ITeslaConsumer;
|
||||
import net.darkhax.tesla.api.ITeslaHolder;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
@@ -57,6 +58,8 @@ public final class Capabilities
|
||||
|
||||
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY;
|
||||
|
||||
public static Capability<IEnergyContainer> GTCE_ENERGY;
|
||||
|
||||
/**
|
||||
* Register AE2 provided capabilities.
|
||||
*/
|
||||
@@ -103,7 +106,19 @@ public final class Capabilities
|
||||
}
|
||||
|
||||
@CapabilityInject( IItemRepository.class )
|
||||
private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap ) { ITEM_REPOSITORY_CAPABILITY = cap; }
|
||||
private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap )
|
||||
{
|
||||
ITEM_REPOSITORY_CAPABILITY = cap;
|
||||
}
|
||||
|
||||
@CapabilityInject( IEnergyContainer.class )
|
||||
private static void capIEnergyContainerRegistered( Capability<IEnergyContainer> cap )
|
||||
{
|
||||
if( IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.GTCE ) )
|
||||
{
|
||||
GTCE_ENERGY = cap;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a storage implementation that does not do anything
|
||||
private static <T> Capability.IStorage<T> createNullStorage()
|
||||
|
||||
@@ -25,8 +25,11 @@ 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;
|
||||
@@ -36,10 +39,7 @@ 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.MouseEvent;
|
||||
import net.minecraftforge.client.event.RenderLivingEvent;
|
||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.client.event.*;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.ForgeModContainer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -75,6 +75,7 @@ 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
|
||||
@@ -315,6 +316,28 @@ 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 )
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package appeng.client.gui;
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
@@ -31,13 +32,17 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.container.slot.*;
|
||||
import appeng.util.Platform;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
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;
|
||||
@@ -71,17 +76,7 @@ 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;
|
||||
@@ -92,6 +87,9 @@ 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
|
||||
@@ -106,6 +104,28 @@ 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 )
|
||||
@@ -140,7 +160,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
|
||||
final List<Slot> slots = this.getInventorySlots();
|
||||
final Iterator<Slot> i = slots.iterator();
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
if( i.next() instanceof SlotME )
|
||||
{
|
||||
@@ -188,6 +208,71 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
this.drawTooltip( (ITooltip) c, mouseX, mouseY );
|
||||
}
|
||||
}
|
||||
GlStateManager.enableDepth();
|
||||
if( Platform.isModLoaded( "jei" ) )
|
||||
{
|
||||
bookmarkedJEIghostItem( mouseX, mouseY );
|
||||
}
|
||||
GlStateManager.disableDepth();
|
||||
}
|
||||
|
||||
@Optional.Method( modid = "jei" )
|
||||
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 )
|
||||
@@ -299,17 +384,13 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
final AppEngSlot aeSlot = (AppEngSlot) slot;
|
||||
if( aeSlot.isSlotEnabled() )
|
||||
{
|
||||
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1,
|
||||
18,
|
||||
18 );
|
||||
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18 );
|
||||
}
|
||||
else
|
||||
{
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 0.4F );
|
||||
GlStateManager.enableBlend();
|
||||
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1,
|
||||
18,
|
||||
18 );
|
||||
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18 );
|
||||
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
|
||||
}
|
||||
}
|
||||
@@ -320,7 +401,6 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
{
|
||||
slot.drawBackground( ox, oy );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -429,18 +509,56 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
{
|
||||
final EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
|
||||
if( slot instanceof SlotFake )
|
||||
if( this.isJeiGhostItem && isDraggingJeiGhostItem )
|
||||
{
|
||||
final InventoryAction action = mouseButton == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
|
||||
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;
|
||||
|
||||
if( this.drag_click.size() > 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, 0 );
|
||||
PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, 0 );
|
||||
NetworkHandler.instance().sendToServer( p );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -560,14 +678,13 @@ 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;
|
||||
}
|
||||
@@ -634,9 +751,7 @@ 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 );
|
||||
}
|
||||
@@ -647,6 +762,12 @@ 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 );
|
||||
}
|
||||
|
||||
@@ -762,7 +883,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
if( stack != ItemStack.EMPTY )
|
||||
{
|
||||
InventoryAction direction = wheel > 0 ? InventoryAction.PLACE_SINGLE : InventoryAction.PICKUP_SINGLE;
|
||||
final PacketInventoryAction p = new PacketInventoryAction( direction , slot.slotNumber , 0);
|
||||
final PacketInventoryAction p = new PacketInventoryAction( direction, slot.slotNumber, 0 );
|
||||
NetworkHandler.instance().sendToServer( p );
|
||||
}
|
||||
}
|
||||
@@ -915,27 +1036,11 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
final float f1 = 0.00390625F;
|
||||
final float f = 0.00390625F;
|
||||
final float par6 = 16;
|
||||
vb.pos( par1 + 0, par2 + par6, this.zLevel )
|
||||
.tex( ( par3 + 0 ) * f, ( par4 + par6 ) * f1 )
|
||||
.color( 1.0f, 1.0f, 1.0f,
|
||||
aes.getOpacityOfIcon() )
|
||||
.endVertex();
|
||||
vb.pos( par1 + 0, par2 + par6, this.zLevel ).tex( ( par3 + 0 ) * f, ( par4 + par6 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
|
||||
final float par5 = 16;
|
||||
vb.pos( par1 + par5, par2 + par6, this.zLevel )
|
||||
.tex( ( par3 + par5 ) * f, ( par4 + par6 ) * f1 )
|
||||
.color( 1.0f, 1.0f, 1.0f,
|
||||
aes.getOpacityOfIcon() )
|
||||
.endVertex();
|
||||
vb.pos( par1 + par5, par2 + 0, this.zLevel )
|
||||
.tex( ( par3 + par5 ) * f, ( par4 + 0 ) * f1 )
|
||||
.color( 1.0f, 1.0f, 1.0f,
|
||||
aes.getOpacityOfIcon() )
|
||||
.endVertex();
|
||||
vb.pos( par1 + 0, par2 + 0, this.zLevel )
|
||||
.tex( ( par3 + 0 ) * f, ( par4 + 0 ) * f1 )
|
||||
.color( 1.0f, 1.0f, 1.0f,
|
||||
aes.getOpacityOfIcon() )
|
||||
.endVertex();
|
||||
vb.pos( par1 + par5, par2 + par6, this.zLevel ).tex( ( par3 + par5 ) * f, ( par4 + par6 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
|
||||
vb.pos( par1 + par5, par2 + 0, this.zLevel ).tex( ( par3 + par5 ) * f, ( par4 + 0 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
|
||||
vb.pos( par1 + 0, par2 + 0, this.zLevel ).tex( ( par3 + 0 ) * f, ( par4 + 0 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex();
|
||||
tessellator.draw();
|
||||
|
||||
}
|
||||
@@ -949,8 +1054,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
{
|
||||
if( ( (AppEngSlot) s ).getIsValid() == hasCalculatedValidness.NotAvailable )
|
||||
{
|
||||
boolean isValid = s.isItemValid(
|
||||
is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled || s instanceof SlotInaccessible || s instanceof SlotFake || s instanceof SlotRestrictedInput || s instanceof SlotDisconnected;
|
||||
boolean isValid = s.isItemValid( is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled || s instanceof SlotInaccessible || s instanceof SlotFake || s instanceof SlotRestrictedInput || s instanceof SlotDisconnected;
|
||||
if( isValid && s instanceof SlotRestrictedInput )
|
||||
{
|
||||
try
|
||||
@@ -1074,4 +1178,5 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,26 +2,23 @@ package appeng.client.gui;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
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 appeng.client.gui.implementations.*;
|
||||
import appeng.container.interfaces.IJEIGhostIngredients;
|
||||
import appeng.container.slot.SlotFake;
|
||||
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
|
||||
import mezz.jei.api.gui.IAdvancedGuiHandler;
|
||||
import net.minecraft.client.renderer.RenderItem;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import mezz.jei.api.gui.IGhostIngredientHandler;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
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>
|
||||
public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngredientHandler<AEBaseGui>
|
||||
{
|
||||
|
||||
@Override
|
||||
public Class<AEBaseGui> getGuiContainerClass()
|
||||
{
|
||||
@@ -39,8 +36,8 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>
|
||||
@Override
|
||||
public Object getIngredientUnderMouse( AEBaseGui guiContainer, int mouseX, int mouseY )
|
||||
{
|
||||
List<IAEItemStack> visual = new ArrayList<>();
|
||||
int guiSlotIdx = 0;
|
||||
List<IAEItemStack> visual;
|
||||
int guiSlotIdx;
|
||||
Object result = null;
|
||||
if( guiContainer instanceof GuiCraftConfirm )
|
||||
{
|
||||
@@ -94,4 +91,54 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>
|
||||
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 || gui instanceof GuiExpandedProcessingPatternTerm )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ package appeng.client.gui.implementations;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -123,6 +124,12 @@ public class GuiCraftAmount extends AEBaseGui
|
||||
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( target instanceof PartExpandedProcessingPatternTerminal )
|
||||
{
|
||||
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( this.originalGui != null && !myIcon.isEmpty() )
|
||||
{
|
||||
this.buttonList.add( this.originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender ) );
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import org.lwjgl.input.Mouse;
|
||||
@@ -104,6 +105,11 @@ public class GuiCraftConfirm extends AEBaseGui
|
||||
{
|
||||
this.OriginalGui = GuiBridge.GUI_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( te instanceof PartExpandedProcessingPatternTerminal )
|
||||
{
|
||||
this.OriginalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAutoStart()
|
||||
|
||||
@@ -25,6 +25,7 @@ package appeng.client.gui.implementations;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
@@ -95,6 +96,12 @@ public class GuiCraftingStatus extends GuiCraftingCPU
|
||||
|
||||
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( target instanceof PartExpandedProcessingPatternTerminal )
|
||||
{
|
||||
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import appeng.api.config.ActionItems;
|
||||
import appeng.api.config.ItemSubstitution;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.storage.ITerminalHost;
|
||||
import appeng.client.gui.widgets.GuiImgButton;
|
||||
import appeng.client.gui.widgets.GuiTabButton;
|
||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
||||
import appeng.container.interfaces.IJEIGhostIngredients;
|
||||
import appeng.container.slot.AppEngSlot;
|
||||
import appeng.container.slot.SlotFake;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketInventoryAction;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import mezz.jei.api.gui.IGhostIngredientHandler;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class GuiExpandedProcessingPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
|
||||
{
|
||||
private static final String BACKGROUND_EXPANDED_PROCESSING_MODE = "guis/pattern_processing_expanded.png";
|
||||
|
||||
private static final String SUBSITUTION_DISABLE = "0";
|
||||
private static final String SUBSITUTION_ENABLE = "1";
|
||||
|
||||
private static final String CRAFTMODE_CRFTING = "1";
|
||||
private static final String CRAFTMODE_PROCESSING = "0";
|
||||
|
||||
private GuiTabButton tabCraftButton;
|
||||
private GuiTabButton tabProcessButton;
|
||||
private GuiImgButton substitutionsEnabledBtn;
|
||||
private GuiImgButton substitutionsDisabledBtn;
|
||||
private GuiImgButton encodeBtn;
|
||||
private GuiImgButton clearBtn;
|
||||
private GuiImgButton x2Btn;
|
||||
private GuiImgButton x3Btn;
|
||||
private GuiImgButton plusOneBtn;
|
||||
private GuiImgButton divTwoBtn;
|
||||
private GuiImgButton divThreeBtn;
|
||||
private GuiImgButton minusOneBtn;
|
||||
private GuiImgButton maxCountBtn;
|
||||
public Map<IGhostIngredientHandler.Target<?>, Object> mapTargetSlot = new HashMap<>();
|
||||
|
||||
public GuiExpandedProcessingPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
|
||||
{
|
||||
super( inventoryPlayer, te, new ContainerExpandedProcessingPatternTerm( inventoryPlayer, te ) );
|
||||
this.setReservedSpace( 81 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed( final GuiButton btn )
|
||||
{
|
||||
super.actionPerformed( btn );
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if( this.tabCraftButton == btn || this.tabProcessButton == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
|
||||
}
|
||||
|
||||
if( this.encodeBtn == btn )
|
||||
{
|
||||
if( isShiftKeyDown() )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "2" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "1" ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( this.clearBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Clear", "1" ) );
|
||||
}
|
||||
|
||||
if( this.x2Btn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByTwo", "1" ) );
|
||||
}
|
||||
|
||||
if( this.x3Btn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByThree", "1" ) );
|
||||
}
|
||||
|
||||
if( this.divTwoBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByTwo", "1" ) );
|
||||
}
|
||||
|
||||
if( this.divThreeBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByThree", "1" ) );
|
||||
}
|
||||
|
||||
if( this.plusOneBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.IncreaseByOne", "1" ) );
|
||||
}
|
||||
|
||||
if( this.minusOneBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DecreaseByOne", "1" ) );
|
||||
}
|
||||
|
||||
if( this.maxCountBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MaximizeCount", "1" ) );
|
||||
}
|
||||
|
||||
if( this.substitutionsEnabledBtn == btn || this.substitutionsDisabledBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
|
||||
}
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.error( e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
|
||||
this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.CRAFTING_TABLE ), GuiText.CraftingPattern.getLocal(), this.itemRender );
|
||||
this.buttonList.add( this.tabCraftButton );
|
||||
|
||||
this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.FURNACE ), GuiText.ProcessingPattern.getLocal(), this.itemRender );
|
||||
this.buttonList.add( this.tabProcessButton );
|
||||
|
||||
this.substitutionsEnabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.ENABLED );
|
||||
this.substitutionsEnabledBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.substitutionsEnabledBtn );
|
||||
|
||||
this.substitutionsDisabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.DISABLED );
|
||||
this.substitutionsDisabledBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.substitutionsDisabledBtn );
|
||||
|
||||
this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE );
|
||||
this.clearBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.clearBtn );
|
||||
|
||||
this.x3Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.MULTIPLY_BY_THREE );
|
||||
this.x3Btn.setHalfSize( true );
|
||||
this.buttonList.add( this.x3Btn );
|
||||
|
||||
this.x2Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.MULTIPLY_BY_TWO );
|
||||
this.x2Btn.setHalfSize( true );
|
||||
this.buttonList.add( this.x2Btn );
|
||||
|
||||
this.plusOneBtn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.INCREASE_BY_ONE );
|
||||
this.plusOneBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.plusOneBtn );
|
||||
|
||||
this.divThreeBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.DIVIDE_BY_THREE );
|
||||
this.divThreeBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.divThreeBtn );
|
||||
|
||||
this.divTwoBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.DIVIDE_BY_TWO );
|
||||
this.divTwoBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.divTwoBtn );
|
||||
|
||||
this.minusOneBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.DECREASE_BY_ONE );
|
||||
this.minusOneBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.minusOneBtn );
|
||||
|
||||
//this.maxCountBtn = new GuiImgButton( this.guiLeft + 128, this.guiTop + this.ySize - 108, Settings.ACTIONS, ActionItems.MAX_COUNT );
|
||||
//this.maxCountBtn.setHalfSize( true );
|
||||
//this.buttonList.add( this.maxCountBtn );
|
||||
|
||||
this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE );
|
||||
this.buttonList.add( this.encodeBtn );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
|
||||
{
|
||||
this.tabCraftButton.visible = false;
|
||||
this.tabProcessButton.visible = true;
|
||||
this.substitutionsEnabledBtn.visible = false;
|
||||
this.substitutionsDisabledBtn.visible = false;
|
||||
this.x2Btn.visible = true;
|
||||
this.x3Btn.visible = true;
|
||||
this.divTwoBtn.visible = true;
|
||||
this.divThreeBtn.visible = true;
|
||||
this.plusOneBtn.visible = true;
|
||||
this.minusOneBtn.visible = true;
|
||||
//this.maxCountBtn.visible = true;
|
||||
|
||||
super.drawFG( offsetX, offsetY, mouseX, mouseY );
|
||||
this.fontRenderer.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.getReservedSpace(), 4210752 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBackground()
|
||||
{
|
||||
return BACKGROUND_EXPANDED_PROCESSING_MODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repositionSlot( final AppEngSlot s )
|
||||
{
|
||||
final int offsetPlayerSide = s.isPlayerSide() ? 5 : 3;
|
||||
|
||||
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IGhostIngredientHandler.Target<?>> getPhantomTargets( Object ingredient )
|
||||
{
|
||||
if( !( ingredient instanceof ItemStack ) )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<IGhostIngredientHandler.Target<?>> targets = new ArrayList<>();
|
||||
for( Slot slot : this.inventorySlots.inventorySlots )
|
||||
{
|
||||
if( slot instanceof SlotFake )
|
||||
{
|
||||
ItemStack itemStack = (ItemStack) ingredient;
|
||||
IGhostIngredientHandler.Target<Object> target = new IGhostIngredientHandler.Target<Object>()
|
||||
{
|
||||
@Override
|
||||
public Rectangle getArea()
|
||||
{
|
||||
return new Rectangle( getGuiLeft() + slot.xPos, getGuiTop() + slot.yPos, 16, 16 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept( Object ingredient )
|
||||
{
|
||||
final PacketInventoryAction p;
|
||||
try
|
||||
{
|
||||
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (SlotFake) slot, AEItemStack.fromItemStack( itemStack ) );
|
||||
NetworkHandler.instance().sendToServer( p );
|
||||
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
targets.add( target );
|
||||
mapTargetSlot.putIfAbsent( target, slot );
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<IGhostIngredientHandler.Target<?>, Object> getFakeSlotTargetMap()
|
||||
{
|
||||
return mapTargetSlot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class GuiInterface extends GuiUpgradeable
|
||||
public GuiInterface( final InventoryPlayer inventoryPlayer, final IInterfaceHost te )
|
||||
{
|
||||
super( new ContainerInterface( inventoryPlayer, te ) );
|
||||
this.ySize = 211;
|
||||
this.ySize = 256;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,8 +62,7 @@ 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 );
|
||||
}
|
||||
|
||||
@@ -86,13 +85,20 @@ 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()
|
||||
{
|
||||
return "guis/interface.png";
|
||||
int upgrades = ( (ContainerInterface) this.cvb ).getPatternUpgrades();
|
||||
if( upgrades == 0 )
|
||||
{
|
||||
return "guis/newinterface.png";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "guis/newinterface" + upgrades + ".png";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,4 +123,5 @@ public class GuiInterface extends GuiUpgradeable
|
||||
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.BlockMode.getSetting(), backwards ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,13 @@ 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;
|
||||
|
||||
@@ -49,6 +55,8 @@ 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;
|
||||
@@ -66,8 +74,10 @@ 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<>();
|
||||
|
||||
@@ -77,6 +87,7 @@ 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 )
|
||||
{
|
||||
@@ -86,7 +97,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
||||
final GuiScrollbar scrollbar = new GuiScrollbar();
|
||||
this.setScrollBar( scrollbar );
|
||||
this.xSize = 208;
|
||||
this.ySize = 256;
|
||||
this.ySize = 255;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,34 +142,43 @@ 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 ex = this.getScrollBar().getCurrentScroll();
|
||||
final int currentScroll = 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 = 51;
|
||||
for( int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
|
||||
int offset = 52;
|
||||
int linesDraw = 0;
|
||||
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && currentScroll + x < this.lines.size(); x++ )
|
||||
{
|
||||
final Object lineObj = this.lines.get( ex + x );
|
||||
final Object lineObj = this.lines.get( currentScroll + x );
|
||||
if( lineObj instanceof ClientDCInternalInv )
|
||||
{
|
||||
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
|
||||
for( int z = 0; z < inv.getInventory().getSlots(); z++ )
|
||||
{
|
||||
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);
|
||||
GuiButton guiButton = new GuiImgButton( guiLeft + 4, guiTop + offset, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE );
|
||||
guiButtonHashMap.put( guiButton, inv );
|
||||
this.buttonList.add( guiButton );
|
||||
int extraLines = numUpgradesMap.get( inv );
|
||||
|
||||
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE ; ++row )
|
||||
{
|
||||
for( int z = 0; z < 9 ; z++ )
|
||||
{
|
||||
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z + ( row * 9 ), ( z * 18 + 22 ), offset ) );
|
||||
if( this.matchedStacks.contains( inv.getInventory().getStackInSlot( z + ( row * 9 ) ) ) )
|
||||
{
|
||||
drawRect( z * 18 + 22, offset, z * 18 + 22 + 16, offset + 16, 0x2A00FF00 );
|
||||
}
|
||||
}
|
||||
linesDraw++;
|
||||
offset += 18;
|
||||
}
|
||||
}
|
||||
else if( lineObj instanceof String )
|
||||
{
|
||||
@@ -169,18 +189,18 @@ 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, 6 + offset, 4210752 );
|
||||
this.fontRenderer.drawString( name, this.offsetX + 2, 5 + offset, 4210752 );
|
||||
linesDraw++;
|
||||
offset += 18;
|
||||
}
|
||||
offset += 18;
|
||||
}
|
||||
|
||||
if( searchFieldInputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( mouseX - guiLeft - offsetX, mouseY - guiTop, "Inputs OR names" );
|
||||
else if( searchFieldOutputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( mouseX - guiLeft - offsetX, mouseY - guiTop, "Outputs OR names" );
|
||||
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" );
|
||||
|
||||
}
|
||||
|
||||
@@ -213,9 +233,21 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
||||
{
|
||||
BlockPos blockPos = blockPosHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
|
||||
BlockPos blockPos2 = mc.player.getPosition();
|
||||
int dimension = mc.world.provider.getDimension();
|
||||
hilightBlock( blockPos, System.currentTimeMillis() + 500 * BlockPosUtils.getDistance(blockPos, blockPos2), dimension );
|
||||
mc.player.sendStatusMessage( new TextComponentString( "The interface is now highlighted at " + "X: " + blockPos.getX() + " Y: " + blockPos.getY() + " Z: " + blockPos.getZ() ), false );
|
||||
int playerDim = mc.world.provider.getDimension();
|
||||
int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
|
||||
if( playerDim != interfaceDim )
|
||||
{
|
||||
try {
|
||||
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
|
||||
} catch(Exception e){
|
||||
mc.player.sendStatusMessage( new TextComponentString( "Interface is located in another dimension and cannot be highlighted" ), false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hilightBlock( blockPos, System.currentTimeMillis() + 500 * BlockPosUtils.getDistance( blockPos, blockPos2 ), playerDim );
|
||||
mc.player.sendStatusMessage( new TextComponentString( "The interface is now highlighted at " + "X: " + blockPos.getX() + " Y: " + blockPos.getY() + " Z: " + blockPos.getZ() ), false );
|
||||
}
|
||||
mc.player.closeScreen();
|
||||
}
|
||||
|
||||
@@ -249,19 +281,28 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
||||
|
||||
int offset = 51;
|
||||
final int ex = this.getScrollBar().getCurrentScroll();
|
||||
|
||||
for( int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
|
||||
int linesDraw = 0;
|
||||
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
|
||||
{
|
||||
final Object lineObj = this.lines.get( ex + x );
|
||||
if( lineObj instanceof ClientDCInternalInv )
|
||||
{
|
||||
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
|
||||
|
||||
GlStateManager.color( 1, 1, 1, 1 );
|
||||
final int width = inv.getInventory().getSlots() * 18;
|
||||
this.drawTexturedModalRect( offsetX + 20, offsetY + offset, 20, 173, width, 18 );
|
||||
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++;
|
||||
}
|
||||
offset += 18;
|
||||
}
|
||||
|
||||
if( this.searchFieldInputs != null )
|
||||
@@ -321,6 +362,8 @@ 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++ )
|
||||
{
|
||||
@@ -355,6 +398,7 @@ 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();
|
||||
@@ -378,21 +422,34 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
||||
// Search if the current inventory holds a pattern containing the search term.
|
||||
if( !found )
|
||||
{
|
||||
int slot = 0;
|
||||
for( final ItemStack itemStack : entry.getInventory() )
|
||||
{
|
||||
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 (slot > 8 + numUpgradesMap.get(entry) * 9) {
|
||||
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())
|
||||
interfaceHasFreeSlots = true;
|
||||
if( found )
|
||||
{
|
||||
break;
|
||||
}
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
// if found, filter skipped or machine name matching the search term, add it
|
||||
@@ -433,7 +490,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
||||
this.lines.addAll( clientInventories );
|
||||
}
|
||||
|
||||
this.getScrollBar().setRange( 0, this.lines.size() - LINES_ON_PAGE, 2 );
|
||||
this.getScrollBar().setRange( 0, this.lines.size() - 1, 1 );
|
||||
}
|
||||
|
||||
private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm,int pass )
|
||||
@@ -523,7 +580,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
||||
|
||||
if( o == null )
|
||||
{
|
||||
this.byId.put( id, o = new ClientDCInternalInv( 9, id, sortBy, string ) );
|
||||
this.byId.put( id, o = new ClientDCInternalInv( DualityInterface.NUMBER_OF_PATTERN_SLOTS, id, sortBy, string ) );
|
||||
this.refreshList = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.ActionItems;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.StorageFilter;
|
||||
import appeng.client.gui.AEBaseGui;
|
||||
import appeng.client.gui.widgets.GuiImgButton;
|
||||
import appeng.client.gui.widgets.GuiTabButton;
|
||||
import appeng.client.gui.widgets.MEGuiTextField;
|
||||
import appeng.container.implementations.ContainerOreDictStorageBus;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.GuiBridge;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketConfigButton;
|
||||
import appeng.core.sync.packets.PacketSwitchGuis;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
import appeng.parts.misc.PartOreDicStorageBus;
|
||||
import appeng.util.item.OreDictFilterMatcher;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class GuiOreDictStorageBus extends AEBaseGui
|
||||
{
|
||||
private final ContainerOreDictStorageBus container;
|
||||
PartOreDicStorageBus part;
|
||||
private GuiTabButton priority;
|
||||
private GuiImgButton partition;
|
||||
private GuiImgButton storageFilter;
|
||||
private GuiImgButton rwMode;
|
||||
private static final Pattern ORE_DICTIONARY_FILTER = Pattern.compile( "[(!]* *[0-9a-zA-Z*]* *\\)*( *[&|^]? *[(!]* *[0-9a-zA-Z*]* *\\)*)*" );
|
||||
private MEGuiTextField searchFieldInputs;
|
||||
|
||||
public GuiOreDictStorageBus( final InventoryPlayer inventoryPlayer, final PartOreDicStorageBus te )
|
||||
{
|
||||
super( new ContainerOreDictStorageBus( inventoryPlayer, te ) );
|
||||
this.container = (ContainerOreDictStorageBus) super.inventorySlots;
|
||||
part = te;
|
||||
this.ySize = 84;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
|
||||
this.searchFieldInputs = new MEGuiTextField( this.fontRenderer, this.guiLeft + 3, this.guiTop + 22, 170, 12 );
|
||||
this.searchFieldInputs.setEnableBackgroundDrawing( false );
|
||||
this.searchFieldInputs.setMaxStringLength( 512 );
|
||||
this.searchFieldInputs.setTextColor( 0xFFFFFF );
|
||||
this.searchFieldInputs.setVisible( true );
|
||||
this.searchFieldInputs.setFocused( false );
|
||||
this.searchFieldInputs.setValidator( str -> ORE_DICTIONARY_FILTER.matcher( str ).matches() );
|
||||
|
||||
this.buttonList.add( this.priority = new GuiTabButton( this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender ) );
|
||||
this.buttonList.add( this.partition = new GuiImgButton( this.guiLeft - 18, this.guiTop + 28, Settings.ACTIONS, ActionItems.WRENCH ) );
|
||||
this.buttonList.add( this.rwMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 48, Settings.ACCESS, AccessRestriction.READ_WRITE ) );
|
||||
this.buttonList.add( this.storageFilter = new GuiImgButton( this.guiLeft - 18, this.guiTop + 68, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY ) );
|
||||
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.getRegex", "1" ) );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void fillRegex( String regex )
|
||||
{
|
||||
this.searchFieldInputs.setText( regex );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed( final GuiButton btn ) throws IOException
|
||||
{
|
||||
super.actionPerformed( btn );
|
||||
|
||||
final boolean backwards = Mouse.isButtonDown( 1 );
|
||||
|
||||
try
|
||||
{
|
||||
if( btn == this.priority )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketSwitchGuis( GuiBridge.GUI_PRIORITY ) );
|
||||
}
|
||||
else if( btn == this.partition )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "StorageBus.Action", "Partition" ) );
|
||||
}
|
||||
else if( btn == this.rwMode )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.rwMode.getSetting(), backwards ) );
|
||||
}
|
||||
else if( btn == this.storageFilter )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.storageFilter.getSetting(), backwards ) );
|
||||
}
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked( final int xCoord, final int yCoord, final int btn ) throws IOException
|
||||
{
|
||||
boolean wasFocused = this.searchFieldInputs.isFocused();
|
||||
this.searchFieldInputs.mouseClicked( xCoord, yCoord, btn );
|
||||
|
||||
if( btn == 1 && this.searchFieldInputs.isMouseIn( xCoord, yCoord ) )
|
||||
{
|
||||
this.searchFieldInputs.setText( "" );
|
||||
}
|
||||
|
||||
if( !searchFieldInputs.isFocused() && wasFocused )
|
||||
{
|
||||
searchFieldInputs.setText( OreDictFilterMatcher.validateExp( searchFieldInputs.getText() ) );
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.save", searchFieldInputs.getText() ) );
|
||||
}
|
||||
|
||||
super.mouseClicked( xCoord, yCoord, btn );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped( final char character, final int key ) throws IOException
|
||||
{
|
||||
if( !this.checkHotbarKeys( key ) )
|
||||
{
|
||||
if( !this.searchFieldInputs.textboxKeyTyped( character, key ) )
|
||||
{
|
||||
super.keyTyped( character, key );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG( int offsetX, int offsetY, int mouseX, int mouseY )
|
||||
{
|
||||
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.OreDictStorageBus.getLocal() ), 8, 6, 4210752 );
|
||||
this.fontRenderer.drawString( this.searchFieldInputs.getText().length() + " / " + this.searchFieldInputs.getMaxStringLength(), 120, 36, 4210752 );
|
||||
this.fontRenderer.drawString( "& = AND " + "| = OR", 8, 36, 4210752 );
|
||||
this.fontRenderer.drawString( "^ = XOR " + "! = NOT", 8, 48, 4210752 );
|
||||
this.fontRenderer.drawString( "() for priority " + "* for wildcard", 8, 60, 4210752 );
|
||||
this.fontRenderer.drawString( "Ex.: *Redstone*&!dustRedstone", 8, 72, 4210752 );
|
||||
|
||||
if( this.storageFilter != null )
|
||||
{
|
||||
this.storageFilter.set( container.getStorageFilter() );
|
||||
}
|
||||
|
||||
if( this.rwMode != null )
|
||||
{
|
||||
this.rwMode.set( container.getReadWriteMode() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBG( int offsetX, int offsetY, int mouseX, int mouseY )
|
||||
{
|
||||
this.bindTexture( "guis/oredictstoragebus.png" );
|
||||
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, 175, 85 );
|
||||
|
||||
if( this.searchFieldInputs != null )
|
||||
{
|
||||
this.searchFieldInputs.drawTextBox();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,11 +19,21 @@
|
||||
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;
|
||||
@@ -40,7 +50,7 @@ import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
|
||||
|
||||
public class GuiPatternTerm extends GuiMEMonitorable
|
||||
public class GuiPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
|
||||
{
|
||||
|
||||
private static final String BACKGROUND_CRAFTING_MODE = "guis/pattern.png";
|
||||
@@ -67,6 +77,7 @@ public class GuiPatternTerm extends GuiMEMonitorable
|
||||
private GuiImgButton divThreeBtn;
|
||||
private GuiImgButton minusOneBtn;
|
||||
private GuiImgButton maxCountBtn;
|
||||
public Map<Target<?>,Object> mapTargetSlot = new HashMap<>();
|
||||
|
||||
public GuiPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
|
||||
{
|
||||
@@ -274,4 +285,52 @@ public class GuiPatternTerm extends GuiMEMonitorable
|
||||
|
||||
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,8 +19,24 @@
|
||||
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;
|
||||
@@ -43,9 +59,9 @@ import appeng.parts.automation.PartExportBus;
|
||||
import appeng.parts.automation.PartImportBus;
|
||||
|
||||
|
||||
public class GuiUpgradeable extends AEBaseGui
|
||||
public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
|
||||
{
|
||||
|
||||
private final Map<Target<?>,Object> mapTargetSlot = new HashMap<>();
|
||||
protected final ContainerUpgradeable cvb;
|
||||
protected final IUpgradeableHost bc;
|
||||
|
||||
@@ -200,4 +216,111 @@ public class GuiUpgradeable extends AEBaseGui
|
||||
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
|
||||
{
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int id;
|
||||
protected final int x;
|
||||
protected final int y;
|
||||
protected final int id;
|
||||
|
||||
public GuiCustomSlot( final int id, final int x, final int y )
|
||||
{
|
||||
|
||||
@@ -87,6 +87,7 @@ public class GuiImgButton extends GuiButton implements ITooltip
|
||||
this.registerApp( 16 * 10, Settings.POWER_UNITS, PowerUnits.AE, ButtonToolTips.PowerUnits, PowerUnits.AE.unlocalizedName );
|
||||
this.registerApp( 16 * 10 + 1, Settings.POWER_UNITS, PowerUnits.EU, ButtonToolTips.PowerUnits, PowerUnits.EU.unlocalizedName );
|
||||
this.registerApp( 16 * 10 + 4, Settings.POWER_UNITS, PowerUnits.RF, ButtonToolTips.PowerUnits, PowerUnits.RF.unlocalizedName );
|
||||
this.registerApp( 16 * 10 + 1, Settings.POWER_UNITS, PowerUnits.GTEU, ButtonToolTips.PowerUnits, PowerUnits.EU.unlocalizedName );
|
||||
|
||||
this.registerApp( 3, Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE, ButtonToolTips.RedstoneMode, ButtonToolTips.AlwaysActive );
|
||||
this.registerApp( 0, Settings.REDSTONE_CONTROLLED, RedstoneMode.LOW_SIGNAL, ButtonToolTips.RedstoneMode, ButtonToolTips.ActiveWithoutSignal );
|
||||
@@ -108,15 +109,11 @@ public class GuiImgButton extends GuiButton implements ITooltip
|
||||
this.registerApp( 16 * 2 + 3, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Auto );
|
||||
this.registerApp( 16 * 2 + 4, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Standard );
|
||||
this.registerApp( 16 * 2 + 5, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIAuto );
|
||||
this.registerApp( 16 * 2 + 6, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_JEIStandard );
|
||||
this.registerApp( 16 * 2 + 6, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIStandard );
|
||||
this.registerApp( 16 * 2 + 7, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_AutoKeep );
|
||||
this.registerApp( 16 * 2 + 8, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_StandardKeep );
|
||||
this.registerApp( 16 * 2 + 9, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH_KEEP, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_JEIAutoKeep );
|
||||
this.registerApp( 16 * 2 + 10, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_JEIStandardKeep );
|
||||
this.registerApp( 16 * 2 + 8, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_StandardKeep );
|
||||
this.registerApp( 16 * 2 + 9, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIAutoKeep );
|
||||
this.registerApp( 16 * 2 + 10, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIStandardKeep );
|
||||
|
||||
this.registerApp( 16 * 5 + 3, Settings.LEVEL_TYPE, LevelType.ENERGY_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Energy );
|
||||
this.registerApp( 16 * 4 + 3, Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Item );
|
||||
@@ -174,19 +171,15 @@ public class GuiImgButton extends GuiButton implements ITooltip
|
||||
this.registerApp( 16 * 11 + 2, Settings.CRAFT_VIA_REDSTONE, YesNo.YES, ButtonToolTips.EmitterMode, ButtonToolTips.CraftViaRedstone );
|
||||
this.registerApp( 16 * 11 + 1, Settings.CRAFT_VIA_REDSTONE, YesNo.NO, ButtonToolTips.EmitterMode, ButtonToolTips.EmitWhenCrafting );
|
||||
|
||||
this.registerApp( 16 * 3 + 5, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY, ButtonToolTips.ReportInaccessibleItems,
|
||||
ButtonToolTips.ReportInaccessibleItemsNo );
|
||||
this.registerApp( 16 * 3 + 6, Settings.STORAGE_FILTER, StorageFilter.NONE, ButtonToolTips.ReportInaccessibleItems,
|
||||
ButtonToolTips.ReportInaccessibleItemsYes );
|
||||
this.registerApp( 16 * 3 + 5, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY, ButtonToolTips.ReportInaccessibleItems, ButtonToolTips.ReportInaccessibleItemsNo );
|
||||
this.registerApp( 16 * 3 + 6, Settings.STORAGE_FILTER, StorageFilter.NONE, ButtonToolTips.ReportInaccessibleItems, ButtonToolTips.ReportInaccessibleItemsYes );
|
||||
|
||||
this.registerApp( 16 * 14, Settings.PLACE_BLOCK, YesNo.YES, ButtonToolTips.BlockPlacement, ButtonToolTips.BlockPlacementYes );
|
||||
this.registerApp( 16 * 14 + 1, Settings.PLACE_BLOCK, YesNo.NO, ButtonToolTips.BlockPlacement, ButtonToolTips.BlockPlacementNo );
|
||||
|
||||
this.registerApp( 16 * 15, Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeDefault );
|
||||
this.registerApp( 16 * 15 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode,
|
||||
ButtonToolTips.SchedulingModeRoundRobin );
|
||||
this.registerApp( 16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode,
|
||||
ButtonToolTips.SchedulingModeRandom );
|
||||
this.registerApp( 16 * 15 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRoundRobin );
|
||||
this.registerApp( 16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRandom );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +329,7 @@ public class GuiImgButton extends GuiButton implements ITooltip
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
while( i + 30 < sb.length() && ( i = sb.lastIndexOf( " ", i + 30 ) ) != -1 )
|
||||
while ( i + 30 < sb.length() && ( i = sb.lastIndexOf( " ", i + 30 ) ) != -1 )
|
||||
{
|
||||
sb.replace( i, i + 1, "\n" );
|
||||
}
|
||||
|
||||
@@ -22,9 +22,10 @@ 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.GlStateManager;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderItem;
|
||||
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.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
@@ -32,6 +33,7 @@ import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
|
||||
/**
|
||||
@@ -121,6 +123,49 @@ 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.
|
||||
*
|
||||
@@ -147,9 +192,9 @@ public class TesrRenderHelper
|
||||
|
||||
public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing )
|
||||
{
|
||||
final ItemStack renderStack = fluidStack.asItemStackRepresentation();
|
||||
final FluidStack renderStack = fluidStack.getFluidStack();
|
||||
|
||||
TesrRenderHelper.renderItem2d( renderStack, scale );
|
||||
TesrRenderHelper.renderFluid2d( renderStack, scale );
|
||||
|
||||
final long stackSize = fluidStack.getStackSize() / 1000;
|
||||
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
|
||||
|
||||
@@ -19,14 +19,9 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
import appeng.block.storage.BlockDrive;
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
@@ -37,9 +32,12 @@ import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
|
||||
import appeng.block.storage.BlockDrive;
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class DriveBakedModel implements IBakedModel
|
||||
@@ -57,13 +55,17 @@ public class DriveBakedModel implements IBakedModel
|
||||
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
|
||||
{
|
||||
|
||||
List<BakedQuad> result = new ArrayList<>();
|
||||
|
||||
result.addAll( this.bakedBase.getQuads( state, side, rand ) );
|
||||
List<BakedQuad> result = new ArrayList<>( this.bakedBase.getQuads( state, side, rand ) );
|
||||
|
||||
if( side == null && state instanceof IExtendedBlockState )
|
||||
{
|
||||
IExtendedBlockState extState = (IExtendedBlockState) state;
|
||||
|
||||
if (!extState.getUnlistedNames().contains( BlockDrive.SLOTS_STATE ))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
DriveSlotsState slotsState = extState.getValue( BlockDrive.SLOTS_STATE );
|
||||
|
||||
for( int row = 0; row < 5; row++ )
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.concurrent.Future;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -149,6 +150,7 @@ public class ContainerCraftConfirm extends AEBaseContainer
|
||||
if( ccr.getCpu() == c )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,11 +347,15 @@ public class ContainerCraftConfirm extends AEBaseContainer
|
||||
originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( ah instanceof PartExpandedProcessingPatternTerminal )
|
||||
{
|
||||
originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( this.result != null && !this.isSimulation() )
|
||||
{
|
||||
final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class );
|
||||
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true,
|
||||
this.getActionSrc() );
|
||||
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true, this.getActionSrc() );
|
||||
this.setAutoStart( false );
|
||||
if( g != null && originalGui != null && this.getOpenContext() != null )
|
||||
{
|
||||
|
||||
@@ -159,56 +159,58 @@ public class ContainerCraftingCPU extends AEBaseContainer implements IMEMonitorH
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
if( Platform.isServer() && this.getMonitor() != null && !this.list.isEmpty() )
|
||||
if( Platform.isServer() && this.getMonitor() != null )
|
||||
{
|
||||
try
|
||||
if( this.getEstimatedTime() >= 0 )
|
||||
{
|
||||
if( this.getEstimatedTime() >= 0 )
|
||||
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
|
||||
{
|
||||
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 );
|
||||
}
|
||||
final PacketMEInventoryUpdate a = new PacketMEInventoryUpdate( (byte) 0 );
|
||||
final PacketMEInventoryUpdate b = new PacketMEInventoryUpdate( (byte) 1 );
|
||||
final PacketMEInventoryUpdate c = new PacketMEInventoryUpdate( (byte) 2 );
|
||||
|
||||
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 )
|
||||
for( final IAEItemStack out : this.list )
|
||||
{
|
||||
if( !a.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( a, (EntityPlayerMP) g );
|
||||
}
|
||||
a.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.STORAGE ) );
|
||||
b.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.ACTIVE ) );
|
||||
c.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.PENDING ) );
|
||||
}
|
||||
|
||||
if( !b.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( b, (EntityPlayerMP) g );
|
||||
}
|
||||
this.list.resetStatus();
|
||||
|
||||
if( !c.isEmpty() )
|
||||
for( final Object g : this.listeners )
|
||||
{
|
||||
if( g instanceof EntityPlayer )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( c, (EntityPlayerMP) g );
|
||||
if( !a.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( a, (EntityPlayerMP) g );
|
||||
}
|
||||
|
||||
if( !b.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( b, (EntityPlayerMP) g );
|
||||
}
|
||||
|
||||
if( !c.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( c, (EntityPlayerMP) g );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
// :P
|
||||
catch( final IOException e )
|
||||
{
|
||||
// :P
|
||||
}
|
||||
}
|
||||
}
|
||||
super.detectAndSendChanges();
|
||||
|
||||
+528
@@ -0,0 +1,528 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.definitions.IDefinitions;
|
||||
import appeng.api.storage.ITerminalHost;
|
||||
import appeng.container.slot.*;
|
||||
import appeng.helpers.IContainerCraftingPacket;
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.IAEAppEngInventory;
|
||||
import appeng.util.inv.InvOperation;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.PlayerInvWrapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static appeng.helpers.PatternHelper.PROCESSING_INPUT_LIMIT;
|
||||
import static appeng.helpers.PatternHelper.PROCESSING_OUTPUT_LIMIT;
|
||||
|
||||
|
||||
public class ContainerExpandedProcessingPatternTerm extends ContainerMEMonitorable implements IAEAppEngInventory, IOptionalSlotHost, IContainerCraftingPacket
|
||||
{
|
||||
private final IItemHandler crafting;
|
||||
private final SlotFakeCraftingMatrix[] gridSlots = new SlotFakeCraftingMatrix[PROCESSING_INPUT_LIMIT];
|
||||
private final OptionalSlotFake[] outputSlots = new OptionalSlotFake[PROCESSING_OUTPUT_LIMIT];
|
||||
private final SlotRestrictedInput patternSlotIN;
|
||||
private final SlotRestrictedInput patternSlotOUT;
|
||||
private final PartExpandedProcessingPatternTerminal expandedProcessingPatternTerminal;
|
||||
|
||||
public ContainerExpandedProcessingPatternTerm( InventoryPlayer ip, ITerminalHost monitorable )
|
||||
{
|
||||
super( ip, monitorable, false );
|
||||
|
||||
this.expandedProcessingPatternTerminal = (PartExpandedProcessingPatternTerminal) monitorable;
|
||||
|
||||
final IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
|
||||
final IItemHandler output = this.getExpandedPatternTerminal().getInventoryByName( "output" );
|
||||
|
||||
this.crafting = this.getExpandedPatternTerminal().getInventoryByName( "crafting" );
|
||||
|
||||
for( int y = 0; y < 4; y++ )
|
||||
{
|
||||
for( int x = 0; x < 4; x++ )
|
||||
{
|
||||
this.addSlotToContainer( this.gridSlots[x + y * 4] = new SlotFakeCraftingMatrix( this.crafting, x + y * 4, 4 + x * 18, -85 + y * 18 ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( int y = 0; y < 3; y++ )
|
||||
{
|
||||
for( int x = 0; x < 2; x++ )
|
||||
{
|
||||
this.addSlotToContainer( this.outputSlots[x + y * 2] = new SlotPatternOutputs( output, this, x + y * 2, 96 + x * 18, -76 + y * 18, 0, 0, 1 ) );
|
||||
this.outputSlots[x + y * 2].setRenderDisabled( false );
|
||||
this.outputSlots[x + y * 2].setIIcon( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
this.addSlotToContainer( this.patternSlotIN = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.BLANK_PATTERN, patternInv, 0, 147, -72 - 9, this.getInventoryPlayer() ) );
|
||||
this.addSlotToContainer( this.patternSlotOUT = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, patternInv, 1, 147, -72 + 34, this.getInventoryPlayer() ) );
|
||||
|
||||
this.patternSlotOUT.setStackLimit( 1 );
|
||||
|
||||
this.bindPlayerInventory( ip, 0, 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
|
||||
{
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
if( this.inventorySlots.get( idx ) instanceof SlotPlayerInv || this.inventorySlots.get( idx ) instanceof SlotPlayerHotBar )
|
||||
{
|
||||
final AppEngSlot clickSlot = (AppEngSlot) this.inventorySlots.get( idx ); // require AE SLots!
|
||||
ItemStack itemStack = clickSlot.getStack();
|
||||
if( AEApi.instance().definitions().materials().blankPattern().isSameAs( itemStack ) )
|
||||
{
|
||||
IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
|
||||
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
|
||||
clickSlot.putStack( remainder );
|
||||
}
|
||||
}
|
||||
return super.transferStackInSlot( p, idx );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChanges()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeInventory( final IItemHandler inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void encodeAndMoveToInventory()
|
||||
{
|
||||
encode();
|
||||
ItemStack output = this.patternSlotOUT.getStack();
|
||||
if( !output.isEmpty() )
|
||||
{
|
||||
if( !getPlayerInv().addItemStackToInventory( output ) )
|
||||
{
|
||||
getPlayerInv().player.dropItem( output, false );
|
||||
}
|
||||
this.patternSlotOUT.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
}
|
||||
|
||||
public void encode()
|
||||
{
|
||||
ItemStack output = this.patternSlotOUT.getStack();
|
||||
|
||||
final ItemStack[] in = this.getInputs();
|
||||
final ItemStack[] out = this.getOutputs();
|
||||
|
||||
// if there is no input, this would be silly.
|
||||
if( in == null || out == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// first check the output slots, should either be null, or a pattern
|
||||
if( !output.isEmpty() && !this.isPattern( output ) )
|
||||
{
|
||||
return;
|
||||
} // if nothing is there we should snag a new pattern.
|
||||
else if( output.isEmpty() )
|
||||
{
|
||||
output = this.patternSlotIN.getStack();
|
||||
if( output.isEmpty() || !this.isPattern( output ) )
|
||||
{
|
||||
return; // no blanks.
|
||||
}
|
||||
|
||||
// remove one, and clear the input slot.
|
||||
output.setCount( output.getCount() - 1 );
|
||||
if( output.getCount() == 0 )
|
||||
{
|
||||
this.patternSlotIN.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
|
||||
// add a new encoded pattern.
|
||||
Optional<ItemStack> maybePattern = AEApi.instance().definitions().items().encodedPattern().maybeStack( 1 );
|
||||
if( maybePattern.isPresent() )
|
||||
{
|
||||
output = maybePattern.get();
|
||||
this.patternSlotOUT.putStack( output );
|
||||
}
|
||||
}
|
||||
|
||||
// encode the slot.
|
||||
final NBTTagCompound encodedValue = new NBTTagCompound();
|
||||
|
||||
final NBTTagList tagIn = new NBTTagList();
|
||||
final NBTTagList tagOut = new NBTTagList();
|
||||
|
||||
for( final ItemStack i : in )
|
||||
{
|
||||
tagIn.appendTag( this.createItemTag( i ) );
|
||||
}
|
||||
|
||||
for( final ItemStack i : out )
|
||||
{
|
||||
tagOut.appendTag( this.createItemTag( i ) );
|
||||
}
|
||||
|
||||
encodedValue.setTag( "in", tagIn );
|
||||
encodedValue.setTag( "out", tagOut );
|
||||
encodedValue.setBoolean( "crafting", false );
|
||||
encodedValue.setBoolean( "substitute", false );
|
||||
|
||||
output.setTagCompound( encodedValue );
|
||||
}
|
||||
|
||||
boolean isPattern( final ItemStack output )
|
||||
{
|
||||
if( output.isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final IDefinitions definitions = AEApi.instance().definitions();
|
||||
|
||||
boolean isPattern = definitions.items().encodedPattern().isSameAs( output );
|
||||
isPattern |= definitions.materials().blankPattern().isSameAs( output );
|
||||
|
||||
return isPattern;
|
||||
}
|
||||
|
||||
NBTBase createItemTag( final ItemStack i )
|
||||
{
|
||||
final NBTTagCompound c = new NBTTagCompound();
|
||||
|
||||
if( !i.isEmpty() )
|
||||
{
|
||||
i.writeToNBT( c );
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlotEnabled( final int idx )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ItemStack[] getInputs()
|
||||
{
|
||||
final ItemStack[] input = new ItemStack[16];
|
||||
boolean hasValue = false;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() )
|
||||
{
|
||||
hasValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( hasValue )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ItemStack[] getOutputs()
|
||||
{
|
||||
final List<ItemStack> list = new ArrayList<>( 3 );
|
||||
boolean hasValue = false;
|
||||
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
|
||||
if( !out.isEmpty() && out.getCount() > 0 )
|
||||
{
|
||||
list.add( out );
|
||||
hasValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( hasValue )
|
||||
{
|
||||
return list.toArray( new ItemStack[0] );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
for( final Slot s : this.gridSlots )
|
||||
{
|
||||
s.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
|
||||
for( final Slot s : this.outputSlots )
|
||||
{
|
||||
s.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
|
||||
this.detectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getInventoryByName( final String name )
|
||||
{
|
||||
if( name.equals( "player" ) )
|
||||
{
|
||||
return new PlayerInvWrapper( this.getInventoryPlayer() );
|
||||
}
|
||||
return this.getExpandedPatternTerminal().getInventoryByName( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useRealItems()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public PartExpandedProcessingPatternTerminal getExpandedPatternTerminal()
|
||||
{
|
||||
return this.expandedProcessingPatternTerminal;
|
||||
}
|
||||
|
||||
public void multiply( int multiple )
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canMultiplyInputs = true;
|
||||
boolean canMultiplyOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() * multiple > input[x].getMaxStackSize() )
|
||||
{
|
||||
canMultiplyInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() * multiple > out.getMaxStackSize() )
|
||||
{
|
||||
canMultiplyOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canMultiplyInputs && canMultiplyOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() * multiple );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() * multiple );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void divide( int divide )
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canDivideInputs = true;
|
||||
boolean canDivideOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() % divide != 0 )
|
||||
{
|
||||
canDivideInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() % divide != 0 )
|
||||
{
|
||||
canDivideOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canDivideInputs && canDivideOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() / divide );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() / divide );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void increase( int increase )
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canIncreaseInputs = true;
|
||||
boolean canIncreaseOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() + increase > input[x].getMaxStackSize() )
|
||||
{
|
||||
canIncreaseInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() + increase > out.getMaxStackSize() )
|
||||
{
|
||||
canIncreaseOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canIncreaseInputs && canIncreaseOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() + increase );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() + increase );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void decrease( int decrease )
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canDecreaseInputs = true;
|
||||
boolean canDecreaseOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() - decrease < 1 )
|
||||
{
|
||||
canDecreaseInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() - decrease < 1 )
|
||||
{
|
||||
canDecreaseOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canDecreaseInputs && canDecreaseOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() - decrease );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() - decrease );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void maximizeCount()
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canGrowInputs = true;
|
||||
boolean canGrowOutputs = true;
|
||||
int maxInputStackGrowth = 0;
|
||||
int maxOutputStackGrowth = 0;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getMaxStackSize() - input[x].getCount() > maxInputStackGrowth )
|
||||
{
|
||||
maxInputStackGrowth = input[x].getMaxStackSize() - input[x].getCount();
|
||||
}
|
||||
if( !input[x].isEmpty() && input[x].getCount() + maxInputStackGrowth > input[x].getMaxStackSize() )
|
||||
{
|
||||
canGrowInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
{
|
||||
maxOutputStackGrowth = out.getMaxStackSize() - out.getCount();
|
||||
}
|
||||
if( !out.isEmpty() && out.getCount() + maxOutputStackGrowth > out.getMaxStackSize() )
|
||||
{
|
||||
canGrowOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canGrowInputs && canGrowOutputs )
|
||||
{
|
||||
int maxStackGrowth = Math.min( maxInputStackGrowth, maxOutputStackGrowth );
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,9 @@
|
||||
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;
|
||||
@@ -26,14 +29,11 @@ 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
|
||||
public class ContainerInterface extends ContainerUpgradeable implements IOptionalSlotHost
|
||||
{
|
||||
|
||||
private final DualityInterface myDuality;
|
||||
@@ -44,16 +44,22 @@ public class ContainerInterface extends ContainerUpgradeable
|
||||
@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 x = 0; x < DualityInterface.NUMBER_OF_PATTERN_SLOTS; x++ )
|
||||
for (int row = 0 ; row < 4 ; ++row)
|
||||
{
|
||||
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 < 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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( int x = 0; x < DualityInterface.NUMBER_OF_CONFIG_SLOTS; x++ )
|
||||
@@ -70,7 +76,7 @@ public class ContainerInterface extends ContainerUpgradeable
|
||||
@Override
|
||||
protected int getHeight()
|
||||
{
|
||||
return 211;
|
||||
return 256;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,16 +88,35 @@ public class ContainerInterface extends ContainerUpgradeable
|
||||
@Override
|
||||
public int availableUpgrades()
|
||||
{
|
||||
return 1;
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlotEnabled( final int idx )
|
||||
{
|
||||
return myDuality.getInstalledUpgrades(Upgrades.PATTERN_EXPANSION) >= idx;
|
||||
}
|
||||
|
||||
@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 )
|
||||
{
|
||||
@@ -118,4 +143,9 @@ public class ContainerInterface extends ContainerUpgradeable
|
||||
{
|
||||
this.iTermMode = iTermMode;
|
||||
}
|
||||
|
||||
public int getPatternUpgrades()
|
||||
{
|
||||
return this.myDuality.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ 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;
|
||||
@@ -403,7 +404,9 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
||||
{
|
||||
tag.setLong( "sortBy", inv.sortBy );
|
||||
tag.setString( "un", inv.unlocalizedName );
|
||||
tag.setTag("pos", NBTUtil.createPosTag( inv.pos ) );
|
||||
tag.setTag( "pos", NBTUtil.createPosTag( inv.pos ) );
|
||||
tag.setInteger( "dim", inv.dim );
|
||||
tag.setInteger( "numUpgrades", inv.numUpgrades );
|
||||
}
|
||||
|
||||
for( int x = 0; x < length; x++ )
|
||||
@@ -435,6 +438,8 @@ 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 )
|
||||
{
|
||||
@@ -443,6 +448,8 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.*;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
import appeng.parts.misc.PartOreDicStorageBus;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import appeng.util.item.OreReference;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class ContainerOreDictStorageBus extends AEBaseContainer
|
||||
{
|
||||
private final PartOreDicStorageBus part;
|
||||
|
||||
@GuiSync( 3 )
|
||||
public AccessRestriction rwMode = AccessRestriction.READ_WRITE;
|
||||
|
||||
@GuiSync( 4 )
|
||||
public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY;
|
||||
|
||||
public ContainerOreDictStorageBus( final InventoryPlayer ip, final PartOreDicStorageBus anchor )
|
||||
{
|
||||
super( ip, anchor );
|
||||
this.part = anchor;
|
||||
|
||||
this.bindPlayerInventory( ip, 14, 256 - /* height of player inventory */82 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
this.verifyPermissions( SecurityPermissions.BUILD, false );
|
||||
|
||||
if( Platform.isServer() )
|
||||
{
|
||||
this.setReadWriteMode( (AccessRestriction) part.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||
this.setStorageFilter( (StorageFilter) part.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
||||
}
|
||||
|
||||
super.detectAndSendChanges();
|
||||
}
|
||||
|
||||
public void partition()
|
||||
{
|
||||
final IMEInventory<IAEItemStack> cellInv = this.part.getInternalHandler();
|
||||
|
||||
if( cellInv == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Integer> oreIDs = new HashSet<>();
|
||||
|
||||
for( IAEItemStack itemStack : cellInv.getAvailableItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) )
|
||||
{
|
||||
OreReference ref = ( (AEItemStack) itemStack ).getOre().orElse( null );
|
||||
if( ref != null )
|
||||
{
|
||||
oreIDs.addAll( ref.getOres() );
|
||||
}
|
||||
}
|
||||
|
||||
String oreMatch = "(";
|
||||
String append = "";
|
||||
|
||||
for( Iterator<Integer> it = oreIDs.iterator(); it.hasNext(); )
|
||||
{
|
||||
int oreID = it.next();
|
||||
if( it.hasNext() )
|
||||
{
|
||||
append = ")|(";
|
||||
}
|
||||
else
|
||||
{
|
||||
append = ")";
|
||||
}
|
||||
oreMatch = oreMatch.concat( OreDictionary.getOreName( oreID ) + append );
|
||||
}
|
||||
|
||||
if( oreMatch.equals( "(" ) )
|
||||
{
|
||||
oreMatch = "";
|
||||
}
|
||||
part.saveOreMatch( oreMatch );
|
||||
|
||||
this.detectAndSendChanges();
|
||||
}
|
||||
|
||||
public void saveOreMatch( String value )
|
||||
{
|
||||
part.saveOreMatch( value );
|
||||
}
|
||||
|
||||
public void sendRegex()
|
||||
{
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendTo( new PacketValueConfig( "OreDictStorageBus.sendRegex", part.getOreExp() ), (EntityPlayerMP) getInventoryPlayer().player );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public AccessRestriction getReadWriteMode()
|
||||
{
|
||||
return this.rwMode;
|
||||
}
|
||||
|
||||
private void setReadWriteMode( final AccessRestriction rwMode )
|
||||
{
|
||||
this.rwMode = rwMode;
|
||||
}
|
||||
|
||||
public StorageFilter getStorageFilter()
|
||||
{
|
||||
return this.storageFilter;
|
||||
}
|
||||
|
||||
private void setStorageFilter( final StorageFilter storageFilter )
|
||||
{
|
||||
this.storageFilter = storageFilter;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ 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;
|
||||
@@ -51,12 +52,6 @@ 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;
|
||||
@@ -132,6 +127,28 @@ 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() )
|
||||
@@ -161,7 +178,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
this.getAndUpdateOutput();
|
||||
}
|
||||
|
||||
private ItemStack getAndUpdateOutput()
|
||||
protected ItemStack getAndUpdateOutput()
|
||||
{
|
||||
final World world = this.getPlayerInv().player.world;
|
||||
final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 );
|
||||
@@ -488,7 +505,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack[] getInputs()
|
||||
protected ItemStack[] getInputs()
|
||||
{
|
||||
final ItemStack[] input = new ItemStack[9];
|
||||
boolean hasValue = false;
|
||||
@@ -510,7 +527,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
return null;
|
||||
}
|
||||
|
||||
private ItemStack[] getOutputs()
|
||||
protected ItemStack[] getOutputs()
|
||||
{
|
||||
if( this.isCraftingMode() )
|
||||
{
|
||||
@@ -518,7 +535,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
|
||||
if( !out.isEmpty() && out.getCount() > 0 )
|
||||
{
|
||||
return new ItemStack[] { out };
|
||||
return new ItemStack[]{out};
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -546,7 +563,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isPattern( final ItemStack output )
|
||||
boolean isPattern( final ItemStack output )
|
||||
{
|
||||
if( output.isEmpty() )
|
||||
{
|
||||
@@ -561,7 +578,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
return isPattern;
|
||||
}
|
||||
|
||||
private NBTBase createItemTag( final ItemStack i )
|
||||
NBTBase createItemTag( final ItemStack i )
|
||||
{
|
||||
final NBTTagCompound c = new NBTTagCompound();
|
||||
|
||||
@@ -807,7 +824,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
return this.patternTerminal;
|
||||
}
|
||||
|
||||
private boolean isSubstitute()
|
||||
boolean isSubstitute()
|
||||
{
|
||||
return this.substitute;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
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, 1, true ).isEmpty();
|
||||
return !this.itemHandler.extractItem( this.index, Integer.MAX_VALUE, true ).isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
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
|
||||
public class SlotFake extends AppEngSlot implements IJEITargetSlot
|
||||
{
|
||||
|
||||
public SlotFake( final IItemHandler inv, final int idx, final int x, final int y )
|
||||
|
||||
@@ -20,11 +20,7 @@ package appeng.core;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -64,13 +60,67 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
private static AEConfig instance;
|
||||
|
||||
// Default Grindstone ores
|
||||
private static final String[] ORES_VANILLA = { "Obsidian", "Ender", "EnderPearl", "Coal", "Iron", "Gold", "Charcoal", "NetherQuartz" };
|
||||
private static final String[] ORES_AE = { "CertusQuartz", "Wheat", "Fluix" };
|
||||
private static final String[] ORES_COMMON = { "Copper", "Tin", "Silver", "Lead", "Bronze" };
|
||||
private static final String[] ORES_MISC = { "Brass", "Platinum", "Nickel", "Invar", "Aluminium", "Electrum", "Osmium", "Zinc" };
|
||||
private static final String[] ORES_VANILLA = {
|
||||
"Obsidian", "Ender", "EnderPearl", "Coal", "Iron", "Gold",
|
||||
"Charcoal", "NetherQuartz"
|
||||
};
|
||||
private static final String[] ORES_AE = {"CertusQuartz", "Wheat", "Fluix"};
|
||||
private static final String[] ORES_COMMON = {
|
||||
"Copper", "Tin", "Silver", "Lead", "Bronze"
|
||||
};
|
||||
private static final String[] ORES_MISC = {
|
||||
"Brass", "Platinum", "Nickel", "Invar", "Aluminium", "Electrum",
|
||||
"Osmium", "Zinc"
|
||||
};
|
||||
|
||||
private String[] nonBlockingItems = {
|
||||
"[gregtech|actuallyadditions]", "gregtech:circuit.integrated",
|
||||
"gregtech:shape.mold.plate", "gregtech:shape.mold.gear",
|
||||
"gregtech:shape.mold.credit", "gregtech:shape.mold.bottle",
|
||||
"gregtech:shape.mold.ingot", "gregtech:shape.mold.ball",
|
||||
"gregtech:shape.mold.block", "gregtech:shape.mold.nugget",
|
||||
"gregtech:shape.mold.cylinder", "gregtech:shape.mold.anvil",
|
||||
"gregtech:shape.mold.name", "gregtech:shape.mold.gear.small",
|
||||
"gregtech:shape.mold.rotor", "gregtech:shape.extruder.plate",
|
||||
"gregtech:shape.extruder.rod", "gregtech:shape.extruder.bolt",
|
||||
"gregtech:shape.extruder.ring", "gregtech:shape.extruder.cell",
|
||||
"gregtech:shape.extruder.ingot", "gregtech:shape.extruder.wire",
|
||||
"gregtech:shape.extruder.pipe.tiny",
|
||||
"gregtech:shape.extruder.pipe.small",
|
||||
"gregtech:shape.extruder.pipe.medium",
|
||||
"gregtech:shape.extruder.pipe.normal",
|
||||
"gregtech:shape.extruder.pipe.large",
|
||||
"gregtech:shape.extruder.pipe.huge",
|
||||
"gregtech:shape.extruder.block", "gregtech:shape.extruder.sword",
|
||||
"gregtech:shape.extruder.pickaxe", "gregtech:shape.extruder.shovel",
|
||||
"gregtech:shape.extruder.axe", "gregtech:shape.extruder.hoe",
|
||||
"gregtech:shape.extruder.hammer", "gregtech:shape.extruder.file",
|
||||
"gregtech:shape.extruder.saw", "gregtech:shape.extruder.gear",
|
||||
"gregtech:shape.extruder.bottle", "gregtech:shape.extruder.foil",
|
||||
"gregtech:shape.extruder.gear_small",
|
||||
"gregtech:shape.extruder.rod_long", "gregtech:shape.extruder.rotor",
|
||||
"gregtech:glass_lens.white", "gregtech:glass_lens.orange",
|
||||
"gregtech:glass_lens.magenta", "gregtech:glass_lens.light_blue",
|
||||
"gregtech:glass_lens.yellow", "gregtech:glass_lens.lime",
|
||||
"gregtech:glass_lens.pink", "gregtech:glass_lens.gray",
|
||||
"gregtech:glass_lens.light_gray", "gregtech:glass_lens.cyan",
|
||||
"gregtech:glass_lens.purple", "gregtech:glass_lens.blue",
|
||||
"gregtech:glass_lens.brown", "gregtech:glass_lens.green",
|
||||
"gregtech:glass_lens.red", "gregtech:glass_lens.black",
|
||||
"contenttweaker:smallgearextrudershape",
|
||||
"contenttweaker:creativeportabletankmold", "ore:lensAlmandine",
|
||||
"ore:lensBlueTopaz", "ore:lensDiamond", "ore:lensEmerald",
|
||||
"ore:lensGreenSapphire", "ore:lensRutile", "ore:lensRuby",
|
||||
"ore:lensSapphire", "ore:lensTopaz", "ore:lensJasper",
|
||||
"ore:lensGlass", "ore:lensOlivine", "ore:lensOpal",
|
||||
"ore:lensAmethyst", "ore:lensLapis", "ore:lensEnderPearl",
|
||||
"ore:lensEnderEye", "ore:lensGarnetRed", "ore:lensGarnetYellow",
|
||||
"ore:lensVinteum", "ore:lensNetherStar",
|
||||
};
|
||||
|
||||
// Default Energy Conversion Rates
|
||||
private static final double DEFAULT_IC2_EXCHANGE = 2.0;
|
||||
private static final double DEFAULT_GTEU_EXCHANGE = 2.0;
|
||||
private static final double DEFAULT_RF_EXCHANGE = 0.5;
|
||||
|
||||
private final IConfigManager settings = new ConfigManager( this );
|
||||
@@ -90,10 +140,10 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
private PowerUnits selectedPowerUnit = PowerUnits.AE;
|
||||
|
||||
// GUI Buttons
|
||||
private final int[] craftByStacks = { 1, 10, 100, 1000 };
|
||||
private final int[] priorityByStacks = { 1, 10, 100, 1000 };
|
||||
private final int[] levelByStacks = { 1, 10, 100, 1000 };
|
||||
private final int[] levelByMillibuckets = { 10, 100, 1000, 10000 };
|
||||
private final int[] craftByStacks = {1, 10, 100, 1000};
|
||||
private final int[] priorityByStacks = {1, 10, 100, 1000};
|
||||
private final int[] levelByStacks = {1, 10, 100, 1000};
|
||||
private final int[] levelByMillibuckets = {10, 100, 1000, 10000};
|
||||
|
||||
// Spatial IO/Dimension
|
||||
private int storageProviderID = -1;
|
||||
@@ -125,7 +175,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
private int minMeteoriteDistanceSq = this.minMeteoriteDistance * this.minMeteoriteDistance;
|
||||
private double meteoriteClusterChance = 0.1;
|
||||
private int meteoriteMaximumSpawnHeight = 180;
|
||||
private int[] meteoriteDimensionWhitelist = { 0 };
|
||||
private int[] meteoriteDimensionWhitelist = {0};
|
||||
|
||||
// Wireless
|
||||
private double wirelessBaseCost = 8;
|
||||
@@ -148,6 +198,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
|
||||
PowerUnits.EU.conversionRatio = this.get( "PowerRatios", "IC2", DEFAULT_IC2_EXCHANGE ).getDouble( DEFAULT_IC2_EXCHANGE );
|
||||
PowerUnits.RF.conversionRatio = this.get( "PowerRatios", "ForgeEnergy", DEFAULT_RF_EXCHANGE ).getDouble( DEFAULT_RF_EXCHANGE );
|
||||
PowerUnits.GTEU.conversionRatio = this.get( "PowerRatios", "GTEU", DEFAULT_GTEU_EXCHANGE ).getDouble( DEFAULT_GTEU_EXCHANGE );
|
||||
|
||||
final double usageEffective = this.get( "PowerRatios", "UsageMultiplier", 1.0 ).getDouble( 1.0 );
|
||||
PowerMultiplier.CONFIG.multiplier = Math.max( 0.01, usageEffective );
|
||||
@@ -155,32 +206,24 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
CondenserOutput.MATTER_BALLS.requiredPower = this.get( "Condenser", "MatterBalls", 256 ).getInt( 256 );
|
||||
CondenserOutput.SINGULARITY.requiredPower = this.get( "Condenser", "Singularity", 256000 ).getInt( 256000 );
|
||||
|
||||
this.removeCrashingItemsOnLoad = this.get( "general", "removeCrashingItemsOnLoad", false,
|
||||
"Will auto-remove items that crash when being loaded from storage. This will destroy those items instead of crashing the game!" ).getBoolean();
|
||||
this.removeCrashingItemsOnLoad = this.get( "general", "removeCrashingItemsOnLoad", false, "Will auto-remove items that crash when being loaded from storage. This will destroy those items instead of crashing the game!" ).getBoolean();
|
||||
|
||||
this.setCategoryComment( "GrindStone",
|
||||
"Creates recipe of the following pattern automatically: '1 oreTYPE => 2 dustTYPE' and '(1 ingotTYPE or 1 crystalTYPE or 1 gemTYPE) => 1 dustTYPE'" );
|
||||
this.grinderOres = this.get( "GrindStone", "grinderOres", this.grinderOres, "The list of types to handle. Specify without a prefix like ore or dust." )
|
||||
.getStringList();
|
||||
this.grinderBlackList = Sets.newHashSet(
|
||||
this.get( "GrindStone", "blacklist", new String[] {}, "Blacklists the exact oredict name from being handled by any recipe." )
|
||||
.getStringList() );
|
||||
this.oreDoublePercentage = this
|
||||
.get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage, "Chance to actually get an output with stacksize > 1." )
|
||||
.getDouble( this.oreDoublePercentage );
|
||||
this.setCategoryComment( "BlockingMode", "Map of items to not block when blockingmode is enabled.\n[modid]\nmodid:item:metadata(optional,default:0)\nSupports more than one modid, so you can block different things between, for example, gregtech or enderio" );
|
||||
this.nonBlockingItems = this.get( "BlockingMode", "nonBlockingItems", nonBlockingItems, "NonBlockingItems" ).getStringList();
|
||||
|
||||
this.setCategoryComment( "GrindStone", "Creates recipe of the following pattern automatically: '1 oreTYPE => 2 dustTYPE' and '(1 ingotTYPE or 1 crystalTYPE or 1 gemTYPE) => 1 dustTYPE'" );
|
||||
this.grinderOres = this.get( "GrindStone", "grinderOres", this.grinderOres, "The list of types to handle. Specify without a prefix like ore or dust." ).getStringList();
|
||||
this.grinderBlackList = Sets.newHashSet( this.get( "GrindStone", "blacklist", new String[]{}, "Blacklists the exact oredict name from being handled by any recipe." ).getStringList() );
|
||||
this.oreDoublePercentage = this.get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage, "Chance to actually get an output with stacksize > 1." ).getDouble( this.oreDoublePercentage );
|
||||
|
||||
this.settings.registerSetting( Settings.SEARCH_TOOLTIPS, YesNo.YES );
|
||||
this.settings.registerSetting( Settings.TERMINAL_STYLE, TerminalStyle.TALL );
|
||||
this.settings.registerSetting( Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH );
|
||||
|
||||
this.spawnChargedChance = (float) ( 1.0 - this.get( "worldGen", "spawnChargedChance", 1.0 - this.spawnChargedChance )
|
||||
.getDouble(
|
||||
1.0 - this.spawnChargedChance ) );
|
||||
this.spawnChargedChance = (float) ( 1.0 - this.get( "worldGen", "spawnChargedChance", 1.0 - this.spawnChargedChance ).getDouble( 1.0 - this.spawnChargedChance ) );
|
||||
this.minMeteoriteDistance = this.get( "worldGen", "minMeteoriteDistance", this.minMeteoriteDistance ).getInt( this.minMeteoriteDistance );
|
||||
this.meteoriteClusterChance = this.get( "worldGen", "meteoriteClusterChance", this.meteoriteClusterChance ).getDouble( this.meteoriteClusterChance );
|
||||
this.meteoriteMaximumSpawnHeight = this.get( "worldGen", "meteoriteMaximumSpawnHeight", this.meteoriteMaximumSpawnHeight )
|
||||
.getInt(
|
||||
this.meteoriteMaximumSpawnHeight );
|
||||
this.meteoriteMaximumSpawnHeight = this.get( "worldGen", "meteoriteMaximumSpawnHeight", this.meteoriteMaximumSpawnHeight ).getInt( this.meteoriteMaximumSpawnHeight );
|
||||
this.meteoriteDimensionWhitelist = this.get( "worldGen", "meteoriteDimensionWhitelist", this.meteoriteDimensionWhitelist ).getIntList();
|
||||
|
||||
this.quartzOresPerCluster = this.get( "worldGen", "quartzOresPerCluster", this.quartzOresPerCluster ).getInt( this.quartzOresPerCluster );
|
||||
@@ -188,23 +231,16 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
|
||||
this.minMeteoriteDistanceSq = this.minMeteoriteDistance * this.minMeteoriteDistance;
|
||||
|
||||
this.addCustomCategoryComment( "wireless",
|
||||
"Range= wirelessBaseRange + wirelessBoosterRangeMultiplier * Math.pow( boosters, wirelessBoosterExp )\nPowerDrain= wirelessBaseCost + wirelessCostMultiplier * Math.pow( boosters, 1 + boosters / wirelessHighWirelessCount )" );
|
||||
this.addCustomCategoryComment( "wireless", "Range= wirelessBaseRange + wirelessBoosterRangeMultiplier * Math.pow( boosters, wirelessBoosterExp )\nPowerDrain= wirelessBaseCost + wirelessCostMultiplier * Math.pow( boosters, 1 + boosters / wirelessHighWirelessCount )" );
|
||||
|
||||
this.wirelessBaseCost = this.get( "wireless", "wirelessBaseCost", this.wirelessBaseCost ).getDouble( this.wirelessBaseCost );
|
||||
this.wirelessCostMultiplier = this.get( "wireless", "wirelessCostMultiplier", this.wirelessCostMultiplier ).getDouble( this.wirelessCostMultiplier );
|
||||
this.wirelessBaseRange = this.get( "wireless", "wirelessBaseRange", this.wirelessBaseRange ).getDouble( this.wirelessBaseRange );
|
||||
this.wirelessBoosterRangeMultiplier = this.get( "wireless", "wirelessBoosterRangeMultiplier", this.wirelessBoosterRangeMultiplier )
|
||||
.getDouble(
|
||||
this.wirelessBoosterRangeMultiplier );
|
||||
this.wirelessBoosterRangeMultiplier = this.get( "wireless", "wirelessBoosterRangeMultiplier", this.wirelessBoosterRangeMultiplier ).getDouble( this.wirelessBoosterRangeMultiplier );
|
||||
this.wirelessBoosterExp = this.get( "wireless", "wirelessBoosterExp", this.wirelessBoosterExp ).getDouble( this.wirelessBoosterExp );
|
||||
this.wirelessTerminalDrainMultiplier = this.get( "wireless", "wirelessTerminalDrainMultiplier", this.wirelessTerminalDrainMultiplier )
|
||||
.getDouble(
|
||||
this.wirelessTerminalDrainMultiplier );
|
||||
this.wirelessTerminalDrainMultiplier = this.get( "wireless", "wirelessTerminalDrainMultiplier", this.wirelessTerminalDrainMultiplier ).getDouble( this.wirelessTerminalDrainMultiplier );
|
||||
|
||||
this.formationPlaneEntityLimit = this.get( "automation", "formationPlaneEntityLimit", this.formationPlaneEntityLimit )
|
||||
.getInt(
|
||||
this.formationPlaneEntityLimit );
|
||||
this.formationPlaneEntityLimit = this.get( "automation", "formationPlaneEntityLimit", this.formationPlaneEntityLimit ).getInt( this.formationPlaneEntityLimit );
|
||||
|
||||
this.wirelessTerminalBattery = this.get( "battery", "wirelessTerminal", this.wirelessTerminalBattery ).getInt( this.wirelessTerminalBattery );
|
||||
this.chargedStaffBattery = this.get( "battery", "chargedStaff", this.chargedStaffBattery ).getInt( this.chargedStaffBattery );
|
||||
@@ -245,8 +281,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
|
||||
try
|
||||
{
|
||||
this.selectedPowerUnit = PowerUnits.valueOf(
|
||||
this.get( "Client", "PowerUnit", this.selectedPowerUnit.name(), this.getListComment( this.selectedPowerUnit ) ).getString() );
|
||||
this.selectedPowerUnit = PowerUnits.valueOf( this.get( "Client", "PowerUnit", this.selectedPowerUnit.name(), this.getListComment( this.selectedPowerUnit ) ).getString() );
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
@@ -262,17 +297,13 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
{
|
||||
this.storageProviderID = this.get( "spatialio", "storageProviderID", this.storageProviderID ).getInt( this.storageProviderID );
|
||||
this.storageDimensionID = this.get( "spatialio", "storageDimensionID", this.storageDimensionID ).getInt( this.storageDimensionID );
|
||||
this.spatialPowerMultiplier = this.get( "spatialio", "spatialPowerMultiplier", this.spatialPowerMultiplier )
|
||||
.getDouble(
|
||||
this.spatialPowerMultiplier );
|
||||
this.spatialPowerMultiplier = this.get( "spatialio", "spatialPowerMultiplier", this.spatialPowerMultiplier ).getDouble( this.spatialPowerMultiplier );
|
||||
this.spatialPowerExponent = this.get( "spatialio", "spatialPowerExponent", this.spatialPowerExponent ).getDouble( this.spatialPowerExponent );
|
||||
}
|
||||
|
||||
if( this.isFeatureEnabled( AEFeature.CRAFTING_CPU ) )
|
||||
{
|
||||
this.craftingCalculationTimePerTick = this.get( "craftingCPU", "craftingCalculationTimePerTick", this.craftingCalculationTimePerTick )
|
||||
.getInt(
|
||||
this.craftingCalculationTimePerTick );
|
||||
this.craftingCalculationTimePerTick = this.get( "craftingCPU", "craftingCalculationTimePerTick", this.craftingCalculationTimePerTick ).getInt( this.craftingCalculationTimePerTick );
|
||||
}
|
||||
|
||||
this.updatable = true;
|
||||
@@ -446,8 +477,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
return true;
|
||||
}
|
||||
|
||||
this.setCategoryComment( "OreCamouflage",
|
||||
"AE2 Automatically uses alternative ores present in your instance of MC to blend better with its surroundings, if you prefer you can disable this selectively using these flags; Its important to note, that some if these items even if enabled may not be craftable in game because other items are overriding their recipes." );
|
||||
this.setCategoryComment( "OreCamouflage", "AE2 Automatically uses alternative ores present in your instance of MC to blend better with its surroundings, if you prefer you can disable this selectively using these flags; Its important to note, that some if these items even if enabled may not be craftable in game because other items are overriding their recipes." );
|
||||
final Property p = this.get( "OreCamouflage", mt.name(), true );
|
||||
p.setComment( "OreDictionary Names: " + mt.getOreName() );
|
||||
|
||||
@@ -715,6 +745,11 @@ public final class AEConfig extends Configuration implements IConfigurableObject
|
||||
return this.quartzOresClusterAmount;
|
||||
}
|
||||
|
||||
public String[] getNonBlockingItems()
|
||||
{
|
||||
return nonBlockingItems;
|
||||
}
|
||||
|
||||
public int getChargedChange()
|
||||
{
|
||||
return this.chargedChange;
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.helpers.NonBlockingItems;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -183,8 +184,7 @@ public final class AppEng
|
||||
AELog.info( "Pre Initialization ( ended after " + watch.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
|
||||
|
||||
// Instantiate all Plugins
|
||||
List<Object> injectables = Lists.newArrayList(
|
||||
AEApi.instance() );
|
||||
List<Object> injectables = Lists.newArrayList( AEApi.instance() );
|
||||
new PluginLoader().loadPlugins( injectables, event.getAsmData() );
|
||||
}
|
||||
|
||||
@@ -239,6 +239,8 @@ public final class AppEng
|
||||
AppEng.proxy.postInit();
|
||||
AEConfig.instance().save();
|
||||
|
||||
NonBlockingItems.INSTANCE.init();
|
||||
|
||||
NetworkRegistry.INSTANCE.registerGuiHandler( this, GuiBridge.GUI_Handler );
|
||||
NetworkHandler.init( "AE2" );
|
||||
|
||||
|
||||
@@ -363,6 +363,8 @@ 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 125;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -86,6 +86,7 @@ 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;
|
||||
@@ -204,6 +205,7 @@ 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 ) );
|
||||
@@ -424,6 +426,9 @@ public final class ApiMaterials implements IMaterials
|
||||
return this.cardCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition cardPatternExpansion(){ return this.cardPatternExpansion;}
|
||||
|
||||
@Override
|
||||
public IItemDefinition cardFuzzy()
|
||||
{
|
||||
|
||||
@@ -52,6 +52,7 @@ public final class ApiParts implements IParts
|
||||
private final IItemDefinition toggleBus;
|
||||
private final IItemDefinition invertedToggleBus;
|
||||
private final IItemDefinition storageBus;
|
||||
private final IItemDefinition oreDictStorageBus;
|
||||
private final IItemDefinition importBus;
|
||||
private final IItemDefinition exportBus;
|
||||
private final IItemDefinition iface;
|
||||
@@ -69,6 +70,7 @@ public final class ApiParts implements IParts
|
||||
private final IItemDefinition p2PTunnelFluids;
|
||||
private final IItemDefinition p2PTunnelEU;
|
||||
private final IItemDefinition p2PTunnelFE;
|
||||
private final IItemDefinition p2PTunnelGTEU;
|
||||
private final IItemDefinition p2PTunnelLight;
|
||||
// private final IItemDefinition p2PTunnelOpenComputers;
|
||||
private final IItemDefinition cableAnchor;
|
||||
@@ -77,6 +79,7 @@ public final class ApiParts implements IParts
|
||||
private final IItemDefinition darkMonitor;
|
||||
private final IItemDefinition interfaceTerminal;
|
||||
private final IItemDefinition patternTerminal;
|
||||
private final IItemDefinition expandedProcessingPatternTerminal;
|
||||
private final IItemDefinition craftingTerminal;
|
||||
private final IItemDefinition terminal;
|
||||
private final IItemDefinition storageMonitor;
|
||||
@@ -89,9 +92,7 @@ public final class ApiParts implements IParts
|
||||
public ApiParts( FeatureFactory registry, PartModels partModels )
|
||||
{
|
||||
final ItemPart itemPart = new ItemPart();
|
||||
registry.item( "part", () -> itemPart )
|
||||
.rendering( new ItemPartRendering( partModels, itemPart ) )
|
||||
.build();
|
||||
registry.item( "part", () -> itemPart ).rendering( new ItemPartRendering( partModels, itemPart ) ).build();
|
||||
|
||||
// Register all part models
|
||||
for( PartType partType : PartType.values() )
|
||||
@@ -112,6 +113,7 @@ public final class ApiParts implements IParts
|
||||
this.toggleBus = new DamagedItemDefinition( "part.toggle_bus", itemPart.createPart( PartType.TOGGLE_BUS ) );
|
||||
this.invertedToggleBus = new DamagedItemDefinition( "part.toggle_bus.inverted", itemPart.createPart( PartType.INVERTED_TOGGLE_BUS ) );
|
||||
this.storageBus = new DamagedItemDefinition( "part.bus.storage", itemPart.createPart( PartType.STORAGE_BUS ) );
|
||||
this.oreDictStorageBus = new DamagedItemDefinition( "part.bus.oredict_storage", itemPart.createPart( PartType.OREDICT_STORAGE_BUS ) );
|
||||
this.importBus = new DamagedItemDefinition( "part.bus.import", itemPart.createPart( PartType.IMPORT_BUS ) );
|
||||
this.exportBus = new DamagedItemDefinition( "part.bus.export", itemPart.createPart( PartType.EXPORT_BUS ) );
|
||||
this.iface = new DamagedItemDefinition( "part.interface", itemPart.createPart( PartType.INTERFACE ) );
|
||||
@@ -119,8 +121,7 @@ public final class ApiParts implements IParts
|
||||
this.levelEmitter = new DamagedItemDefinition( "part.level_emitter", itemPart.createPart( PartType.LEVEL_EMITTER ) );
|
||||
this.fluidLevelEmitter = new DamagedItemDefinition( "part.fluid_level_emitter", itemPart.createPart( PartType.FLUID_LEVEL_EMITTER ) );
|
||||
this.annihilationPlane = new DamagedItemDefinition( "part.plane.annihilation", itemPart.createPart( PartType.ANNIHILATION_PLANE ) );
|
||||
this.identityAnnihilationPlane = new DamagedItemDefinition( "part.plane.annihiliation.identity", itemPart
|
||||
.createPart( PartType.IDENTITY_ANNIHILATION_PLANE ) );
|
||||
this.identityAnnihilationPlane = new DamagedItemDefinition( "part.plane.annihiliation.identity", itemPart.createPart( PartType.IDENTITY_ANNIHILATION_PLANE ) );
|
||||
this.fluidAnnihilationPlane = new DamagedItemDefinition( "part.plane.fluid_annihilation", itemPart.createPart( PartType.FLUID_ANNIHILATION_PLANE ) );
|
||||
this.formationPlane = new DamagedItemDefinition( "part.plane.formation", itemPart.createPart( PartType.FORMATION_PLANE ) );
|
||||
this.fluidFormationPlane = new DamagedItemDefinition( "part.plane.fluid_formation", itemPart.createPart( PartType.FLUID_FORMATION_PLANE ) );
|
||||
@@ -130,6 +131,7 @@ public final class ApiParts implements IParts
|
||||
this.p2PTunnelFluids = new DamagedItemDefinition( "part.tunnel.fluid", itemPart.createPart( PartType.P2P_TUNNEL_FLUIDS ) );
|
||||
this.p2PTunnelEU = new DamagedItemDefinition( "part.tunnel.eu", itemPart.createPart( PartType.P2P_TUNNEL_IC2 ) );
|
||||
this.p2PTunnelFE = new DamagedItemDefinition( "part.tunnel.fe", itemPart.createPart( PartType.P2P_TUNNEL_FE ) );
|
||||
this.p2PTunnelGTEU = new DamagedItemDefinition( "part.tunnel.gteu", itemPart.createPart( PartType.P2P_TUNNEL_GTEU ) );
|
||||
this.p2PTunnelLight = new DamagedItemDefinition( "part.tunnel.light", itemPart.createPart( PartType.P2P_TUNNEL_LIGHT ) );
|
||||
// this.p2PTunnelOpenComputers = new DamagedItemDefinition( itemMultiPart.createPart(
|
||||
// PartType.P2PTunnelOpenComputers ) );
|
||||
@@ -139,6 +141,7 @@ public final class ApiParts implements IParts
|
||||
this.darkMonitor = new DamagedItemDefinition( "part.monitor.dark", itemPart.createPart( PartType.DARK_MONITOR ) );
|
||||
this.interfaceTerminal = new DamagedItemDefinition( "part.terminal.interface", itemPart.createPart( PartType.INTERFACE_TERMINAL ) );
|
||||
this.patternTerminal = new DamagedItemDefinition( "part.terminal.pattern", itemPart.createPart( PartType.PATTERN_TERMINAL ) );
|
||||
this.expandedProcessingPatternTerminal = new DamagedItemDefinition( "part.terminal.expanded_processing_pattern", itemPart.createPart( PartType.EXPANDED_PROCESSING_PATTERN_TERMINAL ) );
|
||||
this.craftingTerminal = new DamagedItemDefinition( "part.terminal.crafting", itemPart.createPart( PartType.CRAFTING_TERMINAL ) );
|
||||
this.terminal = new DamagedItemDefinition( "part.terminal", itemPart.createPart( PartType.TERMINAL ) );
|
||||
this.storageMonitor = new DamagedItemDefinition( "part.monitor.storage", itemPart.createPart( PartType.STORAGE_MONITOR ) );
|
||||
@@ -245,6 +248,12 @@ public final class ApiParts implements IParts
|
||||
return this.storageBus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition oreDictStorageBus()
|
||||
{
|
||||
return this.oreDictStorageBus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition importBus()
|
||||
{
|
||||
@@ -329,6 +338,11 @@ public final class ApiParts implements IParts
|
||||
return this.p2PTunnelFE;
|
||||
}
|
||||
|
||||
public IItemDefinition p2PTunnelGTEU()
|
||||
{
|
||||
return this.p2PTunnelGTEU;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition p2PTunnelLight()
|
||||
{
|
||||
@@ -379,6 +393,12 @@ public final class ApiParts implements IParts
|
||||
return this.patternTerminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition expandedProcessingPatternTerminal()
|
||||
{
|
||||
return this.expandedProcessingPatternTerminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition craftingTerminal()
|
||||
{
|
||||
|
||||
@@ -25,13 +25,13 @@ public enum AEFeature
|
||||
// is just flat out required by tons of
|
||||
// important stuff.
|
||||
CORE( "Core", null )
|
||||
{
|
||||
@Override
|
||||
public boolean isVisible()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
@Override
|
||||
public boolean isVisible()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
CERTUS_QUARTZ_WORLD_GEN( "CertusQuartzWorldGen", Constants.CATEGORY_WORLD ),
|
||||
METEORITE_WORLD_GEN( "MeteoriteWorldGen", Constants.CATEGORY_WORLD ),
|
||||
@@ -126,6 +126,7 @@ public enum AEFeature
|
||||
P2P_TUNNEL_REDSTONE( "P2PTunnelRedstone", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2P_TUNNEL_EU( "P2PTunnelEU", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2P_TUNNEL_FE( "P2PTunnelFE", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2P_TUNNEL_GTEU( "P2PTunnelGTEU", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2P_TUNNEL_FLUIDS( "P2PTunnelFluids", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2P_TUNNEL_LIGHT( "P2PTunnelLight", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
P2P_TUNNEL_OPEN_COMPUTERS( "P2PTunnelOpenComputers", Constants.CATEGORY_P2P_TUNNELS ),
|
||||
@@ -163,8 +164,6 @@ public enum AEFeature
|
||||
MOLECULAR_ASSEMBLER( "MolecularAssembler", Constants.CATEGORY_CRAFTING_FEATURES ),
|
||||
PATTERNS( "Patterns", Constants.CATEGORY_CRAFTING_FEATURES ),
|
||||
CRAFTING_CPU( "CraftingCPU", Constants.CATEGORY_CRAFTING_FEATURES ),
|
||||
CRAFTING_MANAGER_FALLBACK( "CraftingManagerFallback", Constants.CATEGORY_CRAFTING_FEATURES, "Use CraftingManager to find an alternative recipe, after a pattern rejected an ingredient. Should be enabled to avoid issues, but can have a minor performance impact." ),
|
||||
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 ),
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
package appeng.core.features.registries;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import appeng.util.item.OreHelper;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
@@ -67,6 +68,25 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
this.addNewAttunement( new ItemStack( Blocks.TORCH ), TunnelType.LIGHT );
|
||||
this.addNewAttunement( new ItemStack( Blocks.GLOWSTONE ), TunnelType.LIGHT );
|
||||
|
||||
List<String> gtceOreDict = new ArrayList<>();
|
||||
gtceOreDict.add( "wireGtHex" );
|
||||
gtceOreDict.add( "wireGtOctal" );
|
||||
gtceOreDict.add( "wireGtQuadruple" );
|
||||
gtceOreDict.add( "wireGtDouble" );
|
||||
gtceOreDict.add( "wireGtSingle" );
|
||||
gtceOreDict.add( "cableGtHex" );
|
||||
gtceOreDict.add( "cableGtOctal" );
|
||||
gtceOreDict.add( "cableGtQuadruple" );
|
||||
gtceOreDict.add( "cableGtDouble" );
|
||||
gtceOreDict.add( "cableGtSingle" );
|
||||
|
||||
for( String oreDict : gtceOreDict )
|
||||
{
|
||||
Arrays.stream( OreDictionary.getOreNames() ).filter( oreName -> oreName.startsWith( oreDict ) ).forEach( oreName -> {
|
||||
OreHelper.INSTANCE.getCachedOres( oreName ).forEach( stack -> this.addNewAttunement( stack, TunnelType.GTEU_POWER ) );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Forge energy tunnel items
|
||||
*/
|
||||
@@ -127,12 +147,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
this.addNewAttunement( this.getModItem( "enderio", "itemitemconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.ITEM );
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 0 ), TunnelType.ITEM ); // itemduct
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 1 ), TunnelType.ITEM ); // itemduct
|
||||
// (opaque)
|
||||
// (opaque)
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 2 ), TunnelType.ITEM ); // impulse
|
||||
// itemduct
|
||||
// itemduct
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 3 ), TunnelType.ITEM ); // impulse
|
||||
// itemduct
|
||||
// (opaque)
|
||||
// itemduct
|
||||
// (opaque)
|
||||
|
||||
/**
|
||||
* attune based on lots of random item related stuff
|
||||
@@ -148,12 +168,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
|
||||
this.addNewAttunement( this.getModItem( "enderio", "itemliquidconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.FLUID );
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 0 ), TunnelType.FLUID ); // fluiduct
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 1 ), TunnelType.FLUID ); // fluiduct
|
||||
// (opaque)
|
||||
// (opaque)
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 2 ), TunnelType.FLUID ); // fluiduct
|
||||
// hardened
|
||||
// hardened
|
||||
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 3 ), TunnelType.FLUID ); // fluiduct
|
||||
// hardened
|
||||
// (opaque)
|
||||
// hardened
|
||||
// (opaque)
|
||||
|
||||
for( final AEColor c : AEColor.values() )
|
||||
{
|
||||
|
||||
@@ -70,6 +70,7 @@ public enum GuiText
|
||||
EnergyDrain,
|
||||
|
||||
StorageBus,
|
||||
OreDictStorageBus,
|
||||
StorageBusFluids,
|
||||
Priority,
|
||||
Security,
|
||||
@@ -98,6 +99,7 @@ public enum GuiText
|
||||
OCTunnel,
|
||||
LightTunnel,
|
||||
FETunnel,
|
||||
GTEUTunnel,
|
||||
PressureTunnel,
|
||||
|
||||
// spatial
|
||||
|
||||
@@ -31,8 +31,10 @@ public enum WailaText
|
||||
DeviceMissingChannel,
|
||||
|
||||
P2PUnlinked,
|
||||
P2PInputOneOutput,
|
||||
P2PInputManyOutputs,
|
||||
P2P_INPUT_ONE_OUTPUT,
|
||||
P2P_INPUT_MANY_OUTPUTS,
|
||||
P2P_OUTPUT_ONE_INPUT,
|
||||
P2P_OUTPUT_MANY_INPUTS,
|
||||
P2POutput,
|
||||
|
||||
Locked,
|
||||
|
||||
@@ -24,34 +24,9 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import appeng.core.sync.packets.*;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import appeng.core.sync.packets.PacketAssemblerAnimation;
|
||||
import appeng.core.sync.packets.PacketClick;
|
||||
import appeng.core.sync.packets.PacketCompassRequest;
|
||||
import appeng.core.sync.packets.PacketCompassResponse;
|
||||
import appeng.core.sync.packets.PacketCompressedNBT;
|
||||
import appeng.core.sync.packets.PacketConfigButton;
|
||||
import appeng.core.sync.packets.PacketCraftRequest;
|
||||
import appeng.core.sync.packets.PacketFluidSlot;
|
||||
import appeng.core.sync.packets.PacketInventoryAction;
|
||||
import appeng.core.sync.packets.PacketJEIRecipe;
|
||||
import appeng.core.sync.packets.PacketLightning;
|
||||
import appeng.core.sync.packets.PacketMEFluidInventoryUpdate;
|
||||
import appeng.core.sync.packets.PacketMEInventoryUpdate;
|
||||
import appeng.core.sync.packets.PacketMatterCannon;
|
||||
import appeng.core.sync.packets.PacketMockExplosion;
|
||||
import appeng.core.sync.packets.PacketPaintedEntity;
|
||||
import appeng.core.sync.packets.PacketPartPlacement;
|
||||
import appeng.core.sync.packets.PacketPatternSlot;
|
||||
import appeng.core.sync.packets.PacketProgressBar;
|
||||
import appeng.core.sync.packets.PacketSwapSlots;
|
||||
import appeng.core.sync.packets.PacketSwitchGuis;
|
||||
import appeng.core.sync.packets.PacketTargetFluidStack;
|
||||
import appeng.core.sync.packets.PacketTargetItemStack;
|
||||
import appeng.core.sync.packets.PacketTransitionEffect;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
|
||||
|
||||
public class AppEngPacketHandlerBase
|
||||
{
|
||||
@@ -107,7 +82,10 @@ public class AppEngPacketHandlerBase
|
||||
|
||||
PACKET_PAINTED_ENTITY( PacketPaintedEntity.class ),
|
||||
|
||||
PACKET_FLUID_TANK( PacketFluidSlot.class );
|
||||
PACKET_FLUID_TANK( PacketFluidSlot.class ),
|
||||
|
||||
PACKET_INFORM_PLAYER( PacketInformPlayer.class );
|
||||
|
||||
|
||||
private final Class<? extends AppEngPacket> packetClass;
|
||||
private final Constructor<? extends AppEngPacket> packetConstructor;
|
||||
|
||||
@@ -21,6 +21,9 @@ package appeng.core.sync;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import appeng.container.implementations.*;
|
||||
import appeng.parts.misc.PartOreDicStorageBus;
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -53,39 +56,6 @@ import appeng.client.gui.GuiNull;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.ContainerNull;
|
||||
import appeng.container.ContainerOpenContext;
|
||||
import appeng.container.implementations.ContainerCellWorkbench;
|
||||
import appeng.container.implementations.ContainerChest;
|
||||
import appeng.container.implementations.ContainerCondenser;
|
||||
import appeng.container.implementations.ContainerCraftAmount;
|
||||
import appeng.container.implementations.ContainerCraftConfirm;
|
||||
import appeng.container.implementations.ContainerCraftingCPU;
|
||||
import appeng.container.implementations.ContainerCraftingStatus;
|
||||
import appeng.container.implementations.ContainerCraftingTerm;
|
||||
import appeng.container.implementations.ContainerDrive;
|
||||
import appeng.container.implementations.ContainerFormationPlane;
|
||||
import appeng.container.implementations.ContainerGrinder;
|
||||
import appeng.container.implementations.ContainerIOPort;
|
||||
import appeng.container.implementations.ContainerInscriber;
|
||||
import appeng.container.implementations.ContainerInterface;
|
||||
import appeng.container.implementations.ContainerInterfaceTerminal;
|
||||
import appeng.container.implementations.ContainerLevelEmitter;
|
||||
import appeng.container.implementations.ContainerMAC;
|
||||
import appeng.container.implementations.ContainerMEMonitorable;
|
||||
import appeng.container.implementations.ContainerMEPortableCell;
|
||||
import appeng.container.implementations.ContainerNetworkStatus;
|
||||
import appeng.container.implementations.ContainerNetworkTool;
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
import appeng.container.implementations.ContainerPriority;
|
||||
import appeng.container.implementations.ContainerQNB;
|
||||
import appeng.container.implementations.ContainerQuartzKnife;
|
||||
import appeng.container.implementations.ContainerSecurityStation;
|
||||
import appeng.container.implementations.ContainerSkyChest;
|
||||
import appeng.container.implementations.ContainerSpatialIOPort;
|
||||
import appeng.container.implementations.ContainerStorageBus;
|
||||
import appeng.container.implementations.ContainerUpgradeable;
|
||||
import appeng.container.implementations.ContainerVibrationChamber;
|
||||
import appeng.container.implementations.ContainerWireless;
|
||||
import appeng.container.implementations.ContainerWirelessTerm;
|
||||
import appeng.fluids.container.ContainerFluidFormationPlane;
|
||||
import appeng.fluids.container.ContainerFluidIO;
|
||||
import appeng.fluids.container.ContainerFluidInterface;
|
||||
@@ -171,6 +141,8 @@ public enum GuiBridge implements IGuiHandler
|
||||
|
||||
GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_OREDICTSTORAGEBUS( ContainerOreDictStorageBus.class, PartOreDicStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_STORAGEBUS_FLUID( ContainerFluidStorageBus.class, PartFluidStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
@@ -185,6 +157,8 @@ public enum GuiBridge implements IGuiHandler
|
||||
|
||||
GUI_PATTERN_TERMINAL( ContainerPatternTerm.class, PartPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
|
||||
|
||||
GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL( ContainerExpandedProcessingPatternTerm.class, PartExpandedProcessingPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
|
||||
|
||||
GUI_FLUID_TERMINAL( ContainerFluidTerminal.class, ITerminalHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
// extends (Container/Gui) + Bus
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package appeng.core.sync.packets;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PacketInformPlayer extends AppEngPacket
|
||||
{
|
||||
private IAEItemStack actualItem = null;
|
||||
private IAEItemStack reportedItem = null;
|
||||
private final InfoType type;
|
||||
|
||||
public PacketInformPlayer( ByteBuf stream ) throws IOException
|
||||
{
|
||||
this.type = InfoType.values()[stream.readInt()];
|
||||
if( type == InfoType.PARTIAL_ITEM_EXTRACTION )
|
||||
{
|
||||
this.reportedItem = AEItemStack.fromPacket( stream );
|
||||
this.actualItem = AEItemStack.fromPacket( stream );
|
||||
}
|
||||
else if( type == InfoType.NO_ITEMS_EXTRACTED )
|
||||
{
|
||||
this.reportedItem = AEItemStack.fromPacket( stream );
|
||||
}
|
||||
}
|
||||
|
||||
public PacketInformPlayer( final IAEItemStack iaeItemStack ) throws IOException
|
||||
{
|
||||
this( iaeItemStack, null );
|
||||
}
|
||||
|
||||
public PacketInformPlayer( IAEItemStack extra, IAEItemStack result ) throws IOException
|
||||
{
|
||||
this.reportedItem = extra;
|
||||
this.actualItem = result;
|
||||
if( actualItem == null )
|
||||
{
|
||||
this.type = InfoType.NO_ITEMS_EXTRACTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.type = InfoType.PARTIAL_ITEM_EXTRACTION;
|
||||
}
|
||||
|
||||
final ByteBuf data = Unpooled.buffer();
|
||||
|
||||
data.writeInt( this.getPacketID() );
|
||||
|
||||
data.writeInt( type.ordinal() );
|
||||
|
||||
reportedItem.writeToPacket( data );
|
||||
if( actualItem != null )
|
||||
{
|
||||
actualItem.writeToPacket( data );
|
||||
}
|
||||
|
||||
this.configureWrite( data );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clientPacketData( final INetworkInfo network, final AppEngPacket packet, final EntityPlayer player )
|
||||
{
|
||||
TextComponentString msg = null;
|
||||
|
||||
if( this.type == InfoType.PARTIAL_ITEM_EXTRACTION )
|
||||
{
|
||||
AppEng.proxy.getPlayers().get( 0 ).sendStatusMessage( new TextComponentString( "System reported " + reportedItem.getStackSize() + " " + reportedItem.getItem().getItemStackDisplayName( reportedItem.getDefinition() ) + " available but could only extract" + actualItem.getStackSize() ), false );
|
||||
}
|
||||
else if( this.type == InfoType.NO_ITEMS_EXTRACTED )
|
||||
{
|
||||
AppEng.proxy.getPlayers().get( 0 ).sendStatusMessage( new TextComponentString( "System reported " + reportedItem.getStackSize() + " " + reportedItem.getItem().getItemStackDisplayName( reportedItem.getDefinition() ) + " available but could not extract anything" ), false );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum InfoType
|
||||
{
|
||||
PARTIAL_ITEM_EXTRACTION,
|
||||
NO_ITEMS_EXTRACTED
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,16 @@ 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;
|
||||
|
||||
@@ -40,6 +49,7 @@ 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
|
||||
@@ -57,6 +67,7 @@ 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 );
|
||||
@@ -70,7 +81,6 @@ 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." );
|
||||
@@ -101,6 +111,36 @@ 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 )
|
||||
{
|
||||
@@ -150,6 +190,47 @@ public class PacketInventoryAction extends AppEngPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM )
|
||||
{
|
||||
if( sender.openContainer instanceof ContainerFluidConfigurable )
|
||||
{
|
||||
if( this.slotItem != null )
|
||||
{
|
||||
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
|
||||
if( aefs != null )
|
||||
{
|
||||
aefs.setStackSize( 1000 );
|
||||
( (ContainerFluidConfigurable) sender.openContainer ).getFluidConfigInventory().setFluidInSlot( this.slot, aefs );
|
||||
NetworkHandler.instance().sendToServer( new PacketFluidSlot( Collections.singletonMap( this.slot, aefs ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.slot < sender.openContainer.inventorySlots.size() && sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake )
|
||||
{
|
||||
if( 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
baseContainer.doAction( sender, this.action, this.slot, this.id );
|
||||
|
||||
@@ -23,11 +23,12 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -39,6 +40,7 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.fml.common.Optional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -68,8 +70,9 @@ import appeng.util.prioritylist.IPartitionList;
|
||||
public class PacketJEIRecipe extends AppEngPacket
|
||||
{
|
||||
|
||||
private ItemStack[][] recipe;
|
||||
private ItemStack[] output;
|
||||
private List<ItemStack[]> recipe;
|
||||
private List<ItemStack> output;
|
||||
static ItemStack[] emptyArray = {ItemStack.EMPTY};
|
||||
|
||||
|
||||
// automatic.
|
||||
@@ -80,28 +83,35 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
final NBTTagCompound comp = CompressedStreamTools.readCompressed( bytes );
|
||||
if( comp != null )
|
||||
{
|
||||
this.recipe = new ItemStack[9][];
|
||||
for( int x = 0; x < this.recipe.length; x++ )
|
||||
this.recipe = new ArrayList<>();
|
||||
|
||||
for( int x = 0; x < comp.getKeySet().size(); x++ )
|
||||
{
|
||||
final NBTTagList list = comp.getTagList( "#" + x, 10 );
|
||||
if( list.tagCount() > 0 )
|
||||
if( comp.hasKey( "#" + x ) )
|
||||
{
|
||||
this.recipe[x] = new ItemStack[list.tagCount()];
|
||||
for( int y = 0; y < list.tagCount(); y++ )
|
||||
final NBTTagList list = comp.getTagList( "#" + x, 10 );
|
||||
if( list.tagCount() > 0 )
|
||||
{
|
||||
this.recipe[x][y] = new ItemStack( list.getCompoundTagAt( y ) );
|
||||
this.recipe.add( new ItemStack[list.tagCount()] );
|
||||
for( int y = 0; y < list.tagCount(); y++ )
|
||||
{
|
||||
this.recipe.get( x )[y] = new ItemStack( list.getCompoundTagAt( y ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.recipe.add( emptyArray );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( comp.hasKey("outputs") ) {
|
||||
final NBTTagList outputList = comp.getTagList("outputs", 10);
|
||||
this.output = new ItemStack[3];
|
||||
for( int x = 0; x < this.output.length; x++ )
|
||||
|
||||
if( comp.hasKey( "outputs" ) )
|
||||
{
|
||||
final NBTTagList outputList = comp.getTagList( "outputs", 10 );
|
||||
this.output = new ArrayList<>();
|
||||
for( int z = 0; z < outputList.tagCount(); z++ )
|
||||
{
|
||||
if( outputList.tagCount() > 0 )
|
||||
{
|
||||
this.output[x] = new ItemStack(outputList.getCompoundTagAt( x ));
|
||||
}
|
||||
this.output.add( new ItemStack( outputList.getCompoundTagAt( z ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,15 +175,23 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
{
|
||||
ItemStack currentItem = craftMatrix.getStackInSlot( x );
|
||||
|
||||
if( x >= this.recipe.size() )
|
||||
{
|
||||
currentItem = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
// prepare slots
|
||||
if( !currentItem.isEmpty() )
|
||||
{
|
||||
// already the correct item?
|
||||
ItemStack newItem = this.canUseInSlot( x, currentItem );
|
||||
|
||||
if ( !cct.useRealItems() && this.recipe[x] != null ) {
|
||||
if (this.recipe[x].length > 0 )
|
||||
currentItem.setCount( recipe[x][0].getCount() );
|
||||
if( !cct.useRealItems() && this.recipe.get( x ) != null )
|
||||
{
|
||||
if( this.recipe.get( x ).length > 0 )
|
||||
{
|
||||
currentItem.setCount( recipe.get( x )[0].getCount() );
|
||||
}
|
||||
}
|
||||
|
||||
// put away old item
|
||||
@@ -192,12 +210,12 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
}
|
||||
}
|
||||
|
||||
if( currentItem.isEmpty() && this.recipe[x] != null )
|
||||
if( currentItem.isEmpty() && recipe.size() > x && recipe.get( x ) != null )
|
||||
{
|
||||
// for each variant
|
||||
for( int y = 0; y < this.recipe[x].length && currentItem.isEmpty(); y++ )
|
||||
for( int y = 0; y < this.recipe.get( x ).length && currentItem.isEmpty(); y++ )
|
||||
{
|
||||
final IAEItemStack request = AEItemStack.fromItemStack( this.recipe[x][y] );
|
||||
final IAEItemStack request = AEItemStack.fromItemStack( this.recipe.get( x )[y] );
|
||||
if( request != null )
|
||||
{
|
||||
// try ae
|
||||
@@ -211,23 +229,21 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
||||
if( out == null )
|
||||
{
|
||||
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
|
||||
IAEItemStack mostDamaged = null;
|
||||
for( IAEItemStack is : outList )
|
||||
if( request.getItem().isDamageable() || Platform.isGTDamageableItem( request.getItem() ) )
|
||||
{
|
||||
if( !is.isCraftable() && is.getItem().isDamageable() )
|
||||
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
|
||||
for( IAEItemStack is : outList )
|
||||
{
|
||||
if( mostDamaged == null || mostDamaged.getItemDamage() < is.getItemDamage() )
|
||||
if( is.getDefinition().getMetadata() == request.getDefinition().getMetadata() )
|
||||
{
|
||||
mostDamaged = is;
|
||||
out = Platform.poweredExtraction( energy, storage, is.copy().setStackSize( 1 ), cct.getActionSource() );
|
||||
}
|
||||
if( out != null )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( mostDamaged != null )
|
||||
{
|
||||
mostDamaged.setStackSize( 1 );
|
||||
out = Platform.poweredExtraction( energy, storage, mostDamaged, cct.getActionSource() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -246,7 +262,10 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
|
||||
if( out != null )
|
||||
{
|
||||
out.setStackSize( recipe[x][y].getCount() );
|
||||
if( !cct.useRealItems() )
|
||||
{
|
||||
out.setStackSize( recipe.get( x )[y].getCount() );
|
||||
}
|
||||
currentItem = out.createItemStack();
|
||||
}
|
||||
}
|
||||
@@ -258,20 +277,20 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
|
||||
if( cct.useRealItems() )
|
||||
{
|
||||
currentItem = ad.removeSimilarItems(1, this.recipe[x][y],FuzzyMode.IGNORE_ALL, null );
|
||||
currentItem = ad.removeSimilarItems( 1, this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentItem = ad.simulateSimilarRemove(recipe[x][y].getCount(), this.recipe[x][y],FuzzyMode.IGNORE_ALL, null );
|
||||
currentItem = ad.simulateSimilarRemove( recipe.get( x )[y].getCount(), this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cct.useRealItems())
|
||||
if( !cct.useRealItems() )
|
||||
{
|
||||
if( currentItem.isEmpty() && this.recipe[x] != null )
|
||||
if( currentItem.isEmpty() && recipe.size() > x && this.recipe.get( x ) != null )
|
||||
{
|
||||
currentItem = this.recipe[x][0].copy();
|
||||
currentItem = this.recipe.get( x )[0].copy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,30 +299,37 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
|
||||
con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) );
|
||||
|
||||
if( this.output != null && con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() )
|
||||
if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) )
|
||||
{
|
||||
IItemHandler outputSlots = cct.getInventoryByName( "output" );
|
||||
for( int i = 0; i < this.output.length; ++i )
|
||||
for( int i = 0; i < outputSlots.getSlots(); ++i )
|
||||
{
|
||||
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output[i] );
|
||||
ItemHandlerUtil.setStackInSlot( outputSlots, i, ItemStack.EMPTY );
|
||||
}
|
||||
for( int i = 0; i < this.output.size() && i < outputSlots.getSlots(); ++i )
|
||||
{
|
||||
if( this.output.get( i ) == null || this.output.get( i ) == ItemStack.EMPTY )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output.get( i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param slot
|
||||
* @param is itemstack
|
||||
* @param is itemstack
|
||||
* @return is if it can be used, else EMPTY
|
||||
*/
|
||||
private ItemStack canUseInSlot( int slot, ItemStack is )
|
||||
{
|
||||
if( this.recipe[slot] != null )
|
||||
if( this.recipe.get( slot ) != null )
|
||||
{
|
||||
for( ItemStack option : this.recipe[slot] )
|
||||
for( ItemStack option : this.recipe.get( slot ) )
|
||||
{
|
||||
if( is.isItemEqual( option ) )
|
||||
if( ItemStack.areItemStacksEqual( is, option ) )
|
||||
{
|
||||
return is;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package appeng.core.sync.packets;
|
||||
|
||||
|
||||
import appeng.fluids.container.ContainerFluidInterface;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
@@ -90,5 +91,9 @@ public class PacketTargetFluidStack extends AppEngPacket
|
||||
{
|
||||
( (ContainerFluidTerminal) player.openContainer ).setTargetStack( this.stack );
|
||||
}
|
||||
else if( player.openContainer instanceof ContainerFluidInterface )
|
||||
{
|
||||
( (ContainerFluidInterface) player.openContainer ).setTargetStack( this.stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.client.gui.implementations.GuiOreDictStorageBus;
|
||||
import appeng.container.implementations.*;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
@@ -40,17 +42,6 @@ import appeng.api.util.IConfigManager;
|
||||
import appeng.api.util.IConfigurableObject;
|
||||
import appeng.client.gui.implementations.GuiCraftingCPU;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.implementations.ContainerCellWorkbench;
|
||||
import appeng.container.implementations.ContainerCraftConfirm;
|
||||
import appeng.container.implementations.ContainerCraftingCPU;
|
||||
import appeng.container.implementations.ContainerCraftingStatus;
|
||||
import appeng.container.implementations.ContainerLevelEmitter;
|
||||
import appeng.container.implementations.ContainerNetworkTool;
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
import appeng.container.implementations.ContainerPriority;
|
||||
import appeng.container.implementations.ContainerQuartzKnife;
|
||||
import appeng.container.implementations.ContainerSecurityStation;
|
||||
import appeng.container.implementations.ContainerStorageBus;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.fluids.container.ContainerFluidLevelEmitter;
|
||||
@@ -166,58 +157,109 @@ public class PacketValueConfig extends AppEngPacket
|
||||
final ContainerFluidLevelEmitter lvc = (ContainerFluidLevelEmitter) c;
|
||||
lvc.setLevel( Long.parseLong( this.Value ), player );
|
||||
}
|
||||
else if( this.Name.startsWith( "PatternTerminal." ) && c instanceof ContainerPatternTerm )
|
||||
else if( this.Name.startsWith( "PatternTerminal." ) )
|
||||
{
|
||||
final ContainerPatternTerm cpt = (ContainerPatternTerm) c;
|
||||
if( this.Name.equals( "PatternTerminal.CraftMode" ) )
|
||||
if( c instanceof ContainerPatternTerm )
|
||||
{
|
||||
cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Encode" ) )
|
||||
{
|
||||
if (this.Value.equals( "2" )) {
|
||||
cpt.encodeAndMoveToInventory();
|
||||
}
|
||||
else
|
||||
final ContainerPatternTerm cpt = (ContainerPatternTerm) c;
|
||||
if( this.Name.equals( "PatternTerminal.CraftMode" ) )
|
||||
{
|
||||
cpt.encode();
|
||||
cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Encode" ) )
|
||||
{
|
||||
if( this.Value.equals( "2" ) )
|
||||
{
|
||||
cpt.encodeAndMoveToInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
cpt.encode();
|
||||
}
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Clear" ) )
|
||||
{
|
||||
cpt.clear();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
|
||||
{
|
||||
cpt.multiply( 2 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
|
||||
{
|
||||
cpt.multiply( 3 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
|
||||
{
|
||||
cpt.divide( 2 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
|
||||
{
|
||||
cpt.divide( 3 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
|
||||
{
|
||||
cpt.increase( 1 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
|
||||
{
|
||||
cpt.decrease( 1 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
|
||||
{
|
||||
cpt.maximizeCount();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
|
||||
{
|
||||
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
|
||||
}
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Clear" ) )
|
||||
else if( c instanceof ContainerExpandedProcessingPatternTerm )
|
||||
{
|
||||
cpt.clear();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
|
||||
{
|
||||
cpt.multiply(2);
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
|
||||
{
|
||||
cpt.multiply(3);
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
|
||||
{
|
||||
cpt.divide(2);
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
|
||||
{
|
||||
cpt.divide(3);
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
|
||||
{
|
||||
cpt.increase(1);
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
|
||||
{
|
||||
cpt.decrease(1);
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
|
||||
{
|
||||
cpt.maximizeCount();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
|
||||
{
|
||||
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
|
||||
final ContainerExpandedProcessingPatternTerm cept = (ContainerExpandedProcessingPatternTerm) c;
|
||||
if( this.Name.equals( "PatternTerminal.Encode" ) )
|
||||
{
|
||||
if( this.Value.equals( "2" ) )
|
||||
{
|
||||
cept.encodeAndMoveToInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
cept.encode();
|
||||
}
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Clear" ) )
|
||||
{
|
||||
cept.clear();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
|
||||
{
|
||||
cept.multiply( 2 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
|
||||
{
|
||||
cept.multiply( 3 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
|
||||
{
|
||||
cept.divide( 2 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
|
||||
{
|
||||
cept.divide( 3 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
|
||||
{
|
||||
cept.increase( 1 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
|
||||
{
|
||||
cept.decrease( 1 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
|
||||
{
|
||||
cept.maximizeCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.Name.startsWith( "StorageBus." ) )
|
||||
@@ -234,6 +276,11 @@ public class PacketValueConfig extends AppEngPacket
|
||||
{
|
||||
( (ContainerFluidStorageBus) c ).partition();
|
||||
}
|
||||
else if( c instanceof ContainerOreDictStorageBus )
|
||||
{
|
||||
( (ContainerOreDictStorageBus) c ).partition();
|
||||
( (ContainerOreDictStorageBus) c ).sendRegex();
|
||||
}
|
||||
}
|
||||
else if( this.Value.equals( "Clear" ) )
|
||||
{
|
||||
@@ -248,6 +295,20 @@ public class PacketValueConfig extends AppEngPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.Name.startsWith( "OreDictStorageBus" ) )
|
||||
{
|
||||
if( c instanceof ContainerOreDictStorageBus )
|
||||
{
|
||||
if( this.Name.equals( "OreDictStorageBus.save" ) )
|
||||
{
|
||||
( (ContainerOreDictStorageBus) c ).saveOreMatch( this.Value );
|
||||
}
|
||||
if( this.Name.equals( "OreDictStorageBus.getRegex" ) )
|
||||
{
|
||||
( (ContainerOreDictStorageBus) c ).sendRegex();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.Name.startsWith( "CellWorkbench." ) && c instanceof ContainerCellWorkbench )
|
||||
{
|
||||
final ContainerCellWorkbench ccw = (ContainerCellWorkbench) c;
|
||||
@@ -324,6 +385,14 @@ public class PacketValueConfig extends AppEngPacket
|
||||
( (GuiCraftingCPU) gs ).clearItems();
|
||||
}
|
||||
}
|
||||
else if( this.Name.equals( "OreDictStorageBus.sendRegex" ) )
|
||||
{
|
||||
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
|
||||
if( gs instanceof GuiOreDictStorageBus )
|
||||
{
|
||||
( (GuiOreDictStorageBus) gs ).fillRegex( this.Value );
|
||||
}
|
||||
}
|
||||
else if( c instanceof IConfigurableObject )
|
||||
{
|
||||
final IConfigManager cm = ( (IConfigurableObject) c ).getConfigManager();
|
||||
|
||||
@@ -19,15 +19,6 @@
|
||||
package appeng.crafting;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.IGrid;
|
||||
@@ -36,7 +27,6 @@ import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.crafting.ICraftingCallback;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.crafting.ICraftingJob;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
@@ -46,52 +36,64 @@ import appeng.api.storage.data.IItemList;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.core.AELog;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.me.cache.GridStorageCache;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
public class CraftingJob implements Runnable, ICraftingJob
|
||||
{
|
||||
private static final String LOG_CRAFTING_JOB = "CraftingJob (%s) issued by %s requesting [%s] using %s bytes took %s ms";
|
||||
private static final String LOG_CRAFTING_JOB = "CraftingJob (%s) issued by %s requesting [%s] using %s bytes took %s us";
|
||||
private static final String LOG_MACHINE_SOURCE_DETAILS = "Machine[object=%s, %s]";
|
||||
|
||||
private final MECraftingInventory original;
|
||||
private final World world;
|
||||
private final IItemList<IAEItemStack> crafting = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final IItemList<IAEItemStack> neededForLoop = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final Object2ObjectOpenHashMap<CraftingTreeNode, IAEItemStack> reserved = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
|
||||
private final Object monitor = new Object();
|
||||
private CraftingTreeNode tree;
|
||||
private final Stopwatch tickSpreadingWatch = Stopwatch.createUnstarted();
|
||||
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
|
||||
private final IAEItemStack output;
|
||||
private final IActionSource actionSrc;
|
||||
private final ICraftingCallback callback;
|
||||
private CraftingTreeNode tree;
|
||||
private boolean simulate = false;
|
||||
private MECraftingInventory availableCheck;
|
||||
private long bytes = 0;
|
||||
private final IActionSource actionSrc;
|
||||
private final ICraftingCallback callback;
|
||||
private boolean running = false;
|
||||
private boolean done = false;
|
||||
|
||||
private World wrapWorld( final World w )
|
||||
{
|
||||
return w;
|
||||
}
|
||||
private int time;
|
||||
private int incTime;
|
||||
|
||||
public CraftingJob( final World w, final IGrid grid, final IActionSource actionSrc, final IAEItemStack what, final ICraftingCallback callback )
|
||||
{
|
||||
this.world = this.wrapWorld( w );
|
||||
this.world = w;
|
||||
this.output = what.copy();
|
||||
this.actionSrc = actionSrc;
|
||||
|
||||
this.callback = callback;
|
||||
final ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
|
||||
final IStorageGrid sg = grid.getCache( IStorageGrid.class );
|
||||
this.original = new MECraftingInventory( sg
|
||||
.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), actionSrc, false, false, false );
|
||||
|
||||
ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
|
||||
final GridStorageCache sg = grid.getCache( IStorageGrid.class );
|
||||
this.original = sg.getExtractableList( actionSrc );
|
||||
|
||||
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
||||
this.setTree( this.getCraftingTree( cc, what ) );
|
||||
this.availableCheck = null;
|
||||
}
|
||||
|
||||
private CraftingTreeNode getCraftingTree( final ICraftingGrid cc, final IAEItemStack what )
|
||||
{
|
||||
return new CraftingTreeNode( cc, this, what, null, -1, 0 );
|
||||
return new CraftingTreeNode( cc, this, what, what.getStackSize(), null, -1 );
|
||||
}
|
||||
|
||||
void refund( final IAEItemStack o )
|
||||
@@ -104,12 +106,12 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
|
||||
}
|
||||
|
||||
public void writeToNBT( final NBTTagCompound out )
|
||||
IAEItemStack checkAvailable( final IAEItemStack available )
|
||||
{
|
||||
|
||||
return this.availableCheck.extractItems( available, Actionable.SIMULATE, this.actionSrc );
|
||||
}
|
||||
|
||||
void addTask( IAEItemStack what, final long crafts, final ICraftingPatternDetails details, final int depth )
|
||||
void addTask( IAEItemStack what, final long crafts )
|
||||
{
|
||||
if( crafts > 0 )
|
||||
{
|
||||
@@ -125,6 +127,22 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
this.missing.add( what );
|
||||
}
|
||||
|
||||
public void reserve( CraftingTreeNode node, IAEItemStack stack )
|
||||
{
|
||||
this.checkUse( stack );
|
||||
reserved.put( node, stack );
|
||||
}
|
||||
|
||||
public IItemList<IAEItemStack> getNeededForLoop()
|
||||
{
|
||||
return neededForLoop;
|
||||
}
|
||||
|
||||
public Object2ObjectOpenHashMap<CraftingTreeNode, IAEItemStack> getReserved()
|
||||
{
|
||||
return reserved;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@@ -133,14 +151,17 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
try
|
||||
{
|
||||
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
|
||||
|
||||
final Stopwatch timer = Stopwatch.createStarted();
|
||||
this.handlePausing();
|
||||
|
||||
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
||||
craftingInventory.ignore( this.output );
|
||||
|
||||
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
||||
this.reserved.values().forEach( availableCheck::reserve );
|
||||
this.reserved.values().forEach( craftingInventory::reserve );
|
||||
|
||||
craftingTreeWatch.start();
|
||||
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
||||
craftingTreeWatch.stop();
|
||||
this.getTree().dive( this );
|
||||
|
||||
for( final String s : this.opsAndMultiplier.keySet() )
|
||||
@@ -149,9 +170,14 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
||||
}
|
||||
|
||||
this.logCraftingJob( "real", timer );
|
||||
// if ( mode == Actionable.MODULATE )
|
||||
// craftingInventory.moveItemsToStorage( storage );
|
||||
if( actionSrc.player().isPresent() )
|
||||
{
|
||||
this.logCraftingJob( "simulated, success", craftingTreeWatch );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.logCraftingJob( "real, success", craftingTreeWatch );
|
||||
}
|
||||
}
|
||||
catch( final CraftBranchFailure e )
|
||||
{
|
||||
@@ -159,23 +185,32 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
|
||||
try
|
||||
{
|
||||
final Stopwatch timer = Stopwatch.createStarted();
|
||||
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
||||
craftingInventory.ignore( this.output );
|
||||
|
||||
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
||||
|
||||
this.getTree().setSimulate();
|
||||
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
||||
this.getTree().dive( this );
|
||||
|
||||
for( final String s : this.opsAndMultiplier.keySet() )
|
||||
if( actionSrc.player().isPresent() )
|
||||
{
|
||||
final TwoIntegers ti = this.opsAndMultiplier.get( s );
|
||||
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
||||
}
|
||||
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
|
||||
this.getTree().setSimulate();
|
||||
|
||||
this.logCraftingJob( "simulate", timer );
|
||||
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
|
||||
this.reserved.values().forEach( availableCheck::reserve );
|
||||
this.reserved.values().forEach( craftingInventory::reserve );
|
||||
|
||||
craftingTreeWatch.reset().start();
|
||||
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
|
||||
craftingTreeWatch.stop();
|
||||
this.getTree().dive( this );
|
||||
|
||||
for( final String s : this.opsAndMultiplier.keySet() )
|
||||
{
|
||||
final TwoIntegers ti = this.opsAndMultiplier.get( s );
|
||||
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
|
||||
}
|
||||
|
||||
this.logCraftingJob( "simulated, failed", craftingTreeWatch );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.logCraftingJob( "real, failed", craftingTreeWatch );
|
||||
}
|
||||
}
|
||||
catch( final CraftBranchFailure e1 )
|
||||
{
|
||||
@@ -214,6 +249,43 @@ 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.tickSpreadingWatch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
|
||||
{
|
||||
this.running = false;
|
||||
this.craftingTreeWatch.stop();
|
||||
this.tickSpreadingWatch.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 )
|
||||
@@ -223,8 +295,9 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
|
||||
this.availableCheck = null;
|
||||
|
||||
synchronized( this.monitor )
|
||||
synchronized ( this.monitor )
|
||||
{
|
||||
this.running = false;
|
||||
this.done = true;
|
||||
this.monitor.notify();
|
||||
}
|
||||
@@ -270,13 +343,25 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
/**
|
||||
* @return true if this needs more simulation
|
||||
*/
|
||||
public boolean simulateFor()
|
||||
public boolean simulateFor( final int milli )
|
||||
{
|
||||
synchronized( this.monitor ) {
|
||||
if ( this.done ) {
|
||||
this.time = milli;
|
||||
|
||||
synchronized ( this.monitor )
|
||||
{
|
||||
if( this.done )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( !this.actionSrc.player().isPresent() )
|
||||
{
|
||||
this.tickSpreadingWatch.reset();
|
||||
this.tickSpreadingWatch.start();
|
||||
this.monitor.notify();
|
||||
}
|
||||
this.running = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -300,7 +385,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
if( AELog.isCraftingLogEnabled() )
|
||||
{
|
||||
final String itemToOutput = this.output.toString();
|
||||
final long elapsedTime = timer.elapsed( TimeUnit.MILLISECONDS );
|
||||
final long elapsedTime = timer.elapsed( TimeUnit.MICROSECONDS );
|
||||
final String actionSource;
|
||||
|
||||
if( this.actionSrc.player().isPresent() )
|
||||
|
||||
@@ -19,14 +19,6 @@
|
||||
package appeng.crafting;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
@@ -36,9 +28,22 @@ import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketInformPlayer;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Optional;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Optional.Interface( iface = "gregtech.api.items.IToolItem", modid = "gregtech" )
|
||||
public class CraftingTreeNode
|
||||
{
|
||||
|
||||
@@ -53,22 +58,20 @@ public class CraftingTreeNode
|
||||
private final IAEItemStack what;
|
||||
// what are the crafting patterns for this?
|
||||
private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<>();
|
||||
private final boolean canEmit;
|
||||
private CraftingTreeNode loopHead;
|
||||
private int bytes = 0;
|
||||
private boolean canEmit = false;
|
||||
private long missing = 0;
|
||||
private long howManyEmitted = 0;
|
||||
private boolean exhausted = false;
|
||||
|
||||
private boolean sim;
|
||||
|
||||
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth )
|
||||
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, long amount, final CraftingTreeProcess par, final int slot )
|
||||
{
|
||||
this.what = wat;
|
||||
this.parent = par;
|
||||
this.slot = slot;
|
||||
this.world = job.getWorld();
|
||||
this.job = job;
|
||||
this.sim = false;
|
||||
|
||||
this.canEmit = cc.canEmitFor( this.what );
|
||||
|
||||
@@ -80,78 +83,136 @@ public class CraftingTreeNode
|
||||
for( final ICraftingPatternDetails details : cc.getCraftingFor( this.what, this.parent == null ? null : this.parent.details, slot, this.world ) )// in
|
||||
// order.
|
||||
{
|
||||
if( this.parent == null || this.parent.notRecursive( details ) )
|
||||
int times = 1;
|
||||
for( IAEItemStack o : details.getCondensedOutputs() )
|
||||
{
|
||||
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
|
||||
if( what.equals( o ) )
|
||||
{
|
||||
times = (int) ( amount / o.getStackSize() + ( amount % o.getStackSize() != 0 ? 1 : 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( this.parent == null )
|
||||
{
|
||||
this.nodes.add( new CraftingTreeProcess( cc, job, details, times, this ) );
|
||||
continue;
|
||||
}
|
||||
if( details == parent.details )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
CraftingTreeNode recursive = recursiveNode( this );
|
||||
if( recursive == null )
|
||||
{
|
||||
this.nodes.add( new CraftingTreeProcess( cc, job, details, times, this ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
reserveForNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean notRecursive( final ICraftingPatternDetails details )
|
||||
void reserveForNode()
|
||||
{
|
||||
IAEItemStack[] o = details.getCondensedOutputs();
|
||||
|
||||
for( final IAEItemStack i : o )
|
||||
if( this.equals( loopHead ) )
|
||||
{
|
||||
if( i.equals( this.what ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
o = details.getCondensedInputs();
|
||||
|
||||
for( final IAEItemStack i : o )
|
||||
IAEItemStack available = job.checkAvailable( this.what );
|
||||
if( available != null && available.getStackSize() >= this.what.getStackSize() )
|
||||
{
|
||||
if( i.equals( this.what ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.job.reserve( this, this.what.copy() );
|
||||
}
|
||||
|
||||
if( this.parent == null )
|
||||
else
|
||||
{
|
||||
return true;
|
||||
parent.reserveForNode();
|
||||
}
|
||||
|
||||
return this.parent.notRecursive( details );
|
||||
}
|
||||
|
||||
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
{
|
||||
this.job.handlePausing();
|
||||
if( this.canEmit )
|
||||
{
|
||||
final IAEItemStack wat = this.what.copy();
|
||||
wat.setStackSize( l );
|
||||
|
||||
this.howManyEmitted = wat.getStackSize();
|
||||
this.bytes += wat.getStackSize();
|
||||
|
||||
return wat;
|
||||
}
|
||||
|
||||
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
||||
|
||||
IAEItemStack reserved = job.getReserved().get( this );
|
||||
|
||||
final List<IAEItemStack> thingsUsed = new ArrayList<>();
|
||||
|
||||
this.what.setStackSize( l );
|
||||
|
||||
if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
|
||||
{
|
||||
final Collection<IAEItemStack> itemList;
|
||||
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
||||
Collection<IAEItemStack> itemList = new HashSet<>();
|
||||
|
||||
if( this.parent.details.canSubstitute() )
|
||||
if( this.what.getItem().isDamageable() || Platform.isGTDamageableItem( this.what.getItem() ) )
|
||||
{
|
||||
itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL );
|
||||
itemList.addAll( inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) );
|
||||
|
||||
if( this.parent.details.canSubstitute() )
|
||||
{
|
||||
for( IAEItemStack is : inventoryList )
|
||||
{
|
||||
if( is.fuzzyComparison( this.what, FuzzyMode.IGNORE_ALL ) )
|
||||
{
|
||||
itemList.add( is );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
itemList = Lists.newArrayList();
|
||||
|
||||
final IAEItemStack item = inventoryList.findPrecise( this.what );
|
||||
|
||||
if( item != null )
|
||||
{
|
||||
itemList.add( item );
|
||||
}
|
||||
if( this.parent.details.canSubstitute() )
|
||||
{
|
||||
for( IAEItemStack s : parent.details.getSubstituteInputs( this.slot ) )
|
||||
{
|
||||
if( s != null )
|
||||
{
|
||||
for( IAEItemStack ss : inventoryList.findFuzzy( s, FuzzyMode.IGNORE_ALL ) )
|
||||
{
|
||||
if( ss != null )
|
||||
{
|
||||
itemList.add( ss );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( IAEItemStack fuzz : itemList )
|
||||
{
|
||||
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().setStackSize( 1 ).createItemStack(), this.world ) )
|
||||
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.getDefinition(), this.world ) )
|
||||
{
|
||||
fuzz = fuzz.copy();
|
||||
fuzz.setStackSize( l );
|
||||
|
||||
final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
||||
final IAEItemStack available;
|
||||
|
||||
if( reserved != null )
|
||||
{
|
||||
available = reserved;
|
||||
}
|
||||
else
|
||||
{
|
||||
available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
||||
}
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
@@ -164,6 +225,11 @@ public class CraftingTreeNode
|
||||
thingsUsed.add( is.copy() );
|
||||
this.used.add( is );
|
||||
}
|
||||
else if( reserved != null )
|
||||
{
|
||||
thingsUsed.add( reserved.copy() );
|
||||
this.used.add( reserved );
|
||||
}
|
||||
}
|
||||
|
||||
this.bytes += available.getStackSize();
|
||||
@@ -179,7 +245,20 @@ public class CraftingTreeNode
|
||||
}
|
||||
else
|
||||
{
|
||||
final IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
final IAEItemStack available;
|
||||
|
||||
if( parent == null && this.what.equals( job.getOutput() ) )
|
||||
{
|
||||
available = null;
|
||||
}
|
||||
else if( reserved != null )
|
||||
{
|
||||
available = reserved;
|
||||
}
|
||||
else
|
||||
{
|
||||
available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
}
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
@@ -192,6 +271,11 @@ public class CraftingTreeNode
|
||||
thingsUsed.add( is.copy() );
|
||||
this.used.add( is );
|
||||
}
|
||||
else if( reserved != null )
|
||||
{
|
||||
thingsUsed.add( reserved.copy() );
|
||||
this.used.add( reserved );
|
||||
}
|
||||
}
|
||||
|
||||
this.bytes += available.getStackSize();
|
||||
@@ -204,31 +288,19 @@ public class CraftingTreeNode
|
||||
}
|
||||
}
|
||||
|
||||
if( this.canEmit )
|
||||
{
|
||||
final IAEItemStack wat = this.what.copy();
|
||||
wat.setStackSize( l );
|
||||
|
||||
this.howManyEmitted = wat.getStackSize();
|
||||
this.bytes += wat.getStackSize();
|
||||
|
||||
return wat;
|
||||
}
|
||||
|
||||
this.exhausted = true;
|
||||
|
||||
if( this.nodes.size() == 1 )
|
||||
{
|
||||
final CraftingTreeProcess pro = this.nodes.get( 0 );
|
||||
|
||||
while( pro.possible && l > 0 )
|
||||
while ( pro.possible && l > 0 )
|
||||
{
|
||||
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
|
||||
|
||||
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
|
||||
|
||||
madeWhat.setStackSize( l );
|
||||
|
||||
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
@@ -253,10 +325,12 @@ public class CraftingTreeNode
|
||||
{
|
||||
try
|
||||
{
|
||||
while( pro.possible && l > 0 )
|
||||
while ( pro.possible && l > 0 )
|
||||
{
|
||||
final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true );
|
||||
pro.request( subInv, 1, src );
|
||||
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
|
||||
|
||||
pro.request( subInv, pro.getTimes( l, madeWhat.getStackSize() ), src );
|
||||
|
||||
this.what.setStackSize( l );
|
||||
final IAEItemStack available = subInv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
@@ -289,10 +363,10 @@ public class CraftingTreeNode
|
||||
}
|
||||
}
|
||||
|
||||
if( this.sim )
|
||||
if( job.isSimulation() )
|
||||
{
|
||||
this.missing += l;
|
||||
this.bytes += l;
|
||||
this.missing += l;
|
||||
final IAEItemStack rv = this.what.copy();
|
||||
rv.setStackSize( l );
|
||||
return rv;
|
||||
@@ -308,6 +382,26 @@ public class CraftingTreeNode
|
||||
throw new CraftBranchFailure( this.what, l );
|
||||
}
|
||||
|
||||
CraftingTreeNode recursiveNode( CraftingTreeNode node )
|
||||
{
|
||||
if( this.parent == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if( node != this )
|
||||
{
|
||||
if( node.what.equals( this.what ) )
|
||||
{
|
||||
if( node.what.getStackSize() == this.what.getStackSize() )
|
||||
{
|
||||
loopHead = this;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.parent.notRecursive( node );
|
||||
}
|
||||
|
||||
void dive( final CraftingJob job )
|
||||
{
|
||||
if( this.missing > 0 )
|
||||
@@ -316,7 +410,7 @@ public class CraftingTreeNode
|
||||
}
|
||||
// missing = 0;
|
||||
|
||||
job.addBytes( 8 + this.bytes );
|
||||
job.addBytes( this.bytes );
|
||||
|
||||
for( final CraftingTreeProcess pro : this.nodes )
|
||||
{
|
||||
@@ -333,7 +427,6 @@ public class CraftingTreeNode
|
||||
|
||||
void setSimulate()
|
||||
{
|
||||
this.sim = true;
|
||||
this.missing = 0;
|
||||
this.bytes = 0;
|
||||
this.used.resetStatus();
|
||||
@@ -353,6 +446,24 @@ public class CraftingTreeNode
|
||||
|
||||
if( ex == null || ex.getStackSize() != i.getStackSize() )
|
||||
{
|
||||
if( src.player().isPresent() )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( ex == null )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( new PacketInformPlayer( i ), (EntityPlayerMP) src.player().get() );
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkHandler.instance().sendTo( new PacketInformPlayer( ex, i ), (EntityPlayerMP) src.player().get() );
|
||||
}
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
throw new CraftBranchFailure( i, i.getStackSize() );
|
||||
}
|
||||
|
||||
|
||||
@@ -19,241 +19,208 @@
|
||||
package appeng.crafting;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.container.ContainerNull;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongArrayMap;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class CraftingTreeProcess
|
||||
{
|
||||
|
||||
private final CraftingTreeNode parent;
|
||||
final ICraftingPatternDetails details;
|
||||
private final CraftingTreeNode parent;
|
||||
private final CraftingJob job;
|
||||
private final Map<CraftingTreeNode, Long> nodes = new HashMap<>();
|
||||
private final int depth;
|
||||
private final Object2LongArrayMap<CraftingTreeNode> nodes = new Object2LongArrayMap<>();
|
||||
boolean possible = true;
|
||||
private World world;
|
||||
private long crafts = 0;
|
||||
private boolean containerItems;
|
||||
private boolean limitQty;
|
||||
private boolean fullSimulation;
|
||||
private long bytes = 0;
|
||||
private boolean hasContainerItem = false;
|
||||
|
||||
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, final CraftingTreeNode craftingTreeNode, final int depth )
|
||||
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, int times, final CraftingTreeNode craftingTreeNode )
|
||||
{
|
||||
this.parent = craftingTreeNode;
|
||||
this.details = details;
|
||||
this.job = job;
|
||||
this.depth = depth;
|
||||
final World world = job.getWorld();
|
||||
World world = job.getWorld();
|
||||
|
||||
if( details.isCraftable() )
|
||||
final IAEItemStack[] list = details.getInputs();
|
||||
|
||||
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
|
||||
for( IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
final IAEItemStack[] list = details.getInputs();
|
||||
|
||||
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
final IAEItemStack[] is = details.getInputs();
|
||||
for( int x = 0; x < ic.getSizeInventory(); x++ )
|
||||
if( part == null )
|
||||
{
|
||||
ic.setInventorySlotContents( x, is[x] == null ? ItemStack.EMPTY : is[x].createItemStack() );
|
||||
continue;
|
||||
}
|
||||
|
||||
for( int x = 0; x < ic.getSizeInventory(); x++ )
|
||||
for( int x = 0; x < list.length; x++ )
|
||||
{
|
||||
final ItemStack g = ic.getStackInSlot( x );
|
||||
if( !g.isEmpty() && g.getCount() > 1 )
|
||||
final IAEItemStack comparePart = list[x];
|
||||
if( part.equals( comparePart ) )
|
||||
{
|
||||
this.fullSimulation = true;
|
||||
}
|
||||
}
|
||||
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
final ItemStack g = part.createItemStack();
|
||||
|
||||
boolean isAnInput = false;
|
||||
for( final IAEItemStack a : details.getCondensedOutputs() )
|
||||
{
|
||||
if( !g.isEmpty() && a != null && a.equals( g ) )
|
||||
boolean isPartContainer = false;
|
||||
if( part.getItem().hasContainerItem( part.getDefinition() ) )
|
||||
{
|
||||
isAnInput = true;
|
||||
part = list[x];
|
||||
isPartContainer = true;
|
||||
this.hasContainerItem = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( isAnInput )
|
||||
{
|
||||
this.limitQty = true;
|
||||
}
|
||||
long wantedSize = isPartContainer ? part.getStackSize() : part.getStackSize() * times;
|
||||
|
||||
if( g.getItem().hasContainerItem( g ) )
|
||||
{
|
||||
this.limitQty = this.containerItems = true;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean complicated = false;
|
||||
|
||||
if( this.containerItems || complicated )
|
||||
{
|
||||
for( int x = 0; x < list.length; x++ )
|
||||
{
|
||||
final IAEItemStack part = list[x];
|
||||
if( part != null )
|
||||
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
|
||||
{
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
for( int x = 0; x < list.length; x++ )
|
||||
{
|
||||
final IAEItemStack comparePart = list[x];
|
||||
if( part != null && part.equals( comparePart ) )
|
||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||
{
|
||||
// use the first slot...
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
|
||||
break;
|
||||
if( subs.fuzzyComparison( part, FuzzyMode.IGNORE_ALL ) )
|
||||
{
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, subs.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
||||
wantedSize = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//try to order the crafting of a substitute
|
||||
ICraftingPatternDetails prioritizedPattern = null;
|
||||
IAEItemStack prioritizedIAE = null;
|
||||
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
|
||||
{
|
||||
if( subs.equals( part ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ImmutableCollection<ICraftingPatternDetails> detailCollection = cc.getCraftingFor( subs, details, x, world );
|
||||
|
||||
for( ICraftingPatternDetails sp : detailCollection )
|
||||
{
|
||||
if( prioritizedPattern == null )
|
||||
{
|
||||
prioritizedPattern = sp;
|
||||
prioritizedIAE = subs;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sp.getPriority() > prioritizedPattern.getPriority() )
|
||||
{
|
||||
prioritizedPattern = sp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( prioritizedIAE != null )
|
||||
{
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, prioritizedIAE.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
||||
wantedSize = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
final ItemStack g = part.createItemStack();
|
||||
|
||||
boolean isAnInput = false;
|
||||
for( final IAEItemStack a : details.getCondensedOutputs() )
|
||||
{
|
||||
if( !g.isEmpty() && a != null && a.equals( g ) )
|
||||
if( wantedSize > 0 )
|
||||
{
|
||||
isAnInput = true;
|
||||
part = part.copy().setStackSize( wantedSize );
|
||||
// use the first slot...
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), wantedSize, this, x ), part.getStackSize() / times );
|
||||
wantedSize = 0;
|
||||
}
|
||||
if( !isPartContainer && wantedSize == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( isAnInput )
|
||||
{
|
||||
this.limitQty = true;
|
||||
}
|
||||
}
|
||||
|
||||
for( final IAEItemStack part : details.getCondensedInputs() )
|
||||
{
|
||||
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, -1, depth + 1 ), part.getStackSize() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean notRecursive( final ICraftingPatternDetails details )
|
||||
CraftingTreeNode notRecursive( CraftingTreeNode node )
|
||||
{
|
||||
return this.parent == null || this.parent.notRecursive( details );
|
||||
if( parent == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this.parent.recursiveNode( node );
|
||||
}
|
||||
|
||||
long getTimes( final long remaining, final long stackSize )
|
||||
{
|
||||
if( this.limitQty || this.fullSimulation )
|
||||
if( hasContainerItem )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return ( remaining / stackSize ) + ( remaining % stackSize != 0 ? 1 : 0 );
|
||||
}
|
||||
|
||||
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
void request( final MECraftingInventory inv, final long amountOfTimes, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
{
|
||||
this.job.handlePausing();
|
||||
List<IAEItemStack> containerItems = null;
|
||||
|
||||
if( this.fullSimulation )
|
||||
// request and remove inputs...
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
final IAEItemStack stack = entry.getKey().request( inv, details.isCraftable() && hasContainerItem ? 1 : entry.getValue() * amountOfTimes, src );
|
||||
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.entrySet() )
|
||||
if( stack.equals( job.getOutput() ) )
|
||||
{
|
||||
final IAEItemStack item = entry.getKey().getStack( entry.getValue() );
|
||||
final IAEItemStack stack = entry.getKey().request( inv, item.getStackSize(), src );
|
||||
|
||||
ic.setInventorySlotContents( entry.getKey().getSlot(), stack.createItemStack() );
|
||||
job.getNeededForLoop().add( stack.copy() );
|
||||
}
|
||||
|
||||
for( int x = 0; x < ic.getSizeInventory(); x++ )
|
||||
if( details.isCraftable() && stack.getItem().hasContainerItem( stack.getDefinition() ) )
|
||||
{
|
||||
ItemStack is = ic.getStackInSlot( x );
|
||||
is = Platform.getContainerItem( is );
|
||||
|
||||
final IAEItemStack o = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
|
||||
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
|
||||
final IAEItemStack o = AEItemStack.fromItemStack( is );
|
||||
if( o != null )
|
||||
{
|
||||
this.bytes++;
|
||||
inv.injectItems( o, Actionable.MODULATE, src );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// request and remove inputs...
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.entrySet() )
|
||||
{
|
||||
final IAEItemStack item = entry.getKey().getStack( entry.getValue() );
|
||||
final IAEItemStack stack = entry.getKey().request( inv, item.getStackSize() * i, src );
|
||||
|
||||
if( this.containerItems )
|
||||
{
|
||||
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
|
||||
final IAEItemStack o = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
|
||||
if( o != null )
|
||||
if( containerItems == null )
|
||||
{
|
||||
this.bytes++;
|
||||
inv.injectItems( o, Actionable.MODULATE, src );
|
||||
containerItems = new ArrayList<>();
|
||||
}
|
||||
this.bytes++;
|
||||
o.setCachedItemStack( is );
|
||||
containerItems.add( o );
|
||||
}
|
||||
if( containerItems != null )
|
||||
{
|
||||
for( IAEItemStack i : containerItems )
|
||||
{
|
||||
inv.injectItems( i, Actionable.MODULATE, src );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// assume its possible.
|
||||
|
||||
// add crafting results..
|
||||
for( final IAEItemStack out : this.details.getCondensedOutputs() )
|
||||
{
|
||||
final IAEItemStack o = out.copy();
|
||||
o.setStackSize( o.getStackSize() * i );
|
||||
o.setStackSize( o.getStackSize() * amountOfTimes );
|
||||
inv.injectItems( o, Actionable.MODULATE, src );
|
||||
}
|
||||
|
||||
this.crafts += i;
|
||||
this.crafts += amountOfTimes;
|
||||
}
|
||||
|
||||
void dive( final CraftingJob job )
|
||||
{
|
||||
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts, this.details, this.depth );
|
||||
for( final CraftingTreeNode pro : this.nodes.keySet() )
|
||||
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts );
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
pro.dive( job );
|
||||
entry.getKey().dive( job );
|
||||
}
|
||||
|
||||
job.addBytes( 8 + this.crafts + this.bytes );
|
||||
job.addBytes( this.crafts * 8 + this.bytes );
|
||||
}
|
||||
|
||||
IAEItemStack getAmountCrafted( IAEItemStack what2 )
|
||||
@@ -287,9 +254,9 @@ public class CraftingTreeProcess
|
||||
this.crafts = 0;
|
||||
this.bytes = 0;
|
||||
|
||||
for( final CraftingTreeNode pro : this.nodes.keySet() )
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
pro.setSimulate();
|
||||
entry.getKey().setSimulate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,9 +264,9 @@ public class CraftingTreeProcess
|
||||
{
|
||||
craftingCPUCluster.addCrafting( this.details, this.crafts );
|
||||
|
||||
for( final CraftingTreeNode pro : this.nodes.keySet() )
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
pro.setJob( storage, craftingCPUCluster, src );
|
||||
entry.getKey().setJob( storage, craftingCPUCluster, src );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,9 +279,14 @@ public class CraftingTreeProcess
|
||||
plan.addRequestable( i );
|
||||
}
|
||||
|
||||
for( final CraftingTreeNode pro : this.nodes.keySet() )
|
||||
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
|
||||
{
|
||||
pro.getPlan( plan );
|
||||
entry.getKey().getPlan( plan );
|
||||
}
|
||||
}
|
||||
|
||||
public void reserveForNode()
|
||||
{
|
||||
parent.reserveForNode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,13 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketInformPlayer;
|
||||
import appeng.util.inv.ItemListIgnoreCrafting;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
@@ -95,8 +101,7 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
this.injectedCache = null;
|
||||
}
|
||||
|
||||
this.localCache = this.target
|
||||
.getAvailableItems( new ItemListIgnoreCrafting<>( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) );
|
||||
this.localCache = this.target.getAvailableItems( new ItemListIgnoreCrafting<>( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) );
|
||||
|
||||
this.par = parent;
|
||||
}
|
||||
@@ -307,8 +312,25 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
|
||||
if( result == null || result.getStackSize() != extra.getStackSize() )
|
||||
{
|
||||
if( src.player().isPresent() )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( result == null )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( new PacketInformPlayer( extra ), (EntityPlayerMP) src.player().get() );
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkHandler.instance().sendTo( new PacketInformPlayer( extra, result ), (EntityPlayerMP) src.player().get() );
|
||||
}
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,11 +361,6 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addMissing( final IAEItemStack extra )
|
||||
{
|
||||
this.missingCache.add( extra );
|
||||
}
|
||||
|
||||
void ignore( final IAEItemStack what )
|
||||
{
|
||||
final IAEItemStack list = this.localCache.findPrecise( what );
|
||||
@@ -352,4 +369,18 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
list.setStackSize( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void reserve( final IAEItemStack what )
|
||||
{
|
||||
final IAEItemStack list = this.localCache.findPrecise( what );
|
||||
if( list != null )
|
||||
{
|
||||
list.decStackSize( what.getStackSize() );
|
||||
}
|
||||
}
|
||||
|
||||
private void addMissing( final IAEItemStack extra )
|
||||
{
|
||||
this.missingCache.add( extra );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ 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;
|
||||
|
||||
@@ -38,11 +41,12 @@ import appeng.fluids.helper.IFluidInterfaceHost;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
|
||||
|
||||
public class GuiFluidInterface extends GuiUpgradeable
|
||||
public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerHost
|
||||
{
|
||||
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 )
|
||||
@@ -50,6 +54,8 @@ public class GuiFluidInterface extends GuiUpgradeable
|
||||
super( new ContainerFluidInterface( ip, te ) );
|
||||
this.ySize = 231;
|
||||
this.host = te;
|
||||
( this.container = (ContainerFluidInterface) this.inventorySlots ).setGui( this );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,9 +68,7 @@ public class GuiFluidInterface extends GuiUpgradeable
|
||||
|
||||
for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i )
|
||||
{
|
||||
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 GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 57, 16, 64 ) );
|
||||
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
|
||||
}
|
||||
|
||||
@@ -104,9 +108,33 @@ public class GuiFluidInterface extends GuiUpgradeable
|
||||
}
|
||||
}
|
||||
|
||||
@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 )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ 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;
|
||||
@@ -23,7 +24,7 @@ import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
|
||||
|
||||
public class GuiFluidSlot extends GuiCustomSlot
|
||||
public class GuiFluidSlot extends GuiCustomSlot implements IJEITargetSlot
|
||||
{
|
||||
private final IAEFluidTank fluids;
|
||||
private final int slot;
|
||||
|
||||
@@ -19,42 +19,50 @@
|
||||
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 GuiButton implements ITooltip
|
||||
public class GuiFluidTank extends GuiCustomSlot 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, w, h, "" );
|
||||
super( id, x, y );
|
||||
this.tank = tank;
|
||||
this.slot = slot;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton( final Minecraft mc, final int mouseX, final int mouseY, final float partialTicks )
|
||||
public void drawContent( Minecraft mc, int mouseX, int mouseY, float partialTicks )
|
||||
{
|
||||
if( this.visible )
|
||||
final IAEFluidStack fs = this.getFluidStack();
|
||||
if( fs != null )
|
||||
{
|
||||
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 )
|
||||
@@ -72,14 +80,13 @@ public class GuiFluidTank extends GuiButton implements ITooltip
|
||||
int iconHeightRemainder = scaledHeight % 16;
|
||||
if( iconHeightRemainder > 0 )
|
||||
{
|
||||
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder, sprite, 16, iconHeightRemainder );
|
||||
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, 16, iconHeightRemainder );
|
||||
}
|
||||
for( int i = 0; i < scaledHeight / 16; i++ )
|
||||
{
|
||||
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
|
||||
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,19 +107,19 @@ public class GuiFluidTank extends GuiButton implements ITooltip
|
||||
@Override
|
||||
public int xPos()
|
||||
{
|
||||
return this.x - 2;
|
||||
return this.x - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos()
|
||||
{
|
||||
return this.y - 2;
|
||||
return this.y - 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth()
|
||||
{
|
||||
return this.width + 4;
|
||||
return this.width;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,4 +134,24 @@ public class GuiFluidTank extends GuiButton 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,9 +19,17 @@
|
||||
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;
|
||||
|
||||
@@ -33,12 +41,19 @@ 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
|
||||
public class ContainerFluidInterface extends ContainerFluidConfigurable implements IConfigManagerHost
|
||||
{
|
||||
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 )
|
||||
{
|
||||
@@ -60,6 +75,15 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable
|
||||
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()
|
||||
{
|
||||
@@ -97,6 +121,126 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable
|
||||
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,6 +24,9 @@ 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;
|
||||
@@ -70,6 +73,7 @@ import appeng.me.helpers.ChannelPowerSrc;
|
||||
import appeng.util.ConfigManager;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
|
||||
/**
|
||||
@@ -342,6 +346,89 @@ 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 || notInserted.getStackSize() == 0 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
@@ -352,13 +439,9 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
|
||||
}
|
||||
|
||||
final ItemStack held = player.inventory.getItemStack();
|
||||
if( held.getCount() != 1 )
|
||||
{
|
||||
// only support stacksize 1 for now
|
||||
return;
|
||||
}
|
||||
|
||||
final IFluidHandlerItem fh = FluidUtil.getFluidHandler( held );
|
||||
ItemStack heldCopy = held.copy();
|
||||
heldCopy.setCount( 1 );
|
||||
IFluidHandlerItem fh = FluidUtil.getFluidHandler( heldCopy );
|
||||
if( fh == null )
|
||||
{
|
||||
// only fluid handlers items
|
||||
@@ -372,84 +455,122 @@ 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 );
|
||||
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 )
|
||||
int heldAmount = held.getCount();
|
||||
for( int i = 0; i < heldAmount; i++ )
|
||||
{
|
||||
return;
|
||||
}
|
||||
ItemStack copiedFluidContainer = held.copy();
|
||||
copiedFluidContainer.setCount( 1 );
|
||||
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||
|
||||
// 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 )
|
||||
{
|
||||
// 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 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 )
|
||||
// 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
|
||||
{
|
||||
extract.amount = storable.amount;
|
||||
player.inventory.getItemStack().shrink( 1 );
|
||||
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||
{
|
||||
player.dropItem( fh.getContainer(), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
this.updateHeld( player );
|
||||
|
||||
// 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 )
|
||||
}
|
||||
else if( action == InventoryAction.EMPTY_ITEM )
|
||||
{
|
||||
int heldAmount = held.getCount();
|
||||
for( int i = 0; i < heldAmount; i++ )
|
||||
{
|
||||
AELog.error( "Fluid item [%s] reported a different possible amount to drain than it actually provided.", held.getDisplayName() );
|
||||
}
|
||||
ItemStack copiedFluidContainer = held.copy();
|
||||
copiedFluidContainer.setCount( 1 );
|
||||
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||
|
||||
player.inventory.setItemStack( fh.getContainer() );
|
||||
// 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 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
this.updateHeld( player );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,12 +91,10 @@ 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 final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
|
||||
private boolean resetConfigCache = true;
|
||||
private IMEMonitor<IAEFluidStack> configCachedHandler;
|
||||
|
||||
public DualityFluidInterface( final AENetworkProxy networkProxy, final IFluidInterfaceHost ih )
|
||||
{
|
||||
@@ -119,15 +117,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
|
||||
public IUpgradeableHost getHost()
|
||||
{
|
||||
if( this.iHost instanceof IUpgradeableHost )
|
||||
{
|
||||
return this.iHost;
|
||||
}
|
||||
if( this.iHost instanceof IUpgradeableHost )
|
||||
{
|
||||
return this.iHost;
|
||||
}
|
||||
return null;
|
||||
return this.iHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,7 +136,12 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
{
|
||||
if( this.hasConfig() )
|
||||
{
|
||||
return (IMEMonitor<T>) new InterfaceInventory( this );
|
||||
if( resetConfigCache )
|
||||
{
|
||||
resetConfigCache = false;
|
||||
configCachedHandler = new InterfaceInventory( this );
|
||||
}
|
||||
return (IMEMonitor<T>) configCachedHandler;
|
||||
}
|
||||
|
||||
return (IMEMonitor<T>) this.fluids;
|
||||
@@ -383,7 +378,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
else if( this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ).getStorageList().findPrecise( work ) != null )
|
||||
{
|
||||
final IAEFluidStack acquired = Platform.poweredExtraction( src, dest, work, this.interfaceRequestSource );
|
||||
if( acquired != null )
|
||||
@@ -450,7 +445,13 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
|
||||
if( inventory == this.config )
|
||||
{
|
||||
boolean cfg = hasConfig();
|
||||
this.readConfig();
|
||||
if( cfg != hasConfig )
|
||||
{
|
||||
resetConfigCache = true;
|
||||
this.notifyNeighbors();
|
||||
}
|
||||
}
|
||||
else if( inventory == this.tanks )
|
||||
{
|
||||
@@ -555,7 +556,6 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
InterfaceInventory( final DualityFluidInterface tileInterface )
|
||||
{
|
||||
super( tileInterface.tanks );
|
||||
this.setActionSource( new MachineSource( tileInterface.iHost ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,16 +19,15 @@
|
||||
package appeng.fluids.parts;
|
||||
|
||||
|
||||
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.*;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.StorageFilter;
|
||||
import appeng.parts.misc.PartStorageBus;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
||||
@@ -45,7 +44,6 @@ 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;
|
||||
|
||||
@@ -65,17 +63,20 @@ 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 PartStorageBus )
|
||||
if( this.proxyable instanceof PartFluidStorageBus )
|
||||
{
|
||||
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
||||
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
||||
PartFluidStorageBus partFluidStorageBus = (PartFluidStorageBus) this.proxyable;
|
||||
this.mode = ( (StorageFilter) partFluidStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
||||
this.access = ( (AccessRestriction) partFluidStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||
}
|
||||
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode);
|
||||
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode );
|
||||
this.cache.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,11 +95,14 @@ 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 ignore )
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
@@ -123,25 +127,32 @@ 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 ignore )
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
return AEFluidStack.fromFluidStack( gathered );
|
||||
return gatheredAEFluidstack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
List<IAEFluidStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() )
|
||||
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
return TickRateModulation.URGENT;
|
||||
@@ -202,9 +213,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 )
|
||||
{
|
||||
@@ -216,102 +227,46 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
{
|
||||
final List<IAEFluidStack> changes = new ArrayList<>();
|
||||
final IFluidTankProperties[] tankProperties = this.fluidHandler.getTankProperties();
|
||||
final int slots = tankProperties.length;
|
||||
|
||||
// Make room for new slots
|
||||
if( slots > this.cachedAeStacks.length )
|
||||
{
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
|
||||
for( int slot = 0; slot < slots; slot++ )
|
||||
for( IFluidTankProperties tankProperty : tankProperties )
|
||||
{
|
||||
// Save the old stuff
|
||||
final IAEFluidStack oldAEFS = this.cachedAeStacks[slot];
|
||||
FluidStack newFS = tankProperties[slot].getContents();
|
||||
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && newFS != null )
|
||||
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain( 1, false ) == null )
|
||||
{
|
||||
if( this.fluidHandler.drain( 1, false ) == null )
|
||||
{
|
||||
newFS = null;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
this.handlePossibleSlotChanges( slot, oldAEFS, newFS, changes );
|
||||
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
|
||||
}
|
||||
|
||||
// Handle cases where the number of slots actually is lower now than before
|
||||
if( slots < this.cachedAeStacks.length )
|
||||
for ( final IAEFluidStack is : currentlyCached )
|
||||
{
|
||||
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
|
||||
{
|
||||
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 );
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
|
||||
for ( final IAEFluidStack is : currentlyOnStorage )
|
||||
{
|
||||
currentlyCached.add( is );
|
||||
}
|
||||
|
||||
for ( final IAEFluidStack is : currentlyCached )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
changes.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
currentlyCached = currentlyOnStorage;
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public IItemList<IAEFluidStack> getAvailableItems( IItemList<IAEFluidStack> out )
|
||||
{
|
||||
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
|
||||
currentlyCached.iterator().forEachRemaining( out::add );
|
||||
return out;
|
||||
}
|
||||
|
||||
private void handlePossibleSlotChanges( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
||||
{
|
||||
if( oldAeFS != null && oldAeFS.getFluidStack().isFluidEqual( newFS ) )
|
||||
{
|
||||
this.handleStackSizeChanged( slot, oldAeFS, newFS, changes );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.handleFluidChanged( slot, oldAeFS, newFS, changes );
|
||||
}
|
||||
}
|
||||
|
||||
private void handleStackSizeChanged( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
||||
{
|
||||
// Still the same fluid, but amount might have changed
|
||||
final long diff = newFS.amount - oldAeFS.getStackSize();
|
||||
|
||||
if( diff != 0 )
|
||||
{
|
||||
final IAEFluidStack stack = oldAeFS.copy();
|
||||
stack.setStackSize( newFS.amount );
|
||||
|
||||
this.cachedAeStacks[slot] = stack;
|
||||
|
||||
final IAEFluidStack a = stack.copy();
|
||||
a.setStackSize( diff );
|
||||
changes.add( a );
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFluidChanged( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
||||
{
|
||||
// Completely different fluid
|
||||
this.cachedAeStacks[slot] = AEFluidStack.fromFluidStack( newFS );
|
||||
|
||||
// If we had a stack previously in this slot, notify the network about its disappearance
|
||||
if( oldAeFS != null )
|
||||
{
|
||||
oldAeFS.setStackSize( -oldAeFS.getStackSize() );
|
||||
changes.add( oldAeFS );
|
||||
}
|
||||
|
||||
// Notify the network about the new stack. Note that this is null if newFS was null
|
||||
if( this.cachedAeStacks[slot] != null )
|
||||
{
|
||||
changes.add( this.cachedAeStacks[slot] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,8 +178,9 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
|
||||
this.stateChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void updateChannels( final MENetworkChannelsChanged changedChannels )
|
||||
public void chanRender( final MENetworkChannelsChanged changedChannels )
|
||||
{
|
||||
this.stateChanged();
|
||||
}
|
||||
@@ -204,7 +205,7 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
|
||||
@Override
|
||||
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
|
||||
{
|
||||
if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||
if( channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||
{
|
||||
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
|
||||
handler.add( this.myHandler );
|
||||
|
||||
@@ -90,14 +90,16 @@ public class PartFluidInterface extends PartBasicState implements IGridTickable,
|
||||
return this.duality;
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void stateChange( final MENetworkChannelsChanged c )
|
||||
public void chanRender( final MENetworkChannelsChanged c )
|
||||
{
|
||||
this.duality.notifyNeighbors();
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void stateChange( final MENetworkPowerStatusChange c )
|
||||
public void powerRender( final MENetworkPowerStatusChange c )
|
||||
{
|
||||
this.duality.notifyNeighbors();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ package appeng.fluids.parts;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||
import appeng.me.cache.NetworkMonitor;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -34,7 +36,6 @@ 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;
|
||||
@@ -127,15 +128,25 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
||||
this.configureWatchers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void channelChanged( final MENetworkChannelsChanged c )
|
||||
public void powerRender( final MENetworkPowerStatusChange powerEvent )
|
||||
{
|
||||
if (this.getProxy().isActive())
|
||||
{
|
||||
onListUpdate();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void powerChanged( final MENetworkPowerStatusChange c )
|
||||
public void chanRender( final MENetworkChannelsChanged c )
|
||||
{
|
||||
if (this.getProxy().isActive())
|
||||
{
|
||||
onListUpdate();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
@@ -247,10 +258,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
||||
|
||||
if( myStack == null )
|
||||
{
|
||||
this.lastReportedValue = 0;
|
||||
for( final IAEFluidStack st : monitor.getStorageList() )
|
||||
if( monitor instanceof NetworkMonitor )
|
||||
{
|
||||
this.lastReportedValue += st.getStackSize();
|
||||
this.lastReportedValue = ( (NetworkMonitor<IAEFluidStack>) monitor ).getGridCurrentCount();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,42 +19,6 @@
|
||||
package appeng.helpers;
|
||||
|
||||
|
||||
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 com.google.common.collect.ImmutableSet;
|
||||
|
||||
import gregtech.api.block.machines.BlockMachine;
|
||||
import gregtech.api.metatileentity.MetaTileEntity;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.RangedWrapper;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.Settings;
|
||||
@@ -78,11 +42,7 @@ import appeng.api.networking.ticking.IGridTickable;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.networking.ticking.TickingRequest;
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.IStorageMonitorable;
|
||||
import appeng.api.storage.IStorageMonitorableAccessor;
|
||||
import appeng.api.storage.*;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
@@ -93,8 +53,6 @@ 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;
|
||||
@@ -106,25 +64,51 @@ 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.ConfigManager;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.*;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.primitives.Ints;
|
||||
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
|
||||
import gregtech.api.block.machines.BlockMachine;
|
||||
import gregtech.api.metatileentity.MetaTileEntity;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.RangedWrapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
|
||||
|
||||
|
||||
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost
|
||||
{
|
||||
private int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
|
||||
|
||||
public static final int NUMBER_OF_STORAGE_SLOTS = 9;
|
||||
public static final int NUMBER_OF_CONFIG_SLOTS = 9;
|
||||
public static final int NUMBER_OF_PATTERN_SLOTS = 9;
|
||||
public static final int NUMBER_OF_PATTERN_SLOTS = 36;
|
||||
|
||||
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
|
||||
private final IAEItemStack[] requireWork = { null, null, null, null, null, null, null, null, null };
|
||||
private final IAEItemStack[] requireWork = {null, null, null, null, null, null, null, null, null};
|
||||
private final MultiCraftingTracker craftingTracker;
|
||||
private final AENetworkProxy gridProxy;
|
||||
private final IInterfaceHost iHost;
|
||||
@@ -134,28 +118,27 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
private final AppEngInternalAEInventory config = new AppEngInternalAEInventory( this, NUMBER_OF_CONFIG_SLOTS );
|
||||
private final AppEngInternalInventory storage = new AppEngInternalInventory( this, NUMBER_OF_STORAGE_SLOTS );
|
||||
private final AppEngInternalInventory patterns = new AppEngInternalInventory( this, NUMBER_OF_PATTERN_SLOTS );
|
||||
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance()
|
||||
.storage()
|
||||
.getStorageChannel( IItemStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance()
|
||||
.storage()
|
||||
.getStorageChannel( IFluidStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
|
||||
private final UpgradeInventory upgrades;
|
||||
private final Accessor accessor = new Accessor();
|
||||
private boolean hasConfig = false;
|
||||
private int priority;
|
||||
private List<ICraftingPatternDetails> craftingList = null;
|
||||
private List<ItemStack> waitingToSend = null;
|
||||
private IMEInventory<IAEItemStack> destination;
|
||||
private int isWorking = -1;
|
||||
private final Accessor accessor = new Accessor();
|
||||
private GTCEInventoryAdaptor GTad;
|
||||
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
|
||||
private EnumMap<EnumFacing, List<ItemStack>> waitingToSendFacing = new EnumMap<>( EnumFacing.class );
|
||||
private boolean resetConfigCache = true;
|
||||
private IMEMonitor<IAEItemStack> configCachedHandler;
|
||||
|
||||
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, 1 );
|
||||
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4 );
|
||||
this.cm.registerSetting( Settings.BLOCK, YesNo.NO );
|
||||
this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES );
|
||||
|
||||
@@ -170,6 +153,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
this.interfaceRequestSource = new InterfaceRequestSource( this.iHost );
|
||||
}
|
||||
|
||||
private static boolean invIsCustomBlocking( BlockingInventoryAdaptor inv )
|
||||
{
|
||||
return ( inv.containsBlockingItems() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChanges()
|
||||
{
|
||||
@@ -183,10 +171,15 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( inv == this.config )
|
||||
if( inv == this.config && ( !removed.isEmpty() || !added.isEmpty() ) )
|
||||
{
|
||||
boolean cfg = hasConfig();
|
||||
this.readConfig();
|
||||
if( cfg != hasConfig )
|
||||
{
|
||||
resetConfigCache = true;
|
||||
this.notifyNeighbors();
|
||||
}
|
||||
}
|
||||
else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) )
|
||||
{
|
||||
@@ -242,6 +235,27 @@ 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 )
|
||||
@@ -261,9 +275,46 @@ 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" );
|
||||
@@ -296,6 +347,31 @@ 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;
|
||||
@@ -336,25 +412,25 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
// :P
|
||||
}
|
||||
}
|
||||
|
||||
this.notifyNeighbors();
|
||||
}
|
||||
|
||||
private void updateCraftingList()
|
||||
{
|
||||
final Boolean[] accountedFor = { false, false, false, false, false, false, false, false, false }; // 9...
|
||||
|
||||
assert ( accountedFor.length == this.patterns.getSlots() );
|
||||
final Boolean[] accountedFor = new Boolean[this.patterns.getSlots()];
|
||||
Arrays.fill( accountedFor, false );
|
||||
|
||||
if( !this.gridProxy.isReady() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boolean removed = false;
|
||||
|
||||
if( this.craftingList != null )
|
||||
{
|
||||
final Iterator<ICraftingPatternDetails> i = this.craftingList.iterator();
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final ICraftingPatternDetails details = i.next();
|
||||
boolean found = false;
|
||||
@@ -370,47 +446,53 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
if( !found )
|
||||
{
|
||||
removed = true;
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean newPattern = false;
|
||||
|
||||
for( int x = 0; x < accountedFor.length; x++ )
|
||||
{
|
||||
if( !accountedFor[x] )
|
||||
{
|
||||
newPattern = true;
|
||||
this.addToCraftingList( this.patterns.getStackInSlot( x ) );
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
catch( GridAccessException e )
|
||||
{
|
||||
// :P
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasWorkToDo()
|
||||
{
|
||||
if( this.hasItemsToSend() )
|
||||
|
||||
if( hasItemsToSend() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( final IAEItemStack requiredWork : this.requireWork )
|
||||
{
|
||||
if( requiredWork != null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if( hasItemsToSendFacing() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for( final IAEItemStack requiredWork : this.requireWork )
|
||||
{
|
||||
if( requiredWork != null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updatePlan( final int slot )
|
||||
@@ -515,11 +597,52 @@ 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 )
|
||||
{
|
||||
final IAEItemStack out = this.destination.injectItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ),
|
||||
Actionable.SIMULATE, null );
|
||||
final IAEItemStack out = this.destination.injectItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ), Actionable.SIMULATE, null );
|
||||
if( out == null )
|
||||
{
|
||||
return true;
|
||||
@@ -586,11 +709,21 @@ 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;
|
||||
}
|
||||
@@ -606,7 +739,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final World w = tile.getWorld();
|
||||
|
||||
final Iterator<ItemStack> i = this.waitingToSend.iterator();
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
ItemStack whatToSend = i.next();
|
||||
|
||||
@@ -651,6 +784,48 @@ 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 InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
|
||||
final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator();
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
ItemStack whatToSend = i.next();
|
||||
if( ad != null )
|
||||
{
|
||||
final ItemStack result = ad.addItems( whatToSend );
|
||||
if( !result.isEmpty() )
|
||||
{
|
||||
whatToSend.setCount( result.getCount() );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( this.waitingToSendFacing.get( s ).isEmpty() )
|
||||
{
|
||||
this.waitingToSendFacing.remove( s );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateStorage()
|
||||
{
|
||||
boolean didSomething = false;
|
||||
@@ -677,35 +852,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
this.destination = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
final IEnergySource src = this.gridProxy.getEnergy();
|
||||
|
||||
if( this.craftingTracker.isBusy( x ) )
|
||||
{
|
||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||
}
|
||||
else if( itemStack.getStackSize() > 0 )
|
||||
{
|
||||
// make sure strange things didn't happen...
|
||||
if( !adaptor.simulateAdd( itemStack.createItemStack() ).isEmpty() )
|
||||
{
|
||||
changed = true;
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
|
||||
if( acquired != null )
|
||||
{
|
||||
changed = true;
|
||||
final ItemStack issue = adaptor.addItems( acquired.createItemStack() );
|
||||
if( !issue.isEmpty() )
|
||||
{
|
||||
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||
}
|
||||
}
|
||||
else if( itemStack.getStackSize() < 0 )
|
||||
if( itemStack.getStackSize() < 0 )
|
||||
{
|
||||
IAEItemStack toStore = itemStack.copy();
|
||||
toStore.setStackSize( -toStore.getStackSize() );
|
||||
@@ -743,6 +890,51 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( this.craftingTracker.isBusy( x ) )
|
||||
{
|
||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||
}
|
||||
else if( itemStack.getStackSize() > 0 )
|
||||
{
|
||||
// make sure strange things didn't happen...
|
||||
|
||||
ItemStack inputStack = itemStack.getCachedItemStack( itemStack.getStackSize() );
|
||||
|
||||
ItemStack remaining = adaptor.simulateAdd( inputStack );
|
||||
|
||||
if( !remaining.isEmpty() )
|
||||
{
|
||||
itemStack.setCachedItemStack( remaining );
|
||||
changed = true;
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
IAEItemStack storedStack = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findPrecise( itemStack );
|
||||
if( storedStack != null )
|
||||
{
|
||||
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
|
||||
if( acquired != null )
|
||||
{
|
||||
changed = true;
|
||||
inputStack.setCount( Ints.saturatedCast( acquired.getStackSize() ) );
|
||||
final ItemStack issue = adaptor.addItems( inputStack );
|
||||
if( !issue.isEmpty() )
|
||||
{
|
||||
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
|
||||
}
|
||||
}
|
||||
else if( storedStack.isCraftable() )
|
||||
{
|
||||
itemStack.setCachedItemStack( inputStack );
|
||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||
}
|
||||
if( acquired == null )
|
||||
{
|
||||
itemStack.setCachedItemStack( inputStack );
|
||||
}
|
||||
}
|
||||
}
|
||||
// else wtf?
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
@@ -770,17 +962,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null )
|
||||
{
|
||||
if (this.failedCraftTriesSlot[x] <= 0)
|
||||
{
|
||||
boolean crafted = this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
|
||||
this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
|
||||
|
||||
if (crafted) this.failedCraftTriesSlot[x] = 0;
|
||||
else{
|
||||
this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
return this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(), this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
@@ -814,7 +996,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.hasConfig() )
|
||||
{
|
||||
return (IMEMonitor<T>) new InterfaceInventory( this );
|
||||
if( resetConfigCache )
|
||||
{
|
||||
resetConfigCache = false;
|
||||
configCachedHandler = new InterfaceInventory( this );
|
||||
}
|
||||
return (IMEMonitor<T>) configCachedHandler;
|
||||
}
|
||||
|
||||
return (IMEMonitor<T>) this.items;
|
||||
@@ -913,24 +1100,15 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean invIsBlocked( InventoryAdaptor inv )
|
||||
private boolean invIsBlocked( InventoryAdaptor inv )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
return ( !inv.canRemoveAllExceptCircuits() );
|
||||
return ( inv.containsItems() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table )
|
||||
{
|
||||
if( this.hasItemsToSend() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
|
||||
if( this.hasItemsToSend() || this.hasItemsToSendFacing() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -938,8 +1116,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final TileEntity tile = this.iHost.getTileEntity();
|
||||
final World w = tile.getWorld();
|
||||
|
||||
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
|
||||
for( final EnumFacing s : possibleDirections )
|
||||
if( this.visitedFaces.isEmpty() )
|
||||
{
|
||||
this.visitedFaces = this.iHost.getTargets();
|
||||
}
|
||||
|
||||
for( final EnumFacing s : visitedFaces )
|
||||
{
|
||||
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
|
||||
if( te instanceof IInterfaceHost )
|
||||
@@ -948,6 +1130,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( ( (IInterfaceHost) te ).getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -962,6 +1145,7 @@ 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;
|
||||
@@ -970,58 +1154,73 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( ad != null )
|
||||
{
|
||||
if( this.isBlocking() )
|
||||
{
|
||||
if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
|
||||
IPhantomTile phantomTE;
|
||||
if( Loader.isModLoaded( "actuallyadditions" ) && te instanceof IPhantomTile )
|
||||
{
|
||||
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( invIsBlockedGTCE( GTad ) )
|
||||
phantomTE = ( (IPhantomTile) te );
|
||||
if( phantomTE.hasBoundPosition() )
|
||||
{
|
||||
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
||||
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) )
|
||||
{
|
||||
if( isCustomInvBlocking( phantom, s ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
|
||||
{
|
||||
if( isCustomInvBlocking( te, s ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if( invIsBlocked( ad ) )
|
||||
{
|
||||
if( invIsBlocked( ad ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
visitedFaces.remove( s );
|
||||
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() )
|
||||
{
|
||||
final ItemStack added = ad.addItems( is );
|
||||
this.addToSendList( added );
|
||||
addToSendListFacing( is, s );
|
||||
}
|
||||
}
|
||||
this.pushItemsOut( possibleDirections );
|
||||
pushItemsOut( s );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
visitedFaces.remove( s );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy()
|
||||
{
|
||||
if( this.hasItemsToSend() )
|
||||
boolean busy = false;
|
||||
|
||||
if( this.hasItemsToSend() || hasItemsToSendFacing() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean busy = false;
|
||||
|
||||
if( this.isBlocking() )
|
||||
{
|
||||
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
|
||||
@@ -1033,14 +1232,30 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
for( final EnumFacing s : possibleDirections )
|
||||
{
|
||||
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
|
||||
IPhantomTile phantomTE;
|
||||
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( ad != null )
|
||||
{
|
||||
if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
|
||||
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
|
||||
{
|
||||
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( !invIsBlockedGTCE( GTad ) )
|
||||
phantomTE = ( (IPhantomTile) te );
|
||||
if( phantomTE.hasBoundPosition() )
|
||||
{
|
||||
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
||||
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) )
|
||||
{
|
||||
if( !isCustomInvBlocking( phantom, s ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
|
||||
{
|
||||
if( !isCustomInvBlocking( te, s ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
@@ -1053,7 +1268,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1062,6 +1276,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return busy;
|
||||
}
|
||||
|
||||
boolean isCustomInvBlocking( TileEntity te, EnumFacing s )
|
||||
{
|
||||
BlockingInventoryAdaptor blockingInventoryAdaptor = BlockingInventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
return invIsCustomBlocking( blockingInventoryAdaptor );
|
||||
}
|
||||
|
||||
private boolean sameGrid( final IGrid grid ) throws GridAccessException
|
||||
{
|
||||
return grid == this.gridProxy.getGrid();
|
||||
@@ -1082,7 +1302,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !ad.simulateAdd( is.copy() ).isEmpty() )
|
||||
if( !ad.simulateAdd( is ).isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1117,6 +1337,20 @@ 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() )
|
||||
@@ -1241,9 +1475,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final Block directedBlock = directedBlockState.getBlock();
|
||||
ItemStack what = new ItemStack( directedBlock, 1, directedBlock.getMetaFromState( directedBlockState ) );
|
||||
|
||||
if ( Loader.isModLoaded("gregtech") && directedBlock instanceof BlockMachine )
|
||||
if( Loader.isModLoaded( "gregtech" ) && directedBlock instanceof BlockMachine )
|
||||
{
|
||||
MetaTileEntity metaTileEntity = getMetaTileEntity(hostWorld, targ);
|
||||
MetaTileEntity metaTileEntity = getMetaTileEntity( hostWorld, targ );
|
||||
return metaTileEntity.getMetaFullName();
|
||||
}
|
||||
|
||||
@@ -1359,6 +1593,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class InterfaceRequestContext implements Comparable<Integer>
|
||||
{
|
||||
|
||||
@@ -1369,13 +1604,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class InterfaceInventory extends MEMonitorIInventory
|
||||
{
|
||||
|
||||
public InterfaceInventory( final DualityInterface tileInterface )
|
||||
{
|
||||
super( new AdaptorItemHandler( tileInterface.storage ) );
|
||||
this.setActionSource( new MachineSource( DualityInterface.this.iHost ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1407,6 +1642,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class Accessor implements IStorageMonitorableAccessor
|
||||
{
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ public class HighlighterHandler
|
||||
tessellator.draw();
|
||||
|
||||
GlStateManager.enableTexture2D();
|
||||
GlStateManager.enableDepth();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,5 +43,6 @@ public enum InventoryAction
|
||||
ROLL_UP,
|
||||
ROLL_DOWN,
|
||||
AUTO_CRAFT,
|
||||
PLACE_SINGLE
|
||||
PLACE_SINGLE,
|
||||
PLACE_JEI_GHOST_ITEM
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.Future;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -83,57 +84,70 @@ public class MultiCraftingTracker
|
||||
|
||||
public boolean handleCrafting( final int x, final long itemToCraft, final IAEItemStack ais, final InventoryAdaptor d, final World w, final IGrid g, final ICraftingGrid cg, final IActionSource mySrc )
|
||||
{
|
||||
if( ais != null && d.simulateAdd( ais.createItemStack() ).isEmpty() )
|
||||
if( ais != null )
|
||||
{
|
||||
final Future<ICraftingJob> craftingJob = this.getJob( x );
|
||||
ItemStack inputStack = ais.getCachedItemStack( ais.getStackSize() );
|
||||
|
||||
if( this.getLink( x ) != null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if( craftingJob != null )
|
||||
{
|
||||
ItemStack remaining = d.simulateAdd( inputStack );
|
||||
|
||||
try
|
||||
if( remaining.isEmpty() )
|
||||
{
|
||||
ais.setCachedItemStack( inputStack );
|
||||
|
||||
final Future<ICraftingJob> craftingJob = this.getJob( x );
|
||||
|
||||
if( this.getLink( x ) != null )
|
||||
{
|
||||
ICraftingJob job = null;
|
||||
if( craftingJob.isDone() )
|
||||
return false;
|
||||
}
|
||||
else if( craftingJob != null )
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
job = craftingJob.get();
|
||||
}
|
||||
|
||||
if( job != null )
|
||||
{
|
||||
final ICraftingLink link = cg.submitJob( job, this.owner, null, false, mySrc );
|
||||
|
||||
this.setJob( x, null );
|
||||
|
||||
if( link != null )
|
||||
ICraftingJob job = null;
|
||||
if( craftingJob.isDone() )
|
||||
{
|
||||
this.setLink( x, link );
|
||||
job = craftingJob.get();
|
||||
}
|
||||
|
||||
return true;
|
||||
if( job != null )
|
||||
{
|
||||
final ICraftingLink link = cg.submitJob( job, this.owner, null, false, mySrc );
|
||||
|
||||
this.setJob( x, null );
|
||||
|
||||
if( link != null )
|
||||
{
|
||||
this.setLink( x, link );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( final InterruptedException e )
|
||||
{
|
||||
// :P
|
||||
}
|
||||
catch( final ExecutionException e )
|
||||
{
|
||||
// :P
|
||||
}
|
||||
}
|
||||
catch( final InterruptedException e )
|
||||
else
|
||||
{
|
||||
// :P
|
||||
}
|
||||
catch( final ExecutionException e )
|
||||
{
|
||||
// :P
|
||||
if( this.getLink( x ) == null )
|
||||
{
|
||||
final IAEItemStack aisC = ais.copy();
|
||||
aisC.setStackSize( itemToCraft );
|
||||
|
||||
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( this.getLink( x ) == null )
|
||||
{
|
||||
final IAEItemStack aisC = ais.copy();
|
||||
aisC.setStackSize( itemToCraft );
|
||||
|
||||
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
|
||||
}
|
||||
ais.setCachedItemStack( remaining );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
package appeng.helpers;
|
||||
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.util.Platform;
|
||||
import gregtech.api.items.metaitem.MetaItem;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class NonBlockingItems
|
||||
{
|
||||
public static Map<String, Object2ObjectOpenHashMap<Item, IntSet>> NON_BLOCKING_MAP = new HashMap<>();
|
||||
public static NonBlockingItems INSTANCE = new NonBlockingItems();
|
||||
|
||||
private NonBlockingItems()
|
||||
{
|
||||
String[] strings = AEConfig.instance().getNonBlockingItems();
|
||||
String[] modids = new String[0];
|
||||
if( strings.length > 0 )
|
||||
{
|
||||
for( String s : strings )
|
||||
{
|
||||
if( s.startsWith( "[" ) && s.endsWith( "]" ) )
|
||||
{
|
||||
modids = s.substring( 1, s.length() - 1 ).split( "\\|" );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( String modid : modids )
|
||||
{
|
||||
if( !Loader.isModLoaded( modid ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
NON_BLOCKING_MAP.putIfAbsent( modid, new Object2ObjectOpenHashMap<>() );
|
||||
|
||||
String[] ModItemMeta = s.split( ":" );
|
||||
|
||||
if( ModItemMeta.length < 2 || ModItemMeta.length > 3 )
|
||||
{
|
||||
AELog.error( "Invalid non blocking item entry: " + s );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ModItemMeta[0].equals( "gregtech" ) && Platform.isModLoaded( "gregtech" ) )
|
||||
{
|
||||
boolean found = false;
|
||||
for( MetaItem<?> metaItem : MetaItem.getMetaItems() )
|
||||
{
|
||||
MetaItem<?>.MetaValueItem metaItem2 = metaItem.getItem( ModItemMeta[1] );
|
||||
if( metaItem.getItem( ModItemMeta[1] ) != null )
|
||||
{
|
||||
found = true;
|
||||
ItemStack itemStack = metaItem2.getStackForm();
|
||||
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
||||
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
|
||||
{
|
||||
intSet.add( itemStack.getItemDamage() );
|
||||
return intSet;
|
||||
} );
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemStack itemStack = GameRegistry.makeItemStack( ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt( ModItemMeta[2] ) : 0, 1, null );
|
||||
if( !itemStack.isEmpty() )
|
||||
{
|
||||
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
||||
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
|
||||
{
|
||||
intSet.add( itemStack.getItemDamage() );
|
||||
return intSet;
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !found )
|
||||
{
|
||||
AELog.error( "Item not found on nonBlocking config: " + s );
|
||||
}
|
||||
}
|
||||
else if( ModItemMeta[0].equals( "ore" ) )
|
||||
{
|
||||
OreDictionary.getOres( ModItemMeta[1] ).forEach( itemStack ->
|
||||
{
|
||||
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
||||
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
|
||||
{
|
||||
intSet.add( itemStack.getItemDamage() );
|
||||
return intSet;
|
||||
} );
|
||||
} );
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemStack itemStack = GameRegistry.makeItemStack( ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt( ModItemMeta[2] ) : 0, 1, null );
|
||||
if( !itemStack.isEmpty() )
|
||||
{
|
||||
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
|
||||
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
|
||||
{
|
||||
intSet.add( itemStack.getItemDamage() );
|
||||
return intSet;
|
||||
} );
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.error( "Item not found on nonBlocking config: " + s );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object2ObjectOpenHashMap<Item, IntSet>> getMap()
|
||||
{
|
||||
return NON_BLOCKING_MAP;
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -19,21 +19,17 @@
|
||||
package appeng.helpers;
|
||||
|
||||
|
||||
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 java.util.*;
|
||||
|
||||
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;
|
||||
@@ -41,25 +37,33 @@ import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.container.ContainerNull;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.features.AEFeature;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import net.minecraftforge.common.crafting.IShapedRecipe;
|
||||
import net.minecraftforge.fml.common.Optional;
|
||||
|
||||
|
||||
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
|
||||
{
|
||||
|
||||
private static final int CRAFTING_GRID_DIMENSION = 3;
|
||||
private static final int CRAFTING_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION;
|
||||
public static final int PROCESSING_INPUT_HEIGHT = 4;
|
||||
public static final int PROCESSING_INPUT_WIDTH = 4;
|
||||
public static final int PROCESSING_INPUT_LIMIT = PROCESSING_INPUT_HEIGHT * PROCESSING_INPUT_WIDTH;
|
||||
private static final int CRAFTING_OUTPUT_LIMIT = 1;
|
||||
public static final int PROCESSING_OUTPUT_LIMIT = 6;
|
||||
|
||||
private final ItemStack patternItem;
|
||||
private final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
private final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
private final InventoryCrafting crafting;
|
||||
private final InventoryCrafting testFrame;
|
||||
private final ItemStack correctOutput;
|
||||
private final IRecipe standardRecipe;
|
||||
private final IAEItemStack[] condensedInputs;
|
||||
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<>();
|
||||
@@ -80,6 +84,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
final NBTTagList outTag = encodedValue.getTagList( "out", 10 );
|
||||
this.isCrafting = encodedValue.getBoolean( "crafting" );
|
||||
|
||||
crafting = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
|
||||
testFrame = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
|
||||
|
||||
this.canSubstitute = this.isCrafting && encodedValue.getBoolean( "substitute" );
|
||||
this.patternItem = is;
|
||||
this.pattern = AEItemStack.fromItemStack( is );
|
||||
@@ -143,9 +150,11 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
}
|
||||
}
|
||||
}
|
||||
final int outputLength = out.size();
|
||||
|
||||
this.outputs = out.toArray( new IAEItemStack[out.size()] );
|
||||
this.inputs = in.toArray( new IAEItemStack[in.size()] );
|
||||
this.inputs = in.toArray( new IAEItemStack[isCrafting ? CRAFTING_INPUT_LIMIT : PROCESSING_INPUT_LIMIT] );
|
||||
this.outputs = out.toArray( new IAEItemStack[outputLength] );
|
||||
this.substituteInputs = new HashMap<>( CRAFTING_INPUT_LIMIT );
|
||||
|
||||
final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>();
|
||||
|
||||
@@ -239,7 +248,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
|
||||
final TestStatus result = this.getStatus( slotIndex, i );
|
||||
|
||||
switch( result )
|
||||
switch ( result )
|
||||
{
|
||||
case ACCEPT:
|
||||
return true;
|
||||
@@ -257,6 +266,16 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
|
||||
this.testFrame.setInventorySlotContents( slotIndex, i );
|
||||
|
||||
// If we cannot substitute, the items must match exactly
|
||||
if( ( !( i.getItem().isDamageable() || Platform.isGTDamageableItem( i.getItem() ) ) && !canSubstitute ) && slotIndex < inputs.length )
|
||||
{
|
||||
if( !inputs[slotIndex].isSameType( i ) )
|
||||
{
|
||||
this.markItemAs( slotIndex, i, TestStatus.DECLINE );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( this.standardRecipe.matches( this.testFrame, w ) )
|
||||
{
|
||||
final ItemStack testOutput = this.standardRecipe.getCraftingResult( this.testFrame );
|
||||
@@ -268,25 +287,6 @@ 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;
|
||||
@@ -328,6 +328,114 @@ 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 )
|
||||
{
|
||||
@@ -406,24 +514,6 @@ 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 )
|
||||
{
|
||||
@@ -447,7 +537,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
|
||||
private enum TestStatus
|
||||
{
|
||||
ACCEPT, DECLINE, TEST
|
||||
ACCEPT,
|
||||
DECLINE,
|
||||
TEST
|
||||
}
|
||||
|
||||
private static final class TestLookup
|
||||
|
||||
@@ -187,20 +187,16 @@ 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 Iterator<CraftingJob> i = jobSet.iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final CraftingJob cj = i.next();
|
||||
if( !cj.simulateFor() )
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,7 +207,7 @@ public class TickHandler
|
||||
this.tickColors( this.srvPlayerColors );
|
||||
// ready tiles.
|
||||
final HandlerRep repo = this.getRepo();
|
||||
while( !repo.tiles.isEmpty() )
|
||||
while ( !repo.tiles.isEmpty() )
|
||||
{
|
||||
final AEBaseTile bt = repo.tiles.poll();
|
||||
if( !bt.isInvalid() )
|
||||
@@ -243,7 +239,7 @@ public class TickHandler
|
||||
private void tickColors( final HashMap<Integer, PlayerColor> playerSet )
|
||||
{
|
||||
final Iterator<PlayerColor> i = playerSet.values().iterator();
|
||||
while( i.hasNext() )
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final PlayerColor pc = i.next();
|
||||
if( pc.ticksLeft <= 0 )
|
||||
@@ -264,7 +260,7 @@ public class TickHandler
|
||||
final Stopwatch sw = Stopwatch.createStarted();
|
||||
|
||||
IWorldCallable<?> c = null;
|
||||
while( ( c = queue.poll() ) != null )
|
||||
while ( ( c = queue.poll() ) != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -280,15 +276,11 @@ public class TickHandler
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
|
||||
// long time = sw.elapsed( TimeUnit.MILLISECONDS );
|
||||
// if ( time > 0 )
|
||||
// AELog.info( "processQueue Time: " + time + "ms" );
|
||||
}
|
||||
|
||||
public void registerCraftingSimulation( final World world, final CraftingJob craftingJob )
|
||||
{
|
||||
synchronized( this.craftingJobs )
|
||||
synchronized ( this.craftingJobs )
|
||||
{
|
||||
this.craftingJobs.put( world, craftingJob );
|
||||
}
|
||||
|
||||
@@ -30,35 +30,37 @@ import appeng.integration.modules.waila.WailaModule;
|
||||
public enum IntegrationType
|
||||
{
|
||||
IC2( IntegrationSide.BOTH, "Industrial Craft 2", "ic2" )
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return Integrations.setIc2( new IC2Module() );
|
||||
}
|
||||
},
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return Integrations.setIc2( new IC2Module() );
|
||||
}
|
||||
},
|
||||
|
||||
GTCE( IntegrationSide.BOTH, "GregTech", "gregtech" ),
|
||||
|
||||
RC( IntegrationSide.BOTH, "Railcraft", "railcraft" ),
|
||||
|
||||
MFR( IntegrationSide.BOTH, "Mine Factory Reloaded", "minefactoryreloaded" ),
|
||||
|
||||
Waila( IntegrationSide.BOTH, "Waila", "waila" )
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return new WailaModule();
|
||||
}
|
||||
},
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return new WailaModule();
|
||||
}
|
||||
},
|
||||
|
||||
InvTweaks( IntegrationSide.CLIENT, "Inventory Tweaks", "inventorytweaks" )
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return Integrations.setInvTweaks( new InventoryTweaksModule() );
|
||||
}
|
||||
},
|
||||
{
|
||||
@Override
|
||||
public IIntegrationModule createInstance()
|
||||
{
|
||||
return Integrations.setInvTweaks( new InventoryTweaksModule() );
|
||||
}
|
||||
},
|
||||
|
||||
JEI( IntegrationSide.CLIENT, "Just Enough Items", "jei" )
|
||||
{
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package appeng.integration.modules.gregtech;
|
||||
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
|
||||
{
|
||||
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
|
||||
{
|
||||
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
|
||||
{
|
||||
// Attempt getting an IItemHandler for the given side via caps
|
||||
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
|
||||
if (itemHandler != null)
|
||||
{
|
||||
return new GTCEItemHandler(itemHandler);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract boolean canRemoveAllExceptCircuits();
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
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,22 +19,22 @@
|
||||
package appeng.integration.modules.jei;
|
||||
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import appeng.client.gui.AEGuiHandler;
|
||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
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;
|
||||
|
||||
@@ -57,6 +57,9 @@ 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 )
|
||||
{
|
||||
@@ -88,15 +91,13 @@ public class JEIPlugin implements IModPlugin
|
||||
this.registerDescriptions( definitions, registry );
|
||||
|
||||
// Allow recipe transfer from JEI to crafting and pattern terminal
|
||||
registry.getRecipeTransferRegistry()
|
||||
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ),
|
||||
VanillaRecipeCategoryUid.CRAFTING );
|
||||
registry.getRecipeTransferRegistry()
|
||||
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ),
|
||||
Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
|
||||
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), VanillaRecipeCategoryUid.CRAFTING );
|
||||
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
|
||||
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerExpandedProcessingPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
|
||||
|
||||
AEGuiHandler aeGuiHandler = new AEGuiHandler();
|
||||
registry.addAdvancedGuiHandlers(aeGuiHandler);
|
||||
aeGuiHandler = new AEGuiHandler();
|
||||
registry.addAdvancedGuiHandlers( aeGuiHandler );
|
||||
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler );
|
||||
}
|
||||
|
||||
private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
|
||||
@@ -219,5 +220,6 @@ public class JEIPlugin implements IModPlugin
|
||||
{
|
||||
JEIModule jeiModule = (JEIModule) Integrations.jei();
|
||||
jeiModule.setJei( new JeiRuntimeAdapter( jeiRuntime ) );
|
||||
runtime = jeiRuntime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ 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;
|
||||
@@ -73,24 +74,7 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
{
|
||||
final String recipeType = recipeLayout.getRecipeCategory().getUid();
|
||||
|
||||
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
|
||||
if (recipeType.equals( VanillaRecipeCategoryUid.INFORMATION) || recipeType.equals(VanillaRecipeCategoryUid.FUEL))
|
||||
{
|
||||
return RecipeTransferErrorInternal.INSTANCE;
|
||||
}
|
||||
@@ -100,6 +84,30 @@ 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();
|
||||
@@ -139,8 +147,12 @@ 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 );
|
||||
@@ -151,7 +163,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 );
|
||||
|
||||
@@ -35,6 +35,8 @@ public enum TheOneProbeText
|
||||
P2P_UNLINKED,
|
||||
P2P_INPUT_ONE_OUTPUT,
|
||||
P2P_INPUT_MANY_OUTPUTS,
|
||||
P2P_OUTPUT_ONE_INPUT,
|
||||
P2P_OUTPUT_MANY_INPUTS,
|
||||
P2P_OUTPUT,
|
||||
P2P_FREQUENCY,
|
||||
|
||||
|
||||
+29
-5
@@ -57,11 +57,11 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
|
||||
|
||||
// The default state
|
||||
int state = STATE_UNLINKED;
|
||||
int outputCount = 0;
|
||||
int outputCount = getOutputCount( tunnel );
|
||||
int inputCount = getInputCount( tunnel );
|
||||
|
||||
if( !tunnel.isOutput() )
|
||||
{
|
||||
outputCount = getOutputCount( tunnel );
|
||||
if( outputCount > 0 )
|
||||
{
|
||||
// Only set it to INPUT if we know there are any outputs
|
||||
@@ -70,8 +70,7 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
|
||||
}
|
||||
else
|
||||
{
|
||||
final PartP2PTunnel input = tunnel.getInput();
|
||||
if( input != null )
|
||||
if( inputCount > 0 )
|
||||
{
|
||||
state = STATE_OUTPUT;
|
||||
}
|
||||
@@ -83,7 +82,7 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
|
||||
probeInfo.text( TheOneProbeText.P2P_UNLINKED.getLocal() );
|
||||
break;
|
||||
case STATE_OUTPUT:
|
||||
probeInfo.text( TheOneProbeText.P2P_OUTPUT.getLocal() );
|
||||
probeInfo.text( getInputText( inputCount ) );
|
||||
break;
|
||||
case STATE_INPUT:
|
||||
probeInfo.text( getOutputText( outputCount ) );
|
||||
@@ -110,6 +109,19 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
|
||||
}
|
||||
}
|
||||
|
||||
private static int getInputCount( PartP2PTunnel tunnel )
|
||||
{
|
||||
try
|
||||
{
|
||||
return Iterators.size( tunnel.getInputs().iterator() );
|
||||
}
|
||||
catch( GridAccessException e )
|
||||
{
|
||||
// Well... unknown size it is!
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getOutputText( int outputs )
|
||||
{
|
||||
if( outputs <= 1 )
|
||||
@@ -122,4 +134,16 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
|
||||
}
|
||||
}
|
||||
|
||||
private static String getInputText( int inputs )
|
||||
{
|
||||
if( inputs <= 1 )
|
||||
{
|
||||
return TheOneProbeText.P2P_OUTPUT_ONE_INPUT.getLocal();
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.format( TheOneProbeText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ package appeng.integration.modules.waila.part;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import appeng.integration.modules.theoneprobe.TheOneProbeText;
|
||||
import com.google.common.collect.Iterators;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
@@ -117,11 +118,11 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
|
||||
|
||||
// The default state
|
||||
int state = STATE_UNLINKED;
|
||||
int outputCount = 0;
|
||||
int outputCount = getOutputCount( tunnel );
|
||||
int inputCount = getInputCount( tunnel );
|
||||
|
||||
if( !tunnel.isOutput() )
|
||||
{
|
||||
outputCount = getOutputCount( tunnel );
|
||||
if( outputCount > 0 )
|
||||
{
|
||||
// Only set it to INPUT if we know there are any outputs
|
||||
@@ -130,8 +131,7 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
|
||||
}
|
||||
else
|
||||
{
|
||||
PartP2PTunnel input = tunnel.getInput();
|
||||
if( input != null )
|
||||
if( inputCount > 0 )
|
||||
{
|
||||
state = STATE_OUTPUT;
|
||||
}
|
||||
@@ -160,15 +160,40 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
|
||||
}
|
||||
}
|
||||
|
||||
private static int getInputCount( PartP2PTunnel tunnel )
|
||||
{
|
||||
try
|
||||
{
|
||||
return Iterators.size( tunnel.getInputs().iterator() );
|
||||
}
|
||||
catch( GridAccessException e )
|
||||
{
|
||||
// Well... unknown size it is!
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getOutputText( int outputs )
|
||||
{
|
||||
if( outputs <= 1 )
|
||||
{
|
||||
return WailaText.P2PInputOneOutput.getLocal();
|
||||
return WailaText.P2P_INPUT_ONE_OUTPUT.getLocal();
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.format( WailaText.P2PInputManyOutputs.getLocal(), outputs );
|
||||
return String.format( WailaText.P2P_INPUT_MANY_OUTPUTS.getLocal(), outputs );
|
||||
}
|
||||
}
|
||||
|
||||
private static String getInputText( int inputs )
|
||||
{
|
||||
if( inputs <= 1 )
|
||||
{
|
||||
return WailaText.P2P_OUTPUT_ONE_INPUT.getLocal();
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.format( WailaText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package appeng.items.contents;
|
||||
|
||||
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
@@ -42,6 +43,8 @@ import appeng.me.helpers.MEMonitorHandler;
|
||||
import appeng.util.ConfigManager;
|
||||
import appeng.util.Platform;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
|
||||
public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implements IPortableCell, IInventorySlotAware
|
||||
{
|
||||
@@ -83,6 +86,34 @@ public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implement
|
||||
return usePowerMultiplier.divide( this.ips.extractAEPower( this.target, amt, Actionable.MODULATE ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack injectItems( IAEItemStack input, Actionable mode, IActionSource src )
|
||||
{
|
||||
final long size = input.getStackSize();
|
||||
|
||||
final IAEItemStack injected = super.injectItems( input, mode, src );
|
||||
|
||||
if( mode == Actionable.MODULATE && ( injected == null || injected.getStackSize() != size ) )
|
||||
{
|
||||
this.notifyListenersOfChange( Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( injected == null ? 0 : injected.getStackSize() ) ) ), null);
|
||||
}
|
||||
|
||||
return injected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
||||
{
|
||||
final IAEItemStack extractable = super.extractItems( request, mode, src );
|
||||
|
||||
if( mode == Actionable.MODULATE && extractable != null )
|
||||
{
|
||||
this.notifyListenersOfChange( Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), null );
|
||||
}
|
||||
|
||||
return extractable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IAEStack<T>> IMEMonitor<T> getInventory( IStorageChannel<T> channel )
|
||||
{
|
||||
|
||||
@@ -164,6 +164,8 @@ 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,7 +118,10 @@ 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 ) );
|
||||
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 ) );
|
||||
|
||||
|
||||
private final Set<AEFeature> features;
|
||||
private final ModelResourceLocation model;
|
||||
|
||||
@@ -28,6 +28,9 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import appeng.parts.misc.*;
|
||||
import appeng.parts.p2p.*;
|
||||
import appeng.parts.reporting.*;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
@@ -57,33 +60,12 @@ import appeng.parts.automation.PartFormationPlane;
|
||||
import appeng.parts.automation.PartIdentityAnnihilationPlane;
|
||||
import appeng.parts.automation.PartImportBus;
|
||||
import appeng.parts.automation.PartLevelEmitter;
|
||||
import appeng.parts.misc.PartCableAnchor;
|
||||
import appeng.parts.misc.PartInterface;
|
||||
import appeng.parts.misc.PartInvertedToggleBus;
|
||||
import appeng.parts.misc.PartStorageBus;
|
||||
import appeng.parts.misc.PartToggleBus;
|
||||
import appeng.parts.networking.PartCableCovered;
|
||||
import appeng.parts.networking.PartCableGlass;
|
||||
import appeng.parts.networking.PartCableSmart;
|
||||
import appeng.parts.networking.PartDenseCableCovered;
|
||||
import appeng.parts.networking.PartDenseCableSmart;
|
||||
import appeng.parts.networking.PartQuartzFiber;
|
||||
import appeng.parts.p2p.PartP2PFEPower;
|
||||
import appeng.parts.p2p.PartP2PFluids;
|
||||
import appeng.parts.p2p.PartP2PIC2Power;
|
||||
import appeng.parts.p2p.PartP2PItems;
|
||||
import appeng.parts.p2p.PartP2PLight;
|
||||
import appeng.parts.p2p.PartP2PRedstone;
|
||||
import appeng.parts.p2p.PartP2PTunnelME;
|
||||
import appeng.parts.reporting.PartConversionMonitor;
|
||||
import appeng.parts.reporting.PartCraftingTerminal;
|
||||
import appeng.parts.reporting.PartDarkPanel;
|
||||
import appeng.parts.reporting.PartInterfaceTerminal;
|
||||
import appeng.parts.reporting.PartPanel;
|
||||
import appeng.parts.reporting.PartPatternTerminal;
|
||||
import appeng.parts.reporting.PartSemiDarkPanel;
|
||||
import appeng.parts.reporting.PartStorageMonitor;
|
||||
import appeng.parts.reporting.PartTerminal;
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
@@ -92,96 +74,84 @@ public enum PartType
|
||||
INVALID_TYPE( -1, "invalid", EnumSet.of( AEFeature.CORE ), EnumSet.noneOf( IntegrationType.class ), null ),
|
||||
|
||||
CABLE_GLASS( 0, "cable_glass", EnumSet.of( AEFeature.GLASS_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableGlass.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
|
||||
CABLE_COVERED( 20, "cable_covered", EnumSet.of( AEFeature.COVERED_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableCovered.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
|
||||
CABLE_SMART( 40, "cable_smart", EnumSet.of( AEFeature.CHANNELS, AEFeature.SMART_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableSmart.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
|
||||
CABLE_DENSE_SMART( 60, "cable_dense_smart", EnumSet.of( AEFeature.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartDenseCableSmart.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
CABLE_DENSE_SMART( 60, "cable_dense_smart", EnumSet.of( AEFeature.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartDenseCableSmart.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
|
||||
CABLE_DENSE_COVERED( 500, "cable_dense_covered", EnumSet.of( AEFeature.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartDenseCableCovered.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
CABLE_DENSE_COVERED( 500, "cable_dense_covered", EnumSet.of( AEFeature.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartDenseCableCovered.class )
|
||||
{
|
||||
@Override
|
||||
public boolean isCable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() )
|
||||
.map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
|
||||
.collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
protected List<ModelResourceLocation> createItemModels( String baseName )
|
||||
{
|
||||
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() );
|
||||
}
|
||||
},
|
||||
|
||||
TOGGLE_BUS( 80, "toggle_bus", EnumSet.of( AEFeature.TOGGLE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartToggleBus.class ),
|
||||
|
||||
@@ -193,14 +163,13 @@ public enum PartType
|
||||
|
||||
MONITOR( 160, "monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartPanel.class, "itemIlluminatedPanel" ),
|
||||
|
||||
SEMI_DARK_MONITOR( 180, "semi_dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartSemiDarkPanel.class, "itemIlluminatedPanel" ),
|
||||
SEMI_DARK_MONITOR( 180, "semi_dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartSemiDarkPanel.class, "itemIlluminatedPanel" ),
|
||||
|
||||
DARK_MONITOR( 200, "dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartDarkPanel.class, "itemIlluminatedPanel" ),
|
||||
|
||||
STORAGE_BUS( 220, "storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartStorageBus.class ),
|
||||
FLUID_STORAGE_BUS( 221, "fluid_storage_bus", EnumSet.of( AEFeature.FLUID_STORAGE_BUS ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartFluidStorageBus.class ),
|
||||
FLUID_STORAGE_BUS( 221, "fluid_storage_bus", EnumSet.of( AEFeature.FLUID_STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidStorageBus.class ),
|
||||
OREDICT_STORAGE_BUS( 222, "oredict_storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartOreDicStorageBus.class ),
|
||||
|
||||
IMPORT_BUS( 240, "import_bus", EnumSet.of( AEFeature.IMPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartImportBus.class ),
|
||||
|
||||
@@ -211,113 +180,109 @@ public enum PartType
|
||||
FLUID_EXPORT_BUS( 261, "fluid_export_bus", EnumSet.of( AEFeature.FLUID_EXPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidExportBus.class ),
|
||||
|
||||
LEVEL_EMITTER( 280, "level_emitter", EnumSet.of( AEFeature.LEVEL_EMITTER ), EnumSet.noneOf( IntegrationType.class ), PartLevelEmitter.class ),
|
||||
FLUID_LEVEL_EMITTER( 281, "fluid_level_emitter", EnumSet.of( AEFeature.FLUID_LEVEL_EMITTER ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartFluidLevelEmitter.class ),
|
||||
FLUID_LEVEL_EMITTER( 281, "fluid_level_emitter", EnumSet.of( AEFeature.FLUID_LEVEL_EMITTER ), EnumSet.noneOf( IntegrationType.class ), PartFluidLevelEmitter.class ),
|
||||
|
||||
ANNIHILATION_PLANE( 300, "annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartAnnihilationPlane.class ),
|
||||
ANNIHILATION_PLANE( 300, "annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartAnnihilationPlane.class ),
|
||||
|
||||
IDENTITY_ANNIHILATION_PLANE( 301, "identity_annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE, AEFeature.IDENTITY_ANNIHILATION_PLANE ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartIdentityAnnihilationPlane.class ),
|
||||
IDENTITY_ANNIHILATION_PLANE( 301, "identity_annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE, AEFeature.IDENTITY_ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartIdentityAnnihilationPlane.class ),
|
||||
|
||||
FLUID_ANNIHILATION_PLANE( 302, "fluid_annihilation_plane", EnumSet.of( AEFeature.FLUID_ANNIHILATION_PLANE ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartFluidAnnihilationPlane.class ),
|
||||
FLUID_ANNIHILATION_PLANE( 302, "fluid_annihilation_plane", EnumSet.of( AEFeature.FLUID_ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFluidAnnihilationPlane.class ),
|
||||
|
||||
FORMATION_PLANE( 320, "formation_plane", EnumSet.of( AEFeature.FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFormationPlane.class ),
|
||||
|
||||
FLUID_FORMATION_PLANE( 321, "fluid_formation_plane", EnumSet.of( AEFeature.FLUID_FORMATION_PLANE ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartFluidFormationPlane.class ),
|
||||
FLUID_FORMATION_PLANE( 321, "fluid_formation_plane", EnumSet.of( AEFeature.FLUID_FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFluidFormationPlane.class ),
|
||||
|
||||
PATTERN_TERMINAL( 340, "pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartPatternTerminal.class ),
|
||||
|
||||
CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
|
||||
EXPANDED_PROCESSING_PATTERN_TERMINAL( 341, "expanded_processing_pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartExpandedProcessingPatternTerminal.class ),
|
||||
|
||||
CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
|
||||
|
||||
TERMINAL( 380, "terminal", EnumSet.of( AEFeature.TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartTerminal.class ),
|
||||
|
||||
STORAGE_MONITOR( 400, "storage_monitor", EnumSet.of( AEFeature.STORAGE_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartStorageMonitor.class ),
|
||||
|
||||
CONVERSION_MONITOR( 420, "conversion_monitor", EnumSet.of( AEFeature.PART_CONVERSION_MONITOR ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartConversionMonitor.class ),
|
||||
CONVERSION_MONITOR( 420, "conversion_monitor", EnumSet.of( AEFeature.PART_CONVERSION_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartConversionMonitor.class ),
|
||||
|
||||
INTERFACE( 440, "interface", EnumSet.of( AEFeature.INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartInterface.class ),
|
||||
FLUID_INTERFACE( 441, "fluid_interface", EnumSet.of( AEFeature.FLUID_INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartFluidInterface.class ),
|
||||
|
||||
P2P_TUNNEL_ME( 460, "p2p_tunnel_me", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ME ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
P2P_TUNNEL_ME( 460, "p2p_tunnel_me", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ME ), EnumSet.noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
|
||||
P2P_TUNNEL_REDSTONE( 461, "p2p_tunnel_redstone", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_REDSTONE ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
P2P_TUNNEL_REDSTONE( 461, "p2p_tunnel_redstone", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_REDSTONE ), EnumSet.noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
|
||||
P2P_TUNNEL_ITEMS( 462, "p2p_tunnel_items", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ITEMS ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
P2P_TUNNEL_ITEMS( 462, "p2p_tunnel_items", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ITEMS ), EnumSet.noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
|
||||
P2P_TUNNEL_FLUIDS( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
P2P_TUNNEL_FLUIDS( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet.noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
|
||||
P2P_TUNNEL_IC2( 465, "p2p_tunnel_ic2", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_EU ), EnumSet
|
||||
.of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
P2P_TUNNEL_IC2( 465, "p2p_tunnel_ic2", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_EU ), EnumSet.of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
|
||||
P2P_TUNNEL_LIGHT( 467, "p2p_tunnel_light", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIGHT ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
P2P_TUNNEL_LIGHT( 467, "p2p_tunnel_light", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIGHT ), EnumSet.noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
|
||||
P2P_TUNNEL_FE( 469, "p2p_tunnel_fe", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FE ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartP2PFEPower.class, GuiText.FETunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
P2P_TUNNEL_FE( 469, "p2p_tunnel_fe", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FE ), EnumSet.noneOf( IntegrationType.class ), PartP2PFEPower.class, GuiText.FETunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
|
||||
P2P_TUNNEL_GTEU( 470, "p2p_tunnel_gteu", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_GTEU ), EnumSet.of( IntegrationType.GTCE ), PartP2PGTCEPower.class, GuiText.GTEUTunnel )
|
||||
{
|
||||
@Override
|
||||
String getUnlocalizedName()
|
||||
{
|
||||
return "p2p_tunnel";
|
||||
}
|
||||
},
|
||||
|
||||
// P2PTunnelOpenComputers( 468, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelOpenComputers ), EnumSet.of(
|
||||
// IntegrationType.OpenComputers ), PartP2POpenComputers.class, GuiText.OCTunnel ),
|
||||
|
||||
INTERFACE_TERMINAL( 480, "interface_terminal", EnumSet.of( AEFeature.INTERFACE_TERMINAL ), EnumSet
|
||||
.noneOf( IntegrationType.class ), PartInterfaceTerminal.class ),
|
||||
INTERFACE_TERMINAL( 480, "interface_terminal", EnumSet.of( AEFeature.INTERFACE_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartInterfaceTerminal.class ),
|
||||
|
||||
FLUID_TERMINAL( 520, "fluid_terminal", EnumSet.of( AEFeature.FLUID_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartFluidTerminal.class );
|
||||
|
||||
@@ -358,8 +323,7 @@ public enum PartType
|
||||
this.oreName = oreDict;
|
||||
|
||||
// The part is enabled if all features + integrations it needs are enabled
|
||||
this.enabled = features.stream().allMatch( AEConfig.instance()::isFeatureEnabled ) && integrations.stream()
|
||||
.allMatch( IntegrationRegistry.INSTANCE::isEnabled );
|
||||
this.enabled = features.stream().allMatch( AEConfig.instance()::isFeatureEnabled ) && integrations.stream().allMatch( IntegrationRegistry.INSTANCE::isEnabled );
|
||||
|
||||
if( this.enabled )
|
||||
{
|
||||
|
||||
@@ -403,7 +403,7 @@ public class ToolMatterCannon extends AEBasePoweredItem implements IStorageCell<
|
||||
}
|
||||
else if( pos.entityHit.attackEntityFrom( dmgSrc, dmg ) )
|
||||
{
|
||||
hasDestroyed = true;
|
||||
hasDestroyed = pos.entityHit.isEntityAlive();
|
||||
}
|
||||
}
|
||||
else if( pos.typeOfHit == RayTraceResult.Type.BLOCK )
|
||||
|
||||
@@ -19,12 +19,8 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.networking.IGrid;
|
||||
@@ -220,9 +216,7 @@ public class Grid implements IGrid
|
||||
@Override
|
||||
public MENetworkEvent postEvent( final MENetworkEvent ev )
|
||||
{
|
||||
CraftingGridCache.pauseRebuilds();
|
||||
final MENetworkEvent ret = this.eventBus.postEvent( this, ev );
|
||||
CraftingGridCache.unpauseRebuilds();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,12 +59,13 @@ import appeng.me.cache.CraftingGridCache;
|
||||
import appeng.me.pathfinding.IPathItem;
|
||||
import appeng.util.IWorldCallable;
|
||||
import appeng.util.ReadOnlyCollection;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
|
||||
|
||||
public class GridNode implements IGridNode, IPathItem
|
||||
{
|
||||
private static final MENetworkChannelsChanged EVENT = new MENetworkChannelsChanged();
|
||||
private static final int[] CHANNEL_COUNT = { 0, 8, 32 };
|
||||
private static final int[] CHANNEL_COUNT = {0, 8, 32};
|
||||
|
||||
private final List<IGridConnection> connections = new ArrayList<>();
|
||||
private final IGridBlock gridProxy;
|
||||
@@ -165,8 +166,6 @@ public class GridNode implements IGridNode, IPathItem
|
||||
{
|
||||
final Object tracker = new Object();
|
||||
|
||||
CraftingGridCache.pauseRebuilds();
|
||||
|
||||
Deque<GridNode> nextRun = new ArrayDeque<>();
|
||||
nextRun.add( this );
|
||||
|
||||
@@ -177,9 +176,9 @@ public class GridNode implements IGridNode, IPathItem
|
||||
final Deque<IGridConnection> nextConn = new ArrayDeque<>();
|
||||
final IGridConnectionVisitor gcv = (IGridConnectionVisitor) g;
|
||||
|
||||
while( !nextRun.isEmpty() )
|
||||
while ( !nextRun.isEmpty() )
|
||||
{
|
||||
while( !nextConn.isEmpty() )
|
||||
while ( !nextConn.isEmpty() )
|
||||
{
|
||||
gcv.visitConnection( nextConn.poll() );
|
||||
}
|
||||
@@ -195,7 +194,7 @@ public class GridNode implements IGridNode, IPathItem
|
||||
}
|
||||
else
|
||||
{
|
||||
while( !nextRun.isEmpty() )
|
||||
while ( !nextRun.isEmpty() )
|
||||
{
|
||||
final Iterable<GridNode> thisRun = nextRun;
|
||||
nextRun = new ArrayDeque<>();
|
||||
@@ -206,7 +205,6 @@ public class GridNode implements IGridNode, IPathItem
|
||||
}
|
||||
}
|
||||
}
|
||||
CraftingGridCache.unpauseRebuilds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -268,7 +266,7 @@ public class GridNode implements IGridNode, IPathItem
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
while( !this.connections.isEmpty() )
|
||||
while ( !this.connections.isEmpty() )
|
||||
{
|
||||
// not part of this network for real anymore.
|
||||
if( this.connections.size() == 1 )
|
||||
@@ -333,7 +331,11 @@ public class GridNode implements IGridNode, IPathItem
|
||||
@Override
|
||||
public void loadFromNBT( final String name, final NBTTagCompound nodeData )
|
||||
{
|
||||
if( this.myGrid == null )
|
||||
if( this.myGrid != null )
|
||||
{
|
||||
throw new IllegalStateException( "Loading data after part of a grid, this is invalid." );
|
||||
}
|
||||
if( nodeData.hasKey( name, 10 ) )
|
||||
{
|
||||
final NBTTagCompound node = nodeData.getCompoundTag( name );
|
||||
this.playerID = node.getInteger( "p" );
|
||||
@@ -345,7 +347,9 @@ public class GridNode implements IGridNode, IPathItem
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException( "Loading data after part of a grid, this is invalid." );
|
||||
this.playerID = -1; // Unknown owner
|
||||
setLastSecurityKey( -1 );
|
||||
setGridStorage( null );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +375,7 @@ public class GridNode implements IGridNode, IPathItem
|
||||
@Override
|
||||
public boolean meetsChannelRequirements()
|
||||
{
|
||||
return( !this.gridProxy.getFlags().contains( GridFlags.REQUIRE_CHANNEL ) || this.getUsedChannels() > 0 );
|
||||
return ( !this.gridProxy.getFlags().contains( GridFlags.REQUIRE_CHANNEL ) || this.getUsedChannels() > 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -633,10 +637,10 @@ public class GridNode implements IGridNode, IPathItem
|
||||
this.usedChannels = 0;
|
||||
}
|
||||
|
||||
final int idx = this.connections.indexOf( fast );
|
||||
final int idx = this.connections.indexOf( (IGridConnection) fast );
|
||||
if( idx > 0 )
|
||||
{
|
||||
this.connections.remove( fast );
|
||||
this.connections.remove( (IGridConnection) fast );
|
||||
this.connections.add( 0, (IGridConnection) fast );
|
||||
}
|
||||
}
|
||||
|
||||
+82
-66
@@ -30,7 +30,6 @@ 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;
|
||||
@@ -42,6 +41,7 @@ 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,17 +105,17 @@ 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 Map<ICraftingPatternDetails, List<ICraftingMedium>> craftingMethods = new HashMap<>();
|
||||
private final Map<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftableItems = new HashMap<>();
|
||||
private final Object2ObjectMap<ICraftingPatternDetails, List<ICraftingMedium>> craftingMethods = new Object2ObjectOpenHashMap<>();
|
||||
private final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftableItems = new Object2ObjectOpenHashMap<>();
|
||||
private final Set<IAEItemStack> emitableItems = new HashSet<>();
|
||||
private final Map<String, CraftingLinkNexus> craftingLinks = new HashMap<>();
|
||||
private final Multimap<IAEStack, CraftingWatcher> interests = HashMultimap.create();
|
||||
private final GenericInterestManager<CraftingWatcher> interestManager = new GenericInterestManager<>( this.interests );
|
||||
private IStorageGrid storageGrid;
|
||||
private IEnergyGrid energyGrid;
|
||||
int i;
|
||||
private boolean updateList = false;
|
||||
private static int pauseRebuilds = 0;
|
||||
private static Set<CraftingGridCache> rebuildNeeded = new HashSet<>();
|
||||
private boolean updatePatterns = false;
|
||||
|
||||
public CraftingGridCache( final IGrid grid )
|
||||
{
|
||||
@@ -140,8 +140,14 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
this.updateCPUClusters();
|
||||
}
|
||||
|
||||
if( updatePatterns )
|
||||
{
|
||||
this.recalculateCraftingPatterns();
|
||||
this.updatePatterns = false;
|
||||
}
|
||||
|
||||
final Iterator<CraftingLinkNexus> craftingLinkIterator = this.craftingLinks.values().iterator();
|
||||
while( craftingLinkIterator.hasNext() )
|
||||
while ( craftingLinkIterator.hasNext() )
|
||||
{
|
||||
if( craftingLinkIterator.next().isDead( this.grid, this ) )
|
||||
{
|
||||
@@ -160,11 +166,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
{
|
||||
if( machine instanceof ICraftingWatcherHost )
|
||||
{
|
||||
final ICraftingWatcher craftingWatcher = this.craftingWatchers.get( machine );
|
||||
final ICraftingWatcher craftingWatcher = this.craftingWatchers.get( gridNode );
|
||||
if( craftingWatcher != null )
|
||||
{
|
||||
craftingWatcher.reset();
|
||||
this.craftingWatchers.remove( machine );
|
||||
this.craftingWatchers.remove( gridNode );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +193,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
if( machine instanceof ICraftingProvider )
|
||||
{
|
||||
this.craftingProviders.remove( machine );
|
||||
this.updatePatterns();
|
||||
this.updatePatterns = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +227,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
if( machine instanceof ICraftingProvider )
|
||||
{
|
||||
this.craftingProviders.add( (ICraftingProvider) machine );
|
||||
this.updatePatterns();
|
||||
this.updatePatterns = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,52 +248,28 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
// nothing!
|
||||
}
|
||||
|
||||
public static void pauseRebuilds()
|
||||
{
|
||||
pauseRebuilds++;
|
||||
}
|
||||
|
||||
public static void unpauseRebuilds()
|
||||
{
|
||||
pauseRebuilds--;
|
||||
if (pauseRebuilds == 0 && rebuildNeeded.size() > 0)
|
||||
{
|
||||
ImmutableSet<CraftingGridCache> needed = ImmutableSet.copyOf(rebuildNeeded);
|
||||
rebuildNeeded.clear();
|
||||
for ( CraftingGridCache cache: needed )
|
||||
{
|
||||
cache.updatePatterns();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePatterns()
|
||||
{
|
||||
// coalesce change events during a grid traversal to a single rebuild
|
||||
if (pauseRebuilds != 0)
|
||||
{
|
||||
rebuildNeeded.add(this);
|
||||
return;
|
||||
}
|
||||
this.updatePatterns = true;
|
||||
}
|
||||
|
||||
final Map<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = this.craftableItems;
|
||||
private void recalculateCraftingPatterns()
|
||||
{
|
||||
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>( this.craftableItems );
|
||||
final Set<IAEItemStack> oldEmitableItems = new HashSet<>( this.emitableItems );
|
||||
|
||||
// erase list.
|
||||
this.craftingMethods.clear();
|
||||
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 Map<IAEItemStack, Set<ICraftingPatternDetails>> tmpCraft = new HashMap<>();
|
||||
final Object2ObjectMap<IAEItemStack, ObjectSet<ICraftingPatternDetails>> tmpCraft = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
// new craftables!
|
||||
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
|
||||
@@ -298,11 +280,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
out.reset();
|
||||
out.setCraftable( true );
|
||||
|
||||
Set<ICraftingPatternDetails> methods = tmpCraft.get( out );
|
||||
ObjectSet<ICraftingPatternDetails> methods = tmpCraft.get( out );
|
||||
|
||||
if( methods == null )
|
||||
{
|
||||
tmpCraft.put( out, methods = new TreeSet<>( COMPARATOR ) );
|
||||
tmpCraft.put( out, methods = new ObjectRBTreeSet<>( COMPARATOR ) );
|
||||
}
|
||||
|
||||
methods.add( details );
|
||||
@@ -310,13 +292,60 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
}
|
||||
|
||||
// make them immutable
|
||||
for( final Entry<IAEItemStack, Set<ICraftingPatternDetails>> e : tmpCraft.entrySet() )
|
||||
for( final Entry<IAEItemStack, ObjectSet<ICraftingPatternDetails>> e : tmpCraft.entrySet() )
|
||||
{
|
||||
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
|
||||
}
|
||||
|
||||
this.storageGrid.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), this.craftableItems.keySet(),
|
||||
new BaseActionSource() );
|
||||
List<IAEItemStack> craftablesChanged = new ArrayList<>();
|
||||
|
||||
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet();
|
||||
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i )
|
||||
{
|
||||
if( !this.craftableItems.containsKey( ais.getKey() ) )
|
||||
{
|
||||
IAEItemStack changedStack = ais.getKey().copy();
|
||||
changedStack.reset();
|
||||
changedStack.setCraftable( false );
|
||||
craftablesChanged.add( changedStack );
|
||||
}
|
||||
}
|
||||
|
||||
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
|
||||
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j )
|
||||
{
|
||||
if( !oldItems.containsKey( ais ) )
|
||||
{
|
||||
IAEItemStack changedStack = ais.getKey().copy();
|
||||
changedStack.reset();
|
||||
changedStack.setCraftable( true );
|
||||
craftablesChanged.add( changedStack );
|
||||
}
|
||||
}
|
||||
|
||||
for( final IAEItemStack st : oldEmitableItems )
|
||||
{
|
||||
if( !emitableItems.contains( st ) )
|
||||
{
|
||||
IAEItemStack changedStack = st.copy();
|
||||
changedStack.reset();
|
||||
changedStack.setCraftable( false );
|
||||
craftablesChanged.add( changedStack );
|
||||
}
|
||||
}
|
||||
|
||||
for( final IAEItemStack st : this.emitableItems )
|
||||
{
|
||||
if( !oldEmitableItems.contains( st ) )
|
||||
{
|
||||
IAEItemStack changedStack = st.copy();
|
||||
changedStack.reset();
|
||||
changedStack.setCraftable( true );
|
||||
craftablesChanged.add( changedStack );
|
||||
}
|
||||
}
|
||||
|
||||
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged, new BaseActionSource() );
|
||||
}
|
||||
|
||||
private void updateCPUClusters()
|
||||
@@ -494,22 +523,6 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
|
||||
if( res == null )
|
||||
{
|
||||
if( details != null && details.isCraftable() )
|
||||
{
|
||||
for( final IAEItemStack ais : this.craftableItems.keySet() )
|
||||
{
|
||||
if( ais.getItem() == whatToCraft.getItem() && ( !ais.getItem().getHasSubtypes() || ais.getItemDamage() == whatToCraft.getItemDamage() ) )
|
||||
{
|
||||
// TODO: check if OK
|
||||
// TODO: this is slightly hacky, but fine as long as we only deal with itemstacks
|
||||
if( details.isValidItemForSlot( slotIndex, ais.asItemStackRepresentation(), world ) )
|
||||
{
|
||||
return this.craftableItems.get( ais );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@@ -555,8 +568,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort( validCpusClusters, ( firstCluster, nextCluster ) ->
|
||||
{
|
||||
Collections.sort( validCpusClusters, ( firstCluster, nextCluster ) -> {
|
||||
if( prioritizePower )
|
||||
{
|
||||
final int comparison1 = Long.compare( nextCluster.getCoProcessors(), firstCluster.getCoProcessors() );
|
||||
@@ -635,7 +647,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
|
||||
public boolean hasCpu( final ICraftingCPU cpu )
|
||||
{
|
||||
return this.craftingCPUClusters.contains( cpu );
|
||||
if( cpu instanceof CraftingCPUCluster )
|
||||
{
|
||||
return this.craftingCPUClusters.contains( (CraftingCPUCluster) cpu );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public GenericInterestManager<CraftingWatcher> getInterestManager()
|
||||
@@ -665,7 +681,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
|
||||
private void findNext()
|
||||
{
|
||||
while( this.iterator.hasNext() && this.cpuCluster == null )
|
||||
while ( this.iterator.hasNext() && this.cpuCluster == null )
|
||||
{
|
||||
this.cpuCluster = this.iterator.next();
|
||||
if( !this.cpuCluster.isActive() || this.cpuCluster.isDestroyed() )
|
||||
|
||||
+177
-41
@@ -30,6 +30,7 @@ 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;
|
||||
@@ -63,12 +64,10 @@ import appeng.me.energy.EnergyWatcher;
|
||||
public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
|
||||
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() );
|
||||
private static final double MAX_BUFFER_STORAGE = 800;
|
||||
private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(), o1.getProviderStoredEnergy() );
|
||||
|
||||
private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) ->
|
||||
{
|
||||
private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) -> {
|
||||
final double percent1 = ( o1.getProviderStoredEnergy() + 1 ) / ( o1.getProviderMaxEnergy() + 1 );
|
||||
final double percent2 = ( o2.getProviderStoredEnergy() + 1 ) / ( o2.getProviderMaxEnergy() + 1 );
|
||||
|
||||
@@ -76,9 +75,24 @@ 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<>();
|
||||
@@ -110,6 +124,10 @@ 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 )
|
||||
{
|
||||
@@ -143,20 +161,33 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
if( ev.storage.isAEPublicPowerStorage() )
|
||||
{
|
||||
switch( ev.type )
|
||||
if( ev.type == PowerEventType.PROVIDE_POWER )
|
||||
{
|
||||
case PROVIDE_POWER:
|
||||
if( ev.storage.getPowerFlow() != AccessRestriction.WRITE )
|
||||
if( ev.storage.getPowerFlow() != AccessRestriction.WRITE )
|
||||
{
|
||||
if( !ongoingExtractOperation )
|
||||
{
|
||||
this.providers.add( ev.storage );
|
||||
addProvider( ev.storage );
|
||||
}
|
||||
break;
|
||||
case REQUEST_POWER:
|
||||
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
|
||||
else
|
||||
{
|
||||
this.requesters.add( ev.storage );
|
||||
this.providersToAdd.add( ev.storage );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( ev.type == PowerEventType.REQUEST_POWER )
|
||||
{
|
||||
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
|
||||
{
|
||||
if( !ongoingInjectOperation )
|
||||
{
|
||||
addRequester( ev.storage );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.requesterToAdd.add( ev.storage );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -301,19 +332,56 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
double extractedPower = 0;
|
||||
|
||||
this.providers.addAll( providersToAdd );
|
||||
providersToAdd.clear();
|
||||
providers.removeIf( providerToRemove::contains );
|
||||
this.providerToRemove.clear();
|
||||
|
||||
final Iterator<IAEPowerStorage> it = this.providers.iterator();
|
||||
|
||||
while( extractedPower < amt && it.hasNext() )
|
||||
ongoingExtractOperation = true;
|
||||
boolean ls = false;
|
||||
try
|
||||
{
|
||||
final IAEPowerStorage node = it.next();
|
||||
|
||||
final double req = amt - extractedPower;
|
||||
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
|
||||
extractedPower += newPower;
|
||||
|
||||
if( newPower < req && mode == Actionable.MODULATE )
|
||||
while ( extractedPower < amt && it.hasNext() )
|
||||
{
|
||||
it.remove();
|
||||
final IAEPowerStorage node = it.next();
|
||||
if( node != null )
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
} finally
|
||||
{
|
||||
ongoingExtractOperation = false;
|
||||
if( ls && extractedPower < amt )
|
||||
{
|
||||
final double req = amt - extractedPower;
|
||||
final double newPower = localStorage.extractAEPower( req, mode, PowerMultiplier.ONE );
|
||||
|
||||
extractedPower += newPower;
|
||||
|
||||
if( newPower < req )
|
||||
{
|
||||
providers.remove( localStorage );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,17 +406,37 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
final double originalAmount = amt;
|
||||
|
||||
this.requesters.addAll( requesterToAdd );
|
||||
requesterToAdd.clear();
|
||||
requesters.removeIf( requesterToRemove::contains );
|
||||
this.requesterToRemove.clear();
|
||||
|
||||
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
|
||||
|
||||
while( amt > 0 && it.hasNext() )
|
||||
ongoingInjectOperation = true;
|
||||
try
|
||||
{
|
||||
final IAEPowerStorage node = it.next();
|
||||
amt = node.injectAEPower( amt, mode );
|
||||
|
||||
if( amt > 0 && mode == Actionable.MODULATE )
|
||||
while ( amt > 0 && it.hasNext() )
|
||||
{
|
||||
it.remove();
|
||||
final IAEPowerStorage node = it.next();
|
||||
|
||||
if( node != null )
|
||||
{
|
||||
amt = node.injectAEPower( amt, mode );
|
||||
|
||||
if( amt > 0 && mode == Actionable.MODULATE )
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
} finally
|
||||
{
|
||||
ongoingInjectOperation = false;
|
||||
}
|
||||
|
||||
final double overflow = Math.max( 0.0, amt );
|
||||
@@ -367,7 +455,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 )
|
||||
@@ -428,11 +516,7 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
@Override
|
||||
public double getStoredPower()
|
||||
{
|
||||
if( this.availableTicksSinceUpdate > 90 )
|
||||
{
|
||||
this.refreshPower();
|
||||
}
|
||||
|
||||
this.refreshPower();
|
||||
return Math.max( 0.0, this.globalAvailablePower );
|
||||
}
|
||||
|
||||
@@ -505,9 +589,22 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
this.globalMaxPower -= ps.getAEMaxPower();
|
||||
this.globalAvailablePower -= ps.getAECurrentPower();
|
||||
}
|
||||
|
||||
this.providers.remove( ps );
|
||||
this.requesters.remove( ps );
|
||||
if( !ongoingExtractOperation )
|
||||
{
|
||||
removeProvider( ps );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.providerToRemove.add( ps );
|
||||
}
|
||||
if( !ongoingInjectOperation )
|
||||
{
|
||||
removeRequester( ps );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.requesterToRemove.add( ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,6 +620,31 @@ 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 )
|
||||
{
|
||||
@@ -554,12 +676,26 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
if( current > 0 && ps.getPowerFlow() != AccessRestriction.WRITE )
|
||||
{
|
||||
this.globalAvailablePower += current;
|
||||
this.providers.add( ps );
|
||||
if( !ongoingExtractOperation )
|
||||
{
|
||||
addProvider( ps );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.providersToAdd.add( ps );
|
||||
}
|
||||
}
|
||||
|
||||
if( current < max && ps.getPowerFlow() != AccessRestriction.READ )
|
||||
{
|
||||
this.requesters.add( ps );
|
||||
if( !ongoingInjectOperation )
|
||||
{
|
||||
addRequester( ps );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.requesterToAdd.add( ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -686,4 +822,4 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
-20
@@ -19,13 +19,12 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.crafting.MECraftingInventory;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
@@ -55,6 +54,8 @@ import appeng.me.helpers.GenericInterestManager;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import appeng.me.storage.ItemWatcher;
|
||||
import appeng.me.storage.NetworkInventoryHandler;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
|
||||
public class GridStorageCache implements IStorageGrid
|
||||
@@ -66,8 +67,11 @@ public class GridStorageCache implements IStorageGrid
|
||||
private final SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
|
||||
private final GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<>( this.interests );
|
||||
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>();
|
||||
private Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
||||
private Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
||||
private MECraftingInventory localCache = null;
|
||||
private final Int2ObjectMap<MECraftingInventory> extractableItemPriorityMap = new Int2ObjectOpenHashMap<>();
|
||||
private int localDepth;
|
||||
|
||||
public GridStorageCache( final IGrid g )
|
||||
{
|
||||
@@ -81,6 +85,8 @@ public class GridStorageCache implements IStorageGrid
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
this.localCache = null;
|
||||
this.extractableItemPriorityMap.clear();
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.onTick() );
|
||||
}
|
||||
|
||||
@@ -94,19 +100,19 @@ public class GridStorageCache implements IStorageGrid
|
||||
|
||||
this.removeCellProvider( cc, tracker );
|
||||
this.inactiveCellProviders.remove( cc );
|
||||
this.getGrid().postEvent( new MENetworkCellArrayUpdate() );
|
||||
cellUpdate( null );
|
||||
|
||||
tracker.applyChanges();
|
||||
}
|
||||
|
||||
if( machine instanceof IStackWatcherHost )
|
||||
{
|
||||
final IStackWatcher myWatcher = this.watchers.get( machine );
|
||||
final IStackWatcher myWatcher = this.watchers.get( node );
|
||||
|
||||
if( myWatcher != null )
|
||||
{
|
||||
myWatcher.reset();
|
||||
this.watchers.remove( machine );
|
||||
this.watchers.remove( node );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +125,7 @@ public class GridStorageCache implements IStorageGrid
|
||||
final ICellContainer cc = (ICellContainer) machine;
|
||||
this.inactiveCellProviders.add( cc );
|
||||
|
||||
this.getGrid().postEvent( new MENetworkCellArrayUpdate() );
|
||||
cellUpdate( null );
|
||||
|
||||
if( node.isActive() )
|
||||
{
|
||||
@@ -168,6 +174,28 @@ public class GridStorageCache implements IStorageGrid
|
||||
return (IMEMonitor<T>) this.storageMonitors.get( channel );
|
||||
}
|
||||
|
||||
public MECraftingInventory getExtractableList( IActionSource src )
|
||||
{
|
||||
if( src instanceof MachineSource )
|
||||
{
|
||||
if( src.machine().isPresent() )
|
||||
{
|
||||
IActionHost machine = src.machine().get();
|
||||
if( machine instanceof IInterfaceHost )
|
||||
{
|
||||
extractableItemPriorityMap.putIfAbsent( ( (IPriorityHost) machine ).getPriority(), new MECraftingInventory( getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), src, false, false, false ) );
|
||||
return extractableItemPriorityMap.get( ( (IPriorityHost) machine ).getPriority() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( localCache == null )
|
||||
{
|
||||
localCache = new MECraftingInventory( getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), src, false, false, false );
|
||||
}
|
||||
return localCache;
|
||||
}
|
||||
|
||||
private CellChangeTracker addCellProvider( final ICellProvider cc, final CellChangeTracker tracker )
|
||||
{
|
||||
if( this.inactiveCellProviders.contains( cc ) )
|
||||
@@ -177,8 +205,7 @@ public class GridStorageCache implements IStorageGrid
|
||||
|
||||
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
|
||||
|
||||
this.storageMonitors.forEach( ( channel, monitor ) ->
|
||||
{
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> {
|
||||
for( final IMEInventoryHandler<?> h : cc.getCellArray( channel ) )
|
||||
{
|
||||
tracker.postChanges( channel, 1, h, actionSrc );
|
||||
@@ -198,8 +225,7 @@ public class GridStorageCache implements IStorageGrid
|
||||
|
||||
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
|
||||
|
||||
this.storageMonitors.forEach( ( channel, monitor ) ->
|
||||
{
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> {
|
||||
for( final IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( channel ) )
|
||||
{
|
||||
tracker.postChanges( channel, -1, h, actionSrc );
|
||||
@@ -213,6 +239,11 @@ public class GridStorageCache implements IStorageGrid
|
||||
@MENetworkEventSubscribe
|
||||
public void cellUpdate( final MENetworkCellArrayUpdate ev )
|
||||
{
|
||||
if( localDepth > 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
localDepth++;
|
||||
this.storageNetworks.clear();
|
||||
|
||||
final List<ICellProvider> ll = new ArrayList<ICellProvider>();
|
||||
@@ -247,10 +278,9 @@ public class GridStorageCache implements IStorageGrid
|
||||
this.removeCellProvider( cc, tracker );
|
||||
}
|
||||
}
|
||||
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
|
||||
|
||||
tracker.applyChanges();
|
||||
localDepth--;
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.setForceUpdate( true ) );
|
||||
}
|
||||
|
||||
private <T extends IAEStack<T>, C extends IStorageChannel<T>> void postChangesToNetwork( final C chan, final int upOrDown, final IItemList<T> availableItems, final IActionSource src )
|
||||
@@ -281,6 +311,12 @@ 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 )
|
||||
{
|
||||
@@ -324,7 +360,10 @@ public class GridStorageCache implements IStorageGrid
|
||||
|
||||
public void applyChanges()
|
||||
{
|
||||
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
|
||||
if( !this.list.isEmpty() )
|
||||
{
|
||||
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user