Compare commits

...

134 Commits

Author SHA1 Message Date
PrototypeTrousers 7d1c502b41 workss 2022-04-04 15:44:22 -03:00
PrototypeTrousers 63653c1833 added packets for missing items report 2022-04-04 03:55:51 -03:00
PrototypeTrousers 6cadfbdcdc 3 2022-04-01 19:30:18 -03:00
PrototypeTrousers d054c6ab91 2 2022-04-01 19:30:18 -03:00
PrototypeTrousers 234b1c5dc6 meh. crafting gets stuck if the output loops 2022-04-01 19:30:18 -03:00
PrototypeTrousers 8cc29734a2 positive loop support 2022-04-01 19:30:18 -03:00
PrototypeTrousers 1e9e8d2639 more checks if "gregtech" mod is loaded 2022-03-31 21:16:14 -03:00
PrototypeTrousers 19c6e2ff2d support for IC2 damageable items 2022-03-27 08:52:37 -03:00
PrototypeTrousers 4f25c1551b increase internal buffer of ME Chest
Fix item amount not refreshing when inserted/extracted
2022-03-27 08:10:02 -03:00
PrototypeTrousers 3b94e9420d fix NPE with ae2fc and blocking mode 2022-03-25 23:46:52 -03:00
PrototypeTrousers f30f334a23 move nonblocking call out of method used by ae2fc coremod 2022-03-24 23:25:28 -03:00
PrototypeTrousers 706e577dab Fix container item crafting (again)
avoid making some copies
fix crash without JEI
2022-03-16 00:52:38 -03:00
PrototypeTrousers ccc8486571 check if gregtech is loaded before checking for MetaTools 2022-03-12 22:36:22 -03:00
PrototypeTrousers 3e8440644e fix autocrafting with container items 2022-03-12 22:21:04 -03:00
PrototypeTrousers 50f4e08b64 Merge remote-tracking branch 'origin/AE2-Omnifactory' into AE2-Omnifactory 2022-03-12 17:27:17 -03:00
PrototypeTrousers cfa9fa2843 invalidate cached itemstack if its gonna be used in a real insertion 2022-03-12 17:14:37 -03:00
PrototypeTrousers 47f819e021 invalidate cached itemstack if its gonna be used in a real insertion 2022-03-12 11:03:04 -03:00
PrototypeTrousers 6d151bb890 GTCEu blocking mode fix 2022-03-11 23:11:52 -03:00
PrototypeTrousers 3305270a71 clean-up 2022-03-11 22:04:58 -03:00
PrototypeTrousers f824bfd2e1 small optimization 2022-03-10 21:35:18 -03:00
PrototypeTrousers 036f4e1c5b heavily tweaked auto-crafting 2022-03-09 23:14:02 -03:00
PrototypeTrousers 146d3f5628 fix fluid dupe 2022-03-06 08:24:29 -03:00
PrototypeTrousers 9c821cb015 cleaning 2022-03-05 23:29:20 -03:00
PrototypeTrousers 3a83c99b1f fix container items return properly 2022-03-05 11:15:32 -03:00
PrototypeTrousers 447c6debab account for interfaces priority affecting which items are extractable 2022-03-04 22:49:55 -03:00
PrototypeTrousers 50470ae3cf version 2022-03-04 21:44:58 -03:00
PrototypeTrousers 993be652c9 delay container item return when simulating crafting tree 2022-03-04 21:30:26 -03:00
PrototypeTrousers b3bfbd0b58 remove debugging log 2022-03-04 17:08:23 -03:00
PrototypeTrousers 49b3dc8b60 undo partially pattern cache rebuild optimization
enabled pattern substitution now can use substitute patterned items
2022-03-03 22:25:10 -03:00
PrototypeTrousers 71ffcfb839 JEI transfer handler OutOfBounds fix 2022-03-01 13:02:09 -03:00
PrototypeTrousers 73f76a6654 clean up 2022-02-28 23:30:52 -03:00
PrototypeTrousers 645de1d868 Merge branch 'craftingtree-tweaks' into AE2-Omnifactory 2022-02-28 23:17:21 -03:00
PrototypeTrousers 8f40478695 version 2022-02-28 23:16:53 -03:00
PrototypeTrousers 056fcc3818 switch to extractable instead of cached item list 2022-02-28 23:16:53 -03:00
PrototypeTrousers 0ed0eb9d5f better logging 2022-02-28 23:16:49 -03:00
PrototypeTrousers 3ddc846648 Merge branch 'craftingtree-tweaks' into AE2-Omnifactory 2022-02-28 23:06:11 -03:00
PrototypeTrousers f98f6ef852 misc cleaning 2022-02-28 22:57:35 -03:00
PrototypeTrousers 4192d721a0 only fire simulation if a player requested it 2022-02-28 21:25:33 -03:00
PrototypeTrousers a0f3ef9d86 cut crafting tree earlier if ingredients are available 2022-02-28 21:25:13 -03:00
PrototypeTrousers 6b29288de6 remove crafting penalties 2022-02-28 00:13:07 -03:00
PrototypeTrousers 285fc6314c small optimization to crafting tree 2022-02-27 23:04:29 -03:00
PrototypeTrousers 50fd83e96b adjust default blocking mode settings 2022-02-25 00:09:33 -03:00
PrototypeTrousers cc51138a6a blocking mode changes again
misc cleaning
2022-02-24 23:54:50 -03:00
PrototypeTrousers 918df0bf7f clean up 2022-02-22 23:55:52 -03:00
PrototypeTrousers c852199901 bump version 2022-02-22 22:55:44 -03:00
PrototypeTrousers fd95d3de47 fixed typo gtceu -> gteu 2022-02-22 22:37:28 -03:00
PrototypeTrousers c3dd6dabe1 fix blocking mode again... 2022-02-22 22:11:57 -03:00
PrototypeTrousers b0e81ac2d1 fix blocking mode somehow voiding items 2022-02-22 19:40:15 -03:00
PrototypeTrousers 30f4cdf545 attempt at pattern rebuild optimization 2022-02-22 00:02:17 -03:00
PrototypeTrousers ee9441474e tweak cache reset on interface config 2022-02-21 18:25:58 -03:00
PrototypeTrousers 8846202270 More itemstacks caching
Micro optimization on molecular assemblers
2022-02-21 15:11:16 -03:00
PrototypeTrousers 17a900ae9a actually return if a crafting job is running 2022-02-19 23:03:33 -03:00
PrototypeTrousers 66bc243b41 cache more itemstacks 2022-02-19 23:02:40 -03:00
PrototypeTrousers a2bda8f449 tile fluid textures on fluid interfaces properly 2022-02-17 20:15:29 -03:00
PrototypeTrousers a2c2a4df0f oops, add integrated circuit to default non blocking items 2022-02-15 19:33:56 -03:00
PrototypeTrousers b4e237244a fix interfaces with crafting cards attached to storage bus not working
add missing buttons to oredict storagebus
2022-02-14 17:15:51 -03:00
PrototypeTrousers b541ad8d18 misc cleaning
add lenses to non blocking list
2022-02-10 20:15:58 -03:00
PrototypeTrousers 64f29a7dba make it work 2022-02-10 17:59:03 -03:00
PrototypeTrousers 6d25b7ef3c reworked blocking mode. now items are configurable per mod 2022-02-09 22:15:44 -03:00
PrototypeTrousers c3a608ef59 fix export busses exporting items out of nowhere 2022-01-31 16:51:06 -03:00
PrototypeTrousers af1f5c34d2 fix npe when placing down an ore dict storage bus 2022-01-30 17:19:01 -03:00
PrototypeTrousers f5378e060e fix importing from storage drawers 2022-01-29 17:21:12 -03:00
PrototypeTrousers 47407acc42 backport of #5823 - try emptying interfaces first before handling crafting jobs 2022-01-29 17:03:15 -03:00
PrototypeTrousers d7f3428824 fix for infinite loop while loading 2022-01-24 13:19:31 -03:00
PrototypeTrousers 63e339b88b cache itemstacks more aggressively 2022-01-24 13:17:50 -03:00
PrototypeTrousers 98761809fd add the patterns inside the terminal to the drop list of the terminal 2022-01-23 23:08:47 -03:00
PrototypeTrousers 8cb013b686 versioning 2022-01-22 23:19:49 -03:00
PrototypeTrousers f2fe376982 Merge pull request #74 from Syrcan/GTEU-fix
GTEU input fix
2022-01-22 23:06:39 -03:00
Syrcan 603452de1f GTEU input fix 2022-01-22 10:11:23 +01:00
PrototypeTrousers 40bd96d21c tweak crafting job size again
null check
2022-01-21 18:12:18 -03:00
PrototypeTrousers a14d160a07 Reworked oredict storage bus
have a recipe now
expression matcher and validator from GTCEU by brachy84
2022-01-20 22:43:18 -03:00
PrototypeTrousers df28a5520f fix mod name
implement GTCEU Energy adapter
2022-01-20 20:02:26 -03:00
PrototypeTrousers 0d096944cc Merge branch 'gtceu-p2p' into AE2-Omnifactory 2022-01-20 17:48:07 -03:00
PrototypeTrousers 963d3414d8 update version
more of renaming mod
2022-01-20 17:46:07 -03:00
PrototypeTrousers 4414451f5e more gtceu p2p fixes 2022-01-20 17:05:21 -03:00
PrototypeTrousers e0ddb92b81 attune gtce p2p with cables 2022-01-20 13:28:08 -03:00
PrototypeTrousers 6f551ad67f wip gtceu p2p 2022-01-20 00:04:04 -03:00
PrototypeTrousers fd3349614d fix terminal crashing and not cleaning leftovers of larger recipe patterns 2022-01-11 11:23:40 -03:00
PrototypeTrousers 903f211044 fix crash while configuring fluid storage bus 2022-01-10 03:17:46 -03:00
PrototypeTrousers 78e1e26a11 Fix issues with the expanded pattern terminal and its patterns crafting 2022-01-05 21:36:49 -03:00
PrototypeTrousers 2a6de11597 update version 2022-01-04 17:08:55 -03:00
PrototypeTrousers cd2b53af85 Cherry-picked 5554ba903e74c2980b2e395c78555b40fc379e80
Be more lenient with extended block states being passed by other mods.
2022-01-04 17:01:55 -03:00
PrototypeTrousers 1c5565491a finish oredict storage bus 2022-01-03 13:16:27 -03:00
PrototypeTrousers 311cc5c6f6 more oredictbus work 2022-01-03 11:32:48 -03:00
PrototypeTrousers 41796449ed cache oredict filter list 2022-01-03 10:47:35 -03:00
PrototypeTrousers 9eef9d3840 partial implementation of oredict storage bus
missing proper GUI, text, item models, memorycard support.
logic works
2022-01-03 02:33:08 -03:00
PrototypeTrousers 13afa6908a implement expanded processing pattern terminal 2022-01-02 18:27:41 -03:00
PrototypeTrousers 103438f805 do full reset level emitter on stack update 2021-12-13 02:02:02 -03:00
PrototypeTrousers eaa01f7648 flip some boolean so craftables actually show up 2021-12-10 20:26:29 -03:00
PrototypeTrousers e81fb09599 when in off-hand, memory card wild paste as input 2021-12-10 14:02:56 -03:00
PrototypeTrousers 94d73aec7c wwww 2021-12-09 23:34:57 -03:00
PrototypeTrousers b51af43dba item/fluid count changes.. again 2021-12-07 21:10:04 -03:00
PrototypeTrousers 85dc8ae7c1 item costs/ghost fixes 2021-11-29 00:50:32 -03:00
PrototypeTrousers c34176f392 fix (?) item desync issues 2021-11-23 20:25:05 -03:00
PrototypeTrousers 76fe2175a0 moved p2p forge event to an upper class
add an extra update after the network has finished booting
2021-11-15 00:09:04 -03:00
PrototypeTrousers c5d33ed892 p2p fixes redton, light, items 2021-11-11 20:54:40 -03:00
PrototypeTrousers b423d99879 tweak crafting byte costs 2021-11-02 17:56:12 -03:00
PrototypeTrousers 81156b411d version 2021-11-02 15:34:45 -03:00
PrototypeTrousers 6be1660d41 Merge branch 'item-issues' into AE2-Omnifactory 2021-11-02 15:34:02 -03:00
PrototypeTrousers 304f394497 cut crafting tree earlier if the item is available
fix job byte size to 8 per crafting + 1 per item used/stored
2021-11-02 15:33:14 -03:00
PrototypeTrousers 50f21125c8 log if non-patterned items go missing before starting a craft 2021-11-02 02:00:01 -03:00
PrototypeTrousers 30b85bd239 potential fix for showing proper item names when failing to start craft 2021-11-01 23:23:45 -03:00
PrototypeTrousers 9ce00d338f only try to extract if its already in the cache 2021-10-29 17:04:24 -03:00
PrototypeTrousers 11f5b71089 update directly instead of relying on forge events 2021-10-29 15:14:33 -03:00
PrototypeTrousers e7da72163b backported #5349 2021-10-29 15:13:46 -03:00
PrototypeTrousers 6d7c65dd70 potential fix for an infinite loop while adding nodes 2021-10-29 14:09:19 -03:00
PrototypeTrousers 5e21101619 n-to-n p2p
network monitor checks nesting by action source
2021-10-28 23:49:16 -03:00
PrototypeTrousers 3db8d0185f fix security terminal and portable cell stored items not showing 2021-10-23 17:56:15 -03:00
PrototypeTrousers 2f5ecfe638 energy fixes 2021-10-22 15:37:08 -03:00
PrototypeTrousers 75843e802d WIP 2021-10-21 12:22:00 -03:00
PrototypeTrousers e41b6943aa fix swapping cells giving wrong item/fluid count 2021-09-28 23:29:52 -03:00
PrototypeTrousers 92347ad2f5 fix looping item count and hopefully energy issues 2021-09-26 22:07:16 -03:00
PrototypeTrousers 517bd77df7 yet another try at energy issues
fix requesters not being added to the energy grid


partially revert the energy 'fixes'


potential desync on item count


energy and items change
2021-09-17 00:09:49 -03:00
PrototypeTrousers 19f928a9a5 fluid pass 2021-09-13 04:22:52 -03:00
PrototypeTrousers 73251a0fe5 more item count changes.... 2021-09-13 02:10:28 -03:00
PrototypeTrousers 9335daff7d Revert "fixes item showing incorrect amounts"
This reverts commit 618e9390c6.
2021-09-11 22:48:45 -03:00
PrototypeTrousers cc5377d53b fluid storage bus handler cache tweaks and simplify energy cache 2021-09-06 23:51:32 -03:00
Salomão 059f20d801 yet another try at fixing power issues 2021-09-05 20:28:37 -03:00
Salomão d229570495 try to fix energy issues again
fix issue with voiding p2p parts when shift-right clicking with a memory card
2021-09-04 18:59:46 -03:00
PrototypeTrousers c284748b6c fix p2p not updating properly on memory card loading 2021-09-02 20:42:02 -03:00
PrototypeTrousers 880a9c8821 another case of wrong item count caused by weak reset logic overriding
a full reset needed
2021-09-01 16:11:45 -03:00
PrototypeTrousers c68c02ef3b more cases of wrong item counting fixed 2021-08-26 22:03:23 -03:00
PrototypeTrousers 89c4d2736c borrowed some fancy, colored, fluid rendering from gregicality
thank you @Yefancy
2021-08-23 22:35:26 -03:00
PrototypeTrousers 01778794e5 try to fix #51 2021-08-22 23:59:02 -03:00
PrototypeTrousers 8f2a06e457 fix #49. you can now actually clear storage and conversion monitors 2021-08-20 23:26:33 -03:00
PrototypeTrousers 2d71b75019 actually fix it 2021-08-17 07:46:47 -03:00
PrototypeTrousers 9f09cd04d4 enforce cache reset of storage bus attached to interfaces were configs
changed
2021-08-16 21:55:35 -03:00
PrototypeTrousers b041fae0d5 fix storage/monitors wrong item count and interactions 2021-08-16 19:26:25 -03:00
Salomão c466a0e00e fix items in level emitters with crafting cards not showing up 2021-08-14 09:44:47 -03:00
PrototypeTrousers 618e9390c6 fixes item showing incorrect amounts 2021-08-13 00:17:53 -03:00
PrototypeTrousers 9a71bfb0f0 hash drawers handler by the amount of slots 2021-08-10 09:06:18 -03:00
PrototypeTrousers 9680123906 fix JEI targeting disabled slots as valid 2021-08-06 06:25:12 -03:00
PrototypeTrousers 87730894e9 Update CHANGES.md 2021-08-05 21:36:49 -03:00
PrototypeTrousers 71c944daea fix fluid storagebus NPE crash 2021-08-04 20:49:38 -03:00
143 changed files with 8117 additions and 4329 deletions
+13 -2
View File
@@ -15,6 +15,10 @@ Fixes:
- Exclusive Blocking mode for GTCE ( shapes, molds and configured circuits do not block GTCE machines )
- Blocking modes default to block on any item in the iventory the entity exposes
- Fuzzy includes items that report that they're damageable, but report a maxDamage of 0 ( auto-crafting of basic capacitors -> resonant capacitors is now possible ) <- Broken item implementation.
- Fix CME exceptions on the energy grid
- Fix AE going offline even with enough power by extracting from the local buffer always last
- Fix IO-Port copying craftable flag into items
- Fix NBT of old items not clearing on drives that reached 64 types once
Performance:
@@ -24,6 +28,9 @@ Performance:
- Count items set in interfaces before queuing crafting for them needlessly
- Backported b7ca98d ( Avoid copying items on simulated item extraction )
- Cache some level emitters functions
- Reduced import bus insert simulation to 1 before real insertion (if possible)
- Backported itemlist re-implementation along with pattern changes to avoid CraftingManager fallback issues
- Instead of recalculating all the content of the network on every change, track the changes properly and apply them to the cached list of items
QOL:
@@ -31,7 +38,7 @@ QOL:
- Added bar on the interface terminal that search by inputs ( The one on the LEFT, also searchs by interface name )
- Shortcut to molecular assemblers with free slots on the terminal interface by @Theisyat
- Toggle button on interface terminal to hide full interfaces
- JEI "U""R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
- JEI "U", "R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
- Patterns can now be made with items currently showing on JEI. ( This is overriden by Just Enough Energistics. )
- Added multiplier buttons to processing pattern gui
- Switched crafting terminal JEI search to fuzzy mode. If the recipe uses a damageable item, AE will try to grab it ( damaged tools )
@@ -39,7 +46,11 @@ QOL:
- Encoded patterns can be draggred on the interface terminal.
- Storage Monitor and Conversion Monitor now also ccepts fluids
- Draggable JEI ghost items (also works on bookmarked items. SHIFT + Click will move the hovered item into the first free target slot)
-JEI auto switches between crafting and processing patterns
- 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:
+1 -1
View File
@@ -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
View File
@@ -3,20 +3,18 @@ aechannel=stable
aebuild=7
aegroup=appeng
aebasename=appliedenergistics2
trousers=omni-fixes-v46
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 #
#########################################################
+9 -8
View File
@@ -31,7 +31,7 @@ repositories {
maven {
name = "Tesla repo"
url "http://maven.mcmoddev.com"
url "https://maven.mcmoddev.com"
}
maven {
@@ -59,7 +59,7 @@ repositories {
url "http://maven.k-4u.nl/"
}
maven { // CraftTweaker
maven { // CraftTweaker
name 'jared maven'
url "http://maven.blamejared.com/"
}
@@ -70,9 +70,9 @@ repositories {
//}
maven {
name = "CurseForge"
url = "https://minecraft.curseforge.com/api/maven/"
}
name = "CurseForge"
url = "https://minecraft.curseforge.com/api/maven/"
}
}
configurations {
@@ -80,8 +80,7 @@ configurations {
}
dependencies {
compileOnly "gregtechce:gregtech:1.12.2:1.15.1.735"
deobfCompile "gregtechce:gregtech:1.12.2:1.15.1.735"
// installable runtime dependencies
mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev"
@@ -95,9 +94,11 @@ dependencies {
compileOnly "mcjty.theoneprobe:TheOneProbe-1.12:${top_version}:api"
compileOnly "cofh:CoFHCore:${cofhcore_version}:deobf"
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
compileOnly "team.chisel.ctm:CTM:${ctm_version}"
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
deobfCompile "net.sengir.forestry:forestry_${minecraft_version}:$forestry_version"
// at runtime, use the full JEI jar
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
@@ -28,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
@@ -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();
@@ -119,6 +119,10 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
*
* @param is An item stack
*/
boolean equals(ItemStack is);
boolean equals( ItemStack is );
ItemStack getCachedItemStack( long stackSize );
void setCachedItemStack( ItemStack is );
}
@@ -56,7 +56,7 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
@Override
protected IProperty[] getAEStates()
{
return new IProperty[] { POWERED };
return new IProperty[]{POWERED};
}
@Override
@@ -108,4 +108,14 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
return super.onBlockActivated( w, pos, state, p, hand, side, hitX, hitY, hitZ );
}
@Override
public void onNeighborChange( IBlockAccess world, BlockPos pos, BlockPos neighbor )
{
final TileMolecularAssembler tg = this.getTileEntity( world, pos );
if( tg != null )
{
tg.updateNeighbors( world, pos, neighbor );
}
}
}
@@ -20,6 +20,7 @@ package appeng.capabilities;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import gregtech.api.capability.IEnergyContainer;
import net.darkhax.tesla.api.ITeslaConsumer;
import net.darkhax.tesla.api.ITeslaHolder;
import net.minecraft.nbt.NBTBase;
@@ -57,6 +58,8 @@ public final class Capabilities
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY;
public static Capability<IEnergyContainer> GTCE_ENERGY;
/**
* Register AE2 provided capabilities.
*/
@@ -103,7 +106,19 @@ public final class Capabilities
}
@CapabilityInject( IItemRepository.class )
private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap ) { ITEM_REPOSITORY_CAPABILITY = cap; }
private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap )
{
ITEM_REPOSITORY_CAPABILITY = cap;
}
@CapabilityInject( IEnergyContainer.class )
private static void capIEnergyContainerRegistered( Capability<IEnergyContainer> cap )
{
if( IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.GTCE ) )
{
GTCE_ENERGY = cap;
}
}
// Create a storage implementation that does not do anything
private static <T> Capability.IStorage<T> createNullStorage()
+24 -37
View File
@@ -33,6 +33,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import appeng.container.slot.*;
import appeng.util.Platform;
import com.google.common.base.Joiner;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
@@ -159,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 )
{
@@ -208,13 +209,17 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
}
}
GlStateManager.enableDepth();
bookmarkedJEIghostItem(mouseX,mouseY);
if( Platform.isModLoaded( "jei" ) )
{
bookmarkedJEIghostItem( mouseX, mouseY );
}
GlStateManager.disableDepth();
}
void bookmarkedJEIghostItem(final int mouseX, final int mouseY) {
if (!isJeiGhostItem)
@Optional.Method( modid = "jei" )
void bookmarkedJEIghostItem( final int mouseX, final int mouseY )
{
if( !isJeiGhostItem )
{
bookmarkedIngredient = runtime.getBookmarkOverlay().getIngredientUnderMouse();
}
@@ -248,7 +253,9 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
}
}
}
private void drawTargets(int mouseX, int mouseY) {
private void drawTargets( int mouseX, int mouseY )
{
GlStateManager.disableLighting();
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{
@@ -377,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 );
}
}
@@ -506,7 +509,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{
final EntityPlayer player = Minecraft.getMinecraft().player;
if( this.isJeiGhostItem && isDraggingJeiGhostItem)
if( this.isJeiGhostItem && isDraggingJeiGhostItem )
{
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{
@@ -759,7 +762,8 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
this.disableShiftClick = false;
}
if (clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem) {
if( clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem )
{
this.isDraggingJeiGhostItem = true;
return;
}
@@ -879,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 );
}
}
@@ -1032,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();
}
@@ -1066,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
@@ -104,7 +104,7 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
}
if( doStart && GuiScreen.isShiftKeyDown() && Mouse.isButtonDown( 0 ) )
{
if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm )
if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm || gui instanceof GuiExpandedProcessingPatternTerm )
{
IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui );
for( Target<I> target : targets )
@@ -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
@@ -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;
}
}
@@ -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();
}
}
}
@@ -270,12 +270,15 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
@Override
public Rectangle getArea()
{
if( slot instanceof SlotFake )
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
{
return new Rectangle( getGuiLeft() + ( (SlotFake) slot ).xPos, getGuiTop() + ( (SlotFake) slot ).yPos, 16, 16 );
else
}
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
@@ -284,7 +287,7 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
PacketInventoryAction p = null;
try
{
if( slot instanceof SlotFake )
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
{
if( finalItemStack.isEmpty() && finalFluidStack != null )
{
@@ -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 )
{
@@ -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 );
}
}
}
}
}
@@ -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;
}
}
@@ -178,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 );
@@ -505,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;
@@ -527,7 +527,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return null;
}
private ItemStack[] getOutputs()
protected ItemStack[] getOutputs()
{
if( this.isCraftingMode() )
{
@@ -535,7 +535,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
if( !out.isEmpty() && out.getCount() > 0 )
{
return new ItemStack[] { out };
return new ItemStack[]{out};
}
}
else
@@ -563,7 +563,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return null;
}
private boolean isPattern( final ItemStack output )
boolean isPattern( final ItemStack output )
{
if( output.isEmpty() )
{
@@ -578,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();
@@ -824,7 +824,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return this.patternTerminal;
}
private boolean isSubstitute()
boolean isSubstitute()
{
return this.substitute;
}
+88 -53
View File
@@ -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;
+4 -2
View File
@@ -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" );
@@ -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,7 +164,6 @@ public enum AEFeature
MOLECULAR_ASSEMBLER( "MolecularAssembler", Constants.CATEGORY_CRAFTING_FEATURES ),
PATTERNS( "Patterns", Constants.CATEGORY_CRAFTING_FEATURES ),
CRAFTING_CPU( "CraftingCPU", Constants.CATEGORY_CRAFTING_FEATURES ),
CRAFTING_MANAGER_FALLBACK( "CraftingManagerFallback", Constants.CATEGORY_CRAFTING_FEATURES, "Use CraftingManager to find an alternative recipe, after a pattern rejected an ingredient. Should be enabled to avoid issues, but can have a minor performance impact." ),
BASIC_CARDS( "BasicCards", Constants.CATEGORY_UPGRADES ),
ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ),
@@ -19,13 +19,14 @@
package appeng.core.features.registries;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.core.AELog;
import appeng.util.item.OreHelper;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
@@ -67,6 +68,25 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
this.addNewAttunement( new ItemStack( Blocks.TORCH ), TunnelType.LIGHT );
this.addNewAttunement( new ItemStack( Blocks.GLOWSTONE ), TunnelType.LIGHT );
List<String> gtceOreDict = new ArrayList<>();
gtceOreDict.add( "wireGtHex" );
gtceOreDict.add( "wireGtOctal" );
gtceOreDict.add( "wireGtQuadruple" );
gtceOreDict.add( "wireGtDouble" );
gtceOreDict.add( "wireGtSingle" );
gtceOreDict.add( "cableGtHex" );
gtceOreDict.add( "cableGtOctal" );
gtceOreDict.add( "cableGtQuadruple" );
gtceOreDict.add( "cableGtDouble" );
gtceOreDict.add( "cableGtSingle" );
for( String oreDict : gtceOreDict )
{
Arrays.stream( OreDictionary.getOreNames() ).filter( oreName -> oreName.startsWith( oreDict ) ).forEach( oreName -> {
OreHelper.INSTANCE.getCachedOres( oreName ).forEach( stack -> this.addNewAttunement( stack, TunnelType.GTEU_POWER ) );
} );
}
/**
* Forge energy tunnel items
*/
@@ -127,12 +147,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
this.addNewAttunement( this.getModItem( "enderio", "itemitemconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.ITEM );
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 0 ), TunnelType.ITEM ); // itemduct
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 1 ), TunnelType.ITEM ); // itemduct
// (opaque)
// (opaque)
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 2 ), TunnelType.ITEM ); // impulse
// itemduct
// itemduct
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 3 ), TunnelType.ITEM ); // impulse
// itemduct
// (opaque)
// itemduct
// (opaque)
/**
* attune based on lots of random item related stuff
@@ -148,12 +168,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
this.addNewAttunement( this.getModItem( "enderio", "itemliquidconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.FLUID );
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 0 ), TunnelType.FLUID ); // fluiduct
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 1 ), TunnelType.FLUID ); // fluiduct
// (opaque)
// (opaque)
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 2 ), TunnelType.FLUID ); // fluiduct
// hardened
// hardened
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 3 ), TunnelType.FLUID ); // fluiduct
// hardened
// (opaque)
// hardened
// (opaque)
for( final AEColor c : AEColor.values() )
{
@@ -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;
+7 -33
View File
@@ -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
}
}
@@ -192,7 +192,20 @@ public class PacketInventoryAction extends AppEngPacket
}
else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM )
{
if( sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake )
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 )
{
@@ -217,20 +230,6 @@ public class PacketInventoryAction extends AppEngPacket
AELog.debug( e );
}
}
if( sender.openContainer instanceof ContainerFluidConfigurable )
{
if( this.slotItem != null )
{
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
if( aefs != null )
{
aefs.setStackSize( 1000 );
( (ContainerFluidConfigurable) sender.openContainer ).getFluidConfigInventory().setFluidInSlot( this.slot, aefs );
NetworkHandler.instance().sendToServer( new PacketFluidSlot( Collections.singletonMap( this.slot, aefs ) ) );
}
}
}
}
else
{
@@ -23,13 +23,13 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.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 gregtech.common.items.MetaTool;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -40,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;
@@ -69,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.
@@ -81,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 ) ) );
}
}
}
@@ -166,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
@@ -193,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
@@ -212,7 +229,7 @@ public class PacketJEIRecipe extends AppEngPacket
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
if( out == null )
{
if( request.getItem().isDamageable() || ( Platform.isModLoaded( "gregtech" ) && request.getItem() instanceof MetaTool ) )
if( request.getItem().isDamageable() || Platform.isGTDamageableItem( request.getItem() ) )
{
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
for( IAEItemStack is : outList )
@@ -245,9 +262,9 @@ public class PacketJEIRecipe extends AppEngPacket
if( out != null )
{
if (!cct.useRealItems())
if( !cct.useRealItems() )
{
out.setStackSize( recipe[x][y].getCount() );
out.setStackSize( recipe.get( x )[y].getCount() );
}
currentItem = out.createItemStack();
}
@@ -260,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();
}
}
}
@@ -282,29 +299,35 @@ 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 )
{
if( this.output[i] == null ) continue;
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( ItemStack.areItemStacksEqual( is, option ) )
{
@@ -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();
+94 -62
View File
@@ -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,56 +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 final Stopwatch watch = Stopwatch.createUnstarted();
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 int time;
private int incTime;
private World wrapWorld( final World w )
{
return w;
}
public CraftingJob( final World w, final IGrid grid, final IActionSource actionSrc, final IAEItemStack what, final ICraftingCallback callback )
{
this.world = 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 )
@@ -108,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 )
{
@@ -129,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()
{
@@ -139,13 +153,15 @@ public class CraftingJob implements Runnable, ICraftingJob
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
this.handlePausing();
final Stopwatch timer = Stopwatch.createStarted();
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
craftingInventory.ignore( this.output );
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
this.reserved.values().forEach( availableCheck::reserve );
this.reserved.values().forEach( craftingInventory::reserve );
craftingTreeWatch.start();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
craftingTreeWatch.stop();
this.getTree().dive( this );
for( final String s : this.opsAndMultiplier.keySet() )
@@ -154,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 )
{
@@ -164,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 )
{
@@ -226,10 +256,11 @@ public class CraftingJob implements Runnable, ICraftingJob
this.incTime = 0;
synchronized ( this.monitor )
{
if( this.watch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
if( this.tickSpreadingWatch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
{
this.running = false;
this.watch.stop();
this.craftingTreeWatch.stop();
this.tickSpreadingWatch.stop();
this.monitor.notify();
}
@@ -245,12 +276,13 @@ public class CraftingJob implements Runnable, ICraftingJob
AELog.craftingDebug( "crafting job now active" );
}
}
if( Thread.interrupted() )
{
throw new InterruptedException();
}
}
if( Thread.interrupted() )
{
throw new InterruptedException();
}
this.incTime++;
}
@@ -263,7 +295,7 @@ public class CraftingJob implements Runnable, ICraftingJob
this.availableCheck = null;
synchronized( this.monitor )
synchronized ( this.monitor )
{
this.running = false;
this.done = true;
@@ -311,7 +343,7 @@ public class CraftingJob implements Runnable, ICraftingJob
/**
* @return true if this needs more simulation
*/
public boolean simulateFor(final int milli)
public boolean simulateFor( final int milli )
{
this.time = milli;
@@ -323,8 +355,8 @@ public class CraftingJob implements Runnable, ICraftingJob
}
if( !this.actionSrc.player().isPresent() )
{
this.watch.reset();
this.watch.start();
this.tickSpreadingWatch.reset();
this.tickSpreadingWatch.start();
this.monitor.notify();
}
this.running = true;
@@ -353,7 +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,83 +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() ) )
{
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs(this.slot);
itemList = new ArrayList<>(substitutes.size());
itemList.addAll( inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) );
for (IAEItemStack stack : substitutes) {
itemList.addAll(inventoryList.findFuzzy(stack, 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 )
{
@@ -169,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();
@@ -184,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 )
{
@@ -197,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();
@@ -209,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 )
@@ -258,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 );
@@ -294,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;
@@ -313,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 )
@@ -321,7 +410,7 @@ public class CraftingTreeNode
}
// missing = 0;
job.addBytes( 8 + this.bytes );
job.addBytes( this.bytes );
for( final CraftingTreeProcess pro : this.nodes )
{
@@ -338,7 +427,6 @@ public class CraftingTreeNode
void setSimulate()
{
this.sim = true;
this.missing = 0;
this.bytes = 0;
this.used.resetStatus();
@@ -358,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();
if( this.fullSimulation )
List<IAEItemStack> containerItems = null;
// 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,24 +264,29 @@ 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 );
}
}
void getPlan( final IItemList<IAEItemStack> plan )
{
for( IAEItemStack i : this.details.getCondensedOutputs() )
for( IAEItemStack i : this.details.getOutputs() )
{
i = i.copy();
i.setCountRequestable( i.getStackSize() * this.crafts );
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,10 +28,14 @@ import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.me.helpers.PlayerSource;
import appeng.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>
{
@@ -97,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;
}
@@ -311,13 +314,23 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
{
if( src.player().isPresent() )
{
if( result == null )
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could not extract anything" ), false );
else
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could only extract " + result.getStackSize() ), false );
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;
if( !src.player().isPresent() ) break;
}
}
}
@@ -348,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 );
@@ -361,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 );
}
}
@@ -68,7 +68,7 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH
for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i )
{
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 53, 16, 68 ) );
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 57, 16, 64 ) );
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
}
@@ -77,14 +77,14 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite( fluid.getFluid().getStill().toString() );
final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) );
int iconHeightRemainder = scaledHeight % this.getHeight();
int iconHeightRemainder = scaledHeight % 16;
if( iconHeightRemainder > 0 )
{
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, this.getWidth(), iconHeightRemainder );
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, 16, iconHeightRemainder );
}
for( int i = 0; i < scaledHeight / this.getHeight(); i++ )
for( int i = 0; i < scaledHeight / 16; i++ )
{
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, this.getWidth(), this.getHeight() );
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
}
}
}
@@ -113,7 +113,7 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
@Override
public int yPos()
{
return this.y - 1;
return this.y - 4;
}
@Override
@@ -125,7 +125,7 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
@Override
public int getHeight()
{
return this.height + 1;
return this.height + 4;
}
@Override
@@ -414,7 +414,7 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
}
}
if( notInserted == null )
if( notInserted == null || notInserted.getStackSize() == 0 )
{
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
@@ -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
@@ -232,18 +232,11 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
for( IFluidTankProperties tankProperty : tankProperties )
{
FluidStack newFS = tankProperty.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;
}
}
if( newFS != null )
{
currentlyOnStorage.add( AEFluidStack.fromFluidStack( newFS ) );
continue;
}
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
}
for ( final IAEFluidStack is : currentlyCached )
@@ -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();
}
@@ -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,6 @@ package appeng.fluids.parts;
import java.util.Random;
import appeng.api.networking.events.MENetworkChannelChanged;
import appeng.api.storage.data.IItemList;
import appeng.fluids.helper.IConfigurableFluidInventory;
import appeng.me.cache.NetworkMonitor;
@@ -116,9 +115,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
@Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
{
if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && diffStack.equals( this.config.getFluidInSlot( 0 ) ) )
if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && fullStack.equals( this.config.getFluidInSlot( 0 ) ) )
{
this.lastReportedValue += diffStack.getStackSize();
this.lastReportedValue = fullStack.getStackSize();
this.updateState();
}
}
@@ -129,8 +128,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
this.configureWatchers();
}
@Override
@MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange powerEvent )
public void powerRender( final MENetworkPowerStatusChange powerEvent )
{
if (this.getProxy().isActive())
{
@@ -139,8 +139,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
this.updateState();
}
@Override
@MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c )
public void chanRender( final MENetworkChannelsChanged c )
{
if (this.getProxy().isActive())
{
File diff suppressed because it is too large Load Diff
+189 -161
View File
@@ -19,41 +19,6 @@
package appeng.helpers;
import java.util.*;
import javax.annotation.Nullable;
import appeng.api.definitions.IItemDefinition;
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
import appeng.util.*;
import appeng.util.inv.*;
import com.google.common.collect.ImmutableSet;
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
import gregtech.api.block.machines.BlockMachine;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.MetaTileEntityHolder;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.RangedWrapper;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
@@ -77,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;
@@ -103,21 +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.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.*;
import appeng.util.item.AEItemStack;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
import gregtech.api.block.machines.BlockMachine;
import gregtech.api.metatileentity.MetaTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.RangedWrapper;
import javax.annotation.Nullable;
import java.util.*;
import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost
{
private int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
public static final int NUMBER_OF_STORAGE_SLOTS = 9;
public static final int NUMBER_OF_CONFIG_SLOTS = 9;
public static final int NUMBER_OF_PATTERN_SLOTS = 36;
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
private final IAEItemStack[] requireWork = { null, null, null, null, null, null, null, null, null };
private final IAEItemStack[] requireWork = {null, null, null, null, null, null, null, null, null};
private final MultiCraftingTracker craftingTracker;
private final AENetworkProxy gridProxy;
private final IInterfaceHost iHost;
@@ -127,30 +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 EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
private EnumMap<EnumFacing,List<ItemStack>> waitingToSendFacing = new EnumMap<>(EnumFacing.class);
private GTCEInventoryAdaptor GTad;
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, 4);
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4 );
this.cm.registerSetting( Settings.BLOCK, YesNo.NO );
this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES );
@@ -165,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()
{
@@ -178,9 +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() ) )
{
@@ -239,12 +238,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
NBTTagCompound sidedWaitList = new NBTTagCompound();
if (this.waitingToSendFacing != null)
if( this.waitingToSendFacing != null )
{
for( EnumFacing s : this.iHost.getTargets() )
{
NBTTagList waitingListSided = new NBTTagList();
if (this.waitingToSendFacing.containsKey( s ))
if( this.waitingToSendFacing.containsKey( s ) )
{
for( final ItemStack is : this.waitingToSendFacing.get( s ) )
{
@@ -280,6 +279,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" );
for( EnumFacing s : EnumFacing.values() )
{
if( waitingListSided.hasKey( s.name() ) )
{
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
@@ -293,6 +293,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
}
}
this.craftingTracker.readFromNBT( data );
@@ -352,8 +353,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
return;
}
if (this.waitingToSendFacing == null){
this.waitingToSendFacing = new EnumMap<>(EnumFacing.class);
if( this.waitingToSendFacing == null )
{
this.waitingToSendFacing = new EnumMap<>( EnumFacing.class );
}
this.waitingToSendFacing.computeIfAbsent( f, k -> new ArrayList<>() );
@@ -410,7 +412,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
// :P
}
}
this.notifyNeighbors();
}
@@ -424,15 +425,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return;
}
boolean removed = false;
if( this.craftingList != null )
{
final Iterator<ICraftingPatternDetails> i = this.craftingList.iterator();
while( i.hasNext() )
while ( i.hasNext() )
{
final ICraftingPatternDetails details = i.next();
boolean found = false;
for( int x = 0; x < accountedFor.length ; x++ )
for( int x = 0; x < accountedFor.length; x++ )
{
final ItemStack is = this.patterns.getStackInSlot( x );
if( details.getPattern() == is )
@@ -443,41 +446,49 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if( !found )
{
removed = true;
i.remove();
}
}
}
for( int x = 0; x < accountedFor.length ; x++ )
boolean newPattern = false;
for( int x = 0; x < accountedFor.length; x++ )
{
if( !accountedFor[x] )
{
newPattern = true;
this.addToCraftingList( this.patterns.getStackInSlot( x ) );
}
}
try
{
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
}
catch( final GridAccessException e )
catch( GridAccessException e )
{
// :P
e.printStackTrace();
}
}
private boolean hasWorkToDo() {
private boolean hasWorkToDo()
{
if (hasItemsToSend()){
if( hasItemsToSend() )
{
return true;
}
if(hasItemsToSendFacing()){
if( hasItemsToSendFacing() )
{
return true;
}
for (final IAEItemStack requiredWork : this.requireWork) {
if (requiredWork != null) {
for( final IAEItemStack requiredWork : this.requireWork )
{
if( requiredWork != null )
{
return true;
}
}
@@ -588,7 +599,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private boolean hasItemsToSendFacing()
{
if (waitingToSendFacing != null)
if( waitingToSendFacing != null )
{
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{
@@ -608,10 +619,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
List<ItemStack> dropList = new ArrayList<>();
for( int invSlot = 0; invSlot < patterns.getSlots(); invSlot++ )
{
if( invSlot > 8 + this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) * 9 )
if( invSlot > 8 + this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) * 9 )
{
ItemStack is = patterns.getStackInSlot( invSlot );
if( is.isEmpty() ) continue;
if( is.isEmpty() )
{
continue;
}
dropList.add( patterns.extractItem( invSlot, Integer.MAX_VALUE, false ) );
}
}
@@ -628,8 +642,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
@Override
public boolean canInsert( final ItemStack stack )
{
final IAEItemStack out = this.destination.injectItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ),
Actionable.SIMULATE, null );
final IAEItemStack out = this.destination.injectItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ), Actionable.SIMULATE, null );
if( out == null )
{
return true;
@@ -703,7 +716,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.pushItemsOut( this.iHost.getTargets() );
}
if (hasItemsToSendFacing())
if( hasItemsToSendFacing() )
{
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{
@@ -726,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();
@@ -773,8 +786,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private void pushItemsOut( final EnumFacing s )
{
if (!this.waitingToSendFacing.containsKey(s) ||
(this.waitingToSendFacing.containsKey(s) && this.waitingToSendFacing.get( s ).isEmpty())) {
if( !this.waitingToSendFacing.containsKey( s ) || ( this.waitingToSendFacing.containsKey( s ) && this.waitingToSendFacing.get( s ).isEmpty() ) )
{
return;
}
@@ -787,17 +800,18 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return;
}
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator();
while ( i.hasNext() )
{
ItemStack whatToSend = i.next();
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null )
{
final ItemStack result = ad.addItems( whatToSend );
if( !result.isEmpty() )
{
whatToSend.setCount( whatToSend.getCount() - ( whatToSend.getCount() - result.getCount() ) );
whatToSend.setCount( result.getCount() );
}
else
{
@@ -838,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() );
@@ -904,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 )
@@ -931,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 )
@@ -975,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;
@@ -1076,12 +1102,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private boolean invIsBlocked( InventoryAdaptor inv )
{
return (inv.containsItems());
}
private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv )
{
return ( !inv.canRemoveAllExceptCircuits() );
return ( inv.containsItems() );
}
@Override
@@ -1133,35 +1154,36 @@ 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() )
{
IPhantomTile phantomTE = null;
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
IPhantomTile phantomTE;
if( Loader.isModLoaded( "actuallyadditions" ) && te instanceof IPhantomTile )
{
phantomTE = ( (IPhantomTile) te );
if( phantomTE.hasBoundPosition() )
{
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
if( phantom instanceof MetaTileEntityHolder && isGTCEblocked( phantom, s ) )
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) )
{
visitedFaces.remove( s );
continue;
if( isCustomInvBlocking( phantom, s ) )
{
visitedFaces.remove( s );
continue;
}
}
}
}
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
{
if( isGTCEblocked( te, s ) )
if( isCustomInvBlocking( te, s ) )
{
visitedFaces.remove( s );
continue;
}
}
else if( invIsBlocked( ad ) )
{
visitedFaces.remove( s );
@@ -1210,38 +1232,42 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
for( final EnumFacing s : possibleDirections )
{
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
IPhantomTile phantomTE = null;
IPhantomTile phantomTE;
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null )
{
if( Loader.isModLoaded( "actuallyadditions") && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
{
phantomTE = ( (IPhantomTile) te );
if( phantomTE.hasBoundPosition() )
{
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
if( phantom instanceof MetaTileEntityHolder && !isGTCEblocked( phantom, s ) )
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) )
{
allAreBusy = false;
break;
if( !isCustomInvBlocking( phantom, s ) )
{
allAreBusy = false;
break;
}
}
}
}
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
{
if( !isGTCEblocked( te, s ) )
if( !isCustomInvBlocking( te, s ) )
{
allAreBusy = false;
break;
}
}
else if( !invIsBlocked( ad ) )
else
{
allAreBusy = false;
break;
if( !invIsBlocked( ad ) )
{
allAreBusy = false;
break;
}
}
}
}
@@ -1250,10 +1276,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return busy;
}
boolean isGTCEblocked(TileEntity te, EnumFacing s)
boolean isCustomInvBlocking( TileEntity te, EnumFacing s )
{
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
return invIsBlockedGTCE( GTad );
BlockingInventoryAdaptor blockingInventoryAdaptor = BlockingInventoryAdaptor.getAdaptor( te, s.getOpposite() );
return invIsCustomBlocking( blockingInventoryAdaptor );
}
private boolean sameGrid( final IGrid grid ) throws GridAccessException
@@ -1276,7 +1302,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
continue;
}
if( !ad.simulateAdd( is.copy() ).isEmpty() )
if( !ad.simulateAdd( is ).isEmpty() )
{
return false;
}
@@ -1313,13 +1339,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if( this.waitingToSendFacing != null )
{
for (List<ItemStack> itemList : waitingToSendFacing.values())
for( List<ItemStack> itemList : waitingToSendFacing.values() )
{
for (final ItemStack is : itemList)
for( final ItemStack is : itemList )
{
if (!is.isEmpty())
if( !is.isEmpty() )
{
drops.add(is);
drops.add( is );
}
}
}
@@ -1449,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();
}
@@ -1567,6 +1593,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
private class InterfaceRequestContext implements Comparable<Integer>
{
@@ -1577,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
@@ -1615,6 +1642,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
private class Accessor implements IStorageMonitorableAccessor
{
@@ -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()
{
}
}
+68 -44
View File
@@ -20,7 +20,6 @@ package appeng.helpers;
import java.util.*;
import java.util.stream.Collectors;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
@@ -38,25 +37,26 @@ 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 ALL_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION;
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;
private static final int PROCESSING_OUTPUT_LIMIT = 3;
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;
@@ -84,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 );
@@ -147,11 +150,11 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
}
}
}
final int outputLength = this.isCrafting ? CRAFTING_OUTPUT_LIMIT : PROCESSING_OUTPUT_LIMIT;
final int outputLength = out.size();
this.inputs = in.toArray(new IAEItemStack[ALL_INPUT_LIMIT]);
this.outputs = out.toArray(new IAEItemStack[outputLength]);
this.substituteInputs = new HashMap<>(ALL_INPUT_LIMIT);
this.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<>();
@@ -245,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;
@@ -264,9 +267,11 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
this.testFrame.setInventorySlotContents( slotIndex, i );
// If we cannot substitute, the items must match exactly
if (!canSubstitute && slotIndex < inputs.length) {
if (!inputs[slotIndex].isSameType(i)) {
this.markItemAs(slotIndex, i, TestStatus.DECLINE);
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;
}
}
@@ -324,23 +329,26 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
}
@Override
public List<IAEItemStack> getSubstituteInputs(int slot) {
if (this.inputs[slot] == null) {
public List<IAEItemStack> getSubstituteInputs( int slot )
{
if( this.inputs[slot] == null )
{
return Collections.emptyList();
}
return this.substituteInputs.computeIfAbsent(slot, value -> {
ItemStack[] matchingStacks = getRecipeIngredient(slot).getMatchingStacks();
List<IAEItemStack> itemList = new ArrayList<>(matchingStacks.length + 1);
for (ItemStack matchingStack : matchingStacks) {
itemList.add(AEItemStack.fromItemStack(matchingStack));
return this.substituteInputs.computeIfAbsent( slot, value -> {
ItemStack[] matchingStacks = getRecipeIngredient( slot ).getMatchingStacks();
List<IAEItemStack> itemList = new ArrayList<>( matchingStacks.length + 1 );
for( ItemStack matchingStack : matchingStacks )
{
itemList.add( AEItemStack.fromItemStack( matchingStack ) );
}
// Ensure that the specific item put in by the user is at the beginning,
// so that it takes precedence over substitutions
itemList.add(0, this.inputs[slot]);
itemList.add( 0, this.inputs[slot] );
return itemList;
});
} );
}
/**
@@ -350,31 +358,40 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
* ingredient list will be condensed to the actual recipe's grid size. In addition, in our 3x3 grid, the user can
* shift the actual recipe input to the right and down.
*/
private Ingredient getRecipeIngredient(int slot) {
private Ingredient getRecipeIngredient( int slot )
{
if (standardRecipe instanceof IShapedRecipe ) {
if( standardRecipe instanceof IShapedRecipe )
{
IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe;
return getShapedRecipeIngredient(slot, shapedRecipe.getRecipeWidth());
} else {
return getShapelessRecipeIngredient(slot);
return getShapedRecipeIngredient( slot, shapedRecipe.getRecipeWidth() );
}
else
{
return getShapelessRecipeIngredient( slot );
}
}
private Ingredient getShapedRecipeIngredient(int slot, int recipeWidth) {
private Ingredient getShapedRecipeIngredient( int slot, int recipeWidth )
{
// Compute the offset of the user's input vs. crafting grid origin
// Which is >0 if they have empty rows above or to the left of their input
int topOffset = 0;
if (inputs[0] == null && inputs[1] == null && inputs[2] == null) {
if( inputs[0] == null && inputs[1] == null && inputs[2] == null )
{
topOffset++; // First row is fully empty
if (inputs[3] == null && inputs[4] == null && inputs[5] == null) {
if( inputs[3] == null && inputs[4] == null && inputs[5] == null )
{
topOffset++; // Second row is fully empty
}
}
int leftOffset = 0;
if (inputs[0] == null && inputs[3] == null && inputs[6] == null) {
if( inputs[0] == null && inputs[3] == null && inputs[6] == null )
{
leftOffset++; // First column is fully empty
if (inputs[1] == null && inputs[4] == null && inputs[7] == null) {
if( inputs[1] == null && inputs[4] == null && inputs[7] == null )
{
leftOffset++; // Second column is fully empty
}
}
@@ -388,32 +405,37 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
if (ingredientIndex < 0 || ingredientIndex > ingredients.size()) {
if( ingredientIndex < 0 || ingredientIndex > ingredients.size() )
{
return Ingredient.EMPTY;
}
return ingredients.get(ingredientIndex);
return ingredients.get( ingredientIndex );
}
private Ingredient getShapelessRecipeIngredient(int slot) {
private Ingredient getShapelessRecipeIngredient( int slot )
{
// We map the list of *filled* sparse inputs to the shapeless (ergo unordered)
// ingredients. While these do not actually correspond to each other,
// since both lists have the same length, the mapping is at least stable.
int ingredientIndex = 0;
for (int i = 0; i < slot; i++) {
if (inputs[i] != null) {
for( int i = 0; i < slot; i++ )
{
if( inputs[i] != null )
{
ingredientIndex++;
}
}
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
if (ingredientIndex < ingredients.size()) {
return ingredients.get(ingredientIndex);
if( ingredientIndex < ingredients.size() )
{
return ingredients.get( ingredientIndex );
}
return Ingredient.EMPTY;
}
@Override
public ItemStack getOutput( final InventoryCrafting craftingInv, final World w )
{
@@ -515,7 +537,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
private enum TestStatus
{
ACCEPT, DECLINE, TEST
ACCEPT,
DECLINE,
TEST
}
private static final class TestLookup
+7 -10
View File
@@ -190,10 +190,11 @@ public class TickHandler
synchronized ( this.craftingJobs )
{
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
if (!jobSet.isEmpty()) {
if( !jobSet.isEmpty() )
{
final int jobSize = jobSet.size();
final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000;
final int simTime = Math.max(1, microSecondsPerTick / jobSize);
final int simTime = Math.max( 1, microSecondsPerTick / jobSize );
jobSet.removeIf( cj -> !cj.simulateFor( simTime ) );
}
@@ -206,7 +207,7 @@ public class TickHandler
this.tickColors( this.srvPlayerColors );
// ready tiles.
final HandlerRep repo = this.getRepo();
while( !repo.tiles.isEmpty() )
while ( !repo.tiles.isEmpty() )
{
final AEBaseTile bt = repo.tiles.poll();
if( !bt.isInvalid() )
@@ -238,7 +239,7 @@ public class TickHandler
private void tickColors( final HashMap<Integer, PlayerColor> playerSet )
{
final Iterator<PlayerColor> i = playerSet.values().iterator();
while( i.hasNext() )
while ( i.hasNext() )
{
final PlayerColor pc = i.next();
if( pc.ticksLeft <= 0 )
@@ -259,7 +260,7 @@ public class TickHandler
final Stopwatch sw = Stopwatch.createStarted();
IWorldCallable<?> c = null;
while( ( c = queue.poll() ) != null )
while ( ( c = queue.poll() ) != null )
{
try
{
@@ -275,15 +276,11 @@ public class TickHandler
AELog.debug( e );
}
}
// long time = sw.elapsed( TimeUnit.MILLISECONDS );
// if ( time > 0 )
// AELog.info( "processQueue Time: " + time + "ms" );
}
public void registerCraftingSimulation( final World world, final CraftingJob craftingJob )
{
synchronized( this.craftingJobs )
synchronized ( this.craftingJobs )
{
this.craftingJobs.put( world, craftingJob );
}
@@ -30,35 +30,37 @@ import appeng.integration.modules.waila.WailaModule;
public enum IntegrationType
{
IC2( IntegrationSide.BOTH, "Industrial Craft 2", "ic2" )
{
@Override
public IIntegrationModule createInstance()
{
return Integrations.setIc2( new IC2Module() );
}
},
{
@Override
public IIntegrationModule createInstance()
{
return Integrations.setIc2( new IC2Module() );
}
},
GTCE( IntegrationSide.BOTH, "GregTech", "gregtech" ),
RC( IntegrationSide.BOTH, "Railcraft", "railcraft" ),
MFR( IntegrationSide.BOTH, "Mine Factory Reloaded", "minefactoryreloaded" ),
Waila( IntegrationSide.BOTH, "Waila", "waila" )
{
@Override
public IIntegrationModule createInstance()
{
return new WailaModule();
}
},
{
@Override
public IIntegrationModule createInstance()
{
return new WailaModule();
}
},
InvTweaks( IntegrationSide.CLIENT, "Inventory Tweaks", "inventorytweaks" )
{
@Override
public IIntegrationModule createInstance()
{
return Integrations.setInvTweaks( new InventoryTweaksModule() );
}
},
{
@Override
public IIntegrationModule createInstance()
{
return Integrations.setInvTweaks( new InventoryTweaksModule() );
}
},
JEI( IntegrationSide.CLIENT, "Just Enough Items", "jei" )
{
@@ -1,26 +0,0 @@
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemSlot;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
{
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
{
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
{
// Attempt getting an IItemHandler for the given side via caps
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
if (itemHandler != null)
{
return new GTCEItemHandler(itemHandler);
}
}
return null;
}
public abstract boolean canRemoveAllExceptCircuits();
}
@@ -1,58 +0,0 @@
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemHandlerIterator;
import appeng.util.inv.ItemSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class GTCEItemHandler extends GTCEInventoryAdaptor
{
ArrayList<Integer> GTCElenses = new ArrayList<>(Arrays.asList(15085,15214,15092,15111,15113,15219,15218,15243,15244,15209,15117,15206,15216,15331,15212,15213,15154,15122,15157,15190,15247));
ArrayList<Integer> GTCEmolds = new ArrayList<>(Arrays.asList(32301,32303,32304,32305,32306,32307,32308,32309,32313,32314,32315,32317,32350,32351,32352,32353,32354,32355,32356,32358,32359,32360,32361,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373));
Item smallGearExtruderShape = Item.getByNameOrId("contenttweaker:smallgearextrudershape");
Item creativePortableTankMold = Item.getByNameOrId("contenttweaker:creativeportabletankmold");
protected final IItemHandler itemHandler;
public GTCEItemHandler(IItemHandler itemHandler)
{
this.itemHandler = itemHandler;
}
boolean isBlockableItem(ItemStack stack)
{
if ( stack.getItem() == Item.getByNameOrId("gregtech:meta_item_1") ) {
int metadata = stack.getItemDamage();
if ( metadata == 32766 || GTCElenses.contains(metadata) || GTCEmolds.contains(metadata)) {
return false;
}
}
if ( stack.getItem() == smallGearExtruderShape ) return false;
if ( stack.getItem() == creativePortableTankMold) return false;
return true;
}
@Override
public boolean canRemoveAllExceptCircuits()
{
int slots = this.itemHandler.getSlots();
for ( int slot = 0; slot < slots; slot++ ) {
ItemStack is = this.itemHandler.getStackInSlot(slot);
if ( is.isEmpty() || !isBlockableItem(is) ) continue;
return false;
}
return true;
}
@Override
public Iterator<ItemSlot> iterator()
{
return new ItemHandlerIterator( this.itemHandler );
}
}
@@ -26,6 +26,7 @@ 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;
@@ -90,16 +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 = new AEGuiHandler();
registry.addAdvancedGuiHandlers(aeGuiHandler);
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler);
registry.addAdvancedGuiHandlers( aeGuiHandler );
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler );
}
private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
@@ -35,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,
@@ -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 )
{
@@ -225,7 +225,7 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
final ICraftingPatternDetails details = this.getPatternForItem( item, w );
out = details != null ? details.getCondensedOutputs()[0].createItemStack() : ItemStack.EMPTY;
out = details != null ? details.getOutputs()[0].createItemStack() : ItemStack.EMPTY;
SIMPLE_CACHE.put( item, out );
return out;
+149 -185
View File
@@ -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 )
+1 -7
View File
@@ -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;
}
+15 -11
View File
@@ -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
+61 -62
View File
@@ -35,7 +35,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import appeng.api.storage.data.IAEFluidStack;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@@ -114,9 +113,9 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
private final GenericInterestManager<CraftingWatcher> interestManager = new GenericInterestManager<>( this.interests );
private IStorageGrid storageGrid;
private IEnergyGrid energyGrid;
int i;
private boolean updateList = false;
private static int pauseRebuilds = 0;
private static Set<CraftingGridCache> rebuildNeeded = new HashSet<>();
private boolean updatePatterns = false;
public CraftingGridCache( final IGrid grid )
{
@@ -141,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 ) )
{
@@ -188,7 +193,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( machine instanceof ICraftingProvider )
{
this.craftingProviders.remove( machine );
this.updatePatterns();
this.updatePatterns = true;
}
}
@@ -222,7 +227,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( machine instanceof ICraftingProvider )
{
this.craftingProviders.add( (ICraftingProvider) machine );
this.updatePatterns();
this.updatePatterns = true;
}
}
@@ -243,35 +248,15 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
// nothing!
}
public static void pauseRebuilds()
{
pauseRebuilds++;
}
public static void unpauseRebuilds()
{
pauseRebuilds--;
if (pauseRebuilds == 0 && rebuildNeeded.size() > 0)
{
ImmutableSet<CraftingGridCache> needed = ImmutableSet.copyOf(rebuildNeeded);
rebuildNeeded.clear();
for ( CraftingGridCache cache: needed )
{
cache.updatePatterns();
}
}
}
private void updatePatterns()
{
// coalesce change events during a grid traversal to a single rebuild
if (pauseRebuilds != 0)
{
rebuildNeeded.add(this);
return;
}
this.updatePatterns = true;
}
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>(this.craftableItems);
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();
@@ -289,7 +274,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
// new craftables!
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
{
for( IAEItemStack out : details.getCondensedOutputs() )
for( IAEItemStack out : details.getOutputs() )
{
out = out.copy();
out.reset();
@@ -312,24 +297,55 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
}
Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftablesChanged = new Object2ObjectArrayMap<>();
List<IAEItemStack> craftablesChanged = new ArrayList<>();
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet();
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i) {
if (!this.craftableItems.containsKey( ais.getKey() )) {
craftablesChanged.put( ais.getKey().setCraftable( false ), ais.getValue() );
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 )){
craftablesChanged.put( ais.getKey().setCraftable( true ), ais.getValue() );
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j )
{
if( !oldItems.containsKey( ais ) )
{
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.add( changedStack );
}
}
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged.keySet(),
new BaseActionSource() );
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()
@@ -507,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();
}
@@ -568,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() );
@@ -648,7 +647,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
public boolean hasCpu( final ICraftingCPU cpu )
{
if (cpu instanceof CraftingCPUCluster)
if( cpu instanceof CraftingCPUCluster )
{
return this.craftingCPUClusters.contains( (CraftingCPUCluster) cpu );
}
@@ -682,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() )
+115 -138
View File
@@ -19,10 +19,21 @@
package appeng.me.cache;
import java.util.*;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import com.google.common.base.Preconditions;
import com.google.common.collect.*;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
@@ -54,11 +65,9 @@ public class EnergyGridCache implements IEnergyGrid
{
private static final double MAX_BUFFER_STORAGE = 800;
private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(),
o1.getProviderStoredEnergy() );
private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(), o1.getProviderStoredEnergy() );
private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) ->
{
private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) -> {
final double percent1 = ( o1.getProviderStoredEnergy() + 1 ) / ( o1.getProviderMaxEnergy() + 1 );
final double percent2 = ( o2.getProviderStoredEnergy() + 1 ) / ( o2.getProviderMaxEnergy() + 1 );
@@ -70,7 +79,7 @@ public class EnergyGridCache implements IEnergyGrid
// Should only be modified from the add/remove methods below to guard against
// concurrent modifications
private final double averageLength = 40.0;
private final Multimap<Integer,IAEPowerStorage> providers = HashMultimap.create();
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.
@@ -78,7 +87,7 @@ public class EnergyGridCache implements IEnergyGrid
// Should only be modified from the add/remove methods below to guard against
// concurrent modifications
private final Multimap<Integer,IAEPowerStorage> requesters = HashMultimap.create();
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.
@@ -115,16 +124,16 @@ public class EnergyGridCache implements IEnergyGrid
private double lastStoredPower = -1;
private final GridPowerStorage localStorage = new GridPowerStorage();
private Set<IAEPowerStorage> providersToRemove = new HashSet<>();
private Set<IAEPowerStorage> requestersToRemove = new HashSet<>();
private Set<IAEPowerStorage> providerToRemove = new HashSet<>();
private Set<IAEPowerStorage> requesterToRemove = new HashSet<>();
private Set<IAEPowerStorage> providersToAdd = new HashSet<>();
private Set<IAEPowerStorage> requestersToAdd = new HashSet<>();
private Set<IAEPowerStorage> requesterToAdd = new HashSet<>();
public EnergyGridCache( final IGrid g )
{
this.myGrid = g;
this.requesters.put( 0, this.localStorage );
this.providers.put( 1, this.localStorage );
this.requesters.add( this.localStorage );
this.providers.add( this.localStorage );
}
@MENetworkEventSubscribe
@@ -152,34 +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 )
{
if( !ongoingExtractOperation )
{
addProvider( ev.storage );
}
else
{
this.providersToAdd.add( ev.storage );
}
addProvider( ev.storage );
}
break;
case REQUEST_POWER:
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
else
{
if( !ongoingInjectOperation )
{
addRequester( ev.storage );
}
else
{
this.requestersToAdd.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
@@ -307,7 +315,7 @@ public class EnergyGridCache implements IEnergyGrid
{
this.availableTicksSinceUpdate = 0;
this.globalAvailablePower = 0;
for( final IAEPowerStorage p : this.providers.values() )
for( final IAEPowerStorage p : this.providers )
{
this.globalAvailablePower += p.getAECurrentPower();
}
@@ -324,50 +332,57 @@ public class EnergyGridCache implements IEnergyGrid
{
double extractedPower = 0;
providersToAdd.forEach( provider -> {
if( provider instanceof GridPowerStorage )
{
providers.put( 1, provider );
}
else
{
providers.put( 0, provider );
}
} );
this.providers.addAll( providersToAdd );
providersToAdd.clear();
providers.removeIf( providerToRemove::contains );
this.providerToRemove.clear();
final Iterator<IAEPowerStorage> it = this.providers.values().iterator();
final Iterator<IAEPowerStorage> it = this.providers.iterator();
ongoingExtractOperation = true;
boolean ls = false;
try
{
while ( extractedPower < amt && it.hasNext() )
{
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;
final double req = amt - extractedPower;
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower;
if( newPower < req && mode == Actionable.MODULATE )
if( newPower < req && mode == Actionable.MODULATE )
{
it.remove();
}
}
else
{
it.remove();
}
}
} finally
{
providersToRemove.forEach( provider -> {
if( provider instanceof GridPowerStorage )
{
providers.remove( 1, provider );
}
else
{
providers.remove( 0, provider );
}
} );
this.providersToRemove.clear();
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 );
}
}
}
final double result = Math.min( extractedPower, amt );
@@ -391,19 +406,12 @@ public class EnergyGridCache implements IEnergyGrid
{
final double originalAmount = amt;
requestersToAdd.forEach( requester -> {
if( requester instanceof GridPowerStorage )
{
requesters.put( 0, requester );
}
else
{
requesters.put( 1, requester );
}
} );
requestersToAdd.clear();
this.requesters.addAll( requesterToAdd );
requesterToAdd.clear();
requesters.removeIf( requesterToRemove::contains );
this.requesterToRemove.clear();
final Iterator<IAEPowerStorage> it = this.requesters.values().iterator();
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
ongoingInjectOperation = true;
try
@@ -412,26 +420,22 @@ public class EnergyGridCache implements IEnergyGrid
{
final IAEPowerStorage node = it.next();
amt = node.injectAEPower( amt, mode );
if( node != null )
{
amt = node.injectAEPower( amt, mode );
if( amt > 0 && mode == Actionable.MODULATE )
if( amt > 0 && mode == Actionable.MODULATE )
{
it.remove();
}
}
else
{
it.remove();
}
}
} finally
{
requestersToRemove.forEach( requester -> {
if( requester instanceof GridPowerStorage )
{
requesters.remove( 0, requester );
}
else
{
requesters.remove( 1, requester );
}
} );
this.requestersToRemove.clear();
ongoingInjectOperation = false;
}
@@ -450,8 +454,8 @@ public class EnergyGridCache implements IEnergyGrid
{
double required = 0;
final Iterator<IAEPowerStorage> it = this.requesters.values().iterator();
while( required < maxRequired && it.hasNext() )
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
while ( required < maxRequired && it.hasNext() )
{
final IAEPowerStorage node = it.next();
if( node.getPowerFlow() != AccessRestriction.READ )
@@ -591,7 +595,7 @@ public class EnergyGridCache implements IEnergyGrid
}
else
{
this.providersToRemove.add( ps );
this.providerToRemove.add( ps );
}
if( !ongoingInjectOperation )
{
@@ -599,7 +603,7 @@ public class EnergyGridCache implements IEnergyGrid
}
else
{
this.requestersToRemove.add( ps );
this.requesterToRemove.add( ps );
}
}
}
@@ -616,58 +620,31 @@ public class EnergyGridCache implements IEnergyGrid
}
}
private void addRequester(IAEPowerStorage requester) {
Preconditions.checkState(!ongoingInjectOperation,
"Cannot modify energy requesters while energy is being injected.");
if( requester instanceof GridPowerStorage )
{
requesters.put( 0, requester );
}
else
{
requesters.put( 1, requester );
}
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.");
if( requester instanceof GridPowerStorage )
{
requesters.remove( 0, requester );
}
else
{
requesters.remove( 1, 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.");
if( provider instanceof GridPowerStorage )
{
providers.put( 1, provider );
}
else
{
providers.put( 0, provider );
}
}
private void removeProvider(IAEPowerStorage provider)
private void addProvider( IAEPowerStorage provider )
{
Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." );
if( provider instanceof GridPowerStorage )
{
providers.remove( 1, provider );
}
else
{
providers.remove( 0, provider );
}
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 )
{
@@ -717,7 +694,7 @@ public class EnergyGridCache implements IEnergyGrid
}
else
{
this.requestersToAdd.add( ps );
this.requesterToAdd.add( ps );
}
}
}
@@ -845,4 +822,4 @@ public class EnergyGridCache implements IEnergyGrid
}
}
}
}
}
+51 -18
View File
@@ -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,7 +100,7 @@ public class GridStorageCache implements IStorageGrid
this.removeCellProvider( cc, tracker );
this.inactiveCellProviders.remove( cc );
this.getGrid().postEvent( new MENetworkCellArrayUpdate() );
cellUpdate( null );
tracker.applyChanges();
}
@@ -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 )
@@ -330,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 );
}
}
}
+96 -41
View File
@@ -19,7 +19,6 @@
package appeng.me.cache;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.api.AEApi;
@@ -36,20 +35,21 @@ import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.me.storage.ItemWatcher;
import com.google.common.collect.Queues;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.*;
import java.util.Map.Entry;
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{
@Nonnull
private static final Deque<NetworkMonitor<?>> GLOBAL_DEPTH = Queues.newArrayDeque();
private static final HashMap<IActionSource, LinkedList<NetworkMonitor<?>>> src2MonitorsMap = new HashMap<>();
private static final Set<IActionSource> nestingSources = new HashSet<>();
protected boolean wasNested = false;
protected boolean isNested = false;
@Nonnull
private final GridStorageCache myGridCache;
@@ -61,11 +61,9 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
private boolean sendEvent = false;
private boolean forceUpdate = false;
@Nonnegative
private int localDepthSemaphore = 0;
private long gridItemCount;
private long gridFluidCount;
public boolean forceUpdate;
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
{
@@ -136,30 +134,22 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return 0;
}
public long incGridCurrentCount(long count)
public void incGridCurrentCount( long count )
{
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
return gridItemCount += count;
gridItemCount += count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
return gridFluidCount += count;
gridFluidCount += count;
}
return 0;
}
@Nonnull
@Override
public IItemList<T> getStorageList()
{
if( forceUpdate )
{
forceUpdate = false;
this.cachedList.resetStatus();
return this.getAvailableItems( this.cachedList );
}
return this.cachedList;
}
@@ -206,6 +196,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
if( receiver.isValid( o.getValue() ) )
{
receiver.postChange( this, diff, src );
@@ -222,47 +213,52 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
for( final T changedItem : input )
{
if (changedItem.isCraftable()) {
this.cachedList.add( changedItem.copy().setCraftable( true ) );
this.cachedList.add( changedItem );
}
else
{
this.cachedList.findPrecise( changedItem ).setCraftable( false );
T i = this.cachedList.findPrecise( changedItem );
if (i != null)
i.setCraftable( false );
}
}
}
protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src )
{
if( GLOBAL_DEPTH.contains( this ) )
src2MonitorsMap.putIfAbsent( src, new LinkedList<>() );
if( src2MonitorsMap.get( src ).contains( this ) )
{
nestingSources.add( src );
return;
}
GLOBAL_DEPTH.push( this );
src2MonitorsMap.get( src ).add( this );
this.sendEvent = true;
for( final T changedItem : changes )
for( final T change : changes )
{
if( !add && changedItem != null )
//T change = changed;
if( !add && change != null )
{
changedItem.setStackSize( -changedItem.getStackSize() );
//change = changed.copy();
change.setStackSize( -change.getStackSize() );
}
incGridCurrentCount( changedItem.getStackSize() );
this.cachedList.add( changedItem );
incGridCurrentCount( change.getStackSize() );
this.cachedList.addStorage( change );
if( this.myGridCache.getInterestManager().containsKey( changedItem ) )
if( this.myGridCache.getInterestManager().containsKey( change ) )
{
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( changedItem );
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( change );
if( !list.isEmpty() )
{
IAEStack<T> fullStack = this.getStorageList().findPrecise( changedItem );
IAEStack<T> fullStack = this.getStorageList().findPrecise( change );
if( fullStack == null )
{
fullStack = changedItem.copy();
fullStack = change.copy();
fullStack.setStackSize( 0 );
}
@@ -270,7 +266,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
for( final ItemWatcher iw : list )
{
iw.getHost().onStackChange( this.getStorageList(), fullStack, changedItem, src, this.getChannel() );
iw.getHost().onStackChange( this.getStorageList(), fullStack, change, src, this.getChannel() );
}
this.myGridCache.getInterestManager().disableTransactions();
@@ -280,17 +276,73 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
this.notifyListenersOfChange( changes, src );
final NetworkMonitor<?> last = GLOBAL_DEPTH.pop();
if( last != this )
if( src2MonitorsMap.get( src ).getFirst() == this )
{
throw new IllegalStateException( "Invalid Access to Networked Storage API detected." );
boolean nested = nestingSources.contains( src );
src2MonitorsMap.get( src ).forEach( networkMonitor -> networkMonitor.isNested = nested );
src2MonitorsMap.get( src ).forEach( networkMonitor -> {
if( networkMonitor.isNested != networkMonitor.wasNested )
{
networkMonitor.wasNested = networkMonitor.isNested;
networkMonitor.setForceUpdate( true );
}
} );
src2MonitorsMap.remove( src );
nestingSources.remove( src );
}
}
public void setForceUpdate( boolean forceUpdate )
{
this.forceUpdate = forceUpdate;
}
void forceUpdate()
{
this.forceUpdate = true;
forceUpdate = false;
this.cachedList.resetStatus();
this.getAvailableItems( this.cachedList );
long count = 0;
for( T stack : this.cachedList )
{
count += stack.getStackSize();
if( this.myGridCache.getInterestManager().containsKey( stack ) )
{
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( stack );
if( !list.isEmpty() )
{
IAEStack<T> fullStack = this.getStorageList().findPrecise( stack );
if( fullStack == null )
{
fullStack = stack.copy();
fullStack.setStackSize( 0 );
}
this.myGridCache.getInterestManager().enableTransactions();
for ( final ItemWatcher iw : list )
{
iw.getHost().onStackChange( this.getStorageList(), fullStack, stack, null, this.getChannel() );
}
this.myGridCache.getInterestManager().disableTransactions();
}
}
}
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount = count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount = count;
}
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
while ( i.hasNext() )
@@ -311,11 +363,14 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
void onTick()
{
if( forceUpdate )
{
forceUpdate();
}
if( this.sendEvent )
{
this.sendEvent = false;
this.myGridCache.getGrid().postEvent( new MENetworkStorageEvent( this, this.myChannel ) );
}
}
}
+56 -17
View File
@@ -19,7 +19,7 @@
package appeng.me.cache;
import java.util.HashMap;
import java.util.Collection;
import java.util.Random;
import com.google.common.collect.LinkedHashMultimap;
@@ -46,7 +46,7 @@ public class P2PCache implements IGridCache
private static final TunnelCollection<PartP2PTunnel> NULL_COLLECTION = new TunnelCollection<PartP2PTunnel>( null, null );
private final IGrid myGrid;
private final HashMap<Short, PartP2PTunnel> inputs = new HashMap<>();
private final Multimap<Short, PartP2PTunnel> inputs = LinkedHashMultimap.create();
private final Multimap<Short, PartP2PTunnel> outputs = LinkedHashMultimap.create();
private final Random frequencyGenerator;
@@ -110,10 +110,19 @@ public class P2PCache implements IGridCache
}
else
{
this.inputs.remove( t.getFrequency() );
this.inputs.remove( t.getFrequency(), t );
}
this.updateTunnel( t.getFrequency(), !t.isOutput(), false );
if( this.inputs.get( t.getFrequency() ).isEmpty() )
{
this.inputs.removeAll( t.getFrequency() );
}
if( this.outputs.get( t.getFrequency() ).isEmpty() )
{
this.outputs.removeAll( t.getFrequency() );
}
this.updateTunnel( t.getFrequency(), t.isOutput(), false );
}
}
@@ -142,7 +151,7 @@ public class P2PCache implements IGridCache
this.inputs.put( t.getFrequency(), t );
}
this.updateTunnel( t.getFrequency(), !t.isOutput(), false );
this.updateTunnel( t.getFrequency(), t.isOutput(), false );
}
}
@@ -164,6 +173,20 @@ public class P2PCache implements IGridCache
}
public void removeTunnel( final PartP2PTunnel t, short freq )
{
this.outputs.remove( freq, t );
this.inputs.remove( freq, t );
if( this.inputs.get( t.getFrequency() ).isEmpty() )
{
this.inputs.removeAll( t.getFrequency() );
}
if( this.outputs.get( t.getFrequency() ).isEmpty() )
{
this.outputs.removeAll( t.getFrequency() );
}
}
private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange )
{
for( final PartP2PTunnel p : this.outputs.get( freq ) )
@@ -175,8 +198,7 @@ public class P2PCache implements IGridCache
p.onTunnelNetworkChange();
}
final PartP2PTunnel in = this.inputs.get( freq );
if( in != null )
for( final PartP2PTunnel in : this.inputs.get( freq ) )
{
if( configChange )
{
@@ -195,7 +217,7 @@ public class P2PCache implements IGridCache
if( this.inputs.containsValue( t ) )
{
this.inputs.remove( t.getFrequency() );
this.inputs.remove( t.getFrequency(), t );
}
t.setFrequency( newFrequency );
@@ -211,7 +233,6 @@ public class P2PCache implements IGridCache
// AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq );
this.updateTunnel( t.getFrequency(), t.isOutput(), true );
this.updateTunnel( t.getFrequency(), !t.isOutput(), true );
}
public short newFrequency()
@@ -236,25 +257,43 @@ public class P2PCache implements IGridCache
public TunnelCollection<PartP2PTunnel> getOutputs( final short freq, final Class<? extends PartP2PTunnel> c )
{
final PartP2PTunnel in = this.inputs.get( freq );
Collection<PartP2PTunnel> in = this.inputs.get( freq );
if( in == null )
{
return NULL_COLLECTION;
}
final TunnelCollection<PartP2PTunnel> out = this.inputs.get( freq ).getCollection( this.outputs.get( freq ), c );
TunnelCollection<PartP2PTunnel> out;
for( PartP2PTunnel part : this.inputs.get( freq ) )
{
out = part.getCollection( this.outputs.get( freq ), c );
if( out != null )
{
return out;
}
}
return NULL_COLLECTION;
}
public TunnelCollection<PartP2PTunnel> getInputs( final short freq, final Class<? extends PartP2PTunnel> c )
{
Collection<PartP2PTunnel> out = this.outputs.get( freq );
if( out == null )
{
return NULL_COLLECTION;
}
return out;
}
public PartP2PTunnel getInput( final short freq )
{
return this.inputs.get( freq );
TunnelCollection<PartP2PTunnel> in;
for( PartP2PTunnel part : this.outputs.get( freq ) )
{
in = part.getCollection( this.inputs.get( freq ), c );
if( in != null )
{
return in;
}
}
return NULL_COLLECTION;
}
}
@@ -19,21 +19,6 @@
package appeng.me.cluster.implementations;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import appeng.api.config.Upgrades;
import appeng.helpers.DualityInterface;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.FuzzyMode;
@@ -42,14 +27,7 @@ import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.CraftingItemList;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingJob;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingMedium;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingRequester;
import appeng.api.networking.crafting.*;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.events.MENetworkCraftingCpuChange;
import appeng.api.networking.security.IActionSource;
@@ -62,11 +40,8 @@ import appeng.api.storage.data.IItemList;
import appeng.api.util.WorldCoord;
import appeng.container.ContainerNull;
import appeng.core.AELog;
import appeng.crafting.CraftBranchFailure;
import appeng.crafting.CraftingJob;
import appeng.crafting.CraftingLink;
import appeng.crafting.CraftingWatcher;
import appeng.crafting.MECraftingInventory;
import appeng.crafting.*;
import appeng.helpers.PatternHelper;
import appeng.me.cache.CraftingGridCache;
import appeng.me.cluster.IAECluster;
import appeng.me.helpers.MachineSource;
@@ -74,6 +49,17 @@ import appeng.tile.crafting.TileCraftingMonitorTile;
import appeng.tile.crafting.TileCraftingTile;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
@@ -101,6 +87,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
private IAEItemStack finalOutput;
private boolean waiting = false;
private IItemList<IAEItemStack> waitingFor = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private IItemList<IAEItemStack> neededForLoop = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private long availableStorage = 0;
private MachineSource machineSrc = null;
private int accelerator = 0;
@@ -223,13 +210,10 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
public boolean canAccept( final IAEItemStack input )
{
if( input instanceof IAEItemStack )
if( input != null )
{
final IAEItemStack is = this.waitingFor.findPrecise( input );
if( is != null && is.getStackSize() > 0 )
{
return true;
}
return is != null && is.getStackSize() > 0;
}
return false;
}
@@ -238,7 +222,8 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
// also stop accepting items when the job is complete, i.e. to prevent re-insertion when pushing out
// items during storeItems
if (input == null || isComplete) {
if( input == null || isComplete )
{
return input;
}
@@ -302,9 +287,28 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
if( this.finalOutput.equals( what ) )
{
IAEItemStack isLoop = neededForLoop.findPrecise( finalOutput );
IAEItemStack leftover = what;
this.finalOutput.decStackSize( what.getStackSize() );
if( isLoop != null && isLoop.getStackSize() > 0 )
{
if( isLoop.getStackSize() >= what.getStackSize() )
{
leftover = this.inventory.injectItems( what.copy(), type, src );
isLoop.decStackSize( what.getStackSize() );
}
else
{
leftover = this.inventory.injectItems( what.copy().setStackSize( what.getStackSize() - isLoop.getStackSize() ), type, src );
isLoop.decStackSize( what.getStackSize() - isLoop.getStackSize() );
}
if( leftover == null )
{
return null;
}
}
this.finalOutput.decStackSize( leftover.getStackSize() );
if( this.myLastLink != null )
{
@@ -334,9 +338,28 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
if( this.finalOutput.equals( insert ) )
{
IAEItemStack isLoop = neededForLoop.findPrecise( finalOutput );
IAEItemStack leftover = input;
this.finalOutput.decStackSize( insert.getStackSize() );
if( isLoop != null && isLoop.getStackSize() > 0 )
{
if( isLoop.getStackSize() >= insert.getStackSize() )
{
leftover = this.inventory.injectItems( insert.copy(), type, src );
isLoop.decStackSize( insert.getStackSize() );
}
else
{
leftover = this.inventory.injectItems( insert.copy().setStackSize( insert.getStackSize() - isLoop.getStackSize() ), type, src );
isLoop.decStackSize( insert.getStackSize() - isLoop.getStackSize() );
}
if( leftover == null )
{
return null;
}
}
this.finalOutput.decStackSize( leftover.getStackSize() );
if( this.myLastLink != null )
{
@@ -374,7 +397,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
final ImmutableList<IAEItemStack> single = ImmutableList.of( diff.copy() );
while( i.hasNext() )
while ( i.hasNext() )
{
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> o = i.next();
final IMEMonitorHandlerReceiver<IAEItemStack> receiver = o.getKey();
@@ -494,15 +517,14 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
return null;
}
private boolean canCraft(final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs)
private boolean canCraft( final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs )
{
if( !details.isCraftable() )
{
// Processing patterns are relatively easy
for ( IAEItemStack input : condensedInputs )
for( IAEItemStack input : condensedInputs )
{
final IAEItemStack ais = this.inventory.extractItems( input.copy(), Actionable.SIMULATE,
this.machineSrc );
final IAEItemStack ais = this.inventory.extractItems( input.copy(), Actionable.SIMULATE, this.machineSrc );
if( ais == null || ais.getStackSize() < input.getStackSize() )
{
@@ -515,7 +537,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
// When substitutions are allowed, we have to keep track of which items we've reserved
IAEItemStack[] inputs = details.getInputs();
Map<IAEItemStack, Integer> consumedCount = new HashMap<>();
for ( int i = 0; i < inputs.length; i++ )
for( int i = 0; i < inputs.length; i++ )
{
List<IAEItemStack> substitutes = details.getSubstituteInputs( i );
if( substitutes.isEmpty() )
@@ -524,9 +546,9 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
}
boolean found = false;
for ( IAEItemStack substitute : substitutes )
for( IAEItemStack substitute : substitutes )
{
for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( substitute, FuzzyMode.IGNORE_ALL ) )
for( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( substitute, FuzzyMode.IGNORE_ALL ) )
{
int alreadyConsumed = consumedCount.getOrDefault( fuzz, 0 );
if( fuzz.getStackSize() - alreadyConsumed <= 0 )
@@ -536,8 +558,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
fuzz = fuzz.copy();
fuzz.setStackSize( 1 ); // We're iterating over non condensed inputs which means there's 1 of each needed
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE,
this.machineSrc );
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE, this.machineSrc );
if( ais != null && ais.getStackSize() > 0 )
{
@@ -564,11 +585,11 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
// When no substitutions can occur, we can simply check that all items are accounted since
// each type of item should only occur once
for ( IAEItemStack g : condensedInputs )
for( IAEItemStack g : condensedInputs )
{
boolean found = false;
for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL ) )
for( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL ) )
{
fuzz = fuzz.copy();
fuzz.setStackSize( g.getStackSize() );
@@ -674,8 +695,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
this.somethingChanged = false;
this.executeCrafting( eg, cc );
}
while( this.somethingChanged && this.remainingOperations > 0 );
} while ( this.somethingChanged && this.remainingOperations > 0 );
}
this.usedOps[2] = this.usedOps[1];
this.usedOps[1] = this.usedOps[0];
@@ -691,7 +711,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
final Iterator<Entry<ICraftingPatternDetails, TaskProgress>> i = this.tasks.entrySet().iterator();
while( i.hasNext() )
while ( i.hasNext() )
{
final Entry<ICraftingPatternDetails, TaskProgress> e = i.next();
@@ -707,12 +727,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
InventoryCrafting ic = null;
if (!visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty())
if( !visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty() )
{
visitedMediums.put( details, new ArrayDeque<>( cc.getMediums( details ).stream().filter( Objects::nonNull ).collect( Collectors.toList()) ) );
visitedMediums.put( details, new ArrayDeque<>( cc.getMediums( details ).stream().filter( Objects::nonNull ).collect( Collectors.toList() ) ) );
}
while (!visitedMediums.get( details ).isEmpty())
while ( !visitedMediums.get( details ).isEmpty() )
{
ICraftingMedium m = visitedMediums.get( details ).poll();
@@ -742,71 +762,88 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
continue;
}
if( details.isCraftable() )
{
ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
}
else
{
ic = new InventoryCrafting( new ContainerNull(), PatternHelper.PROCESSING_INPUT_WIDTH, PatternHelper.PROCESSING_INPUT_HEIGHT );
}
ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
boolean found = false;
for (int x = 0; x < input.length; x++) {
if (input[x] != null) {
for( int x = 0; x < input.length; x++ )
{
if( input[x] != null )
{
found = false;
if (details.isCraftable()) {
if( details.isCraftable() )
{
final Collection<IAEItemStack> itemList;
if (details.canSubstitute()) {
final List<IAEItemStack> substitutes = details.getSubstituteInputs(x);
itemList = new ArrayList<>(substitutes.size());
if( details.canSubstitute() )
{
final List<IAEItemStack> substitutes = details.getSubstituteInputs( x );
itemList = new ArrayList<>( substitutes.size() );
for (IAEItemStack stack : substitutes) {
itemList.addAll(this.inventory.getItemList().findFuzzy(stack,
FuzzyMode.IGNORE_ALL));
for( IAEItemStack stack : substitutes )
{
itemList.addAll( this.inventory.getItemList().findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
}
} else {
itemList = new ArrayList<>(1);
}
else
{
itemList = new ArrayList<>( 1 );
final IAEItemStack item = this.inventory.getItemList()
.findPrecise(input[x]);
final IAEItemStack item = this.inventory.getItemList().findPrecise( input[x] );
if (item != null) {
itemList.add(item);
if( item != null )
{
itemList.add( item );
}
}
for (IAEItemStack fuzz : itemList) {
for( IAEItemStack fuzz : itemList )
{
fuzz = fuzz.copy();
fuzz.setStackSize(input[x].getStackSize());
fuzz.setStackSize( input[x].getStackSize() );
if (details.isValidItemForSlot(x, fuzz.createItemStack(),
this.getWorld())) {
final IAEItemStack ais = this.inventory.extractItems(fuzz,
Actionable.MODULATE, this.machineSrc);
final ItemStack is = ais == null ? ItemStack.EMPTY
: ais.createItemStack();
if( details.isValidItemForSlot( x, fuzz.createItemStack(), this.getWorld() ) )
{
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.MODULATE, this.machineSrc );
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
if (!is.isEmpty()) {
this.postChange(AEItemStack.fromItemStack(is), this.machineSrc);
ic.setInventorySlotContents(x, is);
if( !is.isEmpty() )
{
this.postChange( AEItemStack.fromItemStack( is ), this.machineSrc );
ic.setInventorySlotContents( x, is );
found = true;
break;
}
}
}
} else {
final IAEItemStack ais = this.inventory.extractItems(input[x].copy(),
Actionable.MODULATE, this.machineSrc);
}
else
{
final IAEItemStack ais = this.inventory.extractItems( input[x].copy(), Actionable.MODULATE, this.machineSrc );
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
if (!is.isEmpty()) {
this.postChange(input[x], this.machineSrc);
ic.setInventorySlotContents(x, is);
if (is.getCount() == input[x].getStackSize()) {
if( !is.isEmpty() )
{
this.postChange( input[x], this.machineSrc );
ic.setInventorySlotContents( x, is );
if( is.getCount() == input[x].getStackSize() )
{
found = true;
continue;
}
}
}
if (!found) {
if( !found )
{
break;
}
}
@@ -890,7 +927,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
private void storeItems()
{
Preconditions.checkState(isComplete, "CPU should be complete to prevent re-insertion when dumping items");
Preconditions.checkState( isComplete, "CPU should be complete to prevent re-insertion when dumping items" );
final IGrid g = this.getGrid();
if( g == null )
@@ -950,10 +987,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
try
{
this.waitingFor.resetStatus();
this.neededForLoop.resetStatus();
( (CraftingJob) job ).getTree().setJob( ci, this, src );
if( ci.commit( src ) )
{
this.finalOutput = job.getOutput();
this.neededForLoop = ( (CraftingJob) job ).getNeededForLoop();
this.waiting = false;
this.isComplete = false;
this.markDirty();
@@ -1004,8 +1043,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
public boolean isBusy()
{
this.tasks.entrySet().removeIf(
taskProgressEntry -> taskProgressEntry.getValue().value <= 0 );
this.tasks.entrySet().removeIf( taskProgressEntry -> taskProgressEntry.getValue().value <= 0 );
if( !this.waitingFor.isEmpty() || !this.tasks.isEmpty() )
{
@@ -1063,8 +1101,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
final int hash = System.identityHashCode( this );
final int hmm = this.finalOutput == null ? 0 : this.finalOutput.hashCode();
return Long.toString( now, Character.MAX_RADIX ) + '-' + Integer.toString( hash, Character.MAX_RADIX ) + '-' + Integer.toString( hmm,
Character.MAX_RADIX );
return Long.toString( now, Character.MAX_RADIX ) + '-' + Integer.toString( hash, Character.MAX_RADIX ) + '-' + Integer.toString( hmm, Character.MAX_RADIX );
}
private NBTTagCompound generateLinkData( final String craftingID, final boolean standalone, final boolean req )
@@ -1091,7 +1128,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
public void getListOfItem( final IItemList<IAEItemStack> list, final CraftingItemList whichList )
{
switch( whichList )
switch ( whichList )
{
case ACTIVE:
for( final IAEItemStack ais : this.waitingFor )
@@ -1162,7 +1199,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{
IAEItemStack is;
switch( storage2 )
switch ( storage2 )
{
case STORAGE:
is = this.inventory.getItemList().findPrecise( what );
@@ -23,11 +23,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import appeng.api.config.FuzzyMode;
import appeng.api.storage.data.IAEStack;
import appeng.util.item.AEItemStack;
import com.google.common.collect.Multimap;
import appeng.api.storage.data.IAEStack;
public class GenericInterestManager<T>
{
@@ -102,30 +101,12 @@ public class GenericInterestManager<T>
public boolean containsKey( final IAEStack stack )
{
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
{
return this.container.keySet().stream().filter( s -> s.isItem() )
.anyMatch( s -> s.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) );
}
return this.container.containsKey( stack );
}
public Collection<T> get( final IAEStack stack )
{
Collection<T> watchers = new ArrayList<>();
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
{
this.container.keySet().stream().filter( s -> s.isItem() )
.filter( k -> k.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
.forEach( key ->
watchers.addAll( this.container.get( key ) )
);
}
else
{
return this.container.get( stack );
}
return watchers;
return this.container.get( stack );
}
private class SavedTransactions
@@ -142,4 +123,4 @@ public class GenericInterestManager<T>
this.iw = watcher;
}
}
}
}
@@ -28,8 +28,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableList;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.IActionSource;
@@ -85,11 +83,7 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
@Override
public T injectItems( final T input, final Actionable mode, final IActionSource src )
{
if( mode == Actionable.SIMULATE )
{
return this.getHandler().injectItems( input, mode, src );
}
return this.monitorDifference( input.copy(), this.getHandler().injectItems( input, mode, src ), false, src );
return this.getHandler().injectItems( input, mode, src );
}
protected IMEInventoryHandler<T> getHandler()
@@ -97,28 +91,7 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
return this.internalHandler;
}
private T monitorDifference( final T original, final T leftOvers, final boolean extraction, final IActionSource src )
{
final T diff = original.copy();
if( extraction )
{
diff.setStackSize( leftOvers == null ? 0 : -leftOvers.getStackSize() );
}
else if( leftOvers != null )
{
diff.decStackSize( leftOvers.getStackSize() );
}
if( diff.getStackSize() != 0 )
{
this.postChangesToListeners( ImmutableList.of( diff ), src );
}
return leftOvers;
}
protected void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
public void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
{
this.notifyListenersOfChange( changes, src );
}
@@ -150,11 +123,7 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
@Override
public T extractItems( final T request, final Actionable mode, final IActionSource src )
{
if( mode == Actionable.SIMULATE )
{
return this.getHandler().extractItems( request, mode, src );
}
return this.monitorDifference( request.copy(), this.getHandler().extractItems( request, mode, src ), true, src );
return this.getHandler().extractItems( request, mode, src );
}
@Override
@@ -19,6 +19,7 @@
package appeng.me.helpers;
import java.util.Objects;
import java.util.Optional;
import net.minecraft.entity.player.EntityPlayer;
@@ -55,4 +56,24 @@ public class MachineSource implements IActionSource
return Optional.empty();
}
@Override
public boolean equals( Object o )
{
if( this == o )
{
return true;
}
if( o == null || getClass() != o.getClass() )
{
return false;
}
MachineSource that = (MachineSource) o;
return via.equals( that.via );
}
@Override
public int hashCode()
{
return Objects.hash( via );
}
}
@@ -19,19 +19,20 @@
package appeng.me.storage;
import appeng.core.features.registries.cell.CreativeCellHandler;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.tile.storage.TileDrive;
import com.google.common.collect.ImmutableList;
import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.networking.security.IActionSource;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.data.IAEStack;
import java.util.Collections;
public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{
@@ -39,16 +40,16 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
private int oldStatus = 0;
private final ItemStack is;
private final ICellHandler handler;
private final IChestOrDrive cord;
private final TileDrive drive;
private IActionSource source;
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final IChestOrDrive cod )
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final TileDrive drive )
{
super( i, i.getChannel() );
this.is = is;
this.handler = han;
this.cord = cod;
this.source = new MachineSource( cod );
this.drive = drive;
this.source = new MachineSource( drive );
}
public int getStatus()
@@ -61,55 +62,58 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{
final long size = input.getStackSize();
final T a = super.injectItems( input, type, src );
final T remainder = super.injectItems( input, type, src );
if( type == Actionable.MODULATE && ( a == null || a.getStackSize() != size ) )
if( type == Actionable.MODULATE && ( remainder == null || remainder.getStackSize() != size ) )
{
final int newStatus = this.getStatus();
if( newStatus != this.oldStatus )
{
this.cord.blinkCell( this.getSlot() );
this.drive.blinkCell( this.getSlot() );
this.oldStatus = newStatus;
}
try
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler))
{
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( input.copy().setStackSize( input.getStackSize() - ( a == null ? 0 : a.getStackSize() ) ) ), this.source );
}
catch( GridAccessException e )
{
e.printStackTrace();
try
{
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( remainder == null ? 0 : remainder.getStackSize() ) ) ), this.source );
} catch ( GridAccessException e )
{
e.printStackTrace();
}
}
}
return a;
return remainder;
}
@Override
public T extractItems( final T request, final Actionable type, final IActionSource src )
{
final T a = super.extractItems( request, type, src );
final T extractable = super.extractItems( request, type, src );
if( type == Actionable.MODULATE && a != null )
if( type == Actionable.MODULATE && extractable != null )
{
final int newStatus = this.getStatus();
if( newStatus != this.oldStatus )
{
this.cord.blinkCell( this.getSlot() );
this.drive.blinkCell( this.getSlot() );
this.oldStatus = newStatus;
}
try
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler ))
{
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( request.copy().setStackSize( -a.getStackSize() ) ), this.source );
}
catch( GridAccessException e )
{
e.printStackTrace();
try
{
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), this.source );
} catch ( GridAccessException e )
{
e.printStackTrace();
}
}
}
return a;
return extractable;
}
}
@@ -19,14 +19,11 @@
package appeng.me.storage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.*;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import appeng.fluids.util.AEFluidStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
@@ -48,16 +45,14 @@ import appeng.api.storage.data.IItemList;
public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor
{
private final IFluidHandler handler;
private final IItemList<IAEFluidStack> list = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
private IItemList<IAEFluidStack> cache = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedFluidStack> memory;
private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIFluidHandler( final IFluidHandler handler )
{
this.handler = handler;
this.memory = new ConcurrentSkipListMap<>();
}
@Override
@@ -82,11 +77,6 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return input.copy();
}
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( filled == input.getStackSize() )
{
return null;
@@ -94,6 +84,15 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
final IAEFluidStack o = input.copy();
o.setStackSize( input.getStackSize() - filled );
if( type == Actionable.MODULATE )
{
IAEFluidStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o;
}
@@ -107,13 +106,18 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return null;
}
if( type == Actionable.MODULATE )
{
this.onTick();
}
final IAEFluidStack o = request.copy();
o.setStackSize( removed.amount );
if( type == Actionable.MODULATE )
{
IAEFluidStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
}
return o;
}
@@ -126,111 +130,51 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public TickRateModulation onTick()
{
final List<IAEFluidStack> changes = new ArrayList<>();
this.list.resetStatus();
int high = 0;
boolean changed = false;
final IFluidTankProperties[] props = this.handler.getTankProperties();
for( int slot = 0; slot < this.handler.getTankProperties().length; ++slot )
final List<IAEFluidStack> changes = new ArrayList<>();
final IFluidTankProperties[] tankProperties = this.handler.getTankProperties();
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
for( IFluidTankProperties tankProperty : tankProperties )
{
final CachedFluidStack old = this.memory.get( slot );
high = Math.max( high, slot );
final FluidStack newIS = !props[slot].canDrain() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? null : props[slot].getContents();
final FluidStack oldIS = old == null ? null : old.fluidStack;
if( isDifferent( newIS, oldIS ) )
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.handler.drain( 1, false ) == null )
{
final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
continue;
}
else
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
}
for( final IAEFluidStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEFluidStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEFluidStack is : cache )
{
if( is.getStackSize() != 0 )
{
final int newSize = newIS == null ? 0 : newIS.amount;
final int diff = newSize - ( oldIS == null ? 0 : oldIS.amount );
IAEFluidStack stack = null;
if( newIS != null )
{
stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IFluidStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
}
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
final IAEFluidStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
changes.add( is );
}
}
// detect dropped items; should fix non IISided Inventory Changes.
final NavigableMap<Integer, CachedFluidStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedFluidStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEFluidStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
cache = currentlyOnStorage;
if( !changes.isEmpty() )
{
this.postDifference( changes );
changed = true;
}
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private static boolean isDifferent( FluidStack a, FluidStack b )
{
if( a == b )
{
return false;
}
if( a == null || b == null )
{
return true;
}
return !a.getFluid().equals( b.getFluid() );
}
private void postDifference( final Iterable<IAEFluidStack> a )
{
if( a != null )
@@ -291,9 +235,9 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public IItemList<IAEFluidStack> getAvailableItems( final IItemList out )
{
for( final CachedFluidStack is : this.memory.values() )
for( final IAEFluidStack fs : cache )
{
out.addStorage( is.aeStack );
out.addStorage( fs );
}
return out;
@@ -302,7 +246,7 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public IItemList<IAEFluidStack> getStorageList()
{
return this.list;
return this.cache;
}
private StorageFilter getMode()
@@ -326,24 +270,4 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
this.mySource = mySource;
}
private static class CachedFluidStack
{
private final FluidStack fluidStack;
private final IAEFluidStack aeStack;
CachedFluidStack( final FluidStack is )
{
if( is == null )
{
this.fluidStack = null;
this.aeStack = null;
}
else
{
this.fluidStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createStack( is );
}
}
}
}
@@ -19,12 +19,8 @@
package appeng.me.storage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.*;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import net.minecraft.item.ItemStack;
@@ -50,16 +46,15 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
{
private final InventoryAdaptor adaptor;
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private IItemList<IAEItemStack> cache = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedItemStack> memory;
private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIInventory( final InventoryAdaptor adaptor )
{
this.adaptor = adaptor;
this.memory = new ConcurrentSkipListMap<>();
}
@Override
@@ -88,11 +83,6 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
out = this.adaptor.addItems( input.createItemStack() );
}
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( out.isEmpty() )
{
return null;
@@ -101,6 +91,15 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
// better then doing construction from scratch :3
final IAEItemStack o = input.copy();
o.setStackSize( out.getCount() );
if( type == Actionable.MODULATE )
{
IAEItemStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o;
}
@@ -129,6 +128,12 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
if( type == Actionable.MODULATE )
{
IAEItemStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
this.onTick();
}
@@ -144,110 +149,52 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public TickRateModulation onTick()
{
boolean changed = false;
final List<IAEItemStack> changes = new ArrayList<>();
this.list.resetStatus();
int high = 0;
boolean changed = false;
for( final ItemSlot is : this.adaptor )
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
for( final ItemSlot is : adaptor )
{
final CachedItemStack old = this.memory.get( is.getSlot() );
high = Math.max( high, is.getSlot() );
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
final ItemStack oldIS = old == null ? ItemStack.EMPTY : old.itemStack;
if( this.isDifferent( newIS, oldIS ) )
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
{
final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
continue;
}
else
currentlyOnStorage.add( is.getAEItemStack() );
}
for( final IAEItemStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEItemStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEItemStack is : cache )
{
if( is.getStackSize() != 0 )
{
final int newSize = ( newIS.isEmpty() ? 0 : newIS.getCount() );
final int diff = newSize - ( oldIS.isEmpty() ? 0 : oldIS.getCount() );
final IAEItemStack stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IItemStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
final IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
changes.add( is );
}
}
// detect dropped items; should fix non IISided Inventory Changes.
final NavigableMap<Integer, CachedItemStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedItemStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEItemStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
cache = currentlyOnStorage;
if( !changes.isEmpty() )
{
this.postDifference( changes );
changed = true;
}
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private boolean isDifferent( final ItemStack a, final ItemStack b )
{
if( a == b && b.isEmpty() )
{
return false;
}
if( ( a.isEmpty() && !b.isEmpty() ) || ( !a.isEmpty() && b.isEmpty() ) )
{
return true;
}
return !Platform.itemComparisons().isSameItem( a, b );
}
private void postDifference( final Iterable<IAEItemStack> a )
{
// AELog.info( a.getItemStack().getUnlocalizedName() + " @ " + a.getStackSize() );
if( a != null )
{
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
@@ -306,9 +253,9 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
{
for( final CachedItemStack is : this.memory.values() )
for( IAEItemStack is : cache )
{
out.addStorage( is.aeStack );
out.addStorage( is );
}
return out;
@@ -317,7 +264,7 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public IItemList<IAEItemStack> getStorageList()
{
return this.list;
return this.cache;
}
private StorageFilter getMode()
@@ -341,24 +288,4 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
this.mySource = mySource;
}
private static class CachedItemStack
{
private final ItemStack itemStack;
private final IAEItemStack aeStack;
public CachedItemStack( final ItemStack is )
{
if( is.isEmpty() )
{
this.itemStack = ItemStack.EMPTY;
this.aeStack = null;
}
else
{
this.itemStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
}
}
}
}
@@ -171,4 +171,5 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
{
this.changeSource = changeSource;
}
}
@@ -19,6 +19,8 @@
package appeng.me.storage;
import appeng.me.helpers.MEMonitorHandler;
import appeng.me.helpers.MachineSource;
import com.mojang.authlib.GameProfile;
import appeng.api.AEApi;
@@ -35,16 +37,20 @@ import appeng.api.storage.data.IItemList;
import appeng.me.GridAccessException;
import appeng.tile.misc.TileSecurityStation;
import java.util.Collections;
public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStack>
{
private final IItemList<IAEItemStack> storedItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final TileSecurityStation securityTile;
private final MachineSource src;
public SecurityStationInventory( final TileSecurityStation ts )
{
this.securityTile = ts;
this.src = new MachineSource( securityTile );
}
@Override
@@ -61,6 +67,11 @@ public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStac
return null;
}
if( securityTile.getProxy().isActive() )
{
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( input.copy() ), this.src );
}
this.getStoredItems().add( input );
this.securityTile.inventoryChanged();
return null;
@@ -101,6 +112,11 @@ public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStac
return output;
}
if( securityTile.getProxy().isActive() )
{
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( target.copy().setStackSize( -target.getStackSize() ) ), this.src );
}
target.setStackSize( 0 );
this.securityTile.inventoryChanged();
return output;
@@ -27,6 +27,7 @@ import net.minecraft.item.ItemStack;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
@@ -59,6 +60,12 @@ public abstract class PartBasicState extends AEBasePart implements IPowerChannel
this.getHost().markForUpdate();
}
@MENetworkEventSubscribe
public void bootingRender( final MENetworkBootingStatusChange bs )
{
this.getHost().markForUpdate();
}
@Override
public void writeToStream( final ByteBuf data ) throws IOException
{
@@ -22,6 +22,7 @@ package appeng.parts.automation;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -70,8 +71,6 @@ import appeng.util.item.AEItemStack;
public class PartExportBus extends PartSharedItemBus implements ICraftingRequester
{
private final int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/export_bus_base" );
@PartModels
@@ -131,10 +130,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
try
{
final InventoryAdaptor destination = this.getHandler();
final IMEMonitor<IAEItemStack> inv = this.getProxy()
.getStorage()
.getInventory(
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
final IMEMonitor<IAEItemStack> inv = this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
final IEnergyGrid energy = this.getProxy().getEnergy();
final ICraftingGrid cg = this.getProxy().getCrafting();
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
@@ -150,21 +146,17 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
final IAEItemStack ais = this.getConfig().getAEStackInSlot( slotToExport );
if( ais == null || this.itemToSend <= 0 ) continue;
if ( this.craftOnly() ) {
if (this.failedCraftTriesSlot[x] <= 0) {
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
else this.failedCraftTriesSlot[x] += 2;
}
this.failedCraftTriesSlot[x] -= 1;
if( ais == null || this.itemToSend <= 0 )
{
continue;
}
if( this.craftOnly() )
{
this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething;
}
final long before = this.itemToSend;
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
@@ -188,15 +180,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( this.itemToSend == before && this.isCraftingEnabled() )
{
if (this.failedCraftTriesSlot[x] <= 0) {
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
else this.failedCraftTriesSlot[x] += 2;
}
this.failedCraftTriesSlot[x] -= 1;
this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething;
}
}
@@ -278,11 +262,30 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( energy.extractAEPower( power, mode, PowerMultiplier.CONFIG ) > power - 0.01 )
{
if( mode == Actionable.MODULATE )
ItemStack inputStack = items.getCachedItemStack( items.getStackSize() );
ItemStack remaining;
if( mode == Actionable.SIMULATE )
{
return AEItemStack.fromItemStack( d.addItems( items.createItemStack() ) );
remaining = d.simulateAdd( inputStack );
items.setCachedItemStack( inputStack );
}
return AEItemStack.fromItemStack( d.simulateAdd( items.createItemStack() ) );
else
{
remaining = d.addItems( inputStack );
if( !remaining.isEmpty() )
{
items.setCachedItemStack( remaining );
}
}
if( remaining == inputStack )
{
return items;
}
return AEItemStack.fromItemStack( remaining );
}
}
}
@@ -318,11 +321,21 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
private void pushItemIntoTarget( final InventoryAdaptor d, final IEnergyGrid energy, final IMEInventory<IAEItemStack> inv, IAEItemStack ais )
{
final ItemStack is = ais.createItemStack();
is.setCount( (int) this.itemToSend );
ItemStack inputStack = ais.getCachedItemStack( ais.getStackSize() );
final ItemStack o = d.simulateAdd( is );
final long canFit = o.isEmpty() ? this.itemToSend : this.itemToSend - o.getCount();
ItemStack remaining = d.simulateAdd( inputStack );
// Store the stack in the cache for next time.
if( !remaining.isEmpty() )
{
ais.setCachedItemStack( remaining );
if( remaining == inputStack )
{
return;
}
}
final long canFit = remaining.isEmpty() ? this.itemToSend : this.itemToSend - remaining.getCount();
if( canFit > 0 )
{
@@ -334,7 +347,9 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
{
this.itemToSend -= itemsToAdd.getStackSize();
final ItemStack failed = d.addItems( itemsToAdd.createItemStack() );
inputStack.setCount( Ints.saturatedCast( itemsToAdd.getStackSize() ) );
final ItemStack failed = d.addItems( inputStack );
if( !failed.isEmpty() )
{
ais.setStackSize( failed.getCount() );
@@ -187,8 +187,9 @@ public class PartFormationPlane extends PartAbstractFormationPlane<IAEItemStack>
this.stateChanged();
}
@Override
@MENetworkEventSubscribe
public void updateChannels( final MENetworkChannelsChanged changedChannels )
public void chanRender( final MENetworkChannelsChanged changedChannels )
{
this.stateChanged();
}
@@ -184,8 +184,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
return flipState ? this.reportingValue >= this.lastReportedValue + 1 : this.reportingValue < this.lastReportedValue + 1;
}
@Override
@MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange powerEvent )
public void powerRender( final MENetworkPowerStatusChange powerEvent )
{
if (this.getProxy().isActive())
{
@@ -194,8 +195,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
this.updateState();
}
@Override
@MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c )
public void chanRender( final MENetworkChannelsChanged c )
{
if (this.getProxy().isActive())
{
@@ -288,37 +290,24 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
try
{
if( myStack == null )
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 || myStack == null )
{
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).addListener( this, this.getProxy().getGrid() );
this.getProxy()
.getStorage()
.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
.addListener( this,
this.getProxy().getGrid() );
}
else
{
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).removeListener( this );
if( this.myWatcher != null )
{
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
Optional<OreReference> ores = OreHelper.INSTANCE.getOre( myStack.getDefinition() );
if( ores.isPresent() )
{
for( IAEItemStack iaeItemStack : ores.get().getAEEquivalents() )
{
this.myWatcher.add( iaeItemStack );
}
}
else
{
this.myWatcher.add( myStack );
}
}
else
{
this.myWatcher.add( myStack );
}
this.myWatcher.add( myStack );
}
}
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
catch( final GridAccessException e )
@@ -363,23 +352,11 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
}
@Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
public void onStackChange( final IItemList o, final IAEStack fullStack, final IAEStack diffStack, final IActionSource src, final IStorageChannel chan )
{
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this.getInstalledUpgrades( Upgrades.FUZZY ) == 0 )
{
IAEItemStack myStack = this.config.getAEStackInSlot( 0 );
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
if( Platform.itemComparisons().isFuzzyEqualItem( myStack.getDefinition(), ( (IAEItemStack) diffStack ).getDefinition(), fzMode ) )
{
this.lastReportedValue += diffStack.getStackSize();
}
}
else if( diffStack.equals( myStack ) )
{
this.lastReportedValue += diffStack.getStackSize();
}
this.lastReportedValue = fullStack.getStackSize();
this.updateState();
}
}
@@ -507,6 +484,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
public void upgradesChanged()
{
this.configureWatchers();
this.updateState();
}
@Override
@@ -19,7 +19,6 @@
package appeng.parts.misc;
import javax.annotation.Nullable;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
@@ -62,8 +61,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private StorageFilter mode;
private AccessRestriction access;
private ItemStack stackCache = null;
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
{
this.itemHandler = itemHandler;
@@ -82,39 +79,31 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{
// Try to reuse the cached stack
@Nullable ItemStack currentCached = stackCache;
stackCache = null;
ItemStack inputStack = iox.getCachedItemStack( iox.getStackSize() );
ItemStack remaining = inputStack;
ItemStack orgInput;
int slotCount = this.itemHandler.getSlots();
if( currentCached != null && iox.isSameType( currentCached ) )
{
// Cache is suitable, just update the count
orgInput = currentCached;
currentCached.setCount( Ints.saturatedCast( iox.getStackSize() ) );
}
else
{
// We need a new stack :-(
orgInput = iox.createItemStack();
}
ItemStack remaining = orgInput;
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
{
remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE );
}
// Store the stack in the cache for next time.
if( !remaining.isEmpty() && remaining != orgInput )
if( type == Actionable.SIMULATE )
{
stackCache = remaining;
iox.setCachedItemStack( inputStack );
}
else
{
if( !remaining.isEmpty() )
{
iox.setCachedItemStack( remaining );
}
}
// At this point, we still have some items left...
if( remaining == orgInput )
if( remaining == inputStack )
{
// The stack remained unmodified, target inventory is full
return iox;
@@ -147,7 +136,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
ItemStack gathered = ItemStack.EMPTY;
final boolean simulate = ( mode == Actionable.SIMULATE );
for ( int i = 0; i < this.itemHandler.getSlots(); i++ )
for( int i = 0; i < this.itemHandler.getSlots(); i++ )
{
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
@@ -157,6 +146,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
}
ItemStack extracted;
int stackSizeCurrentSlot = stackInInventorySlot.getCount();
int remainingCurrentSlot = Math.min( remainingSize, stackSizeCurrentSlot );
@@ -165,24 +155,36 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
do
{
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
if( !extracted.isEmpty() )
{
// In order to guard against broken IItemHandler implementations, we'll try to guess if the returned
// stack (especially in simulate mode) is the same that was returned by getStackInSlot. This is
// obviously not a precise science, but it would catch the previous Forge bug:
// https://github.com/MinecraftForge/MinecraftForge/pull/6580
if( extracted == stackInInventorySlot )
{
extracted = extracted.copy();
}
if( extracted.getCount() > remainingCurrentSlot )
{
// Something broke. It should never return more than we requested...
// We're going to silently eat the remainder
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.",
this.itemHandler.getClass().getName(), extracted.toString(), remainingCurrentSlot );
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.", this.itemHandler.getClass().getName(), extracted.toString(), remainingCurrentSlot );
extracted.setCount( remainingCurrentSlot );
}
// Heuristic for simulation: looping in case of simulations is pointless, since the state of the
// underlying inventory does not change after a simulated extraction. To still support inventories
// that report stacks that are larger than maxStackSize, we use this heuristic
if( simulate && extracted.getCount() == extracted.getMaxStackSize() && remainingCurrentSlot > extracted.getMaxStackSize() )
{
extracted.setCount( remainingCurrentSlot );
}
// We're just gonna use the first stack we get our hands on as the template for the rest.
// In case some stupid itemhandler (aka forge) returns an internal state we have to do a second
// expensive copy again.
if( gathered.isEmpty() )
{
gathered = extracted.copy();
gathered = extracted;
}
else
{
@@ -190,11 +192,9 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
}
remainingCurrentSlot -= extracted.getCount();
}
} while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
} while ( !simulate && !extracted.isEmpty() && remainingCurrentSlot > 0 );
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
// Done?
if( remainingSize <= 0 )
{
break;
@@ -320,26 +320,26 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
for ( final ItemSlot is : this )
for( final ItemSlot is : this )
{
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
if( !newIS.isEmpty() )
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
{
currentlyOnStorage.add( is.getAEItemStack() );
continue;
}
currentlyOnStorage.add( is.getAEItemStack() );
}
for ( final IAEItemStack is : currentlyCached )
for( final IAEItemStack is : currentlyCached )
{
is.setStackSize( -is.getStackSize() );
}
for ( final IAEItemStack is : currentlyOnStorage )
for( final IAEItemStack is : currentlyOnStorage )
{
currentlyCached.add( is );
}
for ( final IAEItemStack is : currentlyCached )
for( final IAEItemStack is : currentlyCached )
{
if( is.getStackSize() != 0 )
{
@@ -35,232 +35,225 @@ import java.util.*;
class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
{
private final Object2ObjectMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new Object2ObjectOpenHashMap<>();
private IActionSource mySource;
private final IItemRepository itemRepository;
private final IGridProxyable proxyable;
private final InventoryCache cache;
private AccessRestriction access;
private final Object2ObjectMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new Object2ObjectOpenHashMap<>();
private IActionSource mySource;
private final IItemRepository itemRepository;
private final IGridProxyable proxyable;
private final InventoryCache cache;
private AccessRestriction access;
private ItemStack stackCache;
ItemRepositoryAdapter( IItemRepository itemRepository, IGridProxyable proxy )
{
this.itemRepository = itemRepository;
this.proxyable = proxy;
this.cache = new InventoryCache( this.itemRepository );
if( this.proxyable instanceof PartStorageBus )
{
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
}
this.cache.update();
}
ItemRepositoryAdapter( IItemRepository itemRepository, IGridProxyable proxy )
{
this.itemRepository = itemRepository;
this.proxyable = proxy;
this.cache = new InventoryCache( this.itemRepository );
if( this.proxyable instanceof PartStorageBus )
{
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
}
this.cache.update();
}
@Override
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{
// Try to reuse the cached stack
ItemStack inputStack = iox.getCachedItemStack( iox.getStackSize() );
@Override
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{
// Try to reuse the cached stack
@Nullable ItemStack currentCached = stackCache;
stackCache = null;
ItemStack remaining;
ItemStack orgInput;
if( currentCached != null && iox.isSameType( currentCached ) )
{
// Cache is suitable, just update the count
orgInput = currentCached;
currentCached.setCount( Ints.saturatedCast( iox.getStackSize() ) );
}
else
{
// We need a new stack :-(
orgInput = iox.createItemStack();
}
ItemStack remaining = this.itemRepository.insertItem( orgInput, type == Actionable.SIMULATE );
remaining = this.itemRepository.insertItem( inputStack, type == Actionable.SIMULATE );
// Store the stack in the cache for next time.
if( !remaining.isEmpty() && remaining != orgInput )
{
stackCache = remaining;
}
// Store the stack in the cache for next time.
if( type == Actionable.SIMULATE )
{
iox.setCachedItemStack( inputStack );
}
else
{
if( !remaining.isEmpty() )
{
iox.setCachedItemStack( remaining );
}
}
// At this point, we still have some items left...
if( remaining == orgInput )
{
// The stack remained unmodified, target inventory is full
return iox;
}
// At this point, we still have some items left...
if( remaining == inputStack )
{
// The stack remained unmodified, target inventory is full
return iox;
}
if( type == Actionable.MODULATE )
{
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
this.cache.currentlyCached.add( added );
this.postDifference( Collections.singletonList( added ) );
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
}
}
if( type == Actionable.MODULATE )
{
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
this.cache.currentlyCached.add( added );
this.postDifference( Collections.singletonList( added ) );
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
}
}
return AEItemStack.fromItemStack( remaining );
return AEItemStack.fromItemStack( remaining );
}
}
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
int remainingSize = Ints.saturatedCast( request.getStackSize() );
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
int remainingSize = Ints.saturatedCast( request.getStackSize() );
final boolean simulate = ( mode == Actionable.SIMULATE );
final boolean simulate = ( mode == Actionable.SIMULATE );
ItemStack extracted = this.itemRepository.extractItem( request.getDefinition(), remainingSize, simulate );
ItemStack extracted = this.itemRepository.extractItem( request.getDefinition(), remainingSize, simulate );
if( extracted.getCount() > remainingSize )
{
// Something broke. It should never return more than we requested...
// We're going to silently eat the remainder
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.",
this.itemRepository.getClass().getName(), extracted.toString(), remainingSize );
extracted.setCount( remainingSize );
}
if( extracted.getCount() > remainingSize )
{
// Something broke. It should never return more than we requested...
// We're going to silently eat the remainder
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.", this.itemRepository.getClass().getName(), extracted.toString(), remainingSize );
extracted.setCount( remainingSize );
}
if( !extracted.isEmpty() )
{
IAEItemStack extractedAEItemStack = AEItemStack.fromItemStack( extracted );
if( mode == Actionable.MODULATE )
{
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
if (cachedStack != null)
{
cachedStack.decStackSize( extractedAEItemStack.getStackSize() );
this.postDifference( Collections.singletonList( extractedAEItemStack.copy().setStackSize( -extractedAEItemStack.getStackSize() ) ) );
}
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
}
}
return extractedAEItemStack;
}
return null;
}
if( !extracted.isEmpty() )
{
IAEItemStack extractedAEItemStack = AEItemStack.fromItemStack( extracted );
if( mode == Actionable.MODULATE )
{
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( extractedAEItemStack.getStackSize() );
this.postDifference( Collections.singletonList( extractedAEItemStack.copy().setStackSize( -extractedAEItemStack.getStackSize() ) ) );
}
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
}
}
return extractedAEItemStack;
}
return null;
}
@Override
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
{
return this.cache.getAvailableItems( out );
}
@Override
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
{
return this.cache.getAvailableItems( out );
}
@Override
public IStorageChannel<IAEItemStack> getChannel()
{
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
}
@Override
public IStorageChannel<IAEItemStack> getChannel()
{
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
}
@Override
public void addListener( IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken )
{
this.listeners.put( l, verificationToken );
}
@Override
public void addListener( IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken )
{
this.listeners.put( l, verificationToken );
}
@Override
public void removeListener( IMEMonitorHandlerReceiver<IAEItemStack> l )
{
this.listeners.remove( l );
}
@Override
public void removeListener( IMEMonitorHandlerReceiver<IAEItemStack> l )
{
this.listeners.remove( l );
}
private void postDifference( Iterable<IAEItemStack> a )
{
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
while ( i.hasNext() )
{
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
if( key.isValid( l.getValue() ) )
{
key.postChange( this, a, this.mySource );
}
else
{
i.remove();
}
}
}
private void postDifference( Iterable<IAEItemStack> a )
{
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
while ( i.hasNext() )
{
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
if( key.isValid( l.getValue() ) )
{
key.postChange( this, a, this.mySource );
}
else
{
i.remove();
}
}
}
@Override
public TickRateModulation onTick()
{
List<IAEItemStack> changes = this.cache.update();
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
}
else
{
return TickRateModulation.SLOWER;
}
}
@Override
public TickRateModulation onTick()
{
List<IAEItemStack> changes = this.cache.update();
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
}
else
{
return TickRateModulation.SLOWER;
}
}
@Override
public void setActionSource( final IActionSource mySource )
{
this.mySource = mySource;
}
@Override
public void setActionSource( final IActionSource mySource )
{
this.mySource = mySource;
}
private static class InventoryCache
{
private IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final IItemRepository iItemRepository;
private static class InventoryCache
{
private IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final IItemRepository iItemRepository;
public InventoryCache( IItemRepository iItemRepository )
{
this.iItemRepository = iItemRepository;
}
public InventoryCache( IItemRepository iItemRepository )
{
this.iItemRepository = iItemRepository;
}
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
{
currentlyCached.iterator().forEachRemaining( out::add );
return out;
}
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
{
currentlyCached.iterator().forEachRemaining( out::add );
return out;
}
public List<IAEItemStack> update()
{
final List<IAEItemStack> changes = new ArrayList<>();
public List<IAEItemStack> update()
{
final List<IAEItemStack> changes = new ArrayList<>();
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
this.iItemRepository.getAllItems().stream().map( s -> AEItemStack.fromItemStack( s.itemPrototype ).setStackSize( s.count ) ).forEach( currentlyOnStorage::add );
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
this.iItemRepository.getAllItems().stream().map( s -> AEItemStack.fromItemStack( s.itemPrototype ).setStackSize( s.count ) ).forEach( currentlyOnStorage::add );
for ( final IAEItemStack is : currentlyCached )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEItemStack is : currentlyCached )
{
is.setStackSize( -is.getStackSize() );
}
for ( final IAEItemStack is : currentlyOnStorage )
{
currentlyCached.add( is );
}
for( final IAEItemStack is : currentlyOnStorage )
{
currentlyCached.add( is );
}
for ( final IAEItemStack is : currentlyCached )
{
if( is.getStackSize() != 0 )
{
changes.add( is );
}
}
for( final IAEItemStack is : currentlyCached )
{
if( is.getStackSize() != 0 )
{
changes.add( is );
}
}
currentlyCached = currentlyOnStorage;
currentlyCached = currentlyOnStorage;
return changes;
}
return changes;
}
}
}
}
@@ -95,14 +95,16 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto
super( is );
}
@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();
}
@@ -0,0 +1,225 @@
package appeng.parts.misc;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.ITickManager;
import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.AppEng;
import appeng.core.sync.GuiBridge;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.cache.GridStorageCache;
import appeng.me.storage.ITickingMonitor;
import appeng.me.storage.MEInventoryHandler;
import appeng.parts.PartModel;
import appeng.util.ConfigManager;
import appeng.util.Platform;
import appeng.util.item.OreHelper;
import appeng.util.prioritylist.IPartitionList;
import appeng.util.prioritylist.OreDictPriorityList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
public class PartOreDicStorageBus extends PartStorageBus
{
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/oredict_storage_bus_base" );
@PartModels
public static final IPartModel MODELS_OFF = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_off" ) );
@PartModels
public static final IPartModel MODELS_ON = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_on" ) );
@PartModels
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_has_channel" ) );
public String oreExp = "";
OreDictPriorityList<IAEItemStack> priorityList;
public PartOreDicStorageBus( ItemStack is )
{
super( is );
}
@Override
public void readFromNBT( NBTTagCompound data )
{
super.readFromNBT( data );
this.oreExp = data.getString( "oreMatch" );
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp );
}
@Override
public void writeToNBT( NBTTagCompound data )
{
super.writeToNBT( data );
data.setString( "oreMatch", getOreExp() );
}
@Override
public boolean onPartActivate( final EntityPlayer player, final EnumHand hand, final Vec3d pos )
{
if( Platform.isServer() )
{
Platform.openGUI( player, this.getHost().getTile(), this.getSide(), GuiBridge.GUI_OREDICTSTORAGEBUS );
}
return true;
}
@Override
public GuiBridge getGuiBridge()
{
return GuiBridge.GUI_OREDICTSTORAGEBUS;
}
@Override
public MEInventoryHandler<IAEItemStack> getInternalHandler()
{
if( this.cached )
{
return this.handler;
}
final boolean wasSleeping = this.monitor == null;
this.cached = true;
final TileEntity self = this.getHost().getTile();
final TileEntity target = self.getWorld().getTileEntity( self.getPos().offset( this.getSide().getFacing() ) );
final int newHandlerHash = this.createHandlerHash( target );
if( newHandlerHash != 0 && newHandlerHash == this.handlerHash )
{
return this.handler;
}
this.handlerHash = newHandlerHash;
this.handler = null;
if( this.monitor != null )
{
( (IBaseMonitor<IAEItemStack>) monitor ).removeListener( this );
}
this.monitor = null;
if( target != null )
{
IMEInventory<IAEItemStack> inv = this.getInventoryWrapper( target );
if( inv instanceof ITickingMonitor )
{
this.monitor = (ITickingMonitor) inv;
this.monitor.setActionSource( mySrc );
this.monitor.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv != null )
{
this.handler = new MEInventoryHandler<>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
this.handler.setBaseAccess( (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS ) );
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
this.handler.setPriority( this.priority );
this.handler.setPartitionList( this.getPriorityList() );
if( inv instanceof IBaseMonitor )
{
if( ( (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS ) ).hasPermission( AccessRestriction.READ ) )
{
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
}
}
}
}
// update sleep state...
if( wasSleeping != ( this.monitor == null ) )
{
try
{
final ITickManager tm = this.getProxy().getTick();
if( this.monitor == null )
{
tm.sleepDevice( this.getProxy().getNode() );
}
else
{
tm.wakeDevice( this.getProxy().getNode() );
}
}
catch( final GridAccessException e )
{
// :(
}
}
try
{
// force grid to update handlers...
( (GridStorageCache) this.getProxy().getGrid().getCache( IStorageGrid.class ) ).cellUpdate( null );
}
catch( final GridAccessException e )
{
// :3
}
return this.handler;
}
private IPartitionList<IAEItemStack> getPriorityList()
{
if( priorityList == null )
{
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp );
}
return priorityList;
}
public String getOreExp()
{
if( this.oreExp == null )
{
return "";
}
return oreExp;
}
public void saveOreMatch( String oreMatch )
{
if( !this.oreExp.equals( oreMatch ) )
{
this.oreExp = oreMatch;
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp );
if( this.handler != null )
{
handler.setPartitionList( this.priorityList );
}
this.getHost().markForSave();
}
}
@Override
public IPartModel getStaticModels()
{
if( this.isActive() && this.isPowered() )
{
return MODELS_HAS_CHANNEL;
}
else if( this.isPowered() )
{
return MODELS_ON;
}
else
{
return MODELS_OFF;
}
}
}
@@ -1,201 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2018, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.parts.misc;
import java.util.Collections;
import java.util.List;
import appeng.api.config.AccessRestriction;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import appeng.api.AEApi;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.storage.ICellContainer;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.util.AECableType;
import appeng.api.util.IConfigManager;
import appeng.helpers.IPriorityHost;
import appeng.me.GridAccessException;
import appeng.parts.automation.PartUpgradeable;
/**
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public abstract class PartSharedStorageBus extends PartUpgradeable implements IGridTickable, ICellContainer, IPriorityHost
{
private boolean wasActive = false;
private int priority = 0;
protected boolean accessChanged;
public PartSharedStorageBus( ItemStack is )
{
super( is );
}
protected void updateStatus()
{
final boolean currentActive = this.getProxy().isActive();
if( this.wasActive != currentActive )
{
this.wasActive = currentActive;
try
{
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
this.getHost().markForUpdate();
}
catch( final GridAccessException ignore )
{
// :P
}
}
}
@MENetworkEventSubscribe
public void updateChannels( final MENetworkChannelsChanged changedChannels )
{
this.updateStatus();
}
/**
* Helper method to get this parts storage channel
*
* @return Storage channel
*/
public IStorageChannel getStorageChannel()
{
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
}
protected abstract void resetCache();
protected abstract void resetCache( boolean fullReset );
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
return Collections.emptyList();
}
@Override
public void blinkCell( int slot )
{
}
@Override
public void saveChanges( ICellInventory<?> cellInventory )
{
}
@Override
public int getPriority()
{
return this.priority;
}
@Override
public void setPriority( final int newValue )
{
this.priority = newValue;
this.getHost().markForSave();
this.resetCache( true );
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
{
this.updateStatus();
}
@Override
public void upgradesChanged()
{
super.upgradesChanged();
this.resetCache( true );
}
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( settingName instanceof AccessRestriction )
{
this.accessChanged = true;
}
this.resetCache( true );
this.getHost().markForSave();
}
@Override
public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor )
{
if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) )
{
this.resetCache( false );
}
}
@Override
public void readFromNBT( final NBTTagCompound data )
{
super.readFromNBT( data );
this.priority = data.getInteger( "priority" );
}
@Override
public void writeToNBT( final NBTTagCompound data )
{
super.writeToNBT( data );
data.setInteger( "priority", this.priority );
}
@Override
public void getBoxes( final IPartCollisionHelper bch )
{
bch.addBox( 3, 3, 15, 13, 13, 16 );
bch.addBox( 2, 2, 14, 14, 14, 15 );
bch.addBox( 5, 5, 12, 11, 11, 14 );
}
@Override
protected int getUpgradeSlots()
{
return 5;
}
@Override
public float getCableConnectionLength( AECableType cable )
{
return 4;
}
}
@@ -19,13 +19,51 @@
package appeng.parts.misc;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import appeng.fluids.parts.FluidHandlerAdapter;
import appeng.me.storage.MEPassThrough;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.ITickManager;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartModel;
import appeng.api.storage.*;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.AECableType;
import appeng.api.util.IConfigManager;
import appeng.capabilities.Capabilities;
import appeng.core.AppEng;
import appeng.core.settings.TickRates;
import appeng.core.sync.GuiBridge;
import appeng.helpers.IPriorityHost;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.cache.GridStorageCache;
import appeng.me.helpers.MachineSource;
import appeng.me.storage.ITickingMonitor;
import appeng.me.storage.MEInventoryHandler;
import appeng.parts.PartModel;
import appeng.parts.automation.PartUpgradeable;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.misc.TileInterface;
import appeng.tile.networking.TileCableBus;
import appeng.util.ConfigManager;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.prioritylist.FuzzyPriorityList;
import appeng.util.prioritylist.PrecisePriorityList;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@@ -42,89 +80,33 @@ import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.FuzzyMode;
import appeng.api.config.IncludeExclude;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.api.config.Upgrades;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.ITickManager;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartModel;
import appeng.api.storage.ICellContainer;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.IStorageMonitorableAccessor;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.AECableType;
import appeng.api.util.AEPartLocation;
import appeng.api.util.IConfigManager;
import appeng.capabilities.Capabilities;
import appeng.core.AppEng;
import appeng.core.settings.TickRates;
import appeng.core.sync.GuiBridge;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.IPriorityHost;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.me.storage.ITickingMonitor;
import appeng.me.storage.MEInventoryHandler;
import appeng.me.storage.MEMonitorIInventory;
import appeng.parts.PartModel;
import appeng.parts.automation.PartUpgradeable;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.prioritylist.FuzzyPriorityList;
import appeng.util.prioritylist.PrecisePriorityList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class PartStorageBus extends PartUpgradeable implements IGridTickable, ICellContainer, IMEMonitorHandlerReceiver<IAEItemStack>, IPriorityHost
{
@CapabilityInject(IItemRepository.class)
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY = null;
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_base" );
@PartModels
public static final IPartModel MODELS_OFF = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_off" ) );
@PartModels
public static final IPartModel MODELS_ON = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_on" ) );
@PartModels
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_has_channel" ) );
private final IActionSource mySrc;
private final AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 );
private int priority = 0;
private boolean cached = false;
private ITickingMonitor monitor = null;
private MEInventoryHandler<IAEItemStack> handler = null;
private int handlerHash = 0;
@CapabilityInject( IItemRepository.class )
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY = null;
protected final IActionSource mySrc;
protected final AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 );
protected int priority = 0;
protected boolean cached = false;
protected ITickingMonitor monitor = null;
protected MEInventoryHandler<IAEItemStack> handler = null;
protected int handlerHash = 0;
private boolean wasActive = false;
private byte resetCacheLogic = 0;
private boolean accessChanged;
private boolean readOncePass;
@Reflected
public PartStorageBus( final ItemStack is )
@@ -161,8 +143,9 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
}
@Override
@MENetworkEventSubscribe
public void updateChannels( final MENetworkChannelsChanged changedChannels )
public void chanRender( final MENetworkChannelsChanged changedChannels )
{
this.updateStatus();
}
@@ -176,7 +159,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( settingName instanceof AccessRestriction )
if( settingName.name().equals( "ACCESS" ) )
{
this.accessChanged = true;
}
@@ -208,6 +191,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
super.readFromNBT( data );
this.Config.readFromNBT( data, "config" );
this.priority = data.getInteger( "priority" );
this.accessChanged = false;
}
@Override
@@ -231,9 +215,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
private void resetCache( final boolean fullReset )
{
if( this.getHost() == null || this.getHost().getTile() == null || this.getHost().getTile().getWorld() == null || this.getHost()
.getTile()
.getWorld().isRemote )
if( this.getHost() == null || this.getHost().getTile() == null || this.getHost().getTile().getWorld() == null || this.getHost().getTile().getWorld().isRemote )
{
return;
}
@@ -242,7 +224,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
{
this.resetCacheLogic = 2;
}
else
else if( this.resetCacheLogic < 2 )
{
this.resetCacheLogic = 1;
}
@@ -266,24 +248,34 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
@Override
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource source )
{
if( this.mySrc.machine().map( machine -> machine == this ).orElse( false ) && monitor != null )
if( this.getProxy().isActive() )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
if( readOncePass )
{
readOncePass = false;
try
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, mySrc );
}
catch( final GridAccessException e )
{
// :(
}
return;
}
if( !currentAccess.hasPermission( AccessRestriction.READ ) )
{
return;
}
}
try
{
if( this.getProxy().isActive() )
try
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, this.mySrc );
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, source );
}
catch( final GridAccessException e )
{
// :(
}
}
catch( final GridAccessException e )
{
// :(
}
}
@@ -309,11 +301,36 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
final TileEntity te = w.getTileEntity( neighbor );
// In case the TE was destroyed, we have to do a full reset immediately.
if( te == null )
if( te instanceof TileCableBus )
{
IPart iPart = ( (TileCableBus) te ).getPart( this.getSide().getOpposite() );
if( iPart == null )
{
this.resetCache( true );
this.resetCache();
}
else if( iPart instanceof PartInterface )
{
if( createHandlerHash( te ) != handlerHash )
{
this.resetCache( true );
this.resetCache();
}
}
}
else if( te == null )
{
this.resetCache( true );
this.resetCache();
}
else if( te instanceof TileInterface )
{
if( createHandlerHash( te ) != handlerHash )
{
this.resetCache( true );
this.resetCache();
}
}
else
{
this.resetCache( false );
@@ -365,8 +382,8 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
this.resetCacheLogic = 0;
final MEInventoryHandler<IAEItemStack> in = this.getInternalHandler();
IItemList<IAEItemStack> before = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
boolean denyRead = false;
if( in != null )
{
if( accessChanged )
@@ -375,7 +392,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
AccessRestriction oldAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getOldSetting( Settings.ACCESS );
if( oldAccess.hasPermission( AccessRestriction.READ ) && !currentAccess.hasPermission( AccessRestriction.READ ) )
{
denyRead = true;
readOncePass = true;
}
in.setBaseAccess( oldAccess );
before = in.getAvailableItems( before );
@@ -396,21 +413,19 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
final MEInventoryHandler<IAEItemStack> out = this.getInternalHandler();
if( in != out || denyRead )
{
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
if( out != null && !denyRead )
if( in != out )
{
if( out != null )
{
after = out.getAvailableItems( after );
}
Platform.postListChanges( before, after, this, this.mySrc );
}
}
private IMEInventory<IAEItemStack> getInventoryWrapper( TileEntity target )
IMEInventory<IAEItemStack> getInventoryWrapper( TileEntity target )
{
EnumFacing targetSide = this.getSide().getFacing().getOpposite();
@@ -434,7 +449,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
// Check via cap for IItemRepository
if (ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ))
if( ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ) )
{
IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide );
if( handlerRepo != null )
@@ -453,7 +468,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
}
private int createHandlerHash( TileEntity target )
int createHandlerHash( TileEntity target )
{
if( target == null )
{
@@ -464,17 +479,16 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
if( target.hasCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide ) )
{
return Objects.hash( target, target.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide ) );
}
if (ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ))
{
final IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide );
if( handlerRepo != null )
IStorageMonitorableAccessor accessor = target.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide );
if( accessor != null )
{
return Objects.hash( target, handlerRepo, handlerRepo.getAllItems().size() );
IStorageMonitorable inventory = accessor.getInventory( this.mySrc );
if( inventory != null )
{
return Objects.hash( target, inventory.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
}
return Objects.hash( target, target.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide ) );
}
final IItemHandler itemHandler = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide );
@@ -508,29 +522,25 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
this.handlerHash = newHandlerHash;
this.handler = null;
if( this.monitor != null )
{
( (IBaseMonitor<IAEItemStack>) monitor ).removeListener( this );
}
this.monitor = null;
if( target != null )
{
IMEInventory<IAEItemStack> inv = this.getInventoryWrapper( target );
if( inv instanceof MEMonitorIInventory )
{
final MEMonitorIInventory h = (MEMonitorIInventory) inv;
h.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv instanceof ITickingMonitor )
{
this.monitor = (ITickingMonitor) inv;
this.monitor.setActionSource( new MachineSource( this ) );
this.monitor.setActionSource( mySrc );
this.monitor.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv != null )
{
this.checkInterfaceVsStorageBus( target, this.getSide().getOpposite() );
this.handler = new MEInventoryHandler<IAEItemStack>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
this.handler = new MEInventoryHandler<>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
this.handler.setBaseAccess( (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS ) );
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
@@ -550,18 +560,19 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
this.handler
.setPartitionList( new FuzzyPriorityList<IAEItemStack>( priorityList, (FuzzyMode) this.getConfigManager()
.getSetting( Settings.FUZZY_MODE ) ) );
this.handler.setPartitionList( new FuzzyPriorityList<>( priorityList, (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ) ) );
}
else
{
this.handler.setPartitionList( new PrecisePriorityList<IAEItemStack>( priorityList ) );
this.handler.setPartitionList( new PrecisePriorityList<>( priorityList ) );
}
if( inv instanceof IBaseMonitor )
{
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
if( ( (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS ) ).hasPermission( AccessRestriction.READ ) )
{
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
}
}
}
}
@@ -590,7 +601,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
try
{
// force grid to update handlers...
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
( (GridStorageCache) this.getProxy().getGrid().getCache( IStorageGrid.class ) ).cellUpdate( null );
}
catch( final GridAccessException e )
{
@@ -600,32 +611,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
return this.handler;
}
private void checkInterfaceVsStorageBus( final TileEntity target, final AEPartLocation side )
{
IInterfaceHost achievement = null;
if( target instanceof IInterfaceHost )
{
achievement = (IInterfaceHost) target;
}
if( target instanceof IPartHost )
{
final Object part = ( (IPartHost) target ).getPart( side );
if( part instanceof IInterfaceHost )
{
achievement = (IInterfaceHost) part;
}
}
if( achievement != null && achievement.getActionableNode() != null )
{
// Platform.addStat( achievement.getActionableNode().getPlayerID(), Achievements.Recursive.getAchievement()
// );
// Platform.addStat( getActionableNode().getPlayerID(), Achievements.Recursive.getAchievement() );
}
}
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
@@ -83,10 +83,19 @@ public class PartP2PFluids extends PartP2PTunnel<PartP2PFluids> implements IFlui
if( this.isOutput() )
{
final PartP2PFluids in = this.getInput();
if( in != null )
try
{
in.onTunnelNetworkChange();
for( PartP2PFluids in : this.getInputs() )
{
if( in != null )
{
in.onTunnelNetworkChange();
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
}
@@ -124,13 +133,21 @@ public class PartP2PFluids extends PartP2PTunnel<PartP2PFluids> implements IFlui
{
if( !this.isOutput() )
{
final PartP2PFluids tun = this.getInput();
if( tun != null )
try
{
return ACTIVE_TANK;
for( PartP2PFluids tun : this.getInputs() )
{
if( tun != null )
{
return ACTIVE_TANK;
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
return INACTIVE_TANK;
}
@@ -0,0 +1,308 @@
package appeng.parts.p2p;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.api.parts.IPartModel;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import gregtech.api.capability.GregtechCapabilities;
import gregtech.api.capability.IEnergyContainer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.common.Optional;
import java.util.ArrayDeque;
import java.util.List;
import java.util.Queue;
public class PartP2PGTCEPower extends PartP2PTunnel<PartP2PGTCEPower>
{
private static final P2PModels MODELS = new P2PModels( "part/p2p/p2p_tunnel_gteu" );
private static final IEnergyContainer NULL_ENERGY_STORAGE = new NullEnergyStorage();
private final IEnergyContainer inputHandler = new InputEnergyStorage();
private final IEnergyContainer outputHandler = new OutputEnergyStorage();
private final Queue<PartP2PGTCEPower> outputs = new ArrayDeque<>();
public PartP2PGTCEPower( ItemStack is )
{
super( is );
}
@PartModels
public static List<IPartModel> getModels()
{
return MODELS.getModels();
}
@Override
public IPartModel getStaticModels()
{
return MODELS.getModel( this.isPowered(), this.isActive() );
}
@Override
public void onTunnelNetworkChange()
{
this.getHost().notifyNeighbors();
}
private IEnergyContainer getAttachedEnergyStorage()
{
if( this.isActive() )
{
final TileEntity self = this.getTile();
final TileEntity te = self.getWorld().getTileEntity( self.getPos().offset( this.getSide().getFacing() ) );
if( te != null && te.hasCapability( GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, this.getSide().getOpposite().getFacing() ) )
{
return te.getCapability( GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, this.getSide().getOpposite().getFacing() );
}
}
return NULL_ENERGY_STORAGE;
}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability )
{
if( capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER )
{
return true;
}
return super.hasCapability( capability );
}
@Nullable
@Override
public <T> T getCapability( @Nonnull Capability<T> capability )
{
if( capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER )
{
if( this.isOutput() )
{
return (T) this.outputHandler;
}
return (T) this.inputHandler;
}
return super.getCapability( capability );
}
class InputEnergyStorage implements IEnergyContainer
{
@Override
public long getEnergyCanBeInserted()
{
long canInsert = 0;
if( outputs.isEmpty() )
{
try
{
for( PartP2PGTCEPower o : PartP2PGTCEPower.this.getOutputs() )
outputs.add( o );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
while ( !outputs.isEmpty() )
{
PartP2PGTCEPower target = outputs.poll();
final IEnergyContainer output = target.getAttachedEnergyStorage();
if( output == null || output.getEnergyCanBeInserted() <= 0 )
{
continue;
}
canInsert += output.getEnergyCanBeInserted();
}
return canInsert;
}
@Override
public long acceptEnergyFromNetwork( EnumFacing facing, long voltage, long amperage )
{
long amperesUsed = 0L;
if( outputs.isEmpty() )
{
try
{
for( PartP2PGTCEPower o : PartP2PGTCEPower.this.getOutputs() )
outputs.add( o );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
while ( !outputs.isEmpty() )
{
PartP2PGTCEPower target = outputs.poll();
final IEnergyContainer output = target.getAttachedEnergyStorage();
if( output == null || !output.inputsEnergy( facing ) || output.getEnergyCanBeInserted() <= 0 )
{
continue;
}
if( voltage > 0 )
{
amperesUsed += output.acceptEnergyFromNetwork( facing, voltage, amperage - amperesUsed );
}
if( amperage == amperesUsed )
{
break;
}
}
return amperesUsed;
}
@Override
public boolean inputsEnergy( EnumFacing enumFacing )
{
return true;
}
@Override
public long changeEnergy( long l )
{
return 0;
}
@Override
public long getEnergyStored()
{
return 0;
}
@Override
public long getEnergyCapacity()
{
return 0;
}
@Override
public long getInputAmperage()
{
return 0;
}
@Override
public long getInputVoltage()
{
return 0;
}
}
class OutputEnergyStorage implements IEnergyContainer
{
@Override
public long acceptEnergyFromNetwork( EnumFacing facing, long voltage, long amperage )
{
if( facing == getSide().getFacing() )
{
return 0;
}
final IEnergyContainer output = getAttachedEnergyStorage();
voltage *= 0.95;
if( voltage > 0 )
{
return output.acceptEnergyFromNetwork( facing, voltage, amperage );
}
return 0;
}
@Override
public boolean inputsEnergy( EnumFacing enumFacing )
{
return false;
}
@Override
public boolean outputsEnergy( EnumFacing side )
{
return true;
}
@Override
public long changeEnergy( long l )
{
return 0;
}
@Override
public long getEnergyStored()
{
return 0;
}
@Override
public long getEnergyCapacity()
{
return 0;
}
@Override
public long getInputAmperage()
{
return 0;
}
@Override
public long getInputVoltage()
{
return 0;
}
}
static class NullEnergyStorage implements IEnergyContainer
{
@Override
public long acceptEnergyFromNetwork( EnumFacing enumFacing, long l, long l1 )
{
return 0;
}
@Override
public boolean inputsEnergy( EnumFacing enumFacing )
{
return false;
}
@Override
public long changeEnergy( long l )
{
return 0;
}
@Override
public long getEnergyStored()
{
return 0;
}
@Override
public long getEnergyCapacity()
{
return 0;
}
@Override
public long getInputAmperage()
{
return 0;
}
@Override
public long getInputVoltage()
{
return 0;
}
}
}
@@ -33,10 +33,6 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.EmptyHandler;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
@@ -74,10 +70,22 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor )
{
this.cachedInv = null;
final PartP2PItems input = this.getInput();
if( input != null && this.isOutput() )
try
{
input.onTunnelNetworkChange();
if( this.isOutput() )
{
for( PartP2PItems input : this.getInputs() )
{
if( input != null )
{
input.onTunnelNetworkChange();
}
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
@@ -162,51 +170,6 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
return wasReq ? TickRateModulation.FASTER : TickRateModulation.SLOWER;
}
@MENetworkEventSubscribe
public void changeStateA( final MENetworkBootingStatusChange bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@MENetworkEventSubscribe
public void changeStateB( final MENetworkChannelsChanged bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@MENetworkEventSubscribe
public void changeStateC( final MENetworkPowerStatusChange bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@Override
public void onTunnelNetworkChange()
{
@@ -222,10 +185,19 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
}
else
{
final PartP2PItems input = this.getInput();
if( input != null )
try
{
input.getHost().notifyNeighbors();
for( PartP2PItems input : this.getInputs() )
{
if( input != null )
{
input.getHost().notifyNeighbors();
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
}
@@ -32,8 +32,6 @@ import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
@@ -62,20 +60,6 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
super( is );
}
@Override
public void chanRender( final MENetworkChannelsChanged c )
{
this.onTunnelNetworkChange();
super.chanRender( c );
}
@Override
public void powerRender( final MENetworkPowerStatusChange c )
{
this.onTunnelNetworkChange();
super.powerRender( c );
}
@Override
public void writeToStream( final ByteBuf data ) throws IOException
{
@@ -115,9 +99,17 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
this.lastValue = newLevel;
try
{
int light = 0;
for( PartP2PLight src : this.getInputs() )
{
if( src != null && src.getProxy().isActive() )
{
light = Math.max( light, src.lastValue );
}
}
for( final PartP2PLight out : this.getOutputs() )
{
out.setLightLevel( this.lastValue );
out.setLightLevel( light );
}
}
catch( final GridAccessException e )
@@ -196,15 +188,23 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
{
if( this.isOutput() )
{
final PartP2PLight src = this.getInput();
if( src != null && src.getProxy().isActive() )
{
this.setLightLevel( src.lastValue );
}
else
try
{
int light = 0;
for( PartP2PLight src : this.getInputs() )
{
if( src != null && src.getProxy().isActive() )
{
light = Math.max( light, src.lastValue );
}
}
this.setLightLevel( light );
this.getHost().markForUpdate();
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
else
{
@@ -31,10 +31,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.parts.IPartModel;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
@@ -60,20 +56,25 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
super( is );
}
@MENetworkEventSubscribe
public void changeStateA( final MENetworkBootingStatusChange bs )
{
this.setNetworkReady();
}
private void setNetworkReady()
{
if( this.isOutput() )
{
final PartP2PRedstone in = this.getInput();
if( in != null )
try
{
this.putInput( in.power );
int power = 0;
for( PartP2PRedstone in : this.getInputs() )
{
if( in != null )
{
power = Math.max( power, in.power );
}
}
this.putInput( power );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
}
@@ -86,12 +87,20 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
}
this.recursive = true;
if( this.isOutput() && this.getProxy().isActive() )
if( this.isOutput() )
{
final int newPower = (Integer) o;
if( this.power != newPower )
if( this.getProxy().isActive() )
{
this.power = newPower;
final int newPower = (Integer) o;
if( this.power != newPower )
{
this.power = newPower;
this.notifyNeighbors();
}
}
else
{
this.power = 0;
this.notifyNeighbors();
}
}
@@ -111,18 +120,6 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
}
}
@MENetworkEventSubscribe
public void changeStateB( final MENetworkChannelsChanged bs )
{
this.setNetworkReady();
}
@MENetworkEventSubscribe
public void changeStateC( final MENetworkPowerStatusChange bs )
{
this.setNetworkReady();
}
@Override
public void readFromNBT( final NBTTagCompound tag )
{
@@ -167,7 +164,22 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
this.power = b.getWeakPower( state, this.getTile().getWorld(), target, srcSide );
this.power = Math.max( this.power, b.getWeakPower( state, this.getTile().getWorld(), target, srcSide ) );
this.sendToOutput( this.power );
int powerOut = this.power;
try
{
for( PartP2PRedstone in : this.getInputs() )
{
if( in != null )
{
powerOut = Math.max( in.power, powerOut );
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.sendToOutput( powerOut );
}
else
{
+117 -29
View File
@@ -24,6 +24,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
@@ -53,6 +57,7 @@ import appeng.me.cache.P2PCache;
import appeng.me.cache.helpers.TunnelCollection;
import appeng.parts.PartBasicState;
import appeng.util.Platform;
import org.lwjgl.input.Keyboard;
public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicState
@@ -77,26 +82,13 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
return null;
}
public T getInput()
public TunnelCollection<T> getInputs() throws GridAccessException
{
if( this.getFrequency() == 0 )
if( this.getProxy().isActive() && this.getFrequency() != 0 )
{
return null;
return (TunnelCollection<T>) this.getProxy().getP2P().getInputs( this.getFrequency(), this.getClass() );
}
try
{
final PartP2PTunnel tunnel = this.getProxy().getP2P().getInput( this.getFrequency() );
if( this.getClass().isInstance( tunnel ) )
{
return (T) tunnel;
}
}
catch( final GridAccessException e )
{
// :P
}
return null;
return new TunnelCollection( new ArrayList(), this.getClass() );
}
public TunnelCollection<T> getOutputs() throws GridAccessException
@@ -165,6 +157,30 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
data.writeShort( this.getFrequency() );
}
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c )
{
this.onTunnelNetworkChange();
super.chanRender( c );
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
{
this.onTunnelNetworkChange();
super.powerRender( c );
}
@Override
@MENetworkEventSubscribe
public void bootingRender( final MENetworkBootingStatusChange bs )
{
this.onTunnelNetworkChange();
super.bootingRender( bs );
}
@Override
public float getCableConnectionLength( AECableType cable )
{
@@ -190,7 +206,13 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
return false;
}
final ItemStack is = player.getHeldItem( hand );
boolean pasteAsOutput = true;
ItemStack is = player.getHeldItem( hand );
if( is.isEmpty() )
{
pasteAsOutput = false;
is = player.getHeldItemOffhand();
}
// UniqueIdentifier id = GameRegistry.findUniqueIdentifierFor( is.getItem() );
// AELog.info( "ID:" + id.toString() + " : " + is.getItemDamage() );
@@ -211,14 +233,29 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final IPart testPart = ( (IPartItem) newType.getItem() ).createPartFromItemStack( newType );
if( testPart instanceof PartP2PTunnel )
{
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), true );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir );
if( newBus instanceof PartP2PTunnel )
{
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( true );
if( pasteAsOutput )
{
newTunnel.setOutput( true );
}
try
{
@@ -246,7 +283,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final IParts parts = AEApi.instance().definitions().parts();
switch( tt )
switch ( tt )
{
case LIGHT:
newType = parts.p2PTunnelLight().maybeStack( 1 ).orElse( ItemStack.EMPTY );
@@ -256,6 +293,10 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
newType = parts.p2PTunnelFE().maybeStack( 1 ).orElse( ItemStack.EMPTY );
break;
case GTEU_POWER:
newType = parts.p2PTunnelGTEU().maybeStack( 1 ).orElse( ItemStack.EMPTY );
break;
case FLUID:
newType = parts.p2PTunnelFluids().maybeStack( 1 ).orElse( ItemStack.EMPTY );
break;
@@ -295,7 +336,17 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final boolean oldOutput = this.isOutput();
final short myFreq = this.getFrequency();
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), false );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir );
@@ -303,7 +354,6 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
{
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( oldOutput );
newTunnel.onTunnelNetworkChange();
try
{
@@ -314,9 +364,10 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
{
// :P
}
newTunnel.onTunnelNetworkChange();
}
Platform.notifyBlocksOfNeighbors( this.getTile().getWorld(), this.getTile().getPos() );
return true;
}
}
@@ -350,9 +401,38 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
if( needsNewFrequency )
{
newFreq = this.getProxy().getP2P().newFrequency();
}
this.getProxy().getP2P().updateFreq( this, newFreq );
final ItemStack newType = this.getHost().getPart( this.getSide() ).getItemStack( PartItemStack.WRENCH );
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), false );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir );
if( newBus instanceof PartP2PTunnel )
{
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( false );
newTunnel.getProxy().getP2P().updateFreq( newTunnel, newFreq );
newTunnel.onTunnelNetworkChange();
}
}
else
{
this.getProxy().getP2P().updateFreq( this, newFreq );
this.onTunnelNetworkChange();
}
Platform.notifyBlocksOfNeighbors( this.getTile().getWorld(), this.getTile().getPos() );
}
catch( final GridAccessException e )
{
@@ -365,12 +445,21 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final String type = p2pItem.getUnlocalizedName();
p2pItem.writeToNBT( data );
data.setShort( "freq", this.getFrequency() );
if( needsNewFrequency )
{
data.setShort( "freq", newFreq );
}
else
{
data.setShort( "freq", this.getFrequency() );
}
final AEColor[] colors = Platform.p2p().toColors( this.getFrequency() );
final int[] colorCode = new int[] {
colors[0].ordinal(), colors[0].ordinal(), colors[1].ordinal(), colors[1].ordinal(),
colors[2].ordinal(), colors[2].ordinal(), colors[3].ordinal(), colors[3].ordinal(),
final int[] colorCode = new int[]{
colors[0].ordinal(), colors[0].ordinal(),
colors[1].ordinal(), colors[1].ordinal(),
colors[2].ordinal(), colors[2].ordinal(),
colors[3].ordinal(), colors[3].ordinal(),
};
data.setIntArray( "colorCode", colorCode );
@@ -395,7 +484,6 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
public void onTunnelNetworkChange()
{
}
protected void queueTunnelDrain( final PowerUnits unit, final double f )
@@ -82,6 +82,7 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
private IAEItemStack configuredItem;
private IAEFluidStack configuredFluid;
private long configuredAmount;
private String lastHumanReadableText;
private boolean isLocked;
private IStackWatcher myWatcher;
@@ -208,14 +209,21 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
fluidInTank = fluidHandlerItem.drain( Integer.MAX_VALUE, false );
}
if (fluidInTank == null)
if( fluidInTank == null )
{
this.configuredFluid = null;
this.configuredItem = AEItemStack.fromItemStack( eq );
if( !eq.isEmpty() )
{
this.configuredItem = AEItemStack.fromItemStack( eq ).setStackSize( 0 );
}
else
{
this.configuredItem = null;
}
}
else if( fluidInTank.amount > 0 )
{
this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank );
this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank ).setStackSize( 0 );
this.configuredItem = null;
}
@@ -299,30 +307,31 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
private <T extends IAEStack<T>> void updateReportingValue ( final IMEMonitor<T> monitor )
{
if( this.configuredItem != null)
{
final IAEItemStack result = (IAEItemStack) monitor.getStorageList().findPrecise( (T) this.configuredItem );
if( result == null )
{
this.configuredItem.setStackSize( 0 );
this.configuredAmount = 0;
}
else
{
this.configuredItem.setStackSize( result.getStackSize() );
this.configuredAmount = result.getStackSize();
}
this.configuredItem.setStackSize( this.configuredAmount );
}
else if( this.configuredFluid != null)
{
final IAEFluidStack result = (IAEFluidStack) monitor.getStorageList().findPrecise( (T) this.configuredFluid );
if( result == null )
{
this.configuredFluid.setStackSize( 0 );
this.configuredAmount = 0;
}
else
{
this.configuredFluid.setStackSize( result.getStackSize() );
this.configuredAmount = result.getStackSize();
}
this.configuredFluid.setStackSize( this.configuredAmount );
}
}
@@ -390,108 +399,35 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
@MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange ev )
{
if( !this.getProxy().isPowered() )
if( this.getProxy().isPowered() )
{
if( this.myWatcher != null )
{
if( this.configuredItem != null )
{
this.configuredItem.setStackSize( 0 );
}
if( this.configuredFluid != null )
{
this.configuredFluid.setStackSize( 0 );
}
}
}
else
{
try
{
if( this.configuredItem != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
if( this.configuredFluid != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
}
}
catch( final GridAccessException e )
{
// ;P
}
this.configureWatchers();
}
}
@MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c )
{
if( !this.getProxy().isPowered() )
if( this.getProxy().isPowered() )
{
if( this.myWatcher != null )
{
if( this.configuredItem != null )
{
this.configuredItem.setStackSize( 0 );
}
if( this.configuredFluid != null )
{
this.configuredFluid.setStackSize( 0 );
}
}
}
else
{
try
{
if( this.configuredItem != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
if( this.configuredFluid != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
}
}
catch( final GridAccessException e )
{
// ;P
}
this.configureWatchers();
}
}
@Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
{
this.configuredAmount = fullStack.getStackSize();
if( this.configuredItem != null )
{
long diff = this.configuredItem.getStackSize() + diffStack.getStackSize();
this.configuredItem.setStackSize( diff >= 0 ? this.configuredItem.getStackSize() + diffStack.getStackSize() : 0 );
final long stackSize = this.configuredItem.getStackSize();
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize );
if( !humanReadableText.equals( this.lastHumanReadableText ) )
{
this.lastHumanReadableText = humanReadableText;
this.getHost().markForUpdate();
}
this.configuredItem.setStackSize( this.configuredAmount );
}
else if( this.configuredFluid != null )
{
long diff = this.configuredFluid.getStackSize() + diffStack.getStackSize();
this.configuredFluid.setStackSize( diff >= 0 ? this.configuredFluid.getStackSize() + diffStack.getStackSize() : 0 );
final long stackSize = this.configuredFluid.getStackSize() / 1000;
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
if( !humanReadableText.equals( this.lastHumanReadableText ) )
{
this.lastHumanReadableText = humanReadableText;
this.getHost().markForUpdate();
}
this.configuredFluid.setStackSize( this.configuredAmount );
}
this.getHost().markForUpdate();
}
@Override

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