Compare commits

...

307 Commits

Author SHA1 Message Date
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
PrototypeTrousers e96b4a698a fluid containers can now be drained/filled from fluid interfaces 2021-08-04 19:38:00 -03:00
PrototypeTrousers 1d5465a4b8 partially revert fda8c8 2021-08-04 09:28:47 -03:00
PrototypeTrousers 09cbfe96d6 fix NPE when configuring storage busses 2021-08-01 17:36:23 -03:00
PrototypeTrousers cbdad7c58e hopefully fix storage busses for good
1
2021-07-31 23:05:59 -03:00
PrototypeTrousers 6be96956a9 small optimization to import/export busses 2021-07-30 23:26:42 -03:00
PrototypeTrousers e376e002e9 actually fix #43 ? .... 2021-07-30 07:51:57 -03:00
PrototypeTrousers 0b9df31d4e fix broken recipes resulting in item dupes 2021-07-28 19:46:42 -03:00
PrototypeTrousers cef6dbf0d7 fix copy-paste error in the fluid storage bus constructor 2021-07-27 19:32:59 -03:00
Salomão e4af7b1947 fix adapters insert-only mode still reporting items 2021-07-27 12:51:24 -03:00
Salomão 6eadb8f861 fix IO-Port transfer stopping too soon 2021-07-27 11:10:45 -03:00
PrototypeTrousers b6b6a83563 do the same for fluid storage bus 2021-07-26 20:34:15 -03:00
PrototypeTrousers 32ab4c6af4 Merge remote-tracking branch 'PrototypeTrousers/AE2-Omnifactory' into AE2-Omnifactory 2021-07-26 18:25:24 -03:00
PrototypeTrousers fda8c87410 attempts to fix #42 and #43 2021-07-26 18:25:08 -03:00
PrototypeTrousers 389e060707 Merge pull request #41 from BalaM314/patch-1
Fix #27
2021-07-23 10:40:01 -03:00
BalaM314 0942a90ef4 Fix #27
Not sure exactly what method is causing a crash, but added a catch to just say it is located in another dimension
2021-07-23 15:11:07 +05:30
PrototypeTrousers 8cef06512a restore breaking API change 2021-07-22 21:50:56 -03:00
PrototypeTrousers 8e4658be20 fix power not going to sub-networks
renamed variables
2021-07-18 17:52:01 -03:00
PrototypeTrousers 0bd2bd6b5a dont pause main thread when calculating 2021-07-17 22:15:54 -03:00
PrototypeTrousers db2c4c4325 ensure the local energy cache is iterated last 2021-07-17 22:11:11 -03:00
Salomão ac793ee847 Merge branch 'delta' into AE2-Omnifactory 2021-07-17 14:48:22 -03:00
Salomão 6404f26cca Merge remote-tracking branch 'origin/fluid-terminal-multiple-containers' into AE2-Omnifactory 2021-07-16 14:22:21 -03:00
Salomão ced6ad865c re-introduce time-based calculation quota
player initiated crafting calculation is not affected
2021-07-16 14:22:09 -03:00
Salomão 24750f00b1 reworked how changes are propagated in the network 2021-07-16 14:13:48 -03:00
Salomão df08ce0513 Fluid terminal is now able to fill/empty stacked tanks 2021-07-04 10:28:36 -03:00
Salomão f9c274fb48 Reduce power flickering by increasing energy polling rate
in testing 84 dense cells could sustain MAX Integer on a FE p2p pair
2021-06-27 23:17:26 -03:00
Salomão 3582582e3f fix off-by-one voiding patterns when removing expansion cards 2021-06-26 10:25:47 -03:00
Salomão 6de48f8541 fixes #34
getAllIngredients() can contain nulls
2021-06-26 07:31:16 -03:00
Salomão 5a2c2d06d3 make pattern expansion recipe shapeless 2021-06-24 22:34:21 -03:00
Salomão 98d3cafdfd Merge branch 'oredictfixes' into AE2-Omnifactory 2021-06-23 10:19:02 -03:00
Salomão 904de49543 wip
fix substitution crafting, for real this time
wip 2


wip. still has NBT issues


fix semantic changes


fix interface with free slots on interface terminal


Auto stash before cherry pick of "fix interface with free slots on interface terminal"
2021-06-23 10:16:59 -03:00
Salomão b0772bf94c backport 223163aa0a
fixes #32
2021-06-21 22:48:25 -03:00
Salomão aa5d5e3623 set idle power usage of expanded interface to a power of four 2021-06-21 16:25:26 -03:00
Salomão 42f4ef2855 tweak GUIs 2021-06-21 15:54:40 -03:00
Salomão 3eb2582f29 Merge branch 'bigger-interfaces' into AE2-Omnifactory 2021-06-21 15:22:13 -03:00
Salomão 307f86ded8 increase AE energy polling rate from once every 90 to once every 3 ticks 2021-06-18 12:48:01 -03:00
Salomão 56f57e18a5 Merge branch 'wip' into AE2-Omnifactory 2021-06-17 23:32:34 -03:00
Salomão eab695b692 try to not void fluids in fluid terminal when running out of power 2021-06-17 23:32:16 -03:00
Salomão 0fb393820b half-undo wip 2021-06-17 00:07:06 -03:00
Salomão 01fe5c7a8b jei transfer tweaks..again 2021-06-16 19:22:52 -03:00
Salomão 8468b47443 workaround for damaged tools and gtce tools not being set as damageable 2021-06-15 12:46:44 -03:00
Salomão 6cb583c918 clear old NBT from cells 2021-06-15 12:41:51 -03:00
Salomão d69395a117 cache fixes 2021-06-14 12:57:49 -03:00
Salomão 59effe8131 save NBT properly 2021-06-14 11:51:17 -03:00
Salomão 6f42876963 Merge branch 'fastutil' into AE2-Omnifactory 2021-06-14 10:54:12 -03:00
Salomão 08952b48dd backported fastutil implementation of the item list 2021-06-14 10:53:50 -03:00
Salomão e3c9c4ce65 clear cells of craftable status
remove unsupported removal call
2021-06-14 10:20:58 -03:00
Salomão 7b91da58c0 resolve suspicious calls 2021-06-14 02:33:43 -03:00
Salomão 26c06bca15 fix IO-Port copying craftable boolean 2021-06-14 02:33:23 -03:00
Salomão 4458bd28ab refresh ETA not only when items are crafted 2021-06-13 20:30:52 -03:00
Salomão df3f00d978 try to fix remaining concurrent modifications to energy grid 2021-06-13 20:29:56 -03:00
Salomão 18ae994ee4 try to avoid CME by copying FE p2p outputs before iterating
backported 1c88ea7b78 and attempt to fix #25 with feedback
2021-06-10 21:13:41 -03:00
Salomão 47888b5546 reworked Adapter caches ( storage busses ) 2021-06-09 16:31:49 -03:00
Salomão e18593feb5 fix pattern inventory size mismatch 2021-06-08 23:46:37 -03:00
Salomão af4c3de55e fix client desync 2021-06-08 23:23:12 -03:00
Salomão bea29331a3 implement pattern expansion cards for interfaces
Maximum of 4 rows
Uses 4x the previous tier for crafting operations (4 rows = 64 interfaces consumption)
2021-06-08 23:23:12 -03:00
Salomão 9b9579b358 storage drawer cache optimisation 2021-06-08 23:22:00 -03:00
Salomão 52da4f9528 fix shift-clicking patterns from pattern slot sometimes voiding them 2021-06-05 18:54:26 -03:00
Salomão 50aac2c768 send the player a message if the crafting job succeeds on simulation
but fails on real extraction
2021-06-02 23:46:35 -03:00
Salomão 33946438bd fix JEI ghost fluids not working for filtering fluid storage bus 2021-05-30 13:40:21 -03:00
Salomão 9372cb2f14 Merge remote-tracking branch 'PrototypeTrousers/AE2-Omnifactory' into AE2-Omnifactory 2021-05-29 20:13:43 -03:00
Salomão 00037ace77 Blank Pattern Slot has priority when shift clicking blank patterns 2021-05-29 16:48:59 -03:00
PrototypeTrousers e13af643ba Update CHANGES.md 2021-05-29 14:32:51 -03:00
PrototypeTrousers ffcfd809d8 Add files via upload 2021-05-29 14:32:23 -03:00
Salomão 7c10a6b883 fix damaged tools not being selected for JEI recipe transfer 2021-05-27 17:15:19 -03:00
Salomão c2bddc30c4 fix NPE transfering recipes without an actual output 2021-05-26 16:09:40 -03:00
Salomão 024655f84d fix fluid terminal not having a recipe 2021-05-24 15:42:25 -03:00
Salomão 589e48ac01 restore depth on highlight
fixes #21
2021-05-23 18:14:07 -03:00
Salomão 43d3a2c1c0 add dimension info to the interface highlighting
implements #20
2021-05-23 17:46:28 -03:00
Salomão c432fa7200 automatically change between crafting/processing recipes on jei transfer 2021-05-23 01:06:39 -03:00
Salomão cc744ab8b9 Revert "level emitter changes"
This reverts commit 9d6026635d.
2021-05-17 21:11:08 -03:00
Salomão 8fe4229a8e add extra checks 2021-05-17 00:27:53 -03:00
Salomão 3f86884965 fix GTCE blocking mode 2021-05-16 23:28:05 -03:00
Salomão 1319ec79c9 allow GTCE blocking mode to work through phantom faces 2021-05-16 13:30:27 -03:00
Salomão 31a3afc18b revert inventory merging code to keep compatibility with ae2fc 2021-05-14 12:43:34 -03:00
Salomão 9d6026635d level emitter changes 2021-05-13 19:32:03 -03:00
Salomão 39038ac935 revert iitemrepository cache changes 2021-05-12 23:22:54 -03:00
Salomão 4f627b234c invert comparison 2021-05-12 03:26:12 -03:00
Salomão 6180c188e6 Revert "remove crafting failure penalty"
This reverts commit 0240a5d76a.
2021-05-12 02:42:34 -03:00
Salomão 7ada6d18ee small optimizations 2021-05-12 00:19:55 -03:00
Salomão f493767243 fix out of bounds crash 2021-05-09 22:00:20 -03:00
Salomão ba4cdbcb85 fix #16 2021-05-09 10:59:31 -03:00
Salomão f3877aa1ec Merge branch 'iir-cache' into AE2-Omnifactory 2021-05-08 22:46:56 -03:00
Salomão 366b31b3aa import bus optimization 2021-05-08 22:11:13 -03:00
Salomão 533fb5c34b initial test 2021-05-08 19:40:58 -03:00
Salomão 62d1d904c6 update item cache directly on insert/removal
import bus fails faster and throttles down when inventory is full
2021-05-08 19:08:21 -03:00
Salomão 03fb43db16 revert blocking mode to previous implementation 2021-05-05 19:45:25 -03:00
Salomão 9576bec855 renamed method. fixed round robin while blocking mode on 2021-05-04 22:51:20 -03:00
Salomão b5da6730a1 loop optimization 2021-05-04 15:15:09 -03:00
Salomão 039bab4811 drop items waiting to be injected when interface is broken 2021-05-04 11:07:31 -03:00
Salomão 4b5bdf9893 fix NPE 2021-05-04 10:57:01 -03:00
Salomão 3c3c23712d Merge branch 'rr-interfaces' into AE2-Omnifactory 2021-05-03 21:38:43 -03:00
Salomão af91c04ea1 re - implement blocking mode 2021-05-03 21:34:59 -03:00
Salomão 0240a5d76a remove crafting failure penalty 2021-05-03 21:09:03 -03:00
Salomão 0c0aafba2f make ItemSlots copy-able 2021-05-03 21:07:51 -03:00
Salomão b541025738 implement patterned input-based blocking mode
remove GTCE-specific handler and adaptor
2021-05-03 21:07:12 -03:00
Salomão 62f842d4ef visit crafting mediums in round-robin 2021-05-03 21:05:14 -03:00
Salomão fc154d8568 remove slotless capability implementation from inventory adaptor
affects  interface,import and export busses
2021-05-03 21:00:35 -03:00
Salomão 4641e48529 push patterns in round-robin 2021-04-30 12:20:36 -03:00
Salomão 0fae87afc7 allow left clicking on bookmarked items on GUIs without fake slots 2021-04-26 23:53:43 -03:00
Salomão ee1b6bb0d7 Add bookmarked ghost items support
fixed fluid dragging not working on servers
2021-04-18 21:01:09 -03:00
Salomão 36ca8b9f0a JEI Bookmark dragnDrop 2021-04-15 22:58:57 -03:00
Salomão 9c94c7342b Merge branch 'JEI-drag-phantom-items' into AE2-Omnifactory 2021-04-14 21:46:40 -03:00
Salomão 399d67b42c made jei recipe transfer more strict when keeping items on the table
few cleanup
2021-04-14 21:37:06 -03:00
Salomão 10761a1e9d missing click cancel 2021-04-14 00:04:07 -03:00
Salomão d1ddf53d99 wip 2 2021-04-13 14:54:52 -03:00
Salomão f776b4d548 wip 2021-04-13 12:36:20 -03:00
Salomão 41180792e1 Cellworkbench acts weird
missing bookmark dragging
2021-04-12 23:51:49 -03:00
Salomão 2269c05d98 implement #14
also fix tooltip position
2021-04-10 09:46:48 -03:00
Salomão 63616e5730 try fix #13 2021-04-10 09:30:44 -03:00
Salomão 6ca3e6e696 add tooltip to fluid level emitter number box 2021-04-05 00:11:30 -03:00
Salomão a4b5cfc3b9 fix lightning issue while tooltip is showing on interface terminal 2021-04-04 22:17:14 -03:00
Salomão 38b0a7a153 handle interface slots serverside 2021-04-04 01:29:27 -03:00
Salomão aa4863a979 Added Fluid support for the Storage Monitor and Conversion Monitor
Highlighted interfaces is turned off after switching dimensions
2021-04-02 08:31:14 -03:00
Salomão 44c7a46315 fix advancements not triggering 2021-04-02 08:29:32 -03:00
PrototypeTrousers c3b1dea7c5 better level emitting 2021-03-31 17:34:43 -03:00
Salomão 40ec517480 level emitters cache rework 2021-03-30 23:05:15 -03:00
Salomão 2fdc16d3a8 Merge remote-tracking branch 'ALongStringOfNumbers/recipeConditions' into AE2-Omnifactory 2021-03-30 21:58:46 -03:00
Salomão 053485a95a another try at fixing level emitters 2021-03-30 21:57:53 -03:00
ALongStringOfNumbers e910af7734 Fix advancements to check if their parent item is enabled to prevent more logging 2021-03-30 15:36:25 -07:00
Salomão 59d7bd6c16 JEI recipe transfer fixes
re-checks the amount of items in the recipe
only do fuzzy search for damageable items
2021-03-29 21:20:46 -03:00
Salomão 1a11462ddd can now drag encoded patterns on the interface terminal 2021-03-29 01:53:59 -03:00
Salomão 77d615559f Add proper button and tooltips to interface terminal 2021-03-28 16:20:37 -03:00
ALongStringOfNumbers 6878bfa4b0 Fix parts 2021-03-27 01:26:29 -07:00
ALongStringOfNumbers f1d50eca1a More minor fixes 2021-03-26 22:10:24 -07:00
ALongStringOfNumbers 4ee32dd0b0 Fix some recipes not showing up due to bad conditions 2021-03-26 21:48:03 -07:00
ALongStringOfNumbers 66e589324a Make recipes and advancements conditional
Fix crash when fluix was disabled
2021-03-26 19:12:49 -07:00
Salomão 362b001cb4 level emitter dying fix 2021-03-25 22:48:42 -03:00
Salomão b6fd4b3c0f changed priority of JEI items on the 2021-03-23 22:23:58 -03:00
Salomão e364603a5a Changed level emitters to update only once when they tick 2021-03-17 21:35:26 -03:00
Salomão c58bebc346 Fix gregtech tileentities showing up as unnamed or draconium lens 2021-03-07 23:59:39 -03:00
Salomão 97f11f0c61 Fix storage drawers showing up as nothing on interface terminal 2021-03-07 23:56:52 -03:00
Salomão 5c2fa72f95 mix pattern terminal multiplying items above maxitemstack size 2021-03-07 00:01:01 -03:00
Salomão ebd8501301 fix inaccessible items setting in storage bus not being respected 2021-03-07 00:00:16 -03:00
Salomão fa07247bd7 Revert "also shrink the fluid skiplist if the tanks change sizes"
This reverts commit 892c919ee2.
2021-03-04 23:08:08 -03:00
Salomão 95d25ddf47 Revert "Skip un-extractable slots."
This reverts commit e2e6f6e83f.
2021-03-04 23:07:58 -03:00
Salomão 7a45e1faf4 Revert "rebuild skipslotlist if the the inventory grows or shrinks"
This reverts commit 7796c6d4b6.
2021-03-04 23:07:34 -03:00
Salomão 1f88494832 fix not being able to swap patterns on interface terminal 2021-03-03 09:57:02 -03:00
PrototypeTrousers c629b4e0cf Merge pull request #4 from Theisyat/AE2-Omnifactory
Fixed 'Only show Empty' in Interface Terminal
2021-03-02 19:56:16 -03:00
PrototypeTrousers 65ca607134 Merge branch 'AE2-Omnifactory' into AE2-Omnifactory 2021-03-02 19:55:52 -03:00
Salomão 898c07ca01 fix toggling full interfaces hiding all interfaces 2021-03-02 18:45:14 -03:00
Theisyat 883c267aa8 Fixed Interface Terminal and Added Stuff
Fixed 'Hide Full' Button

First Free Molecular Assembler Button

Added Button in Interface Terminal, which Searches for 'Molecular
Assembler' and sets the Interface Terminal to only show Assemblers with
free Slots.
2021-03-02 07:00:48 +01:00
Salomão 22cf913708 highlight interfaces from interface terminal. 2021-02-28 21:32:11 -03:00
Salomão b4ba1af1ec bind BlockPos of the interface on the list 2021-02-28 02:03:00 -03:00
Salomão 892c919ee2 also shrink the fluid skiplist if the tanks change sizes 2021-02-24 18:08:57 -03:00
Salomão a65b3d2ceb fix interface terminal GUI 2021-02-24 13:24:04 -03:00
Salomão c826a3e24f Add second search bar to Interface Terminal 2021-02-23 20:48:45 -03:00
Salomão fc98505f22 even more JEI integration
get ingredient from the crafting calculation GUIs
2021-02-22 22:33:05 -03:00
Salomão ea54ccbcf5 More JEI integration 2021-02-22 18:35:46 -03:00
Salomão 7796c6d4b6 rebuild skipslotlist if the the inventory grows or shrinks 2021-02-22 14:33:06 -03:00
Salomão e2e6f6e83f Skip un-extractable slots. 2021-02-21 23:08:16 -03:00
Salomão a7a1a87cd8 Holding SHIFT with an empty hand will increase the amount of items set
on interfaces and on pattern terminal
2021-02-21 20:26:52 -03:00
Salomão e50eb7965f undo monitor ticking limit 2021-02-21 03:24:03 -03:00
Salomão d25a8a53a2 fix IItemRepository insert and extraction 2021-02-21 02:24:50 -03:00
Salomão 92b48f01a2 do not use java equals to compare stacks 2021-02-20 21:18:20 -03:00
Salomão 42f0d37c44 Merge branch 'IItemRepository' into AE2-Omnifactory 2021-02-18 23:26:49 -03:00
Salomão 088a1827be implement IItemRepository 2021-02-18 18:33:06 -03:00
Salomão 6a21968dab add storagedrawers to the gradle deps 2021-02-17 12:30:07 -03:00
Salomão 7c5ff5322a Fix JEI transfer fix. Typo correction. 2021-02-16 16:47:22 -03:00
Salomão 7834028459 Rebuild itemlist only once per tick
re-enabled level-emitters update
2021-02-15 15:41:48 -03:00
Salomão c43cbbef43 Switched JEI search to crafting terminal to fuzzy mode 2021-02-14 02:14:15 -03:00
Salomão ead6274ca4 FIX JEI transfer not working correctly
Missing on the crafting terminal
2021-02-13 21:48:37 -03:00
Salomão f1c41bab3f Implement MouseTweaks API
can now set item quantities in pattern terminal and interfaces by right clicking with the same configured item
2021-02-12 20:26:21 -03:00
Salomão 12e74dc0de Merge remote-tracking branch 'origin/AE2-Omnifactory' into AE2-Omnifactory 2021-02-11 23:07:43 -03:00
Salomão c10088d907 Fill pattern with items from JEI
Just Enough Energistics overrides this
2021-02-11 23:07:26 -03:00
PrototypeTrousers a12d29c4a0 Update README.md 2021-02-09 18:58:08 -03:00
PrototypeTrousers 2227510acf Update README.md 2021-02-09 18:55:22 -03:00
Salomão 97ae7e1f14 encoded patterns now stack up to 64 2021-02-08 22:14:37 -03:00
Salomão fc119070b2 Actually copy level emitters set values 2021-01-15 17:41:40 -03:00
Salomão 82e3a95f11 fix memory card not saving fluids an level emitters 2021-01-12 18:24:05 -03:00
Salomão e6998913e1 remove forced level emitters update
remove unneeded itemStack creation.
2021-01-04 14:18:07 -03:00
Salomão a3e69ce608 add hardcoded id range for molds and shapes for GTCE blocking mode 2020-12-08 22:42:04 -03:00
Salomão ceef176a2a remove time-based thread syncinc 2020-12-01 17:26:42 -03:00
Salomão c2e2696707 Fix fuzzy search for items that have metadata > maxdamage 2020-12-01 17:25:52 -03:00
Salomão 4d6c61dfcb backport e82093eec9459be3211564a83166455150c51259 2020-11-23 00:45:49 -03:00
Salomão 932141cc9e backport b7ca98d1e24e5797a8e42ca861ae4187ab5839ec 2020-11-23 00:45:49 -03:00
Salomão adf59774d4 Remove uneeded Forge Event Firing
improves crafting calculation performance
2020-11-18 20:22:40 -03:00
Salomão 9c6668b0f7 disable "smart" button
wasn't so smart
2020-11-13 17:42:41 -03:00
Salomão 1b7f11a12e buttons work and set quantities properly 2020-11-12 23:27:56 -03:00
Salomão 3cf4f9122c works..ish 2020-11-12 20:42:30 -03:00
Salomão d97996070a x2 button on the right place 2020-11-12 18:40:10 -03:00
Salomão 8a165bea09 ease punishment a bit 2020-10-28 19:50:57 -03:00
Salomão f707f95373 Revert "undo penalties"
This reverts commit d6499c16b0.
2020-10-28 19:49:23 -03:00
Salomão b2a660ec9b formating fixes 2020-10-28 17:50:40 -03:00
Salomão d6499c16b0 undo penalties 2020-10-28 16:59:51 -03:00
Salomão de3e0178a4 update forge and jei 2020-10-27 03:38:12 -03:00
Salomão 203522316c more tweaks testing 2020-10-25 18:57:42 -03:00
Salomão 719ea5090b move gtce blocking code out of generic item adaptor
fixes crash with ae2 fluid crafting
2020-10-25 01:04:48 -03:00
Salomão 00e19d67a2 Tune punishment 2020-10-23 21:39:36 -03:00
Salomão 169f6393d1 move penalty up the chain 2020-10-22 11:24:16 -03:00
Salomão 12bf337238 Re-do Blocking mode logic 2020-10-21 15:44:43 -03:00
Salomão 3b544c2486 Merge remote-tracking branch 'PrototypeTrousers/AE2-Omnifactory' into AE2-Omnifactory 2020-10-20 23:52:18 -03:00
Salomão 660e17d167 Merge remote-tracking branch 'talchas/on-upstream' into AE2-Omnifactory 2020-10-20 23:52:11 -03:00
Salomão b10246a67b Merge remote-tracking branch 'talchas/on-upstream' into AE2-Omnifactory 2020-10-20 23:04:44 -03:00
Salomão 74362bb543 Merge branch 'ae2-interface-export-bus-fixes' into AE2-Omnifactory 2020-10-20 23:02:53 -03:00
Salomão 81df58afa5 dont try to re-request craft immediately, if we cant craft it now 2020-10-20 23:01:09 -03:00
Salomão 535289e694 Change interface behavior
skip complete configured stacks
postpone crafting job start
2020-10-20 14:30:08 -03:00
yueh d730503378 Fixes #4388: Ensure correct ticking priority order (#4393) 2020-05-27 16:13:20 +02:00
yueh f3349b0a2d Fixes #4372: Limit validated itemstack to a size of 1 (#4373) 2020-05-07 11:49:00 +02:00
yueh f667e9a5f0 Reduce lock time 2020-04-25 18:28:33 +02:00
Hinara 2c0a2975de Fix #4114 (#4357) 2020-04-25 18:05:14 +02:00
yueh 2e3d6b721a Run daily after the initial cleanup is done 2020-03-30 11:00:43 +02:00
yueh 94e294f4e9 Remove redundant option 2020-03-27 21:28:55 +01:00
yueh 91620a0042 Handle issues and prs 2020-03-27 21:23:29 +01:00
yueh ffc79b5494 Run workflow hourly 2020-03-27 19:43:09 +01:00
yueh ce7c29d0ac Create lock.yml 2020-03-27 18:06:46 +01:00
talchas 5ac8db41e7 option for a blocking mode that actually works 2020-02-06 18:13:31 -08:00
yueh 6ece190ac4 Fixes #4127: Increase JEI box for grindstone recipes (#4270) 2020-01-30 10:06:14 +01:00
yueh 00a596ea8f Fixes #4268: Disabled JEI facade recipe when disabled. (#4269) 2020-01-30 09:35:45 +01:00
yueh 1fc1d5517d Fixes #4213: Prevent NPE when inserting via conversion monitor (#4265) 2020-01-26 13:36:06 +01:00
yueh d5fc7a5b21 Fixes #4256: Cache AESharedItemStack#hashCode() (#4257) 2020-01-16 13:22:42 +01:00
Rik Pronk 1f85d0f607 Fix CraftTweaker Grindstone second optional output (#4250)
Fixes an issue where the CraftTweaker Grindstone integration registered the second optional output as first optional output
2020-01-16 10:57:18 +01:00
talchas dfe5b82bda Safer implementation of CraftingGridCache updatePatterns coalescing 2019-12-31 10:57:23 -08:00
talchas c7f8f4249e Avoid quadratic behavior from rebuilding the entire crafting cache for
each interface visited. Instead rebuild it at most once per tick, like
cpu clusters.

This is particularly important when channels are disabled, since in
that case even adding a cable visits every grid node.
2019-12-31 10:57:23 -08:00
ruifung 5efa6d6251 Update API JavaDocs for clarification (#4180)
* Fix javadoc for IGridBlock.getMachineRepresentation()

Javadoc should state proper semantics for that method, and telling people to return null there is a sure crash. #4178

* Update IPart interface javadoc.

Update the javadoc to state that functional parts should not be allowed to be placed on dense cables.
2019-12-19 10:18:27 +01:00
Andrew Motz 4269a66a4b Fix Typos in README.md (#4183)
"Summery" to "Summary"
2019-12-19 10:16:59 +01:00
Chan, Danny df2a7c1858 Add "cullface" into charged_quartz_ore.json (#4108) 2019-08-07 10:08:05 +02:00
yueh c483bd17f5 Fixes #4089: Render cable core on straight lines of different types. (#4103) 2019-07-23 21:12:17 +02:00
yueh 92536fceb4 Fixes #4090 Portable cell incorrect empty itemstack handling (#4093) 2019-07-23 20:13:15 +02:00
yueh ded71cb2bd Fixes #4062: Rounding error due to float precision. (#4064) 2019-06-20 10:47:28 +02:00
yueh 41a4518c5b Fixes #4005: Persist cell after cleanup. (#4009) 2019-04-21 22:30:45 +02:00
yueh 87643094c3 Fixes #3925: Incorrect API JavaDoc (#4008)
`IGridBlock#getMachineRepresentation()` must be non null.
2019-04-21 22:30:35 +02:00
yueh 8a4c9b58e6 Fixes #3911: Incorrectly used string format. (#4007) 2019-04-21 22:30:21 +02:00
InterPlay 5436e6bf08 Added support for fluids in pt-BR lang file (#3904) 2019-04-21 13:20:57 +02:00
yueh 078112d97b Disable modmaven due to build issues for now (#4011) 2019-04-21 13:10:02 +02:00
yueh 46355a4e9b Fixes #3899: Put fluid interface into configured mode when needed. (#3903) 2019-01-15 12:52:12 +01:00
yueh eb389971a3 Fixes #3901: Ensure fluid terminal respects reported stacksizes. (#3902) 2019-01-15 12:52:00 +01:00
yueh a38ebf7c4d Fixes #3886: Initialise sleeping import bus in pulse mode. (#3887) 2018-12-26 23:28:17 +01:00
yueh dfcba264f3 Fixes #3880: Incorrect compare with empty itemstack. (#3882) 2018-12-25 21:21:19 +01:00
yueh d343ac47f5 Added CTM as actual soft dependency. (#3881) 2018-12-25 21:21:08 +01:00
yueh 05db930a4e Fixes #3821: Unconfigured level emitter now report all fluids. (#3875) 2018-12-24 14:44:40 +01:00
yueh 33bc0a6a3f Fixes #3776: Fixes dupe bug with cell upgrades. (#3874) 2018-12-24 14:11:45 +01:00
yueh f2f48a8d59 Fixes #3767: Fluid Annihilation plane too strict about leftover (#3872) 2018-12-23 23:33:15 +01:00
yueh 0f0af2349b Fixes #3866: Use blockstates to avoid the missing fluid block. (#3869) 2018-12-23 22:42:25 +01:00
yueh 32a4fcab77 Fixes #3768: Damageable items with nbt and without damage could crash. (#3867) 2018-12-23 22:42:09 +01:00
yueh a847a01d8a Feature #3832: Made onRequestChange() less ambiguous (#3833) 2018-12-23 22:41:52 +01:00
yueh ed643787df Updated gradle scripts (#3871)
Includes #3819
2018-12-23 22:41:11 +01:00
covers1624 524b26d2a2 Implement caching for facade item models. 2018-12-19 12:46:43 +01:00
covers1624 184b1f8efb Guard against models providing quads with null orientations. 2018-12-19 12:46:43 +01:00
E. Kim 06cca13087 Update ko_kr.lang (#3674) 2018-11-17 10:31:29 +01:00
徐晨曦 8e735e72ff Update zh_cn.lang (#3570) 2018-11-17 10:31:01 +01:00
yueh d3dd137570 Fixes #3817: Missing 1k Crafting Storage and Monitor from Network Status (#3818) 2018-11-11 13:11:45 +01:00
yueh 78e1126c38 Fixes #3814: IO Port no longer put to sleep on load when having work. (#3816) 2018-11-11 11:52:13 +01:00
yueh ebe3ff045d Fixes #3811: Display crafting unit as themself in the network monitor. (#3815) 2018-11-11 11:52:03 +01:00
yueh 6291a545c3 Fixes #3793: Limit filling fluid inventories to their max capacity. (#3794) 2018-10-21 11:18:02 +02:00
yueh 99fd5a9d53 Fixes #3790: Correctly handle fluids with NBT data. (#3791) 2018-10-21 11:17:27 +02:00
yueh 416c7d2683 Input P2P tunnels can now be assigned a new frequency. (#3765)
Shift right clicking an existing tunnel only allowed to copied the
stored frequency.

When shift right clicking now and the stored frequency being the same as
already stored one, it will now create a new one and save it to the memory
card. In other words doubling clicking will reset now, otherwise the old
behaviour is still kept.
2018-10-21 11:17:01 +02:00
yueh 0c88d1e7ee Fixes #3746: Revert OreDict use for cable anchors. Blame Forge for crashes. (#3764) 2018-10-06 00:02:41 +02:00
fscan d88f550eb0 Switch to new IItemHandler (#3669) 2018-10-04 20:39:06 +02:00
yueh e21c59b326 Fixes #3146: Prevent crash when GlassState is missing. (#3758) 2018-10-04 19:33:10 +02:00
yueh d8af8d26be Updated to new Forge RB (#3760) 2018-10-04 19:32:47 +02:00
yueh 02426bc101 Update bug_report.md
Fixed missing *
2018-10-02 17:38:22 +02:00
yueh 11f8471772 Updated issue templates
Updated bug report
Added feature request
2018-10-01 13:12:44 +02:00
yueh d35b720a16 Update issue templates (#3751) 2018-10-01 13:00:07 +02:00
mezz 7a5b84c10a Allow JEI to differentiate between different cable facades (#3750) 2018-10-01 11:18:38 +02:00
covers1624 800860d4e6 Fixes #3747: Fix issues with facade breaking textures. (#3748) 2018-10-01 11:12:38 +02:00
yueh ac81418684 Changed some fluid recipes to match their item variant. (#3744) 2018-09-28 18:25:05 +02:00
yueh 7daad58607 Fixes #3742: Do not use storableInStorageCell() to identify generic c… (#3743)
Annotated IStorageCell with Nonnull where appropriate.
2018-09-28 17:38:08 +02:00
yueh 038ca23523 Fixes #3688: Invalidate Storage Bus cache immediately upon missing TE. (#3737) 2018-09-28 17:36:58 +02:00
yueh 37d8833b95 Fixes #3708: Move knifes/wrenches to oredict as constants are unreliable (#3729) 2018-09-22 20:14:28 +02:00
yueh fdcba13369 Power off a network in case it losses its local buffer. (#3703)
This better indicates power issue with dynamic consumption like
extracting/inserting items into a network. E.g. the terminals will
shutdown, no light/channel/etc indicators.

Due to the networks trying to extract from the largest possible energy
storage first, the network buffer will be used as last option after
energy cells or controllers.

Potentially needs evaluation in case of adhoc networks with a high
transfer rate locally. Increasing the local buffer might be an idea or
have it scale with the amount of local gridnodes. As long as it does not
invalidates energy cells.
2018-09-02 14:00:15 +02:00
yueh b1ac0adfd8 Added a new facade config. (#3706)
The whitelist is now based on manually add explicit entries instead of
automatically adding every existing block. This alone should save a few
MB of RAM depending on the modpack size.

Additionally the FacadeConfig is no longer extending the normal
Configuration provided by Forge. It will only parse the file once per
start and store the settings in an optimised collection to further
reduce memory consumption.

Any full block without a TileEntity and having a model is whitelisted
automatically and does not need an explicit entry anymore.

By default vanilla and AE2 glass is added as they are no fullblocks
technically.

The whitelist technically allows many more blocks now. E.g. stairs,
slabs or even items like saplings. But with various rendering quality.

Further there is an option to allow facades based on TileEntities, this
is completely unsupported and can work or corrupt the whole save.
2018-09-02 13:59:18 +02:00
covers1624 7ba2893635 New facade system (#3702)
Completely new system to render facades.

It will now support many more cases compared to the old system.
For example connected textures are now possible, as well as multilayer models and so on.
2018-09-02 13:26:20 +02:00
fscan ed8baf8c15 Fix tooltip for vibration chamber (#3675) 2018-08-30 23:13:38 +02:00
yueh 758377ed5d Various code fixes (#3704)
Correctly close streams.
Avoid ArithmeticException in case of /0.
2018-08-30 23:12:35 +02:00
yueh a2091d10fe Code cleanup
Added missing this, annotations, etc.
2018-08-30 20:33:08 +02:00
yueh fed12cb99f Organise Imports 2018-08-30 20:32:01 +02:00
yueh 66c365d11f Code Formatting 2018-08-30 20:31:27 +02:00
yueh 044f4c9ed3 Added jacoco for coverage reports (#3700) 2018-08-30 20:09:36 +02:00
yueh 91a74813d9 Updated Travis CI caches (#3699) 2018-08-30 20:09:25 +02:00
yueh a0b645a0a7 Added SonarCloud integration (#3698)
Updated gradle wrapper to 4.8
2018-08-29 23:24:55 +02:00
fscan d439fb2915 Fix fluid parts item models (#3676) 2018-08-29 19:09:04 +02:00
yueh 7efd4d872f Readded forge as required dependency. (#3678)
Version will automatically be computed based on the release used to
build as well as the next major release being marked as exclusive upper
bound.
2018-08-29 19:08:46 +02:00
yueh 1b09760631 Followup #3646: Assemblers actually have to render in both layers. (#3662) 2018-08-05 13:11:36 +02:00
fscan 04daadceed Increase Vibration Chamber AE/t (#3635) 2018-08-01 00:27:19 +02:00
yueh 4d3df96350 Fixes #3646: Render assemblers in the correct layer. (#3658) 2018-08-01 00:26:28 +02:00
fscan d7e2ae8fcb Fix ConcurrentModificatonException in NetworkEventBus (#3654)
Fixes #3653
2018-08-01 00:20:47 +02:00
fscan 73f471e685 Make search box toggle key configurable (#3650)
Fixes #3641
2018-08-01 00:20:17 +02:00
fscan 390ad875ee Fix Platform#postChanges to check all registered channels (#3644) 2018-08-01 00:19:49 +02:00
fscan e5f43bf315 Allow ME Chest to work with any cell (#3640) 2018-08-01 00:17:43 +02:00
fscan 8a72ebca89 check if actually added before removing (#3639)
Fixes #3634
2018-08-01 00:17:10 +02:00
fscan ad1eff2adb Condensor improvements (#3636) 2018-08-01 00:15:30 +02:00
fscan 9e252df8d9 Fix dupe bug with shulker box (#3633)
Fixes #3632
2018-08-01 00:13:58 +02:00
yueh 67584083c6 Fixes #3630: Formation planes not respecting the entity limit. (#3631) 2018-08-01 00:13:20 +02:00
fscan c1c7e94cf6 Generic ICellInventoryHandler (#3624)
Allows addons who register a custom IStorageChannel to use the IStorageCell interface without registering a cell handler. Also adds some helpers (poweredInsert/poweredExtract).
This breaks API!
2018-07-22 19:20:47 +02:00
fscan 85dec35366 Fix buckets in vibration chamber (#3626) 2018-07-20 21:51:05 +02:00
710 changed files with 17953 additions and 5988 deletions
+30
View File
@@ -0,0 +1,30 @@
---
name: Bug report
about: You found a bug or encountered a crash? Please report it here.
---
<!-- Provide a summary of the issue in the Title above, please do not "[Tag]" it. -->
**Describe the bug**
<!-- Always use the most recent version from ae-mod.info, it might already be fixed. -->
**To Reproduce**
<!-- Please provide the steps to reproduce it, otherwise we might not be able to fix it. -->
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Additional context**
<!-- Screenshots, crashlogs, etc. -->
<!-- A complete crashlog is required when reporting a crash. No excerpts. -->
<!-- Please use pastebin or gist for posting the complete crashlog. -->
**Environment**
<!-- Include as many relevant details about the environment -->
<!-- Like the used version, SP/MP, other mods and their version -->
<!-- The following ones are required, please note "latest" is not a version -->
- Minecraft Version:
- AE2 Version:
- Forge Version:
+17
View File
@@ -0,0 +1,17 @@
---
name: Feature Request
about: A feature request or suggestion to improve Applied Energistics 2
---
<!-- Provide a summary of the issue in the Title above, please do not "[Tag]" it. -->
**Describe the feature**
<!-- Tell us how it should work. -->
**Reasons why it should be considered**
<!-- This can help us in various degrees, e.g. to determine if it fits our design ideas. -->
**Additional Context**
<!-- Use this for further details, e.g. screenshots, links to mods for integrations. -->
<!-- Features will only be considered for the latest/next version. -->
+15
View File
@@ -0,0 +1,15 @@
name: 'Lock threads'
on:
schedule:
- cron: '0 0 * * *'
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: '180'
pr-lock-inactive-days: '180'
+19 -6
View File
@@ -7,14 +7,27 @@ jdk:
- openjdk8
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
- rm -f $HOME/.gradle/caches/minecraft/deobfedDeps/providedDummy.jar
- rm -f $HOME/.gradle/caches/minecraft/deobfedDeps/compileDummy.jar
- rm -f $HOME/.gradle/caches/minecraft/ForgeVersion.json
- rm -f $HOME/.gradle/caches/minecraft/ForgeVersion.json.etag
- rm -fr $HOME/.gradle/caches/minecraft/deobfedDeps
- rm -f $HOME/.gradle/caches/*/fileHashes/fileHashes.bin
- rm -f $HOME/.gradle/caches/*/fileHashes/fileHashes.lock
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'
- '$HOME/.gradle/wrapper'
- '$HOME/.gradle/caches'
addons:
sonarcloud:
organization: "appliedenergistics"
install: "./gradlew setupCIWorkspace"
script: "./gradlew build test"
script:
- "./gradlew build"
- "./gradlew test"
- "./gradlew sonarqube"
+58
View File
@@ -0,0 +1,58 @@
Changes so far :
Design changes/breakages:
- Interfaces no longer spill items of one pattern on other faces
- Interfaces now push patterns in round-robin (Interfaces, then sides)
Fixes:
- Fix gregtech machines appearing with 'unnamed' or 'draconium lens' on the interface terminal on specific situations.
- Add memorycard support for fluid interfaces, import/export/storage busses and level emitters ( this fix was upstreamed to AE2 for MC 1.16)
- Storage busses now hide/show inaccessible items as configured.
- Exclusive Blocking mode for GTCE ( shapes, molds and configured circuits do not block GTCE machines )
- Blocking modes default to block on any item in the iventory the entity exposes
- Fuzzy includes items that report that they're damageable, but report a maxDamage of 0 ( auto-crafting of basic capacitors -> resonant capacitors is now possible ) <- Broken item implementation.
- Fix CME exceptions on the energy grid
- Fix AE going offline even with enough power by extracting from the local buffer always last
- Fix IO-Port copying craftable flag into items
- Fix NBT of old items not clearing on drives that reached 64 types once
Performance:
- Added @talchas fixes for insane channelless AE networks.
- Implemented StorageDrawers slotless itemrepository.
- Removed CraftedEvent calls (really bad lag with craftweaker versions before CraftTweaker2-1.12-4.1.20.626)
- Count items set in interfaces before queuing crafting for them needlessly
- Backported b7ca98d ( Avoid copying items on simulated item extraction )
- Cache some level emitters functions
- Reduced import bus insert simulation to 1 before real insertion (if possible)
- Backported itemlist re-implementation along with pattern changes to avoid CraftingManager fallback issues
- Instead of recalculating all the content of the network on every change, track the changes properly and apply them to the cached list of items
QOL:
- added highlight interface button to interface terminal ("?" button on the left of the interface slots)
- Added bar on the interface terminal that search by inputs ( The one on the LEFT, also searchs by interface name )
- Shortcut to molecular assemblers with free slots on the terminal interface by @Theisyat
- Toggle button on interface terminal to hide full interfaces
- JEI "U", "R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
- Patterns can now be made with items currently showing on JEI. ( This is overriden by Just Enough Energistics. )
- Added multiplier buttons to processing pattern gui
- Switched crafting terminal JEI search to fuzzy mode. If the recipe uses a damageable item, AE will try to grab it ( damaged tools )
- Encoded patterns stack up to 64 ( holding shift and clicking the encode arrow will transfer the encoded pattern to the player inventory)
- Encoded patterns can be draggred on the interface terminal.
- Storage Monitor and Conversion Monitor now also ccepts fluids
- Draggable JEI ghost items (also works on bookmarked items. SHIFT + Click will move the hovered item into the first free target slot)
- JEI auto switches between crafting and processing patterns
- GTCE Blocking mode work through phantom itemfaces
- Shift-clicking blank patterns into the pattern terminal will try to fill the blank pattern slots first
- Mismached simulated/real item count ( most often due to compacting drawers ) will now tell the player wich item cause the failure when trying to start a craft
- Added 'pattern expansion' cards that adds an extra row of patterns to interfaces. up to 3 card on an interface. (each card will increase the interface idle power draw by 4 times)
HOTKEYS:
- Implemented mousetweaks API. AE2 custom keybinds now work. (Try right clicking and use the scroll-wheel on the terminals)
- Holding SHIFT and scrolling UP and DOWN will increase the items set on the configured slots of Interfaces and Pattern Terminal (Processing mode)
+5 -216
View File
@@ -1,34 +1,15 @@
[![Travis](https://img.shields.io/travis/AppliedEnergistics/Applied-Energistics-2.svg?maxAge=2592000&style=flat-square)](https://travis-ci.org/AppliedEnergistics/Applied-Energistics-2)
[![Latest Release](https://img.shields.io/github/release/AppliedEnergistics/Applied-Energistics-2.svg?label=Latest%20Release&style=flat-square)](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases)
This is a fork of AE2 i made for trying to solve issues for the [Omnifactory](https://www.curseforge.com/minecraft/modpacks/omnifactory) modpack.
# Applied Energistics 2
See https://github.com/PrototypeTrousers/Applied-Energistics-2/tree/AE2-Omnifactory branch for commits
and
https://github.com/PrototypeTrousers/Applied-Energistics-2/releases for the compiled jars.
## Table of Contents
* [About](#about)
* [Contacts](#contacts)
* [License](#license)
* [Downloads](#downloads)
* [Installation](#installation)
* [Issues](#issues)
* [Building](#building)
* [Contribution](#contribution)
* [API](#applied-energistics-2-api)
* [CraftTweaker](#applied-energistics-2-crafttweaker)
* [Localization](#applied-energistics-2-localization)
* [Credits](#credits)
# Applied Energistics 2 (PrototypeTrousers fork for Omnifactory)
## About
A Mod about Matter, Energy and using them to conquer the world..
## Contacts
* [Website](http://ae-mod.info/)
* [IRC #appliedenergistics on esper.net](http://webchat.esper.net/?channels=appliedenergistics&prompt=1)
* [GitHub](https://github.com/AppliedEnergistics/Applied-Energistics-2)
* [Discord](https://discord.gg/GygKjjm)
## License
* Applied Energistics 2 API
@@ -43,198 +24,6 @@ A Mod about Matter, Energy and using them to conquer the world..
* Text and Translations
- [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/)
## Downloads
Downloads can be found on [CurseForge](http://www.curse.com/mc-mods/minecraft/223794-applied-energistics-2) or on the [official website](http://ae-mod.info/Downloads/).
## Installation
You install this mod by putting it into the `minecraft/mods/` folder. It has no additional hard dependencies.
## Issues
Applied Energistics 2 crashing, have a suggestion, found a bug? Create an issue now!
1. Make sure your issue has not already been answered or fixed and you are using the latest version. Also think about whether your issue is a valid one before submitting it.
* If it is already possible with vanilla and AE2 itself, the suggestion will be considered invalid.
* Asking for a smaller version, more compact version, or more efficient version of something will also be considered invalid.
2. Go to [the issues page](https://github.com/AppliedEnergistics/Applied-Energistics-2/issues) and click [new issue](https://github.com/AppliedEnergistics/Applied-Energistics-2/issues/new)
3. Enter your a title of your issue (something that summarizes your issue), and then create a detailed description of the issue.
* Do not tag it with something like `[Feature]`, `[Bug]`, or a version.
* Restrict it to a single bug or feature, it makes managing them way easier for us.
* The following details are required. Also refer to the issue template when creating one.
* Forge version
* AE2 version
* Crash log, when reporting a crash (Please make sure to use [pastebin](http://pastebin.com/))
* Never post an excerpt of what you consider important
* Always post the full log
* Other mods and their version, when reporting an issue between AE and another mod
* Also consider updating these before submitting a new issue, it might be already fixed
* A detailed description of the bug or feature
* To further help in resolving your issues please try to include the follow if applicable:
* What was expected?
* How to reproduce the problem?
* This is usually a great detail and allows us to fix it way faster
* Server or Single Player?
* Screen shots or Pictures of the problem
* Mod Pack using and version?
* Keep in mind that some mods might use an outdated version of AE2
* If so you should report it to your modpack
4. Click `Submit New Issue`, and wait for feedback!
Providing as many details as possible does help us to find and resolve the issue faster and also you getting a fixed version as fast as possible.
Please note that we might close any issue not matching these requirements.
## Building
1. Clone this repository via
- SSH `git clone git@github.com:AppliedEnergistics/Applied-Energistics-2.git` or
- HTTPS `git clone https://github.com/AppliedEnergistics/Applied-Energistics-2.git`
2. Setup workspace
- Decompiled source `gradlew setupDecompWorkspace`
- Obfuscated source `gradlew setupDevWorkspace`
- CI server `gradlew setupCIWorkspace`
3. Build `gradlew build`. Jar will be in `build/libs`
4. For core developer: Setup IDE
- IntelliJ: Import into IDE, execute `gradlew genIntellijRuns` and change RunConfiguration to `*_main` as quickfix for [ForgeGradle](https://github.com/MinecraftForge/ForgeGradle/issues/357)
- Eclipse: execute `gradlew eclipse`
5. For add-on developer: Core-Mod Detection
- In order to have FML detect AE from your dev environment, add the following VM Option to your run profile
- `-Dfml.coreMods.load=appeng.coremod.AppEngCore`
## Contribution
Before you want to add major changes, you might want to discuss them with us first, before wasting your time.
If you are still willing to contribute to this project, you can contribute via [Pull-Request](https://help.github.com/articles/creating-a-pull-request).
The [guidelines for contributing](https://github.com/AppliedEnergistics/Applied-Energistics-2/blob/master/.github/CONTRIBUTING.md) contain more detailed information about topics like the used code style and should also be considered.
Here are a few things to keep in mind that will help get your PR approved.
* A PR should be focused on content. Any PRs where the changes are only syntax will be rejected.
* Use the file you are editing as a style guide.
* Consider your feature. [Suggestion Guidelines](http://ae-mod.info/Suggestion-Guidelines/)
- Is your suggestion already possible using Vanilla + AE2?
- Make sure your feature isn't already in the works, or hasn't been rejected previously.
- Does your feature simplify another feature of AE2? These changes will not be accepted.
- If your feature can be done by any popular mod, discuss with us first.
**Getting Started**
1. Fork this repository
2. Clone the fork via
* SSH `git clone git@github.com:<your username>/Applied-Energistics-2.git` or
* HTTPS `git clone https://github.com/<your username>/Applied-Energistics-2.git`
3. Change code base
4. Add changes to git `git add -A`
5. Commit changes to your clone `git commit -m "<summery of made changes>"`
6. Push to your fork `git push`
7. Create a Pull-Request on GitHub
8. Wait for review
9. Squash commits for cleaner history
If you are only doing single file pull requests, GitHub supports using a quick way without the need of cloning your fork. Also read up about [synching](https://help.github.com/articles/syncing-a-fork) if you plan to contribute on regular basis.
## Applied Energistics 2 API
The API for Applied Energistics 2. It is open source to discuss changes, improve documentation, and provide better add-on support in general.
Universal builds obtained [Here](http://ae2.ae-mod.info/Downloads/) should work in a development environment.
### Maven
When compiling against the AE2 API you can use gradle dependencies, just add
dependencies {
compile "appeng:appliedenergistics2:rv_-_____-__:api"
}
or add the compile line to your existing dependencies task to your build.gradle
Where the __ are filled in with the correct version criteria; AE2 is available from the default forge maven so no additional repositories are necessary.
An example string would be `appeng:appliedenergistics2:rv5-stable-1:api` for the API only or `appeng:appliedenergistics2:rv5-stable-1` for the whole mod.
## Applied Energistics 2 CraftTweaker
### Inscriber
Add a recipe. When `inscribe` is true the bottom and top inputs are not consumed.
mods.appliedenergistics2.Inscriber.addRecipe(ItemStack output, ItemStack input, boolean inscribe,
@Optional ItemStack topInput, @Optional ItemStack bottomInput );
Remove all recipes for this output stack.
mods.appliedenergistics2.Inscriber.removeRecipe(ItemStack output);
### Grindstone
Add a recipe.
mods.appliedenergistics2.Grinder.addRecipe( ItemStack output, ItemStack input, int turns,
@Optional ItemStack secondary1Output, @Optional float secondary1Chance,
@Optional ItemStack secondary2Output, @Optional float secondary2Chance);
Remove recipes for this input.
mods.appliedenergistics2.Grinder.removeRecipe(ItemStack input);
### Spatial
Whitelist a TileEntity class for Spatial IO.
mods.appliedenergistics2.Spatial.whitelistEntity( String fullEntityClassName );
### Attunement
Attune a ItemStack or ModID to a specific P2P-Tunnel type. ModID's are used as fallback when no ItemStack was found.
mods.appliedenergistics2.Attunement.attuneME( ItemStack itemStack );
mods.appliedenergistics2.Attunement.attuneME( String modID );
mods.appliedenergistics2.Attunement.attuneItem( ItemStack itemStack );
mods.appliedenergistics2.Attunement.attuneItem( String modID );
mods.appliedenergistics2.Attunement.attuneFluid( ItemStack itemStack );
mods.appliedenergistics2.Attunement.attuneFluid( String modID );
mods.appliedenergistics2.Attunement.attuneRedstone( ItemStack itemStack );
mods.appliedenergistics2.Attunement.attuneRedstone( String modID );
mods.appliedenergistics2.Attunement.attuneRF( ItemStack itemStack );
mods.appliedenergistics2.Attunement.attuneRF( String modID );
mods.appliedenergistics2.Attunement.attuneIC2( ItemStack itemStack );
mods.appliedenergistics2.Attunement.attuneIC2( String modID );
mods.appliedenergistics2.Attunement.attuneLight( ItemStack itemStack );
mods.appliedenergistics2.Attunement.attuneLight( String modID );
### Cannon
Add ammo types for the matter cannon.
mods.appliedenergistics2.Cannon.registerAmmo( ItemStack itemStack, double weight );
## Applied Energistics 2 Localization
### English Text
`en_US` is included in this repository, fixes to typos are welcome.
### Encoding
Files must be encoded as UTF-8.
### New or updated Translations
The language files are located in `/src/main/resources/assets/appliedenergistics2/lang/` and use the [appropriate locale code](http://minecraft.gamepedia.com/Language) as name and `.lang` as extension.
To update an translation edit the corresponding file and improve/correct the existing entry. Or copy any entries from `en_US.lang` for missing translation.
To create a new translation, copy the contents of `en_US.lang`, create a new file with appropriate filename, and translate it to your language.
Please keep in mind that we use [String format](https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html) to pass additional data to the text for displaying.
Therefore you should preserve parts like `%s` or `%1$d%%`, which allows us to replace them with the correct values while you still have the option to change their order for match the rules of grammar.
This might not be possible for some languages. Should this be the case, please contact us.
### Final Note
If you have have issues localizing something feel free to contact us on IRC, at #AppliedEnergistics on Esper.net
Thanks to everyone helping out to improve localization of AE2.
## Credits
Thanks to
+8 -2
View File
@@ -30,7 +30,13 @@ buildscript {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
}
}
plugins {
id "org.sonarqube" version "2.6"
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: 'jacoco'
repositories {
mavenLocal()
@@ -51,7 +57,7 @@ tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
version = aeversion + "-" + aechannel + "-" + aebuild
version = aeversion + "-" + aechannel + "-" + aebuild + " " + trousers
group = aegroup
archivesBaseName = aebasename
@@ -112,4 +118,4 @@ processResources
// move access transformer to META-INF
rename '(.+_at.cfg)', 'META-INF/$1'
}
}
+7 -5
View File
@@ -1,15 +1,16 @@
aeversion=rv5
aechannel=alpha
aebuild=0
aeversion=rv6
aechannel=stable
aebuild=7
aegroup=appeng
aebasename=appliedenergistics2
trousers=omni-fixes-v46aa
#########################################################
# Versions #
#########################################################
minecraft_version=1.12.2
mcp_mappings=snapshot_20171003
forge_version=14.23.3.2655
forge_version=14.23.5.2847
#########################################################
# Installable #
@@ -19,13 +20,14 @@ hwyla_version=1.8.26-B41_1.12.2
#########################################################
# Provided APIs #
#########################################################
jei_version=4.10.0.198
jei_version=4.16.1.302
tesla_version=1.0.63
ic2_version=2.8.73-ex112
top_version=1.12-1.4.23-16
cofhcore_version=1.12.2-4.5.2.19
crafttweaker_version=4.1.8.9
inventorytweaks_version=1.63
ctm_version=MC1.12.2-0.3.1.16
#########################################################
# Deployment #
+24 -16
View File
@@ -24,36 +24,44 @@ allprojects {
}
javadoc {
options.encoding = 'UTF-8'
options.charSet = 'UTF-8'
options.encoding = 'UTF-8'
options.charSet = 'UTF-8'
}
task javadocs(type: Javadoc) {
source = sourceSets.api.java
include "appeng/api/**"
source = sourceSets.api.java
include "appeng/api/**"
// Due to ForgeGradle having to be a special snowflake,
// we have to add some custom configurations to the normal compile configuration and hope it does not break.
classpath = configurations.compile + configurations.forgeGradleMc + configurations.forgeGradleMcDeps
// Due to ForgeGradle having to be a special snowflake,
// we have to add some custom configurations to the normal compile configuration and hope it does not break.
classpath = configurations.compile + configurations.forgeGradleMc + configurations.forgeGradleMcDeps
}
task javadocJar(type: Jar, dependsOn: javadocs) {
from javadoc.destinationDir
classifier = 'javadoc'
classifier = 'javadoc'
}
task apiJar(type: Jar) {
from sourceSets.api.java
include "appeng/api/**"
from sourceSets.api.java
include "appeng/api/**"
from sourceSets.api.output
include "appeng/api/**"
from sourceSets.api.output
include "appeng/api/**"
classifier = 'api'
classifier = 'api'
}
task sourceJar(type: Jar, overwrite: true) {
from sourceSets.api.allSource
from sourceSets.main.allSource
classifier = 'sources'
}
artifacts {
archives apiJar
archives javadocJar
archives sourceJar
archives apiJar
archives javadocJar
archives sourceJar
}
+15 -11
View File
@@ -34,6 +34,11 @@ repositories {
url "http://maven.mcmoddev.com"
}
maven {
name "Ellpeck"
url "https://maven.ellpeck.de"
}
maven {
name = "IC2 repo"
url = "http://maven.ic2.player.to"
@@ -54,21 +59,16 @@ repositories {
url "http://maven.k-4u.nl/"
}
maven { // Hwyla
name 'tehnut'
url "http://tehnut.info/maven"
}
maven { // CraftTweaker
name 'jared maven'
url "http://maven.blamejared.com/"
}
maven { // modmaven, maven proxy
name 'modmaven'
url "https://modmaven.k-4u.nl/"
}
//maven { // modmaven, maven proxy
// name 'modmaven'
// url "https://modmaven.k-4u.nl/"
//}
maven {
name = "CurseForge"
url = "https://minecraft.curseforge.com/api/maven/"
@@ -80,6 +80,8 @@ configurations {
}
dependencies {
compileOnly "gregtechce:gregtech:1.12.2:1.15.1.735"
// installable runtime dependencies
mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev"
@@ -94,7 +96,9 @@ dependencies {
compileOnly "cofh:CoFHCore:${cofhcore_version}:deobf"
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
compileOnly "team.chisel.ctm:CTM:${ctm_version}"
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
// at runtime, use the full JEI jar
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
Binary file not shown.
+1 -2
View File
@@ -1,6 +1,5 @@
#Tue Jul 04 22:38:49 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip
Vendored
+17 -9
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
##############################################################################
##
@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
warn () {
echo "$*"
}
die ( ) {
die () {
echo
echo "$*"
echo
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
Vendored
-6
View File
@@ -49,7 +49,6 @@ goto fail
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
+6
View File
@@ -30,6 +30,7 @@ import appeng.api.networking.IGridHelper;
import appeng.api.networking.IGridNode;
import appeng.api.parts.IPartHelper;
import appeng.api.storage.IStorageHelper;
import appeng.api.util.IClientHelper;
@AEInjectable
@@ -60,4 +61,9 @@ public interface IAppEngApi
*/
IDefinitions definitions();
/**
* @return Utility methods primarily useful for client side stuff
*/
IClientHelper client();
}
@@ -26,5 +26,20 @@ package appeng.api.config;
public enum ActionItems
{
WRENCH, CLOSE, STASH, ENCODE, SUBSTITUTION
WRENCH,
CLOSE,
STASH,
ENCODE,
SUBSTITUTION,
MULTIPLY_BY_TWO,
MULTIPLY_BY_THREE,
INCREASE_BY_ONE,
DIVIDE_BY_TWO,
DIVIDE_BY_THREE,
DECREASE_BY_ONE,
MAX_COUNT,
FREE_MOLECULAR_SLOT_SHORTCUT,
TOGGLE_SHOW_FULL_INTERFACES_ON,
TOGGLE_SHOW_FULL_INTERFACES_OFF,
HIGHLIGHT_INTERFACE
}
+7 -2
View File
@@ -37,12 +37,17 @@ public enum Upgrades
/**
* Gold Tier Upgrades.
*/
CAPACITY( 0 ), REDSTONE( 0 ), CRAFTING( 0 ),
CAPACITY( 0 ),
REDSTONE( 0 ),
CRAFTING( 0 ),
/**
* Diamond Tier Upgrades.
*/
FUZZY( 1 ), SPEED( 1 ), INVERTER( 1 );
FUZZY( 1 ),
SPEED( 1 ),
INVERTER( 1 ),
PATTERN_EXPANSION(1);
private final int tier;
private final Map<ItemStack, Integer> supportedMax = new HashMap<>();
@@ -89,6 +89,8 @@ public interface IMaterials
IItemDefinition cardCapacity();
IItemDefinition cardPatternExpansion();
IItemDefinition cardFuzzy();
IItemDefinition cardInverter();
@@ -121,6 +121,6 @@ public interface IParts
IItemDefinition fluidLevelEmitter();
IItemDefinition fluidAnnihilationPlane();
IItemDefinition fluidFormationnPlane();
}
@@ -47,7 +47,9 @@ public interface IP2PTunnelRegistry
* @param type - the type of tunnel. Nullable, but then ignored
*/
void addNewAttunement( @Nonnull ItemStack trigger, @Nullable TunnelType type );
void addNewAttunement( @Nonnull String ModId, @Nullable TunnelType type );
void addNewAttunement( @Nonnull Capability<?> cap, @Nullable TunnelType type );
/**
@@ -35,6 +35,6 @@ import appeng.api.networking.IGridHost;
public interface INetworkTool extends IGuiItemObject
{
IGridHost getGridHost(); // null for most purposes.
IItemHandler getInventory();
}
@@ -24,6 +24,8 @@
package appeng.api.implementations.items;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import appeng.api.storage.ICellWorkbenchItem;
@@ -52,7 +54,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return number of bytes
*/
int getBytes( ItemStack cellItem );
int getBytes( @Nonnull ItemStack cellItem );
/**
* Determines the number of bytes used for any type included on the cell.
@@ -61,7 +63,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return number of bytes
*/
int getBytesPerType( ItemStack cellItem );
int getBytesPerType( @Nonnull ItemStack cellItem );
/**
* Must be between 1 and 63, indicates how many types you want to store on
@@ -71,7 +73,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return number of types
*/
int getTotalTypes( ItemStack cellItem );
int getTotalTypes( @Nonnull ItemStack cellItem );
/**
* Allows you to fine tune which items are allowed on a given cell, if you
@@ -83,7 +85,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return true to preventAdditionOfItem
*/
boolean isBlackListed( ItemStack cellItem, T requestedAddition );
boolean isBlackListed( @Nonnull ItemStack cellItem, @Nonnull T requestedAddition );
/**
* Allows you to specify if this storage cell can be stored inside other
@@ -104,7 +106,7 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
*
* @return if the ItemStack should behavior as a storage cell.
*/
boolean isStorageCell( ItemStack i );
boolean isStorageCell( @Nonnull ItemStack i );
/**
* @return drain in ae/t this storage cell will use.
@@ -114,5 +116,6 @@ public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem
/**
* @return the type of channel your cell should be part of
*/
@Nonnull
IStorageChannel<T> getChannel();
}
@@ -29,5 +29,5 @@ package appeng.api.implementations.items;
*/
public enum MemoryCardMessages
{
INVALID_MACHINE, SETTINGS_LOADED, SETTINGS_SAVED, SETTINGS_CLEARED
INVALID_MACHINE, SETTINGS_LOADED, SETTINGS_SAVED, SETTINGS_RESET, SETTINGS_CLEARED
}
@@ -23,6 +23,7 @@
package appeng.api.implementations.tiles;
import net.minecraftforge.items.IItemHandler;
@@ -23,6 +23,7 @@
package appeng.api.implementations.tiles;
import net.minecraftforge.items.IItemHandler;
@@ -28,7 +28,6 @@ import java.util.EnumSet;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
@@ -124,8 +123,8 @@ public interface IGridBlock
/**
* Determines what item stack is used to render this node in the GUI.
*
* @return the render item stack to use to render this node, null is valid, and will not show this node.
* @return the render item stack to use to render this node. Returning an empty ItemStack will not show this node.
*/
@Nullable
@Nonnull
ItemStack getMachineRepresentation();
}
@@ -99,9 +99,18 @@ public interface ICraftingGrid extends IGridCache
/**
* is this item being crafted?
*
* @param aeStackInSlot item being crafted
* @param what item being crafted
*
* @return true if it is being crafting
*/
boolean isRequesting( IAEItemStack aeStackInSlot );
boolean isRequesting( IAEItemStack what );
/**
* The total amount being requested across all crafting cpus of a grid.
*
* @param what item being requested, ignores stacksize
*
* @return The total amount being requested.
*/
long requesting( IAEItemStack what );
}
@@ -31,6 +31,9 @@ import net.minecraft.world.World;
import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.storage.data.IAEItemStack;
import java.util.Collections;
import java.util.List;
/**
* do not implement provided by {@link ICraftingPatternItem}
@@ -84,6 +87,11 @@ public interface ICraftingPatternDetails
*/
boolean canSubstitute();
default List<IAEItemStack> getSubstituteInputs( int slot )
{
return Collections.emptyList();
}
/**
* Allow using this INSTANCE of the pattern details to preform the crafting action with performance enhancements.
*
@@ -44,10 +44,7 @@ public interface IStackWatcherHost
/**
* Called when a watched item changes amounts.
*
* @param o changed item list
* @param fullStack old stack
* @param diffStack new stack
* @param src action source
* @param chan storage channel
*/
void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan );
@@ -51,6 +51,7 @@ public interface IStorageGrid extends IGridCache, IStorageMonitorable
* @param input injected items
*/
void postAlterationOfStoredItems( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src );
void postCraftablesChanges( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src);
/**
* Used to add a cell provider to the storage system
@@ -1,3 +1,4 @@
/*
* The MIT License (MIT)
*
+4 -1
View File
@@ -291,6 +291,9 @@ public interface IPart extends IBoxProvider, ICustomCableConnection
/**
* Used to determine which parts can be placed on what cables.
*
* Dense cables are not allowed for functional (getGridNode returns a node) parts.
* Doing so will result in crashes.
*
* @param what placed part
*
@@ -365,4 +368,4 @@ public interface IPart extends IBoxProvider, ICustomCableConnection
return null;
}
}
}
+1 -1
View File
@@ -72,7 +72,7 @@ public interface IPartHost extends ICustomCableConnection
* @return null if the item failed to add, the side it was placed on other wise ( may different for cables,
* {@link AEPartLocation}.UNKNOWN )
*/
AEPartLocation addPart( ItemStack is, AEPartLocation side, EntityPlayer owner, EnumHand hand );
AEPartLocation addPart( ItemStack is, AEPartLocation side, EntityPlayer owner, EnumHand hand );
/**
* Get part by side ( center is {@link AEPartLocation}.UNKNOWN )
@@ -23,6 +23,7 @@
package appeng.api.parts;
/**
* TODO: Consider removing and replacing with capabilities.
*/
@@ -30,6 +30,7 @@ import appeng.api.exceptions.MissingIngredientException;
import appeng.api.exceptions.RecipeException;
import appeng.api.exceptions.RegistrationException;
@Deprecated
public interface ICraftHandler
{
@@ -29,6 +29,7 @@ import net.minecraft.item.ItemStack;
import appeng.api.exceptions.MissingIngredientException;
import appeng.api.exceptions.RegistrationException;
@Deprecated
public interface IIngredient
{
@@ -28,6 +28,7 @@ import java.io.BufferedReader;
import javax.annotation.Nonnull;
@Deprecated
public interface IRecipeLoader
{
@@ -0,0 +1,47 @@
package appeng.api.storage;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.storage.data.IAEStack;
public interface ICellGuiHandler
{
/**
* Return true if this handler can show GUI for this channel.
*
* @param channel Storage channel
* @return True if handled, else false.
*/
<T extends IAEStack<T>> boolean isHandlerFor( IStorageChannel<T> channel );
/**
* Return true to prioritize this handler for the provided {@link ItemStack}.
*
* @param is Cell ItemStack
* @return True, if specialized else false.
*/
default boolean isSpecializedFor( ItemStack is )
{
return false;
}
/**
* Called when the storage cell is placed in an ME Chest and the user tries to open the terminal side, if your item
* is not available via ME Chests simply tell the user they can't use it, or something, other wise you should open
* your gui and display the cell to the user.
*
* @param player player opening chest gui
* @param chest to be opened chest
* @param cellHandler cell handler
* @param inv inventory handler
* @param is item
* @param chan storage channel
*/
<T extends IAEStack<T>> void openChestGui( EntityPlayer player, IChestOrDrive chest, ICellHandler cellHandler, IMEInventoryHandler<T> inv, ItemStack is, IStorageChannel<T> chan );
}
@@ -24,10 +24,8 @@
package appeng.api.storage;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.storage.data.IAEStack;
@@ -59,20 +57,6 @@ public interface ICellHandler
*/
<T extends IAEStack<T>> ICellInventoryHandler<T> getCellInventory( ItemStack is, ISaveProvider host, IStorageChannel<T> channel );
/**
* Called when the storage cell is planed in an ME Chest and the user tries to open the terminal side, if your item
* is not available via ME Chests simply tell the user they can't use it, or something, other wise you should open
* your gui and display the cell to the user.
*
* @param player player opening chest gui
* @param chest to be opened chest
* @param cellHandler cell handler
* @param inv inventory handler
* @param is item
* @param chan storage channel
*/
<T extends IAEStack<T>> void openChestGui( EntityPlayer player, IChestOrDrive chest, ICellHandler cellHandler, IMEInventoryHandler<T> inv, ItemStack is, IStorageChannel<T> chan );
/**
* 0 - cell is missing.
*
@@ -87,10 +71,31 @@ public interface ICellHandler
*
* @return get the status of the cell based on its contents.
*/
<T extends IAEStack<T>> int getStatusForCell( ItemStack is, IMEInventory<T> handler );
default <T extends IAEStack<T>> int getStatusForCell( ItemStack is, ICellInventoryHandler<T> handler )
{
if( handler.getCellInv() != null )
{
int val = handler.getCellInv().getStatusForCell();
if( val == 1 && handler.isPreformatted() )
{
val = 2;
}
return val;
}
return 0;
}
/**
* @return the ae/t to drain for this storage cell inside a chest/drive.
*/
<T extends IAEStack<T>> double cellIdleDrain( ItemStack is, IMEInventory<T> handler );
default <T extends IAEStack<T>> double cellIdleDrain( ItemStack is, ICellInventoryHandler<T> handler )
{
if( handler.getCellInv() != null )
{
return handler.getCellInv().getIdleDrain();
}
return 1.0;
}
}
@@ -40,7 +40,7 @@ public interface ICellInventory<T extends IAEStack<T>> extends IMEInventory<T>
ItemStack getItemStack();
/**
* @return idle cost for this Storage Cell
* @return the ae/t to drain for this storage cell inside a chest/drive.
*/
double getIdleDrain();
@@ -115,7 +115,15 @@ public interface ICellInventory<T extends IAEStack<T>> extends IMEInventory<T>
int getUnusedItemCount();
/**
* @return the status number for this drive.
* 0 - cell is missing.
*
* 1 - green, ( usually means available room for types or items. )
*
* 2 - orange, ( usually means available room for items, but not types. )
*
* 3 - red, ( usually means the cell is 100% full )
*
* @return get the status of the cell based on its contents.
*/
int getStatusForCell();
@@ -24,6 +24,8 @@
package appeng.api.storage;
import javax.annotation.Nullable;
import appeng.api.config.IncludeExclude;
import appeng.api.storage.data.IAEStack;
@@ -32,8 +34,11 @@ public interface ICellInventoryHandler<T extends IAEStack<T>> extends IMEInvento
{
/**
* Get access to the ICellInventory. Can be null for custom cells.
*
* @return get access to the Cell Inventory.
*/
@Nullable
ICellInventory<T> getCellInv();
boolean isPreformatted();
@@ -53,6 +53,13 @@ public interface ICellRegistry
*/
void addCellHandler( @Nonnull ICellHandler handler );
/**
* Register a new handler
*
* @param handler cell gui handler
*/
void addCellGuiHandler( @Nonnull ICellGuiHandler handler );
/**
* return true, if you can get a InventoryHandler for the item passed.
*
@@ -64,7 +71,7 @@ public interface ICellRegistry
boolean isCellHandled( ItemStack is );
/**
* get the handler, for the requested type.
* get the handler, for the requested item.
*
* @param is to be checked item
*
@@ -74,13 +81,23 @@ public interface ICellRegistry
ICellHandler getHandler( ItemStack is );
/**
* returns an IMEInventoryHandler for the provided item.
* get the handler, for the requested channel.
*
* @param channel requested channel
* @param Cell ItemStack
* @return the handler registered for this channel.
*/
@Nullable
<T extends IAEStack<T>> ICellGuiHandler getGuiHandler( IStorageChannel<T> channel, ItemStack is );
/**
* returns an ICellInventoryHandler for the provided item by querying all registered handlers.
*
* @param is item with inventory handler
* @param host can be null. If provided, the host is responsible for persisting the cell content.
* @param chan the storage channel to request the handler for.
*
* @return new IMEInventoryHandler, or null if there isn't one.
* @return new ICellInventoryHandler, or null if there isn't one.
*/
@Nullable
<T extends IAEStack<T>> ICellInventoryHandler<T> getCellInventory( ItemStack is, ISaveProvider host, IStorageChannel<T> chan );
@@ -24,11 +24,19 @@
package appeng.api.storage;
import javax.annotation.Nullable;
/**
* Tells the cell provider that changes have been made an the cell must be persisted
*
*/
public interface ISaveProvider
{
void saveChanges( ICellInventory<?> cellInventory );
/**
* Cell has changed and needs to be changed.
*
* @param cellInventory can be null for custom cells.
*/
void saveChanges( @Nullable ICellInventory<?> cellInventory );
}
@@ -32,10 +32,9 @@ import javax.annotation.Nullable;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.IActionSource;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
@@ -56,6 +55,17 @@ public interface IStorageChannel<T extends IAEStack<T>>
return 1;
}
/**
* The number of units (eg item count, or millibuckets) that can be stored per byte in a storage cell.
* Standard value for items is 8, and for fluids it's 8000
*
* @return number of units
*/
default int getUnitsPerByte()
{
return 8;
}
/**
* Create a new {@link IItemList} of the specific type.
*
@@ -68,9 +78,12 @@ public interface IStorageChannel<T extends IAEStack<T>>
* Create a new {@link IAEStack} subtype of the specific object.
*
* The parameter is unbound to allow a slightly more flexible approach.
* But the general intention is about converting an {@link ItemStack} into the corresponding {@link IAEItemStack}.
* But the general intention is about converting an {@link ItemStack} or {@link FluidStack} into the corresponding
* {@link IAEStack}.
* Another valid case might be to use it instead of {@link IAEStack#copy()}, but this might not be supported by all
* types.
* IAEStacks that use custom items for {@link IAEStack#asItemStackRepresentation()} must also be able to convert
* these.
*
* @param input The object to turn into an {@link IAEStack}
* @return The converted stack or null
@@ -88,29 +101,11 @@ public interface IStorageChannel<T extends IAEStack<T>>
T readFromPacket( @Nonnull ByteBuf input ) throws IOException;
/**
* use energy from energy, to remove request items from cell, at the request of src.
*
* @param energy to be drained energy source
* @param cell cell of requested items
* @param request requested items
* @param src action source
*
* @return items that successfully extracted.
* create from nbt data
*
* @param nbt
* @return
*/
@Nullable
T poweredExtraction( @Nonnull IEnergySource energy, @Nonnull IMEInventory<T> cell, @Nonnull T request, @Nonnull IActionSource src );
/**
* use energy from energy, to inject input items into cell, at the request of src
*
* @param energy to be added energy source
* @param cell injected cell
* @param input to be injected items
* @param src action source
*
* @return items that failed to insert.
*/
@Nullable
T poweredInsert( @Nonnull IEnergySource energy, @Nonnull IMEInventory<T> cell, @Nonnull T input, @Nonnull IActionSource src );
T createFromNBT( @Nonnull NBTTagCompound nbt );
}
@@ -28,10 +28,15 @@ import java.util.Collection;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import appeng.api.config.Actionable;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingRequester;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
@@ -90,4 +95,38 @@ public interface IStorageHelper
*/
ICraftingLink loadCraftingLink( NBTTagCompound data, ICraftingRequester req );
/**
* Extracts items from a {@link IMEInventory} respecting power requirements.
*
* @param energy Energy source.
* @param inv Inventory to extract from.
* @param request Requested item and count.
* @param src Action source.
* @param mode Simulate or modulate
* @return extracted items or {@code null} of nothing was extracted.
*/
<T extends IAEStack<T>> T poweredExtraction( final IEnergySource energy, final IMEInventory<T> inv, final T request, final IActionSource src, final Actionable mode );
/**
* Inserts items into a {@link IMEInventory} respecting power requirements.
*
* @param energy Energy source.
* @param inv Inventory to insert into.
* @param request Items to insert.
* @param src Action source.
* @param mode Simulate or modulate
* @return items not inserted or {@code null} if everything was inserted.
*/
<T extends IAEStack<T>> T poweredInsert( final IEnergySource energy, final IMEInventory<T> inv, final T input, final IActionSource src, final Actionable mode );
/**
* Posts alteration of stored items to the provided {@link IStorageGrid}.
* This can be used by cell containers to notify the grid of storage cell changes.
*
* @param gs the storage grid.
* @param removedCell the removed cell itemstack
* @param addedCell the added cell itemstack
* @param src the action source
*/
void postChanges( @Nonnull final IStorageGrid gs, @Nonnull final ItemStack removedCell, @Nonnull final ItemStack addedCell, @Nonnull final IActionSource src );
}
@@ -112,4 +112,13 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
* @return definition stack
*/
ItemStack getDefinition();
/**
* Compare this AE item stack to another item stack, but ignores
* the amount. It checks the item type, NBT and damage values.
*
* @param is An item stack
*/
boolean equals(ItemStack is);
}
@@ -75,12 +75,12 @@ public enum AECableType
public AECableSize size()
{
return size;
return this.size;
}
public AECableVariant variant()
{
return variant;
return this.variant;
}
public boolean isValid()
+12 -6
View File
@@ -74,25 +74,30 @@ public enum AEColor
TRANSPARENT( "gui.appliedenergistics2.Fluix", null, 0x1B2344, 0x895CA8, 0xD7BBEC );
public static final List<AEColor> VALID_COLORS = Arrays.asList( WHITE, ORANGE, MAGENTA, LIGHT_BLUE, YELLOW, LIME, PINK, GRAY, LIGHT_GRAY, CYAN, PURPLE, BLUE, BROWN, GREEN, RED, BLACK );
public static final List<AEColor> VALID_COLORS = Arrays.asList( WHITE, ORANGE, MAGENTA, LIGHT_BLUE, YELLOW, LIME, PINK, GRAY, LIGHT_GRAY, CYAN, PURPLE,
BLUE, BROWN, GREEN, RED, BLACK );
/**
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #blackVariant dark variant} of the apprioriate AE color.
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #blackVariant dark
* variant} of the apprioriate AE color.
*/
public static final int TINTINDEX_DARK = 1;
/**
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #mediumVariant medium variant} of the apprioriate AE color.
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #mediumVariant medium
* variant} of the apprioriate AE color.
*/
public static final int TINTINDEX_MEDIUM = 2;
/**
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #whiteVariant bright variant} of the apprioriate AE color.
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #whiteVariant bright
* variant} of the apprioriate AE color.
*/
public static final int TINTINDEX_BRIGHT = 3;
/**
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get a color between the {@link #mediumVariant medium}
* The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get a color between the
* {@link #mediumVariant medium}
* and {@link #whiteVariant bright variant} of the apprioriate AE color.
*/
public static final int TINTINDEX_MEDIUM_BRIGHT = 4;
@@ -141,7 +146,8 @@ public enum AEColor
{
switch( tintIndex )
{
// Please note that tintindex 0 is hardcoded for the block breaking particles. Returning anything other than -1 for tintindex=0 here
// Please note that tintindex 0 is hardcoded for the block breaking particles. Returning anything other than
// -1 for tintindex=0 here
// will cause issues with those particles
case 0:
return -1;
@@ -0,0 +1,21 @@
package appeng.api.util;
import java.util.List;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.data.IAEStack;
public interface IClientHelper
{
/**
* Add cell information to the provided list. Used for tooltip content.
*
* @param handler Cell handler.
* @param lines List of lines to add to.
*/
<T extends IAEStack<T>> void addCellInformation( ICellInventoryHandler<T> handler, List<String> lines );
}
@@ -23,8 +23,10 @@
package appeng.api.util;
import net.minecraft.util.math.RayTraceResult;
/**
* Implement on Tile or part to customize if the info gui opens, or an action is preformed.
*/
@@ -0,0 +1,143 @@
package com.jaquadro.minecraft.storagedrawers.api.capabilities;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import javax.annotation.Nonnull;
import java.util.function.Predicate;
/**
* An interface for treating an inventory as a slotless, central repository of items.
*
* For all operations that accept a predicate, if a predicate is supplied, a stored ItemStack must pass the predicate
* in order to be considered for the given operation.
*
* An IItemRepository implementation MAY relax or eliminate its own internal tests when a predicate is supplied. If
* the predicate is derived from DefaultPredicate, then the implementation MUST apply any tests it would have applied
* had no predicate been provided at all, in addition to testing the predicate itself.
*/
public interface IItemRepository
{
/**
* Gets a list of all items in the inventory. The same item may appear multiple times with varying counts.
* @return A list of zero or more items in the inventory.
*/
@Nonnull
NonNullList<ItemRecord> getAllItems ();
/**
* Inserts an ItemStack into the inventory and returns the remainder.
*
* @param stack ItemStack to insert.
* @param simulate If true, the insertion is only simulated
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return The remaining ItemStack that was not inserted. If the entire stack was accepted, returns
* ItemStack.EMPTY instead.
*/
@Nonnull
ItemStack insertItem (@Nonnull ItemStack stack, boolean simulate, Predicate<ItemStack> predicate);
@Nonnull
default ItemStack insertItem (@Nonnull ItemStack stack, boolean simulate) {
return insertItem(stack, simulate, null);
}
/**
* Tries to extract the given ItemStack from the inventory. The returned value will be a matching ItemStack
* with a stack size equal to or less than amount, or the empty ItemStack if the item could not be found at all.
* The returned stack size may exceed the ItemStack's getMaxStackSize() value.
* @param stack The item to extract. The stack size is ignored.
* @param amount Amount to extract (may be greater than the stacks max limit)
* @param simulate If true, the extraction is only simulated
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return ItemStack extracted from the inventory, or ItemStack.EMPTY if nothing could be extracted.
*/
@Nonnull
ItemStack extractItem (@Nonnull ItemStack stack, int amount, boolean simulate, Predicate<ItemStack> predicate);
@Nonnull
default ItemStack extractItem (@Nonnull ItemStack stack, int amount, boolean simulate) {
return extractItem(stack, amount, simulate, null);
}
/**
* Gets the number of items matching the given ItemStack stored by the inventory.
* @param stack ItemStack to query.
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return The number of stored matching items. A value of Integer.MAX_VALUE may indicate an infinite item source.
*/
default int getStoredItemCount (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
ItemStack amount = extractItem(stack, Integer.MAX_VALUE, true, predicate);
return amount.getCount();
}
default int getStoredItemCount (@Nonnull ItemStack stack) {
return getStoredItemCount(stack, null);
}
/**
* Gets the number items matching the given ItemStack that additionally still be stored by the inventory.
* Remaining capacity may include space that is internally empty or unassigned to any given item.
*
* @param stack ItemStack to query.
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return The available remaining space for matching items.
*/
default int getRemainingItemCapacity (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
stack = stack.copy();
stack.setCount(Integer.MAX_VALUE);
ItemStack remainder = insertItem(stack, true, predicate);
return Integer.MAX_VALUE - remainder.getCount();
}
default int getRemainingItemCapacity (@Nonnull ItemStack stack) {
return getRemainingItemCapacity(stack, null);
}
/**
* Gets the total inventory capacity for items matching the given ItemStack.
* Total capacity may include space that is internally empty or unassigned to any given item.
*
* @param stack ItemStack to query.
* @param predicate See interface notes about predicates. Passing null specifies default matching.
* @return The total capacity for matching items.
*/
default int getItemCapacity (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
long capacity = getStoredItemCount(stack, predicate) + getRemainingItemCapacity(stack, predicate);
if (capacity > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
return (int)capacity;
}
default int getItemCapacity (@Nonnull ItemStack stack) {
return getItemCapacity(stack, null);
}
/**
* An item record representing an item and the amount stored.
*
* The ItemStack held by itemPrototype always reports a stack size of 1.
* IT IS IMPORTANT THAT YOU NEVER MODIFY itemPrototype.
*/
class ItemRecord
{
@Nonnull
public final ItemStack itemPrototype;
public final int count;
public ItemRecord (@Nonnull ItemStack itemPrototype, int count) {
this.itemPrototype = itemPrototype;
this.count = count;
}
}
/**
* A variant of the standard Predicate interface that when passed to IItemRepository functions, will ask the
* internal default predicate to be tested in addition to the custom predicate. An IItemRepository function
* may choose to enforce its own predicate regardless.
*/
interface DefaultPredicate<T> extends Predicate<T> { }
}
@@ -0,0 +1,87 @@
package yalter.mousetweaks.api;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
/**
* This is the interface you want to implement in your GuiScreen to make it compatible with Mouse Tweaks.
* If this interface is not enough (for example, you need a custom slot click function, or if you use a custom Container
* which happens to be incompatible), check IMTModGuiContainer2Ex instead.
* If you just need to disable Mouse Tweaks or the wheel tweak, see the MouseTweaksIgnore
* or the MouseTweaksDisableWheelTweak annotations.
*/
public interface IMTModGuiContainer2 {
/**
* If you want to disable Mouse Tweaks in your GuiScreen, return true from this method.
*
* @return True if Mouse Tweaks should be disabled, false otherwise.
*/
boolean MT_isMouseTweaksDisabled();
/**
* If you want to disable the Wheel Tweak in your GuiScreen, return true from this method.
*
* @return True if the Wheel Tweak should be disabled, false otherwise.
*/
boolean MT_isWheelTweakDisabled();
/**
* Returns the Container.
*
* @return Container that is currently in use.
*/
Container MT_getContainer();
/**
* Returns the Slot that is currently selected by the player, or null if no Slot is selected.
*
* @return Slot that is located under the mouse, or null if no Slot it currently under the mouse.
*/
Slot MT_getSlotUnderMouse();
/**
* Return true if the given Slot behaves like the vanilla crafting output slots (inside the crafting table,
* or the furnace output slot, or the anvil output slot, etc.). These slots are handled differently by Mouse Tweaks.
*
* @param slot the slot to check
* @return True if slot is a crafting output slot.
*/
boolean MT_isCraftingOutput(Slot slot);
/**
* Return true if the given Slot should be ignored by Mouse Tweaks. Examples of ignored slots are the item select
* slots and the Destroy Item slot in the vanilla creative inventory.
*
* @param slot the slot to check
* @return Tru if slot should be ignored by Mouse Tweaks.
*/
boolean MT_isIgnored(Slot slot);
/**
* If your container has an RMB dragging functionality (like vanilla containers), disable it inside this method.
* This method is called every frame (render tick), which is after all mouseClicked / mouseClickMove / mouseReleased
* events are handled (although note these events are handled every game tick, which is far less frequent than every
* render tick).<br><br>
*
* If true is returned from this method, Mouse Tweaks (after checking other conditions like isIgnored) will click
* the slot on which the right mouse button was initially pressed (in most cases this is the slot currently under
* mouse). This is needed because the vanilla RMB dragging functionality prevents the initial slot click.<br><br>
*
* For vanilla containers this method looks like this:
* <pre>
* this.ignoreMouseUp = true;
*
* if (this.dragSplitting) {
* if (this.dragSplittingButton == 1) {
* this.dragSplitting = false;
* return true;
* }
* }
*
* return false;
* </pre>
*
* @return True if Mouse Tweaks should click the slot on which the RMB was pressed.
*/
boolean MT_disableRMBDraggingFunctionality();
}
@@ -56,15 +56,18 @@ public class AEBaseItemBlockChargeable extends AEBaseItemBlock implements IAEIte
double internalCurrentPower = 0;
final double internalMaxPower = this.getMaxEnergyCapacity();
if( tag != null )
if( internalMaxPower > 0 )
{
internalCurrentPower = tag.getDouble( "internalCurrentPower" );
if( tag != null )
{
internalCurrentPower = tag.getDouble( "internalCurrentPower" );
}
final double percent = internalCurrentPower / internalMaxPower;
lines.add( GuiText.StoredEnergy.getLocal() + ':' + MessageFormat.format( " {0,number,#} ", internalCurrentPower ) + Platform
.gui_localize( PowerUnits.AE.unlocalizedName ) + " - " + MessageFormat.format( " {0,number,#.##%} ", percent ) );
}
final double percent = internalCurrentPower / internalMaxPower;
lines.add( GuiText.StoredEnergy.getLocal() + ':' + MessageFormat.format( " {0,number,#} ", internalCurrentPower ) + Platform
.gui_localize( PowerUnits.AE.unlocalizedName ) + " - " + MessageFormat.format( " {0,number,#.##%} ", percent ) );
}
@Override
@@ -87,7 +87,7 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
@Override
public boolean canRenderInLayer( IBlockState state, BlockRenderLayer layer )
{
return layer == BlockRenderLayer.TRANSLUCENT;
return layer == BlockRenderLayer.CUTOUT || layer == BlockRenderLayer.TRANSLUCENT;
}
@Override
@@ -150,9 +150,9 @@ public class BlockLightDetector extends AEBaseTileBlock implements IOrientableBl
public void neighborChanged( IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos )
{
final EnumFacing up = this.getOrientable( world, pos ).getUp();
if( !this.canPlaceAt( (World) world, pos, up.getOpposite() ) )
if( !this.canPlaceAt( world, pos, up.getOpposite() ) )
{
this.dropTorch( (World) world, pos );
this.dropTorch( world, pos );
}
}
@@ -61,10 +61,12 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import appeng.api.AEApi;
import appeng.api.parts.IFacadeContainer;
import appeng.api.parts.IFacadePart;
import appeng.api.parts.PartItemStack;
import appeng.api.parts.SelectedPart;
import appeng.api.util.AEColor;
import appeng.api.util.AEPartLocation;
import appeng.block.AEBaseTileBlock;
import appeng.client.UnlistedProperty;
import appeng.client.render.cablebus.CableBusBakedModel;
@@ -74,6 +76,7 @@ import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketClick;
import appeng.helpers.AEGlassMaterial;
import appeng.integration.abstraction.IAEFacade;
import appeng.parts.ICableBusContainer;
import appeng.parts.NullCableBusContainer;
import appeng.tile.AEBaseTile;
@@ -83,7 +86,7 @@ import appeng.tile.networking.TileCableBusTESR;
import appeng.util.Platform;
public class BlockCableBus extends AEBaseTileBlock
public class BlockCableBus extends AEBaseTileBlock implements IAEFacade
{
public static final UnlistedProperty<CableBusRenderState> RENDER_STATE_PROPERTY = new UnlistedProperty<>( "cable_bus_render_state", CableBusRenderState.class );
@@ -122,6 +125,8 @@ public class BlockCableBus extends AEBaseTileBlock
public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos )
{
CableBusRenderState renderState = this.cb( world, pos ).getRenderState();
renderState.setWorld( world );
renderState.setPos( pos );
return ( (IExtendedBlockState) state ).withProperty( RENDER_STATE_PROPERTY, renderState );
}
@@ -317,13 +322,14 @@ public class BlockCableBus extends AEBaseTileBlock
for( int l = 0; l < 4; ++l )
{
// Randomly select one of the textures if the cable bus has more than just one possibility here
TextureAtlasSprite texture = Platform.pickRandom( textures );
final TextureAtlasSprite texture = Platform.pickRandom( textures );
final double d0 = pos.getX() + ( j + 0.5D ) / 4.0D;
final double d1 = pos.getY() + ( k + 0.5D ) / 4.0D;
final double d2 = pos.getZ() + ( l + 0.5D ) / 4.0D;
final ParticleDigging particle = new DestroyFX( world, d0, d1, d2, d0 - pos.getX() - 0.5D, d1 - pos
.getY() - 0.5D, d2 - pos.getZ() - 0.5D, this.getDefaultState() ).setBlockPos( pos );
double d0 = (double) pos.getX() + ( (double) j + 0.5D ) / 4.0D;
double d1 = (double) pos.getY() + ( (double) k + 0.5D ) / 4.0D;
double d2 = (double) pos.getZ() + ( (double) l + 0.5D ) / 4.0D;
ParticleDigging particle = new DestroyFX( world, d0, d1, d2, d0 - (double) pos.getX() - 0.5D, d1 - (double) pos
.getY() - 0.5D, d2 - (double) pos.getZ() - 0.5D, this.getDefaultState() ).setBlockPos( pos );
particle.setParticleTexture( texture );
effectRenderer.addEffect( particle );
}
@@ -356,6 +362,20 @@ public class BlockCableBus extends AEBaseTileBlock
return out == null ? NULL_CABLE_BUS : out;
}
@Nullable
private IFacadeContainer fc( final IBlockAccess w, final BlockPos pos )
{
final TileEntity te = w.getTileEntity( pos );
IFacadeContainer out = null;
if( te instanceof TileCableBus )
{
out = ( (TileCableBus) te ).getCableBus().getFacadeContainer();
}
return out;
}
@Override
public void onBlockClicked( World worldIn, BlockPos pos, EntityPlayer playerIn )
{
@@ -436,14 +456,25 @@ public class BlockCableBus extends AEBaseTileBlock
@Override
public boolean canRenderInLayer( IBlockState state, BlockRenderLayer layer )
{
if( AEApi.instance().partHelper().getCableRenderMode().transparentFacades )
return true;
}
@Override
public IBlockState getFacadeState( IBlockAccess world, BlockPos pos, EnumFacing side )
{
if( side != null )
{
return layer == BlockRenderLayer.CUTOUT || layer == BlockRenderLayer.TRANSLUCENT;
}
else
{
return layer == BlockRenderLayer.CUTOUT;
IFacadeContainer container = this.fc( world, pos );
if( container != null )
{
IFacadePart facade = container.getFacade( AEPartLocation.fromFacing( side ) );
if( facade != null )
{
return facade.getBlockState();
}
}
}
return world.getBlockState( pos );
}
public static Class<? extends AEBaseTile> getNoTesrTile()
@@ -34,8 +34,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import appeng.api.AEApi;
import appeng.api.storage.ICellHandler;
import appeng.api.util.AEPartLocation;
import appeng.block.AEBaseTileBlock;
import appeng.core.localization.PlayerMessages;
@@ -108,14 +106,7 @@ public class BlockChest extends AEBaseTileBlock
}
else
{
final ItemStack cell = tg.getCell();
if( !cell.isEmpty() )
{
final ICellHandler ch = AEApi.instance().registries().cell().getHandler( cell );
tg.openGui( p, ch, cell, side );
}
else
if( !tg.openGui( p ) )
{
p.sendMessage( PlayerMessages.ChestCannotReadStorageCell.get() );
}
@@ -136,7 +136,7 @@ public class FeatureFactory
private <T extends IBootstrapComponent> void addBootstrapComponent( Class<? extends IBootstrapComponent> eventType, T component )
{
bootstrapComponents.computeIfAbsent( eventType, c -> new ArrayList<IBootstrapComponent>() ).add( component );
this.bootstrapComponents.computeIfAbsent( eventType, c -> new ArrayList<IBootstrapComponent>() ).add( component );
}
@SideOnly( Side.CLIENT )
@@ -1,10 +1,13 @@
package appeng.bootstrap.components;
import net.minecraftforge.fml.common.registry.EntityEntry;
import net.minecraftforge.registries.IForgeRegistry;
import appeng.bootstrap.IBootstrapComponent;
@FunctionalInterface
public interface IEntityRegistrationComponent extends IBootstrapComponent
{
@@ -19,6 +19,7 @@
package appeng.capabilities;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.darkhax.tesla.api.ITeslaConsumer;
import net.darkhax.tesla.api.ITeslaHolder;
import net.minecraft.nbt.NBTBase;
@@ -54,6 +55,8 @@ public final class Capabilities
public static Capability<IEnergyStorage> FORGE_ENERGY;
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY;
/**
* Register AE2 provided capabilities.
*/
@@ -99,6 +102,9 @@ public final class Capabilities
FORGE_ENERGY = cap;
}
@CapabilityInject( IItemRepository.class )
private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap ) { ITEM_REPOSITORY_CAPABILITY = cap; }
// Create a storage implementation that does not do anything
private static <T> Capability.IStorage<T> createNullStorage()
{
@@ -0,0 +1,28 @@
package appeng.client;
import org.lwjgl.input.Keyboard;
public enum ActionKey
{
TOGGLE_FOCUS( Keyboard.KEY_TAB );
private final int defaultKey;
private ActionKey( int defaultKey )
{
this.defaultKey = defaultKey;
}
public String getTranslationKey()
{
return "key." + this.name().toLowerCase() + ".desc";
}
public int getDefaultKey()
{
return this.defaultKey;
}
}
+57 -3
View File
@@ -21,11 +21,17 @@ package appeng.client;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Random;
import appeng.client.gui.AEBaseGui;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.helpers.HighlighterHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.tileentity.TileEntity;
@@ -33,13 +39,12 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.MouseEvent;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.event.*;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -70,10 +75,14 @@ import appeng.hooks.TickHandler;
import appeng.hooks.TickHandler.PlayerColor;
import appeng.server.ServerHelper;
import appeng.util.Platform;
import org.lwjgl.input.Mouse;
public class ClientHelper extends ServerHelper
{
private final static String KEY_CATEGORY = "key.appliedenergistics2.category";
private final EnumMap<ActionKey, KeyBinding> bindings = new EnumMap<>( ActionKey.class );
@Override
public void preinit()
@@ -92,6 +101,17 @@ public class ClientHelper extends ServerHelper
@Override
public void init()
{
for( ActionKey key : ActionKey.values() )
{
final KeyBinding binding = new KeyBinding( key.getTranslationKey(), key.getDefaultKey(), KEY_CATEGORY );
ClientRegistry.registerKeyBinding( binding );
this.bindings.put( key, binding );
}
}
@SubscribeEvent
public void renderWorldLastEvent( RenderWorldLastEvent event) {
HighlighterHandler.tick(event);
}
@Override
@@ -296,6 +316,28 @@ public class ClientHelper extends ServerHelper
Minecraft.getMinecraft().effectRenderer.addEffect( fx );
}
@SubscribeEvent
public void MouseClickEvent( final GuiScreenEvent.MouseInputEvent.Pre me )
{
final Minecraft mc = Minecraft.getMinecraft();
if( mc.currentScreen instanceof IJEIGhostIngredients )
{
AEBaseGui gui = ( (AEBaseGui) mc.currentScreen );
Object ingredient = gui.getBookmarkedIngredient();
if( ingredient != null )
{
if( GuiScreen.isShiftKeyDown() )
{
me.setCanceled( true );
}
else if( Mouse.isButtonDown( 0 ) )
{
me.setCanceled( true );
}
}
}
}
@SubscribeEvent
public void wheelEvent( final MouseEvent me )
{
@@ -332,4 +374,16 @@ public class ClientHelper extends ServerHelper
ParticleTextures.registerSprite( event );
InscriberTESR.registerTexture( event );
}
@Override
public boolean isKeyPressed( ActionKey key )
{
return this.bindings.get( key ).isPressed();
}
@Override
public boolean isActionKey( ActionKey key, int pressedKeyCode )
{
return this.bindings.get( key ).isActiveAndMatches( pressedKeyCode );
}
}
+259 -28
View File
@@ -19,6 +19,7 @@
package appeng.client.gui;
import java.awt.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.ParseException;
@@ -31,10 +32,16 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import appeng.container.slot.*;
import com.google.common.base.Joiner;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.Gui;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fml.common.Optional;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
@@ -68,17 +75,7 @@ import appeng.client.me.SlotDisconnected;
import appeng.client.me.SlotME;
import appeng.client.render.StackSizeRenderer;
import appeng.container.AEBaseContainer;
import appeng.container.slot.AppEngCraftingSlot;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.AppEngSlot.hasCalculatedValidness;
import appeng.container.slot.IOptionalSlot;
import appeng.container.slot.SlotCraftingTerm;
import appeng.container.slot.SlotDisabled;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotInaccessible;
import appeng.container.slot.SlotOutput;
import appeng.container.slot.SlotPatternTerm;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
@@ -87,9 +84,14 @@ import appeng.core.sync.packets.PacketSwapSlots;
import appeng.fluids.client.render.FluidStackSizeRenderer;
import appeng.fluids.container.slots.IMEFluidSlot;
import appeng.helpers.InventoryAction;
import yalter.mousetweaks.api.IMTModGuiContainer2;
import static appeng.integration.modules.jei.JEIPlugin.aeGuiHandler;
import static appeng.integration.modules.jei.JEIPlugin.runtime;
public abstract class AEBaseGui extends GuiContainer
@Optional.Interface( iface = "yalter.mousetweaks.api.IMTModGuiContainer2", modid = "mousetweaks" )
public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContainer2
{
private final List<InternalSlotME> meSlots = new ArrayList<>();
// drag y
@@ -101,6 +103,28 @@ public abstract class AEBaseGui extends GuiContainer
private Stopwatch dbl_clickTimer = Stopwatch.createStarted();
private ItemStack dbl_whichItem = ItemStack.EMPTY;
private Slot bl_clicked;
private Stopwatch lastClicked = Stopwatch.createStarted();
private List<IGhostIngredientHandler.Target<Object>> hoveredIngredientTargets = new ArrayList<>();
private Object bookmarkedIngredient;
private boolean isDraggingJeiGhostItem;
public void setJeiGhostItem( boolean jeiGhostItem )
{
isJeiGhostItem = jeiGhostItem;
}
private boolean isJeiGhostItem;
public Object getBookmarkedIngredient()
{
return bookmarkedIngredient;
}
public List<GuiCustomSlot> getGuiSlots()
{
return guiSlots;
}
protected final List<GuiCustomSlot> guiSlots = new ArrayList<>();
public AEBaseGui( final Container container )
@@ -161,16 +185,16 @@ public abstract class AEBaseGui extends GuiContainer
super.drawScreen( mouseX, mouseY, partialTicks );
GlStateManager.pushMatrix();
GlStateManager.translate( (float) this.guiLeft, (float) this.guiTop, 0.0F );
GlStateManager.translate( this.guiLeft, this.guiTop, 0.0F );
GlStateManager.enableDepth();
for( final GuiCustomSlot c : this.guiSlots )
{
drawGuiSlot( c, mouseX, mouseY, partialTicks );
this.drawGuiSlot( c, mouseX, mouseY, partialTicks );
}
GlStateManager.disableDepth();
for( final GuiCustomSlot c : this.guiSlots )
{
drawTooltip( c, mouseX - this.guiLeft, mouseY - this.guiTop );
this.drawTooltip( c, mouseX - this.guiLeft, mouseY - this.guiTop );
}
GlStateManager.popMatrix();
@@ -180,9 +204,68 @@ public abstract class AEBaseGui extends GuiContainer
{
if( c instanceof ITooltip )
{
drawTooltip( (ITooltip) c, mouseX, mouseY );
this.drawTooltip( (ITooltip) c, mouseX, mouseY );
}
}
GlStateManager.enableDepth();
bookmarkedJEIghostItem(mouseX,mouseY);
GlStateManager.disableDepth();
}
void bookmarkedJEIghostItem(final int mouseX, final int mouseY) {
if (!isJeiGhostItem)
{
bookmarkedIngredient = runtime.getBookmarkOverlay().getIngredientUnderMouse();
}
if( bookmarkedIngredient != null )
{
hoveredIngredientTargets = aeGuiHandler.getTargets( this, bookmarkedIngredient, false );
ItemStack dragItem = ItemStack.EMPTY;
if( hoveredIngredientTargets.size() > 0 )
{
if( isShiftKeyDown() && Mouse.isButtonDown( 0 ) && this.lastClicked.elapsed( TimeUnit.MILLISECONDS ) > 200 )
{
this.lastClicked = Stopwatch.createStarted();
aeGuiHandler.getTargets( this, bookmarkedIngredient, true );
}
else if( Mouse.isButtonDown( 0 ) && this.lastClicked.elapsed( TimeUnit.MILLISECONDS ) > 200 )
{
this.lastClicked = Stopwatch.createStarted();
if( bookmarkedIngredient instanceof ItemStack )
{
dragItem = ( (ItemStack) bookmarkedIngredient );
}
else if( bookmarkedIngredient instanceof FluidStack )
{
dragItem = FluidUtil.getFilledBucket( ( (FluidStack) bookmarkedIngredient ) );
}
mc.player.inventory.setItemStack( dragItem.copy() );
this.isJeiGhostItem = true;
}
drawTargets( mouseX, mouseY );
}
}
}
private void drawTargets(int mouseX, int mouseY) {
GlStateManager.disableLighting();
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{
Rectangle area = target.getArea();
Color color;
if( area.contains( mouseX, mouseY ) )
{
color = new Color( 76, 201, 25, 128 );
}
else
{
color = new Color( 19, 201, 10, 64 );
}
Gui.drawRect( area.x, area.y, area.x + area.width, area.y + area.height, color.getRGB() );
}
GlStateManager.color( 1f, 1f, 1f, 1f );
GlStateManager.enableDepth();
}
protected void drawGuiSlot( GuiCustomSlot slot, int mouseX, int mouseY, float partialTicks )
@@ -315,7 +398,6 @@ public abstract class AEBaseGui extends GuiContainer
{
slot.drawBackground( ox, oy );
}
}
@Override
@@ -375,6 +457,43 @@ public abstract class AEBaseGui extends GuiContainer
}
}
}
else if( slot instanceof SlotDisconnected )
{
this.drag_click.add( slot );
if( this.drag_click.size() > 1 )
{
if( !itemstack.isEmpty() )
{
for( final Slot dr : this.drag_click )
{
if( slot.getStack().isEmpty() )
{
InventoryAction action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
final PacketInventoryAction p = new PacketInventoryAction( action, dr.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance().sendToServer( p );
}
}
}
else if( isShiftKeyDown() )
{
for( final Slot dr : this.drag_click )
{
InventoryAction action = null;
if( !slot.getStack().isEmpty() )
{
action = InventoryAction.SHIFT_CLICK;
}
if( action != null )
{
final PacketInventoryAction p = new PacketInventoryAction( action, dr.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance().sendToServer( p );
}
}
}
}
}
else
{
super.mouseClickMove( x, y, c, d );
@@ -387,18 +506,56 @@ public abstract class AEBaseGui extends GuiContainer
{
final EntityPlayer player = Minecraft.getMinecraft().player;
if( slot instanceof SlotFake )
if( this.isJeiGhostItem && isDraggingJeiGhostItem)
{
final InventoryAction action = mouseButton == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{
Rectangle area = target.getArea();
final int x = Mouse.getEventX() * this.width / this.mc.displayWidth;
final int y = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1;
if( area.contains( x, y ) )
{
target.accept( bookmarkedIngredient );
break;
}
}
this.isJeiGhostItem = false;
this.isDraggingJeiGhostItem = false;
ItemStack dragItem = ItemStack.EMPTY;
if( runtime.getBookmarkOverlay().getIngredientUnderMouse() != null )
{
bookmarkedJEIghostItem( Mouse.getX(), this.mc.displayHeight - Mouse.getY() );
if( bookmarkedIngredient instanceof ItemStack )
{
dragItem = ( (ItemStack) bookmarkedIngredient );
}
else if( bookmarkedIngredient instanceof FluidStack )
{
dragItem = FluidUtil.getFilledBucket( ( (FluidStack) bookmarkedIngredient ) );
}
mc.player.inventory.setItemStack( dragItem.copy() );
this.isJeiGhostItem = true;
}
else
{
mc.player.inventory.setItemStack( dragItem );
}
}
else if( slot instanceof SlotFake )
{
final InventoryAction action;
action = mouseButton == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
if( this.drag_click.size() > 1 )
{
return;
}
final PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, 0 );
PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, 0 );
NetworkHandler.instance().sendToServer( p );
return;
}
@@ -468,12 +625,24 @@ public abstract class AEBaseGui extends GuiContainer
if( slot instanceof SlotDisconnected )
{
if( this.drag_click.size() > 1 )
{
return;
}
InventoryAction action = null;
switch( clickType )
switch ( clickType )
{
case PICKUP: // pickup / set-down.
action = ( mouseButton == 1 ) ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
if( slot.getStack().isEmpty() && !player.inventory.getItemStack().isEmpty() )
{
action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
}
if( !slot.getStack().isEmpty() && player.inventory.getItemStack().getCount() <= 1 )
{
action = InventoryAction.PICKUP_OR_SET_DOWN;
}
break;
case QUICK_MOVE:
action = ( mouseButton == 1 ) ? InventoryAction.PICKUP_SINGLE : InventoryAction.SHIFT_CLICK;
@@ -506,14 +675,13 @@ public abstract class AEBaseGui extends GuiContainer
InventoryAction action = null;
IAEItemStack stack = null;
switch( clickType )
switch ( clickType )
{
case PICKUP: // pickup / set-down.
action = ( mouseButton == 1 ) ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
stack = ( (SlotME) slot ).getAEStack();
if( stack != null && action == InventoryAction.PICKUP_OR_SET_DOWN && stack.getStackSize() == 0 && player.inventory.getItemStack()
.isEmpty() )
if( stack != null && action == InventoryAction.PICKUP_OR_SET_DOWN && stack.getStackSize() == 0 && player.inventory.getItemStack().isEmpty() )
{
action = InventoryAction.AUTO_CRAFT;
}
@@ -580,9 +748,7 @@ public abstract class AEBaseGui extends GuiContainer
final List<Slot> slots = this.getInventorySlots();
for( final Slot inventorySlot : slots )
{
if( inventorySlot != null && inventorySlot.canTakeStack(
this.mc.player ) && inventorySlot.getHasStack() && inventorySlot.isSameInventory( slot ) && Container.canAddItemToSlot(
inventorySlot, this.dbl_whichItem, true ) )
if( inventorySlot != null && inventorySlot.canTakeStack( this.mc.player ) && inventorySlot.getHasStack() && inventorySlot.isSameInventory( slot ) && Container.canAddItemToSlot( inventorySlot, this.dbl_whichItem, true ) )
{
this.handleMouseClick( inventorySlot, inventorySlot.slotNumber, 0, ClickType.QUICK_MOVE );
}
@@ -593,6 +759,11 @@ public abstract class AEBaseGui extends GuiContainer
this.disableShiftClick = false;
}
if (clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem) {
this.isDraggingJeiGhostItem = true;
return;
}
super.handleMouseClick( slot, slotIdx, mouseButton, clickType );
}
@@ -702,6 +873,16 @@ public abstract class AEBaseGui extends GuiContainer
}
}
}
if( slot instanceof SlotFake )
{
final ItemStack stack = ( (SlotFake) slot ).getStack();
if( stack != ItemStack.EMPTY )
{
InventoryAction direction = wheel > 0 ? InventoryAction.PLACE_SINGLE : InventoryAction.PICKUP_SINGLE;
final PacketInventoryAction p = new PacketInventoryAction( direction , slot.slotNumber , 0);
NetworkHandler.instance().sendToServer( p );
}
}
}
protected boolean enableSpaceClicking()
@@ -961,4 +1142,54 @@ public abstract class AEBaseGui extends GuiContainer
{
return this.meSlots;
}
@Override
@Optional.Method( modid = "mousetweaks" )
public boolean MT_isMouseTweaksDisabled()
{
return false;
}
@Override
@Optional.Method( modid = "mousetweaks" )
public boolean MT_isWheelTweakDisabled()
{
return true;
}
@Override
@Optional.Method( modid = "mousetweaks" )
public Container MT_getContainer()
{
return this.inventorySlots;
}
@Override
@Optional.Method( modid = "mousetweaks" )
public Slot MT_getSlotUnderMouse()
{
return getSlotUnderMouse();
}
@Override
@Optional.Method( modid = "mousetweaks" )
public boolean MT_isCraftingOutput( Slot slot )
{
return slot instanceof SlotOutput || slot instanceof AppEngCraftingSlot;
}
@Override
@Optional.Method( modid = "mousetweaks" )
public boolean MT_isIgnored( Slot slot )
{
return false;
}
@Override
@Optional.Method( modid = "mousetweaks" )
public boolean MT_disableRMBDraggingFunctionality()
{
return false;
}
}
@@ -0,0 +1,144 @@
package appeng.client.gui;
import javax.annotation.Nullable;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.implementations.*;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.SlotFake;
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
import mezz.jei.api.gui.IAdvancedGuiHandler;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiScreen;
import org.lwjgl.input.Mouse;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngredientHandler<AEBaseGui>
{
@Override
public Class<AEBaseGui> getGuiContainerClass()
{
return AEBaseGui.class;
}
@Nullable
@Override
public List<Rectangle> getGuiExtraAreas( AEBaseGui guiContainer )
{
return Collections.emptyList();
}
@Nullable
@Override
public Object getIngredientUnderMouse( AEBaseGui guiContainer, int mouseX, int mouseY )
{
List<IAEItemStack> visual;
int guiSlotIdx;
Object result = null;
if( guiContainer instanceof GuiCraftConfirm )
{
guiSlotIdx = getSlotidx( guiContainer, mouseX, mouseY, ( (GuiCraftConfirm) guiContainer ).getDisplayedRows() );
visual = ( (GuiCraftConfirm) guiContainer ).getVisual();
if( guiSlotIdx < visual.size() && guiSlotIdx != -1 )
{
result = visual.get( guiSlotIdx ).getDefinition();
}
else
{
return null;
}
}
if( guiContainer instanceof GuiCraftingCPU )
{
guiSlotIdx = getSlotidx( guiContainer, mouseX, mouseY, ( (GuiCraftingCPU) guiContainer ).getDisplayedRows() );
visual = ( (GuiCraftingCPU) guiContainer ).getVisual();
if( guiSlotIdx < visual.size() && guiSlotIdx != -1 )
{
result = visual.get( guiSlotIdx ).getDefinition();
}
else
{
return null;
}
}
if( guiContainer instanceof GuiCraftAmount )
{
if( guiContainer.getSlotUnderMouse() != null )
{
result = guiContainer.getSlotUnderMouse().getStack();
}
}
return result;
}
private int getSlotidx(AEBaseGui guiContainer, int mouseX, int mouseY, int rows)
{
int guileft = guiContainer.getGuiLeft();
int guitop = guiContainer.getGuiTop();
int currentScroll = guiContainer.getScrollBar().getCurrentScroll();
final int xo = 9;
final int yo = 19;
int guiSlotx = ( mouseX - guileft - xo ) / 67;
if( guiSlotx > 2 || mouseX < guileft + xo ) return -1;
int guiSloty = ( mouseY - guitop - yo ) / 23;
if( guiSloty > ( rows - 1 ) || mouseY < guitop + yo ) return -1;
return ( guiSloty * 3 ) + guiSlotx + ( currentScroll * 3 );
}
@Override
public <I> List<Target<I>> getTargets( AEBaseGui gui, I ingredient, boolean doStart )
{
ArrayList<Target<I>> targets = new ArrayList<>();
if( gui instanceof IJEIGhostIngredients )
{
IJEIGhostIngredients g = (IJEIGhostIngredients) gui;
List<Target<?>> phantomTargets = g.getPhantomTargets( ingredient );
targets.addAll( (List<Target<I>>) (Object) phantomTargets );
}
if( doStart && GuiScreen.isShiftKeyDown() && Mouse.isButtonDown( 0 ) )
{
if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm )
{
IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui );
for( Target<I> target : targets )
{
if( ghostGui.getFakeSlotTargetMap().get( target ) instanceof SlotFake )
{
if( ( (SlotFake) ghostGui.getFakeSlotTargetMap().get( target ) ).getStack().isEmpty() )
{
target.accept( ingredient );
break;
}
}
else if( ghostGui.getFakeSlotTargetMap().get( target ) instanceof GuiFluidSlot )
{
if( ( (GuiFluidSlot) ghostGui.getFakeSlotTargetMap().get( target ) ).getFluidStack() == null )
{
target.accept( ingredient );
break;
}
}
}
}
}
return targets;
}
@Override
public void onComplete(){
}
@Override
public boolean shouldHighlightTargets()
{
return true;
}
}
@@ -582,4 +582,14 @@ public class GuiCraftConfirm extends AEBaseGui
}
}
}
public List<IAEItemStack> getVisual()
{
return visual;
}
public int getDisplayedRows()
{
return this.rows;
}
}
@@ -493,4 +493,14 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource
{
return ViewItems.ALL;
}
public List<IAEItemStack> getVisual()
{
return visual;
}
public int getDisplayedRows()
{
return DISPLAYED_ROWS;
}
}
@@ -50,7 +50,7 @@ public class GuiInterface extends GuiUpgradeable
public GuiInterface( final InventoryPlayer inventoryPlayer, final IInterfaceHost te )
{
super( new ContainerInterface( inventoryPlayer, te ) );
this.ySize = 211;
this.ySize = 256;
}
@Override
@@ -62,8 +62,7 @@ public class GuiInterface extends GuiUpgradeable
this.BlockMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO );
this.buttonList.add( this.BlockMode );
this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal
.getLocal(), GuiText.InterfaceTerminalHint.getLocal() );
this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal() );
this.buttonList.add( this.interfaceMode );
}
@@ -86,13 +85,20 @@ public class GuiInterface extends GuiUpgradeable
this.fontRenderer.drawString( GuiText.StoredItems.getLocal(), 8, 6 + 60 + 7, 4210752 );
this.fontRenderer.drawString( GuiText.Patterns.getLocal(), 8, 6 + 73 + 7, 4210752 );
this.fontRenderer.drawString( GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752 );
}
@Override
protected String getBackground()
{
return "guis/interface.png";
int upgrades = ( (ContainerInterface) this.cvb ).getPatternUpgrades();
if( upgrades == 0 )
{
return "guis/newinterface.png";
}
else
{
return "guis/newinterface" + upgrades + ".png";
}
}
@Override
@@ -117,4 +123,5 @@ public class GuiInterface extends GuiUpgradeable
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.BlockMode.getSetting(), backwards ) );
}
}
}
@@ -20,20 +20,23 @@ package appeng.client.gui.implementations;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.*;
import appeng.api.config.ActionItems;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.core.worlddata.IWorldPlayerMapping;
import appeng.helpers.DualityInterface;
import appeng.parts.misc.PartInterface;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.misc.TileInterface;
import appeng.util.BlockPosUtils;
import com.google.common.collect.HashMultimap;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
@@ -49,6 +52,14 @@ import appeng.container.implementations.ContainerInterfaceTerminal;
import appeng.core.localization.GuiText;
import appeng.parts.reporting.PartInterfaceTerminal;
import appeng.util.Platform;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.DimensionManager;
import org.lwjgl.input.Mouse;
import static appeng.client.render.BlockPosHighlighter.hilightBlock;
public class GuiInterfaceTerminal extends AEBaseGui
@@ -57,26 +68,36 @@ public class GuiInterfaceTerminal extends AEBaseGui
private static final int LINES_ON_PAGE = 6;
// TODO: copied from GuiMEMonitorable. It looks not changed, maybe unneeded?
private final int offsetX = 9;
private final int offsetX = 21;
private final HashMap<Long, ClientDCInternalInv> byId = new HashMap<>();
private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create();
private final HashMap<ClientDCInternalInv,BlockPos> blockPosHashMap = new HashMap<>();
private final HashMap<GuiButton,ClientDCInternalInv> guiButtonHashMap = new HashMap<>();
private final Map<ClientDCInternalInv,Integer> numUpgradesMap = new HashMap<>();
private final ArrayList<String> names = new ArrayList<>();
private final ArrayList<Object> lines = new ArrayList<>();
private final Set<Object> matchedStacks = new HashSet<>();
private final Map<String, Set<Object>> cachedSearches = new WeakHashMap<>();
private boolean refreshList = false;
private MEGuiTextField searchField;
private MEGuiTextField searchFieldOutputs;
private MEGuiTextField searchFieldInputs;
private PartInterfaceTerminal partInterfaceTerminal;
private GuiButton guiButtonHide;
private GuiButton guiButtonNextAssembler;
private HashMap<ClientDCInternalInv,Integer> dimHashMap = new HashMap<>();
public GuiInterfaceTerminal( final InventoryPlayer inventoryPlayer, final PartInterfaceTerminal te )
{
super( new ContainerInterfaceTerminal( inventoryPlayer, te ) );
this.partInterfaceTerminal = te;
final GuiScrollbar scrollbar = new GuiScrollbar();
this.setScrollBar( scrollbar );
this.xSize = 195;
this.ySize = 222;
this.xSize = 208;
this.ySize = 255;
}
@Override
@@ -84,45 +105,79 @@ public class GuiInterfaceTerminal extends AEBaseGui
{
super.initGui();
this.getScrollBar().setLeft( 175 );
this.getScrollBar().setLeft( 189 );
this.getScrollBar().setHeight( 106 );
this.getScrollBar().setTop( 18 );
this.getScrollBar().setTop( 51 );
this.searchField = new MEGuiTextField( this.fontRenderer, this.guiLeft + Math.max( 104, this.offsetX ), this.guiTop + 4, 65, 12 );
this.searchField.setEnableBackgroundDrawing( false );
this.searchField.setMaxStringLength( 25 );
this.searchField.setTextColor( 0xFFFFFF );
this.searchField.setVisible( true );
this.searchField.setFocused( true );
this.searchFieldInputs = new MEGuiTextField( this.fontRenderer, this.guiLeft + Math.max( 32, this.offsetX ), this.guiTop + 25, 65, 12 );
this.searchFieldInputs.setEnableBackgroundDrawing( false );
this.searchFieldInputs.setMaxStringLength( 25 );
this.searchFieldInputs.setTextColor( 0xFFFFFF );
this.searchFieldInputs.setVisible( true );
this.searchFieldInputs.setFocused( false );
this.searchFieldOutputs = new MEGuiTextField( this.fontRenderer, this.guiLeft + Math.max( 32, this.offsetX ), this.guiTop + 38, 65, 12 );
this.searchFieldOutputs.setEnableBackgroundDrawing( false );
this.searchFieldOutputs.setMaxStringLength( 25 );
this.searchFieldOutputs.setTextColor( 0xFFFFFF );
this.searchFieldOutputs.setVisible( true );
this.searchFieldOutputs.setFocused( true );
this.searchFieldInputs.setText( partInterfaceTerminal.in );
this.searchFieldOutputs.setText( partInterfaceTerminal.out );
}
@Override
public void onGuiClosed()
{
partInterfaceTerminal.saveSearchStrings( this.searchFieldInputs.getText().toLowerCase(), this.searchFieldOutputs.getText().toLowerCase() );
super.onGuiClosed();
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.buttonList.clear();
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.InterfaceTerminal.getLocal() ), 8, 6, 4210752 );
this.fontRenderer.drawString( GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752 );
this.fontRenderer.drawString( GuiText.inventory.getLocal(), this.offsetX + 2, this.ySize - 96 + 3, 4210752 );
final int ex = this.getScrollBar().getCurrentScroll();
final int currentScroll = this.getScrollBar().getCurrentScroll();
final Iterator<Slot> o = this.inventorySlots.inventorySlots.iterator();
while( o.hasNext() )
this.guiButtonNextAssembler = new GuiImgButton( guiLeft + 123, guiTop + 25, Settings.ACTIONS, ActionItems.FREE_MOLECULAR_SLOT_SHORTCUT );
this.buttonList.add( guiButtonNextAssembler );
guiButtonHide = new GuiImgButton( guiLeft + 141, guiTop + 25, Settings.ACTIONS, this.partInterfaceTerminal.onlyInterfacesWithFreeSlots ? ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF : ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON );
this.buttonList.add( guiButtonHide );
this.inventorySlots.inventorySlots.removeIf( slot -> slot instanceof SlotDisconnected );
int offset = 52;
int linesDraw = 0;
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && currentScroll + x < this.lines.size(); x++ )
{
if( o.next() instanceof SlotDisconnected )
{
o.remove();
}
}
int offset = 17;
for( int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
{
final Object lineObj = this.lines.get( ex + x );
final Object lineObj = this.lines.get( currentScroll + x );
if( lineObj instanceof ClientDCInternalInv )
{
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
for( int z = 0; z < inv.getInventory().getSlots(); z++ )
GuiButton guiButton = new GuiImgButton( guiLeft + 4, guiTop + offset, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE );
guiButtonHashMap.put( guiButton, inv );
this.buttonList.add( guiButton );
int extraLines = numUpgradesMap.get( inv );
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE ; ++row )
{
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z, z * 18 + 8, 1 + offset ) );
for( int z = 0; z < 9 ; z++ )
{
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z + ( row * 9 ), ( z * 18 + 22 ), offset ) );
if( this.matchedStacks.contains( inv.getInventory().getStackInSlot( z + ( row * 9 ) ) ) )
{
drawRect( z * 18 + 22, offset, z * 18 + 22 + 16, offset + 16, 0x2A00FF00 );
}
}
linesDraw++;
offset += 18;
}
}
else if( lineObj instanceof String )
@@ -134,57 +189,130 @@ public class GuiInterfaceTerminal extends AEBaseGui
name = name + " (" + rows + ')';
}
while( name.length() > 2 && this.fontRenderer.getStringWidth( name ) > 155 )
while ( name.length() > 2 && this.fontRenderer.getStringWidth( name ) > 155 )
{
name = name.substring( 0, name.length() - 1 );
}
this.fontRenderer.drawString( name, 10, 6 + offset, 4210752 );
this.fontRenderer.drawString( name, this.offsetX + 2, 5 + offset, 4210752 );
linesDraw++;
offset += 18;
}
offset += 18;
}
if( searchFieldInputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Inputs OR names" );
else if( searchFieldOutputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Outputs OR names" );
}
@Override
protected void mouseClicked( final int xCoord, final int yCoord, final int btn ) throws IOException
{
this.searchField.mouseClicked( xCoord, yCoord, btn );
this.searchFieldInputs.mouseClicked( xCoord, yCoord, btn );
if( btn == 1 && this.searchField.isMouseIn( xCoord, yCoord ) )
if( btn == 1 && this.searchFieldInputs.isMouseIn( xCoord, yCoord ) )
{
this.searchField.setText( "" );
this.searchFieldInputs.setText( "" );
this.refreshList();
}
this.searchFieldOutputs.mouseClicked( xCoord, yCoord, btn );
if( btn == 1 && this.searchFieldOutputs.isMouseIn( xCoord, yCoord ) )
{
this.searchFieldOutputs.setText( "" );
this.refreshList();
}
super.mouseClicked( xCoord, yCoord, btn );
}
@Override
protected void actionPerformed( final GuiButton btn ) throws IOException
{
if( guiButtonHashMap.containsKey( btn ) )
{
BlockPos blockPos = blockPosHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
BlockPos blockPos2 = mc.player.getPosition();
int playerDim = mc.world.provider.getDimension();
int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
if( playerDim != interfaceDim )
{
try {
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
} catch(Exception e){
mc.player.sendStatusMessage( new TextComponentString( "Interface is located in another dimension and cannot be highlighted" ), false );
}
}
else
{
hilightBlock( blockPos, System.currentTimeMillis() + 500 * BlockPosUtils.getDistance( blockPos, blockPos2 ), playerDim );
mc.player.sendStatusMessage( new TextComponentString( "The interface is now highlighted at " + "X: " + blockPos.getX() + " Y: " + blockPos.getY() + " Z: " + blockPos.getZ() ), false );
}
mc.player.closeScreen();
}
if (btn == guiButtonHide)
{
partInterfaceTerminal.onlyInterfacesWithFreeSlots = !partInterfaceTerminal.onlyInterfacesWithFreeSlots;
this.refreshList();
}
if (btn == guiButtonNextAssembler)
{
// Set Search to "Molecular Assembler" and set "Only Free Interface"
boolean currentOnlyInterfacesWithFreeSlots = this.partInterfaceTerminal.onlyInterfacesWithFreeSlots;
String currentSearchText = this.searchFieldOutputs.getText();
this.partInterfaceTerminal.onlyInterfacesWithFreeSlots = true;
this.searchFieldOutputs.setText("Molecular Assembler");
this.refreshList();
this.partInterfaceTerminal.onlyInterfacesWithFreeSlots = currentOnlyInterfacesWithFreeSlots;
this.searchFieldOutputs.setText(currentSearchText);
}
}
@Override
public void drawBG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.bindTexture( "guis/interfaceterminal.png" );
this.bindTexture( "guis/newinterfaceterminal.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, this.xSize, this.ySize );
int offset = 17;
int offset = 51;
final int ex = this.getScrollBar().getCurrentScroll();
for( int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
int linesDraw = 0;
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
{
final Object lineObj = this.lines.get( ex + x );
if( lineObj instanceof ClientDCInternalInv )
{
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
GlStateManager.color( 1, 1, 1, 1 );
final int width = inv.getInventory().getSlots() * 18;
this.drawTexturedModalRect( offsetX + 7, offsetY + offset, 7, 139, width, 18 );
final int width = 9 * 18;
int extraLines = numUpgradesMap.get( lineObj );
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE; ++row )
{
this.drawTexturedModalRect( offsetX + 20, offsetY + offset , 20, 173, width, 18 );
offset += 18;
linesDraw++;
}
}
else {
offset += 18;
linesDraw++;
}
offset += 18;
}
if( this.searchField != null )
if( this.searchFieldInputs != null )
{
this.searchField.drawTextBox();
this.searchFieldInputs.drawTextBox();
}
if( this.searchFieldOutputs != null )
{
this.searchFieldOutputs.drawTextBox();
}
}
@@ -193,15 +321,21 @@ public class GuiInterfaceTerminal extends AEBaseGui
{
if( !this.checkHotbarKeys( key ) )
{
if( character == ' ' && this.searchField.getText().isEmpty() )
if( character == ' ' && this.searchFieldInputs.getText().isEmpty() && this.searchFieldInputs.isFocused() )
{
return;
}
if( this.searchField.textboxKeyTyped( character, key ) )
if( character == ' ' && this.searchFieldOutputs.getText().isEmpty() && this.searchFieldOutputs.isFocused())
{
return;
}
if( this.searchFieldInputs.textboxKeyTyped( character, key ) || this.searchFieldOutputs.textboxKeyTyped( character, key ))
{
this.refreshList();
}
else
{
super.keyTyped( character, key );
@@ -227,6 +361,9 @@ public class GuiInterfaceTerminal extends AEBaseGui
final long id = Long.parseLong( key.substring( 1 ), Character.MAX_RADIX );
final NBTTagCompound invData = in.getCompoundTag( key );
final ClientDCInternalInv current = this.getById( id, invData.getLong( "sortBy" ), invData.getString( "un" ) );
blockPosHashMap.put( current, NBTUtil.getPosFromTag( invData.getCompoundTag( "pos" )) );
dimHashMap.put( current, invData.getInteger( "dim" ));
numUpgradesMap.put( current, invData.getInteger("numUpgrades"));
for( int x = 0; x < current.getInventory().getSlots(); x++ )
{
@@ -260,41 +397,73 @@ public class GuiInterfaceTerminal extends AEBaseGui
private void refreshList()
{
this.byName.clear();
this.buttonList.clear();
this.matchedStacks.clear();
final String searchFilterLowerCase = this.searchField.getText().toLowerCase();
final String searchFieldInputs = this.searchFieldInputs.getText().toLowerCase();
final String searchFieldOutputs = this.searchFieldOutputs.getText().toLowerCase();
final Set<Object> cachedSearch = this.getCacheForSearchTerm( searchFilterLowerCase );
final Set<Object> cachedSearch = this.getCacheForSearchTerm( "IN:" + searchFieldInputs + " OUT:" + searchFieldOutputs + partInterfaceTerminal.onlyInterfacesWithFreeSlots);
final boolean rebuild = cachedSearch.isEmpty();
for( final ClientDCInternalInv entry : this.byId.values() )
{
// ignore inventory if not doing a full rebuild or cache already marks it as miss.
// ignore inventory if not doing a full rebuild and cache already marks it as miss.
if( !rebuild && !cachedSearch.contains( entry ) )
{
continue;
}
// Shortcut to skip any filter if search term is ""/empty
boolean found = searchFilterLowerCase.isEmpty();
boolean found = (searchFieldInputs.isEmpty() && searchFieldOutputs.isEmpty() && !partInterfaceTerminal.onlyInterfacesWithFreeSlots);
boolean interfaceHasFreeSlots = false;
// Search if the current inventory holds a pattern containing the search term.
if( !found && !searchFilterLowerCase.isEmpty() )
if( !found )
{
int slot = 0;
for( final ItemStack itemStack : entry.getInventory() )
{
found = this.itemStackMatchesSearchTerm( itemStack, searchFilterLowerCase );
if( found )
{
if (slot > 8 + numUpgradesMap.get(entry) * 9) {
break;
}
if( !searchFieldInputs.isEmpty() && !searchFieldOutputs.isEmpty() ) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0) || this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
found = true;
matchedStacks.add(itemStack);
}
}
else if( !searchFieldInputs.isEmpty() ) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0)) {
found = true;
matchedStacks.add(itemStack);
}
}
else if( !searchFieldOutputs.isEmpty() ) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
found = true;
matchedStacks.add(itemStack);
}
}
// If only Interfaces with empty slots should be shown, check that here
if(itemStack.isEmpty())
interfaceHasFreeSlots = true;
slot++;
}
}
// if found, filter skipped or machine name matching the search term, add it
if( found || entry.getName().toLowerCase().contains( searchFilterLowerCase ) )
if( found || (entry.getName().toLowerCase().contains( searchFieldInputs ) && entry.getName().toLowerCase().contains( searchFieldOutputs )))
{
this.byName.put( entry.getName(), entry );
cachedSearch.add( entry );
if (!partInterfaceTerminal.onlyInterfacesWithFreeSlots)
{
this.byName.put( entry.getName(), entry );
cachedSearch.add( entry );
}
else if ( interfaceHasFreeSlots ){
this.byName.put( entry.getName(), entry );
cachedSearch.add( entry );
}
}
else
{
@@ -321,10 +490,10 @@ public class GuiInterfaceTerminal extends AEBaseGui
this.lines.addAll( clientInventories );
}
this.getScrollBar().setRange( 0, this.lines.size() - LINES_ON_PAGE, 2 );
this.getScrollBar().setRange( 0, this.lines.size() - 1, 1 );
}
private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm )
private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm,int pass )
{
if( itemStack.isEmpty() )
{
@@ -338,14 +507,21 @@ public class GuiInterfaceTerminal extends AEBaseGui
return false;
}
// Potential later use to filter by input
// NBTTagList inTag = encodedValue.getTagList( "in", 10 );
final NBTTagList outTag = encodedValue.getTagList( "out", 10 );
NBTTagList tag = new NBTTagList();
for( int i = 0; i < outTag.tagCount(); i++ )
if (pass == 0)
{
tag = encodedValue.getTagList( "in", 10 );
}
else
{
tag = encodedValue.getTagList( "out", 10 );
}
for( int i = 0; i < tag.tagCount(); i++ )
{
final ItemStack parsedItemStack = new ItemStack( outTag.getCompoundTagAt( i ) );
final ItemStack parsedItemStack = new ItemStack( tag.getCompoundTagAt( i ) );
if( !parsedItemStack.isEmpty() )
{
final String displayName = Platform
@@ -404,7 +580,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
if( o == null )
{
this.byId.put( id, o = new ClientDCInternalInv( 9, id, sortBy, string ) );
this.byId.put( id, o = new ClientDCInternalInv( DualityInterface.NUMBER_OF_PATTERN_SLOTS, id, sortBy, string ) );
this.refreshList = true;
}
@@ -40,6 +40,7 @@ import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseMEGui;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiScrollbar;
@@ -54,6 +55,7 @@ import appeng.container.slot.SlotCraftingMatrix;
import appeng.container.slot.SlotFakeCraftingMatrix;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import appeng.core.sync.GuiBridge;
import appeng.core.sync.network.NetworkHandler;
@@ -481,7 +483,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
if( !this.checkHotbarKeys( key ) )
{
if( key == Keyboard.KEY_TAB )
if( AppEng.proxy.isActionKey( ActionKey.TOGGLE_FOCUS, key ) )
{
this.searchField.setFocused( !this.searchField.isFocused() );
return;
@@ -19,11 +19,21 @@
package appeng.client.gui.implementations;
import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.List;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.SlotFake;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import mezz.jei.api.gui.IGhostIngredientHandler.Target;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import appeng.api.config.ActionItems;
@@ -40,7 +50,7 @@ import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketValueConfig;
public class GuiPatternTerm extends GuiMEMonitorable
public class GuiPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
{
private static final String BACKGROUND_CRAFTING_MODE = "guis/pattern.png";
@@ -60,6 +70,14 @@ public class GuiPatternTerm extends GuiMEMonitorable
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<Target<?>,Object> mapTargetSlot = new HashMap<>();
public GuiPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
@@ -78,13 +96,20 @@ public class GuiPatternTerm extends GuiMEMonitorable
if( this.tabCraftButton == btn || this.tabProcessButton == btn )
{
NetworkHandler.instance().sendToServer(
new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
NetworkHandler.instance()
.sendToServer(
new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
}
if( this.encodeBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "1" ) );
if ( isShiftKeyDown() ){
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "2" ) );
}
else
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "1" ) );
}
}
if( this.clearBtn == btn )
@@ -92,10 +117,46 @@ public class GuiPatternTerm extends GuiMEMonitorable
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 ) );
NetworkHandler.instance()
.sendToServer(
new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
}
}
catch( final IOException e )
@@ -129,6 +190,34 @@ public class GuiPatternTerm extends GuiMEMonitorable
this.clearBtn.setHalfSize( true );
this.buttonList.add( this.clearBtn );
this.x3Btn = new GuiImgButton( this.guiLeft + 128, 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 + 128, 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 + 128, this.guiTop + this.ySize - 138, Settings.ACTIONS, ActionItems.INCREASE_BY_ONE );
this.plusOneBtn.setHalfSize( true );
this.buttonList.add( this.plusOneBtn );
this.divThreeBtn = new GuiImgButton( this.guiLeft + 100, 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 + 100, 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 + 100, this.guiTop + this.ySize - 138, 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 );
}
@@ -140,6 +229,13 @@ public class GuiPatternTerm extends GuiMEMonitorable
{
this.tabCraftButton.visible = true;
this.tabProcessButton.visible = false;
this.x2Btn.visible = false;
this.x3Btn.visible = false;
this.divTwoBtn.visible = false;
this.divThreeBtn.visible = false;
this.plusOneBtn.visible = false;
this.minusOneBtn.visible = false;
//this.maxCountBtn.visible = false;
if( this.container.substitute )
{
@@ -158,6 +254,13 @@ public class GuiPatternTerm extends GuiMEMonitorable
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 );
@@ -182,4 +285,52 @@ public class GuiPatternTerm extends GuiMEMonitorable
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
}
@Override
public List<Target<?>> getPhantomTargets(Object ingredient) {
if (!(ingredient instanceof ItemStack )) {
return Collections.emptyList();
}
List<Target<?>> targets = new ArrayList<>();
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotFake )
{
ItemStack itemStack = (ItemStack) ingredient;
Target<Object> target = new Target<Object>()
{
@Override
public Rectangle getArea()
{
return new Rectangle( getGuiLeft() + slot.xPos, getGuiTop() + slot.yPos, 16, 16 );
}
@Override
public void accept( Object ingredient )
{
final PacketInventoryAction p;
try
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (SlotFake) slot, AEItemStack.fromItemStack( itemStack ) );
NetworkHandler.instance().sendToServer( p );
}
catch( IOException e )
{
e.printStackTrace();
}
}
};
targets.add( target );
mapTargetSlot.putIfAbsent( target, slot );
}
}
return targets;
}
@Override
public Map<Target<?>, Object> getFakeSlotTargetMap()
{
return mapTargetSlot;
}
}
@@ -19,8 +19,24 @@
package appeng.client.gui.implementations;
import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.List;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.IJEITargetSlot;
import appeng.container.slot.SlotFake;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
import appeng.fluids.util.AEFluidStack;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import mezz.jei.api.gui.IGhostIngredientHandler.Target;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.*;
import org.lwjgl.input.Mouse;
import net.minecraft.client.gui.GuiButton;
@@ -43,9 +59,9 @@ import appeng.parts.automation.PartExportBus;
import appeng.parts.automation.PartImportBus;
public class GuiUpgradeable extends AEBaseGui
public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
{
private final Map<Target<?>,Object> mapTargetSlot = new HashMap<>();
protected final ContainerUpgradeable cvb;
protected final IUpgradeableHost bc;
@@ -200,4 +216,111 @@ public class GuiUpgradeable extends AEBaseGui
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.schedulingMode.getSetting(), backwards ) );
}
}
@Override
public List<Target<?>> getPhantomTargets(Object ingredient)
{
mapTargetSlot.clear();
FluidStack fluidStack = null;
ItemStack itemStack = ItemStack.EMPTY;
if( ingredient instanceof ItemStack )
{
itemStack = (ItemStack) ingredient;
fluidStack = FluidUtil.getFluidContained( itemStack );
}
else if( ingredient instanceof FluidStack )
{
fluidStack = (FluidStack) ingredient;
}
if( !( ingredient instanceof ItemStack ) && !( ingredient instanceof FluidStack ) )
return Collections.emptyList();
List<Target<?>> targets = new ArrayList<>();
List<IJEITargetSlot> slots = new ArrayList<>();
if( this.inventorySlots.inventorySlots.size() > 0 )
{
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotFake && ( !itemStack.isEmpty() || this instanceof GuiCellWorkbench && fluidStack != null ) )
{
slots.add( (IJEITargetSlot) slot );
}
}
}
if( this.getGuiSlots().size() > 0 )
{
for( GuiCustomSlot slot : this.getGuiSlots() )
{
if( slot instanceof GuiFluidSlot && fluidStack != null )
{
slots.add( (IJEITargetSlot) slot );
}
}
}
for( Object slot : slots )
{
ItemStack finalItemStack = itemStack;
FluidStack finalFluidStack = fluidStack;
Target<Object> targetItem = new Target<Object>()
{
@Override
public Rectangle getArea()
{
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
{
return new Rectangle( getGuiLeft() + ( (SlotFake) slot ).xPos, getGuiTop() + ( (SlotFake) slot ).yPos, 16, 16 );
}
else if( slot instanceof GuiFluidSlot && ( (GuiFluidSlot) slot ).isSlotEnabled() )
{
return new Rectangle( getGuiLeft() + ( (GuiFluidSlot) slot ).xPos(), getGuiTop() + ( (GuiFluidSlot) slot ).yPos(), 16, 16 );
}
return new Rectangle();
}
@Override
public void accept( Object ingredient )
{
PacketInventoryAction p = null;
try
{
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
{
if( finalItemStack.isEmpty() && finalFluidStack != null )
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( FluidUtil.getFilledBucket( finalFluidStack ) ) );
}
else if( !finalItemStack.isEmpty() )
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( finalItemStack ) );
}
}
else
{
if( finalFluidStack == null ) return;
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( AEFluidStack.fromFluidStack( finalFluidStack ).asItemStackRepresentation() ) );
}
NetworkHandler.instance().sendToServer( p );
}
catch( IOException e )
{
e.printStackTrace();
}
}
};
targets.add( targetItem );
mapTargetSlot.putIfAbsent( targetItem, slot );
}
return targets;
}
@Override
public Map<Target<?>, Object> getFakeSlotTargetMap()
{
return mapTargetSlot;
}
}
@@ -58,11 +58,11 @@ public class GuiVibrationChamber extends AEBaseGui
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.VibrationChamber.getLocal() ), 8, 6, 4210752 );
this.fontRenderer.drawString( GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752 );
this.pb.setFullMsg( this.cvc.getAePerTick() * this.cvc.getCurrentProgress() / 100 + " AE/t" );
this.pb.setFullMsg( TileVibrationChamber.POWER_PER_TICK * this.cvc.getCurrentProgress() / TileVibrationChamber.DILATION_SCALING + " AE/t" );
if( this.cvc.getCurrentProgress() > 0 )
if( this.cvc.getRemainingBurnTime() > 0 )
{
final int i1 = this.cvc.getCurrentProgress();
final int i1 = this.cvc.getRemainingBurnTime() * 12 / 100;
this.bindTexture( "guis/vibchamber.png" );
GlStateManager.color( 1, 1, 1 );
final int l = -15;
@@ -10,9 +10,9 @@ import net.minecraft.item.ItemStack;
public abstract class GuiCustomSlot extends Gui implements ITooltip
{
private final int x;
private final int y;
private final int id;
protected final int x;
protected final int y;
protected final int id;
public GuiCustomSlot( final int id, final int x, final int y )
{
@@ -23,7 +23,7 @@ public abstract class GuiCustomSlot extends Gui implements ITooltip
public int getId()
{
return id;
return this.id;
}
public boolean canClick( final EntityPlayer player )
@@ -134,6 +134,19 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 6, Settings.ACTIONS, ActionItems.CLOSE, ButtonToolTips.Clear, ButtonToolTips.ClearSettings );
this.registerApp( 6, Settings.ACTIONS, ActionItems.STASH, ButtonToolTips.Stash, ButtonToolTips.StashDesc );
this.registerApp( 6 + 4 * 16, Settings.ACTIONS, ActionItems.MULTIPLY_BY_TWO, ButtonToolTips.MultiplyByTwo, ButtonToolTips.MultiplyByTwoDesc );
this.registerApp( 7 + 4 * 16, Settings.ACTIONS, ActionItems.MULTIPLY_BY_THREE, ButtonToolTips.MultiplyByThree, ButtonToolTips.MultiplyByThreeDesc );
this.registerApp( 8 + 4 * 16, Settings.ACTIONS, ActionItems.INCREASE_BY_ONE, ButtonToolTips.IncreaseByOne, ButtonToolTips.IncreaseByOneDesc );
this.registerApp( 9 + 4 * 16, Settings.ACTIONS, ActionItems.DIVIDE_BY_TWO, ButtonToolTips.DivideByTwo, ButtonToolTips.DivideByTwoDesc );
this.registerApp( 10 + 4 * 16, Settings.ACTIONS, ActionItems.DIVIDE_BY_THREE, ButtonToolTips.DivideByThree, ButtonToolTips.DivideByThreeDesc );
this.registerApp( 11 + 4 * 16, Settings.ACTIONS, ActionItems.DECREASE_BY_ONE, ButtonToolTips.DecreaseByOne, ButtonToolTips.DecreaseByOneDesc );
this.registerApp( 12 + 4 * 16, Settings.ACTIONS, ActionItems.MAX_COUNT, ButtonToolTips.MaxCount, ButtonToolTips.MaxCountDesc );
this.registerApp( 6 + 5 * 16, Settings.ACTIONS, ActionItems.FREE_MOLECULAR_SLOT_SHORTCUT, ButtonToolTips.FreeMolecularSlotShortcut, ButtonToolTips.FreeMolecularSlotShortcutDesc );
this.registerApp( 7 + 5 * 16, Settings.ACTIONS, ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON, ButtonToolTips.ToggleShowFullInterfaces, ButtonToolTips.ToggleShowFullInterfacesOnDesc );
this.registerApp( 8 + 5 * 16, Settings.ACTIONS, ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF, ButtonToolTips.ToggleShowFullInterfaces, ButtonToolTips.ToggleShowFullInterfacesOffDesc );
this.registerApp( 6 + 6 * 16, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE, ButtonToolTips.HighlightInterface, "" );
this.registerApp( 8, Settings.ACTIONS, ActionItems.ENCODE, ButtonToolTips.Encode, ButtonToolTips.EncodeDescription );
this.registerApp( 4 + 3 * 16, Settings.ACTIONS, ItemSubstitution.ENABLED, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDescEnabled );
this.registerApp( 7 + 3 * 16, Settings.ACTIONS, ItemSubstitution.DISABLED, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDescDisabled );
@@ -131,7 +131,9 @@ public class MEGuiTextField extends GuiTextField
public void drawSelectionBox( int startX, int startY, int endX, int endY )
{
if( !this.isFocused() )
{
return;
}
if( startX < endX )
{
@@ -165,20 +167,20 @@ public class MEGuiTextField extends GuiTextField
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer();
float red = (float) ( this.selectionColor >> 16 & 255 ) / 255.0F;
float blue = (float) ( this.selectionColor >> 8 & 255 ) / 255.0F;
float green = (float) ( this.selectionColor & 255 ) / 255.0F;
float alpha = (float) ( this.selectionColor >> 24 & 255 ) / 255.0F;
float red = ( this.selectionColor >> 16 & 255 ) / 255.0F;
float blue = ( this.selectionColor >> 8 & 255 ) / 255.0F;
float green = ( this.selectionColor & 255 ) / 255.0F;
float alpha = ( this.selectionColor >> 24 & 255 ) / 255.0F;
GlStateManager.color( red, green, blue, alpha );
GlStateManager.disableTexture2D();
GlStateManager.enableColorLogic();
GlStateManager.colorLogicOp( GlStateManager.LogicOp.OR_REVERSE );
bufferbuilder.begin( 7, DefaultVertexFormats.POSITION );
bufferbuilder.pos( (double) startX, (double) endY, 0.0D ).endVertex();
bufferbuilder.pos( (double) endX, (double) endY, 0.0D ).endVertex();
bufferbuilder.pos( (double) endX, (double) startY, 0.0D ).endVertex();
bufferbuilder.pos( (double) startX, (double) startY, 0.0D ).endVertex();
bufferbuilder.pos( startX, endY, 0.0D ).endVertex();
bufferbuilder.pos( endX, endY, 0.0D ).endVertex();
bufferbuilder.pos( endX, startY, 0.0D ).endVertex();
bufferbuilder.pos( startX, startY, 0.0D ).endVertex();
tessellator.draw();
GlStateManager.disableColorLogic();
GlStateManager.enableTexture2D();
@@ -37,7 +37,7 @@ public class ClientDCInternalInv implements Comparable<ClientDCInternalInv>
public ClientDCInternalInv( final int size, final long id, final long sortBy, final String unlocalizedName )
{
this.inventory = new AppEngInternalInventory( null, size );
this.inventory = new AppEngInternalInventory( null, size, 1 );
this.unlocalizedName = unlocalizedName;
this.id = id;
this.sortBy = sortBy;
@@ -0,0 +1,34 @@
package appeng.client.render;
import net.minecraft.util.math.BlockPos;
// taken from McJty's McJtyLib
public class BlockPosHighlighter
{
private static BlockPos hilightedBlock;
private static long expireHilight;
private static int dimension;
public static void hilightBlock( BlockPos c, long expireHilight, int dimension ) {
hilightedBlock = c;
BlockPosHighlighter.expireHilight = expireHilight;
BlockPosHighlighter.dimension = dimension;
}
public static BlockPos getHilightedBlock() {
return hilightedBlock;
}
public static long getExpireHilight() {
return expireHilight;
}
public static int getDimension()
{
return dimension;
}
}
@@ -41,6 +41,7 @@ import net.minecraft.util.EnumFacing;
public class DummyFluidBakedModel implements IBakedModel
{
private final ImmutableList<BakedQuad> quads;
public DummyFluidBakedModel( ImmutableList<BakedQuad> quads )
{
this.quads = quads;
@@ -49,7 +50,7 @@ public class DummyFluidBakedModel implements IBakedModel
@Override
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
return quads;
return this.quads;
}
@Override
@@ -104,13 +104,13 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel
fluidStack = new FluidStack( FluidRegistry.WATER, Fluid.BUCKET_VOLUME );
}
TextureAtlasSprite sprite = bakedTextureGetter.apply( fluidStack.getFluid().getStill( fluidStack ) );
TextureAtlasSprite sprite = DummyFluidDispatcherBakedModel.this.bakedTextureGetter.apply( fluidStack.getFluid().getStill( fluidStack ) );
if( sprite == null )
{
return new DummyFluidBakedModel( ImmutableList.of() );
}
return new DummyFluidBakedModel( ItemLayerModel.getQuadsForSprite( 0, sprite, format, Optional.empty() ) );
return new DummyFluidBakedModel( ItemLayerModel.getQuadsForSprite( 0, sprite, DummyFluidDispatcherBakedModel.this.format, Optional.empty() ) );
}
};
}
@@ -51,7 +51,7 @@ public class DummyFluidItemModel implements IModel
{
try
{
baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
this.baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
}
catch( Exception e )
{
@@ -78,12 +78,12 @@ public class DummyFluidItemModel implements IModel
{
IBakedModel bakedBaseModel = this.getBaseModel().bake( state, format, bakedTextureGetter );
return new DummyFluidDispatcherBakedModel( bakedBaseModel, format, bakedTextureGetter );
return new DummyFluidDispatcherBakedModel( bakedBaseModel, format, bakedTextureGetter );
}
@Override
public IModelState getDefaultState()
{
return getBaseModel().getDefaultState();
return this.getBaseModel().getDefaultState();
}
}
@@ -0,0 +1,91 @@
/*
* 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.client.render;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import appeng.client.render.cablebus.FacadeBuilder;
/**
* This model used the provided FacadeBuilder to "slice" the item quads for the facade provided.
*
* @author covers1624
*/
public class FacadeBakedItemModel extends DelegateBakedModel
{
private final ItemStack textureStack;
private final FacadeBuilder facadeBuilder;
private List<BakedQuad> quads = null;
protected FacadeBakedItemModel( IBakedModel base, ItemStack textureStack, FacadeBuilder facadeBuilder )
{
super( base );
this.textureStack = textureStack;
this.facadeBuilder = facadeBuilder;
}
@Override
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
if( side != null )
{
return Collections.emptyList();
}
if( quads == null )
{
quads = new ArrayList<>();
quads.addAll( this.facadeBuilder.buildFacadeItemQuads( this.textureStack, EnumFacing.NORTH ) );
quads.addAll( this.getBaseModel().getQuads( state, side, rand ) );
quads = Collections.unmodifiableList( quads );
}
return quads;
}
@Override
public boolean isGui3d()
{
return false;
}
@Override
public boolean isBuiltInRenderer()
{
return false;
}
@Override
public ItemOverrideList getOverrides()
{
return ItemOverrideList.NONE;
}
}
@@ -21,9 +21,12 @@ package appeng.client.render;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -34,6 +37,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import appeng.client.render.cablebus.FacadeBuilder;
import appeng.items.parts.ItemFacade;
@@ -45,11 +49,14 @@ import appeng.items.parts.ItemFacade;
public class FacadeDispatcherBakedModel extends DelegateBakedModel
{
private final VertexFormat format;
private final FacadeBuilder facadeBuilder;
private final Int2ObjectMap<FacadeBakedItemModel> cache = new Int2ObjectArrayMap<>();
public FacadeDispatcherBakedModel( IBakedModel baseModel, VertexFormat format )
public FacadeDispatcherBakedModel( IBakedModel baseModel, VertexFormat format, FacadeBuilder facadeBuilder )
{
super( baseModel );
this.format = format;
this.facadeBuilder = facadeBuilder;
}
// This is never used. See the item override list below.
@@ -86,11 +93,17 @@ public class FacadeDispatcherBakedModel extends DelegateBakedModel
ItemFacade itemFacade = (ItemFacade) stack.getItem();
IBlockState state = itemFacade.getTextureBlockState( stack );
ItemStack textureItem = itemFacade.getTextureItem( stack );
return new FacadeWithBlockBakedModel( FacadeDispatcherBakedModel.this
.getBaseModel(), state, textureItem, FacadeDispatcherBakedModel.this.format );
int hash = Objects.hash( textureItem.getItem().getRegistryName(), textureItem.getMetadata(), textureItem.getTagCompound() );
FacadeBakedItemModel model = FacadeDispatcherBakedModel.this.cache.get( hash );
if( model == null )
{
model = new FacadeBakedItemModel(FacadeDispatcherBakedModel.this.getBaseModel(), textureItem, FacadeDispatcherBakedModel.this.facadeBuilder);
FacadeDispatcherBakedModel.this.cache.put(hash, model);
}
return model;
}
};
}
@@ -31,6 +31,7 @@ import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.model.IModelState;
import appeng.client.render.cablebus.FacadeBuilder;
import appeng.core.AppEng;
@@ -71,8 +72,9 @@ public class FacadeItemModel implements IModel
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
{
IBakedModel bakedBaseModel = this.getBaseModel().bake( state, format, bakedTextureGetter );
FacadeBuilder facadeBuilder = new FacadeBuilder();
return new FacadeDispatcherBakedModel( bakedBaseModel, format );
return new FacadeDispatcherBakedModel( bakedBaseModel, format, facadeBuilder );
}
@Override
@@ -1,106 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, 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.client.render;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.client.render.cablebus.FacadeBuilder;
/**
* This is the actual baked model that will combine the north face of a given block state
* with the base facade item model to achieve what is then actually rendered on screen.
*/
public class FacadeWithBlockBakedModel extends DelegateBakedModel
{
private final IBlockState blockState;
private final IBakedModel textureModel;
private final VertexFormat format;
private final ItemStack textureItem;
public FacadeWithBlockBakedModel( IBakedModel baseModel, IBlockState blockState, ItemStack textureItem, VertexFormat format )
{
super( baseModel );
this.blockState = blockState;
this.textureItem = textureItem;
this.textureModel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState( blockState );
this.format = format;
}
@Override
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
// Only the north side is actually read from the base model for item models
if( side == EnumFacing.NORTH )
{
List<BakedQuad> quads = new ArrayList<>( 1 );
CubeBuilder builder = new CubeBuilder( this.format, quads );
FacadeBuilder.TextureAtlasAndTint sprite = FacadeBuilder.getSprite( this.textureModel, this.blockState, side, rand );
if( sprite != null && sprite.getSprite() != null )
{
if( sprite.getTint() != -1 )
{
builder.setColor( Minecraft.getMinecraft().getItemColors().colorMultiplier( this.textureItem, sprite.getTint() ) );
}
builder.setTexture( sprite.getSprite() );
builder.setDrawFaces( EnumSet.of( EnumFacing.NORTH ) );
builder.addCube( 0, 0, 0, 16, 16, 16 );
return quads;
}
}
return this.getBaseModel().getQuads( state, side, rand );
}
@Override
public boolean isGui3d()
{
return false;
}
@Override
public boolean isBuiltInRenderer()
{
return false;
}
@Override
public ItemOverrideList getOverrides()
{
return ItemOverrideList.NONE;
}
}
@@ -19,17 +19,21 @@
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;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.IWideReadableNumberConverter;
import appeng.util.ReadableNumberConverter;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
/**
@@ -119,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.
*
@@ -143,4 +190,23 @@ public class TesrRenderHelper
}
public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing )
{
final FluidStack renderStack = fluidStack.getFluidStack();
TesrRenderHelper.renderFluid2d( renderStack, scale );
final long stackSize = fluidStack.getStackSize() / 1000;
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
// Render the item count
final FontRenderer fr = Minecraft.getMinecraft().fontRenderer;
final int width = fr.getStringWidth( renderedStackSize );
GlStateManager.translate( 0.0f, spacing, 0 );
GlStateManager.scale( 1.0f / 62.0f, 1.0f / 62.0f, 1.0f / 62.0f );
GlStateManager.translate( -0.5f * width, 0.0f, 0.5f );
fr.drawString( renderedStackSize, 0, 0, 0 );
}
}
@@ -493,6 +493,11 @@ class CableBuilder
this.addCoveredConnection( facing, cableColor, connectionType, cableBusAdjacent, quadsOut );
return;
}
else if( connectionType == AECableType.DENSE_COVERED )
{
this.addDenseCoveredConnection( facing, cableColor, connectionType, cableBusAdjacent, quadsOut );
return;
}
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
@@ -88,8 +88,9 @@ public class CableBusBakedModel implements IBakedModel
List<BakedQuad> quads = new ArrayList<>();
// The core parts of the cable will only be rendered in the CUTOUT layer. TRANSLUCENT is used only for
// translucent facades further down below.
// The core parts of the cable will only be rendered in the CUTOUT layer.
// Facades will add them selves to what ever the block would be rendered with,
// except when transparent facades are enabled, they are forced to TRANSPARENT.
if( layer == BlockRenderLayer.CUTOUT )
{
@@ -138,14 +139,7 @@ public class CableBusBakedModel implements IBakedModel
}
}
}
this.facadeBuilder.addFacades(
layer,
renderState.getFacades(),
renderState.getBoundingBoxes(),
renderState.getAttachments().keySet(),
rand,
quads );
this.facadeBuilder.buildFacadeQuads( layer, renderState, rand, quads, this.partModels::get );
return quads;
}
@@ -178,7 +172,7 @@ public class CableBusBakedModel implements IBakedModel
final AECableType secondType = sides.get( firstSide.getOpposite() );
return firstType == secondType;
return firstType == secondType && cableType == firstType && cableType == secondType;
}
private void addCableQuads( CableBusRenderState renderState, List<BakedQuad> quadsOut )
@@ -65,7 +65,6 @@ public class CableBusModel implements IModel
{
return ImmutableList.<ResourceLocation>builder()
.addAll( CableBuilder.getTextures() )
.addAll( FacadeBuilder.getTextures() )
.build();
}
@@ -75,7 +74,7 @@ public class CableBusModel implements IModel
Map<ResourceLocation, IBakedModel> partModels = this.loadPartModels( state, format, bakedTextureGetter );
CableBuilder cableBuilder = new CableBuilder( format, bakedTextureGetter );
FacadeBuilder facadeBuilder = new FacadeBuilder( format, bakedTextureGetter );
FacadeBuilder facadeBuilder = new FacadeBuilder();
// This should normally not be used, but we *have* to provide a particle texture or otherwise damage models will
// crash
@@ -19,6 +19,7 @@
package appeng.client.render.cablebus;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.EnumSet;
@@ -27,6 +28,8 @@ import java.util.Objects;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
@@ -69,6 +72,10 @@ public class CableBusRenderState
// Contains the facade to use for each side that has a facade attached
private EnumMap<EnumFacing, FacadeRenderState> facades = new EnumMap<>( EnumFacing.class );
// Used for Facades.
private WeakReference<IBlockAccess> world;
private BlockPos pos;
// Contains the bounding boxes of all parts on the cable bus to allow facades to cut out holes for the parts. This
// list is only populated if there are
// facades on this cable bus
@@ -151,6 +158,26 @@ public class CableBusRenderState
return this.facades;
}
public IBlockAccess getWorld()
{
return this.world.get();
}
public void setWorld( IBlockAccess world )
{
this.world = new WeakReference<>( world );
}
public BlockPos getPos()
{
return this.pos;
}
public void setPos( BlockPos pos )
{
this.pos = pos;
}
public List<AxisAlignedBB> getBoundingBoxes()
{
return this.boundingBoxes;
@@ -188,7 +215,7 @@ public class CableBusRenderState
{
return false;
}
if( getClass() != obj.getClass() )
if( this.getClass() != obj.getClass() )
{
return false;
}
@@ -196,9 +223,8 @@ public class CableBusRenderState
final CableBusRenderState other = (CableBusRenderState) obj;
return this.cableColor == other.cableColor && this.cableType == other.cableType && this.coreType == other.coreType && Objects
.equals( this.attachmentConnections, other.attachmentConnections ) && Objects.equals( this.cableBusAdjacent,
other.cableBusAdjacent ) && Objects.equals( this.channelsOnSide, other.channelsOnSide ) && Objects.equals( this.connectionTypes,
other.connectionTypes ) && Objects.equals( this.partFlags, other.partFlags );
.equals( this.attachmentConnections, other.attachmentConnections ) && Objects.equals( this.cableBusAdjacent, other.cableBusAdjacent ) && Objects
.equals( this.channelsOnSide, other.channelsOnSide ) && Objects.equals( this.connectionTypes, other.connectionTypes ) && Objects
.equals( this.partFlags, other.partFlags );
}
}
@@ -0,0 +1,115 @@
/*
* 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.client.render.cablebus;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.WorldType;
import net.minecraft.world.biome.Biome;
/**
* This is used to retrieve the ExtendedState of a block for facade rendering.
* It fakes the block at BlockPos provided as the IBlockState provided.
*
* @author covers1624
*/
public class FacadeBlockAccess implements IBlockAccess
{
private final IBlockAccess world;
private final BlockPos pos;
private final EnumFacing side;
private final IBlockState state;
public FacadeBlockAccess( IBlockAccess world, BlockPos pos, EnumFacing side, IBlockState state )
{
this.world = world;
this.pos = pos;
this.side = side;
this.state = state;
}
@Nullable
@Override
public TileEntity getTileEntity( BlockPos pos )
{
return this.world.getTileEntity( pos );
}
@Override
public int getCombinedLight( BlockPos pos, int lightValue )
{
return this.world.getCombinedLight( pos, lightValue );
}
@Override
public IBlockState getBlockState( BlockPos pos )
{
if( this.pos == pos )
{
return this.state;
}
return this.world.getBlockState( pos );
}
@Override
public boolean isAirBlock( BlockPos pos )
{
IBlockState state = this.getBlockState( pos );
return state.getBlock().isAir( state, this.world, pos );
}
@Override
public Biome getBiome( BlockPos pos )
{
return this.world.getBiome( pos );
}
@Override
public int getStrongPower( BlockPos pos, EnumFacing direction )
{
return this.world.getStrongPower( pos, direction );
}
@Override
public WorldType getWorldType()
{
return this.world.getWorldType();
}
@Override
public boolean isSideSolid( BlockPos pos, EnumFacing side, boolean _default )
{
if( pos.getX() < -30000000 || pos.getZ() < -30000000 || pos.getX() >= 30000000 || pos.getZ() >= 30000000 )
{
return _default;
}
else
{
return this.getBlockState( pos ).isSideSolid( this, pos, side );
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
* 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
@@ -19,370 +19,372 @@
package appeng.client.render.cablebus;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;
import javax.vecmath.Vector3f;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumFacing.Axis;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.MinecraftForgeClient;
import appeng.api.AEApi;
import appeng.api.util.AEAxisAlignedBB;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.parts.misc.PartCableAnchor;
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
import appeng.thirdparty.codechicken.lib.model.Quad;
import appeng.thirdparty.codechicken.lib.model.pipeline.BakedPipeline;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadAlphaOverride;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadClamper;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadCornerKicker;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadFaceStripper;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadReInterpolator;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadTinter;
/**
* Handles creating the quads for facades attached to cable busses.
* The FacadeBuilder builds for facades..
*
* @author covers1624
*/
public class FacadeBuilder
{
private static final ResourceLocation TEXTURE_FACADE = new ResourceLocation( AppEng.MOD_ID, "parts/cable_anchor" );
public static final double THICK_THICKNESS = 2D / 16D;
public static final double THIN_THICKNESS = 1D / 16D;
private final VertexFormat format;
public static final AxisAlignedBB[] THICK_FACADE_BOXES = new AxisAlignedBB[] {
new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, THICK_THICKNESS, 1.0 ),
new AxisAlignedBB( 0.0, 1.0 - THICK_THICKNESS, 0.0, 1.0, 1.0, 1.0 ),
new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, THICK_THICKNESS ),
new AxisAlignedBB( 0.0, 0.0, 1.0 - THICK_THICKNESS, 1.0, 1.0, 1.0 ),
new AxisAlignedBB( 0.0, 0.0, 0.0, THICK_THICKNESS, 1.0, 1.0 ),
new AxisAlignedBB( 1.0 - THICK_THICKNESS, 0.0, 0.0, 1.0, 1.0, 1.0 )
};
private final TextureAtlasSprite facadeTexture;
public static final AxisAlignedBB[] THIN_FACADE_BOXES = new AxisAlignedBB[] {
new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, THIN_THICKNESS, 1.0 ),
new AxisAlignedBB( 0.0, 1.0 - THIN_THICKNESS, 0.0, 1.0, 1.0, 1.0 ),
new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, THIN_THICKNESS ),
new AxisAlignedBB( 0.0, 0.0, 1.0 - THIN_THICKNESS, 1.0, 1.0, 1.0 ),
new AxisAlignedBB( 0.0, 0.0, 0.0, THIN_THICKNESS, 1.0, 1.0 ),
new AxisAlignedBB( 1.0 - THIN_THICKNESS, 0.0, 0.0, 1.0, 1.0, 1.0 )
};
private static final Set<ResourceLocation> warnedFor = new HashSet<>();
private ThreadLocal<BakedPipeline> pipelines = ThreadLocal.withInitial( () -> BakedPipeline.builder()
// Clamper is responsible for clamping the vertex to the bounds specified.
.addElement( "clamper", QuadClamper.FACTORY )
// Strips faces if they match a mask.
.addElement( "face_stripper", QuadFaceStripper.FACTORY )
// Kicks the edge inner corners in, solves Z fighting
.addElement( "corner_kicker", QuadCornerKicker.FACTORY )
// Re-Interpolates the UV's for the quad.
.addElement( "interp", QuadReInterpolator.FACTORY )
// Tints the quad if we need it to. Disabled by default.
.addElement( "tinter", QuadTinter.FACTORY, false )
// Overrides the quad's alpha if we are forcing transparent facades.
.addElement( "transparent", QuadAlphaOverride.FACTORY, false, e -> e.setAlphaOverride( 0x4C / 255F ) )
.build()//
);
private ThreadLocal<Quad> collectors = ThreadLocal.withInitial( Quad::new );
FacadeBuilder( VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
{
this.format = format;
this.facadeTexture = bakedTextureGetter.apply( TEXTURE_FACADE );
}
static Collection<ResourceLocation> getTextures()
{
return Collections.singletonList( TEXTURE_FACADE );
}
void addFacades( BlockRenderLayer layer, Map<EnumFacing, FacadeRenderState> facadesState, List<AxisAlignedBB> partBoxes, Set<EnumFacing> sidesWithParts, long rand, List<BakedQuad> quads )
public void buildFacadeQuads( BlockRenderLayer layer, CableBusRenderState renderState, long rand, List<BakedQuad> quads, Function<ResourceLocation, IBakedModel> modelLookup )
{
BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get();
boolean transparent = AEApi.instance().partHelper().getCableRenderMode().transparentFacades;
Map<EnumFacing, FacadeRenderState> facadeStates = renderState.getFacades();
List<AxisAlignedBB> partBoxes = renderState.getBoundingBoxes();
Set<EnumFacing> sidesWithParts = renderState.getAttachments().keySet();
IBlockAccess parentWorld = renderState.getWorld();
BlockPos pos = renderState.getPos();
BlockColors blockColors = Minecraft.getMinecraft().getBlockColors();
boolean thinFacades = isUseThinFacades( partBoxes );
CubeBuilder builder = new CubeBuilder( this.format, quads );
facadesState.forEach( ( side, state ) ->
for( Entry<EnumFacing, FacadeRenderState> entry : facadeStates.entrySet() )
{
AxisAlignedBB facadeBox = getFacadeBox( side, thinFacades );
AEAxisAlignedBB cutOutBox = getCutOutBox( facadeBox, partBoxes );
EnumFacing side = entry.getKey();
int sideIndex = side.ordinal();
FacadeRenderState facadeRenderState = entry.getValue();
boolean renderStilt = !sidesWithParts.contains( side );
if( layer == BlockRenderLayer.CUTOUT && renderStilt )
{
for( ResourceLocation part : PartCableAnchor.FACADE_MODELS.getModels() )
{
IBakedModel partModel = modelLookup.apply( part );
QuadRotator rotator = new QuadRotator();
quads.addAll( rotator.rotateQuads( gatherQuads( partModel, null, rand ), side, EnumFacing.UP ) );
}
}
// If we are forcing transparency and this isn't the Translucent layer.
if( transparent && layer != BlockRenderLayer.TRANSLUCENT )
{
continue;
}
IBlockState blockState = facadeRenderState.getSourceBlock();
// If we aren't forcing transparency let the block decide if it should render.
if( !transparent && layer != null )
{
if( !blockState.getBlock().canRenderInLayer( blockState, layer ) )
{
continue;
}
}
AxisAlignedBB fullBounds = thinFacades ? THIN_FACADE_BOXES[sideIndex] : THICK_FACADE_BOXES[sideIndex];
AxisAlignedBB facadeBox = fullBounds;
// If we are a transparent facade, we need to modify out BB.
if( facadeRenderState.isTransparent() )
{
double offset = thinFacades ? THIN_THICKNESS : THICK_THICKNESS;
AEAxisAlignedBB tmpBB = null;
for( EnumFacing face : EnumFacing.VALUES )
{
// Only faces that aren't on our axis
if( face.getAxis() != side.getAxis() )
{
FacadeRenderState otherState = facadeStates.get( face );
if( otherState != null && !otherState.isTransparent() )
{
if( tmpBB == null )
{
tmpBB = AEAxisAlignedBB.fromBounds( facadeBox );
}
switch( face )
{
case DOWN:
tmpBB.minY += offset;
break;
case UP:
tmpBB.maxY -= offset;
break;
case NORTH:
tmpBB.minZ += offset;
break;
case SOUTH:
tmpBB.maxZ -= offset;
break;
case WEST:
tmpBB.minX += offset;
break;
case EAST:
tmpBB.maxX -= offset;
break;
default:
throw new RuntimeException( "Switch falloff. " + String.valueOf( face ) );
}
}
}
}
if( tmpBB != null )
{
facadeBox = tmpBB.getBoundingBox();
}
}
AEAxisAlignedBB cutOutBox = getCutOutBox( facadeBox, partBoxes );
List<AxisAlignedBB> holeStrips = getBoxes( facadeBox, cutOutBox, side.getAxis() );
IBlockAccess facadeAccess = new FacadeBlockAccess( parentWorld, pos, side, blockState );
BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
try
{
this.addFacade( layer, facadesState, side, cutOutBox, thinFacades, renderStilt, rand, builder );
blockState = blockState.getActualState( facadeAccess, pos );
}
catch( Throwable t )
catch( Exception ignored )
{
AELog.debug( t );
}
} );
}
public static TextureAtlasAndTint getSprite( IBakedModel blockModel, IBlockState state, EnumFacing facing, long rand )
{
TextureAtlasAndTint firstFound = null;
BlockRenderLayer orgLayer = MinecraftForgeClient.getRenderLayer();
try
{
// Some other mods also distinguish between layers, so we're doing this in a loop from most likely to least
// likely
for( BlockRenderLayer layer : BlockRenderLayer.values() )
IBakedModel model = dispatcher.getModelForState( blockState );
try
{
blockState = blockState.getBlock().getExtendedState( blockState, facadeAccess, pos );
}
catch( Exception ignored )
{
}
List<BakedQuad> modelQuads = new ArrayList<>();
// If we are forcing transparent facades, fake the render layer, and grab all quads.
if( transparent || layer == null )
{
for( BlockRenderLayer forcedLayer : BlockRenderLayer.values() )
{
// Check if the block renders on the layer we want to force.
if( blockState.getBlock().canRenderInLayer( blockState, forcedLayer ) )
{
// Force the layer and gather quads.
ForgeHooksClient.setRenderLayer( forcedLayer );
modelQuads.addAll( gatherQuads( model, blockState, rand ) );
}
}
// Reset.
ForgeHooksClient.setRenderLayer( layer );
}
else
{
modelQuads.addAll( gatherQuads( model, blockState, rand ) );
}
for( BakedQuad bakedQuad : blockModel.getQuads( state, facing, rand ) )
{
return new TextureAtlasAndTint( bakedQuad );
}
// No quads.. Cool, next!
if( modelQuads.isEmpty() )
{
continue;
}
for( BakedQuad bakedQuad : blockModel.getQuads( state, null, rand ) )
// Grab out pipeline elements.
QuadClamper clamper = pipeline.getElement( "clamper", QuadClamper.class );
QuadFaceStripper edgeStripper = pipeline.getElement( "face_stripper", QuadFaceStripper.class );
QuadTinter tinter = pipeline.getElement( "tinter", QuadTinter.class );
QuadCornerKicker kicker = pipeline.getElement( "corner_kicker", QuadCornerKicker.class );
// Set global element states.
// calculate the side mask.
int facadeMask = 0;
for( Entry<EnumFacing, FacadeRenderState> ent : facadeStates.entrySet() )
{
EnumFacing s = ent.getKey();
if( s.getAxis() != side.getAxis() )
{
if( firstFound == null )
FacadeRenderState otherState = ent.getValue();
if( !otherState.isTransparent() )
{
firstFound = new TextureAtlasAndTint( bakedQuad );
facadeMask |= 1 << s.ordinal();
}
if( bakedQuad.getFace() == facing )
}
}
// Setup the edge stripper.
edgeStripper.setBounds( fullBounds );
edgeStripper.setMask( facadeMask );
// Setup the kicker.
kicker.setSide( sideIndex );
kicker.setFacadeMask( facadeMask );
kicker.setBox( fullBounds );
kicker.setThickness( thinFacades ? THIN_THICKNESS : THICK_THICKNESS );
for( BakedQuad quad : modelQuads )
{
// lookup the format in CachedFormat.
CachedFormat format = CachedFormat.lookup( quad.getFormat() );
// If this quad has a tint index, setup the tinter.
if( quad.hasTintIndex() )
{
tinter.setTint( blockColors.colorMultiplier( blockState, facadeAccess, pos, quad.getTintIndex() ) );
}
for( AxisAlignedBB box : holeStrips )
{
// setup the clamper for this box
clamper.setClampBounds( box );
// Reset the pipeline, clears all enabled/disabled states.
pipeline.reset( format );
// Reset out collector.
collectorQuad.reset( format );
// Enable / disable the optional elements
pipeline.setElementState( "tinter", quad.hasTintIndex() );
pipeline.setElementState( "transparent", transparent );
// Prepare the pipeline for a quad.
pipeline.prepare( collectorQuad );
// Pipe our quad into the pipeline.
quad.pipe( pipeline );
// Check if the collector got any data.
if( collectorQuad.full )
{
return new TextureAtlasAndTint( bakedQuad );
// Add the result.
quads.add( collectorQuad.bake() );
}
}
}
}
catch( Exception e )
{
if( warnedFor.add( state.getBlock().getRegistryName() ) )
{
AELog.warn( "Unable to get facade sprite for blockstate %s. Supressing further warnings for this block.", state );
AELog.debug( e );
}
}
finally
{
ForgeHooksClient.setRenderLayer( orgLayer );
}
// Fall back to the particle texture, if we havent found anything else so far.
if( firstFound == null )
{
try
{
return new TextureAtlasAndTint( blockModel.getParticleTexture(), -1 );
}
catch( Exception e )
{
if( warnedFor.add( state.getBlock().getRegistryName() ) )
{
AELog.warn( "Unable to get facade sprite particle texture fallback for blockstate %s. Supressing further warnings for this block.", state );
AELog.debug( e );
}
}
}
return firstFound;
}
private void addFacade( BlockRenderLayer layer, Map<EnumFacing, FacadeRenderState> facades, EnumFacing side, AEAxisAlignedBB busBounds, boolean thinFacades, boolean renderStilt, long rand, CubeBuilder builder )
/**
* This is slow, so should be cached.
*
* @return The model.
*/
public List<BakedQuad> buildFacadeItemQuads( ItemStack textureItem, EnumFacing side )
{
List<BakedQuad> facadeQuads = new ArrayList<>();
IBakedModel model = Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides( textureItem, null, null );
List<BakedQuad> modelQuads = gatherQuads( model, null, 0 );
FacadeRenderState facadeState = facades.get( side );
IBlockState blockState = facadeState.getSourceBlock();
BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get();
builder.setDrawFaces( EnumSet.allOf( EnumFacing.class ) );
// Grab pipeline elements.
QuadClamper clamper = pipeline.getElement( "clamper", QuadClamper.class );
QuadTinter tinter = pipeline.getElement( "tinter", QuadTinter.class );
// Reset to no color multiplicator
builder.setColorRGB( 0xFFFFFF );
builder.useStandardUV();
// We only render the stilt if we don't intersect with any part directly, and if there's no part on our side
if( renderStilt && busBounds == null && layer == BlockRenderLayer.CUTOUT )
for( BakedQuad quad : modelQuads )
{
builder.setTexture( this.facadeTexture );
switch( side )
// Lookup the CachedFormat for this quads format.
CachedFormat format = CachedFormat.lookup( quad.getFormat() );
// Reset the pipeline.
pipeline.reset( format );
// Reset the collector.
collectorQuad.reset( format );
// If we have a tint index, setup the tinter and enable it.
if( quad.hasTintIndex() )
{
case DOWN:
builder.addCube( 7, 1, 7, 9, 6, 9 );
break;
case UP:
builder.addCube( 7, 10, 7, 9, 15, 9 );
break;
case NORTH:
builder.addCube( 7, 7, 1, 9, 9, 6 );
break;
case SOUTH:
builder.addCube( 7, 7, 10, 9, 9, 15 );
break;
case WEST:
builder.addCube( 1, 7, 7, 6, 9, 9 );
break;
case EAST:
builder.addCube( 10, 7, 7, 15, 9, 9 );
break;
}
}
// Do not add the translucent facade in any other layer than translucent
boolean translucent = AEApi.instance().partHelper().getCableRenderMode().transparentFacades;
if( translucent && layer != BlockRenderLayer.TRANSLUCENT )
{
return;
}
final float thickness = thinFacades ? 1 : 2;
BlockRendererDispatcher blockRendererDispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
IBakedModel blockModel = blockRendererDispatcher.getModelForState( blockState );
final int color;
if( translucent )
{
color = 0x4CFFFFFF;
}
else
{
color = 0xFFFFFFFF;
}
// TODO: Cache this
for( EnumFacing facing : facadeState.getOpenFaces() )
{
TextureAtlasAndTint spriteAndTint = getSprite( blockModel, blockState, facing, rand );
if( spriteAndTint != null && spriteAndTint.sprite != null )
{
// Use the tint color from the item stack here, which is based upon the assumption that the
// model used for the block will use the same meaning for tint indices as the item model does
if( spriteAndTint.tint != -1 )
{
int tintColor = facadeState.resolveTintColor( spriteAndTint.tint );
// Still apply the transparency color
tintColor &= 0xFFFFFF;
tintColor |= color & 0xFF000000;
builder.setColor( tintColor );
}
else
{
builder.setColor( color );
}
builder.setTexture( facing, spriteAndTint.sprite );
}
else
{
builder.setColor( color );
builder.setTexture( facing, this.facadeTexture );
}
}
builder.setDrawFaces( facadeState.getOpenFaces() );
AxisAlignedBB primaryBox = getFacadeBox( side, thinFacades );
Vector3f min = new Vector3f( (float) primaryBox.minX * 16, (float) primaryBox.minY * 16, (float) primaryBox.minZ * 16 );
Vector3f max = new Vector3f( (float) primaryBox.maxX * 16, (float) primaryBox.maxY * 16, (float) primaryBox.maxZ * 16 );
if( busBounds == null )
{
// Adjust the facade for neighboring facades so that facade cubes dont overlap with each other
if( side == EnumFacing.NORTH || side == EnumFacing.SOUTH )
{
if( facades.containsKey( EnumFacing.UP ) )
{
max.y -= thickness;
}
if( facades.containsKey( EnumFacing.DOWN ) )
{
min.y += thickness;
}
}
else if( side == EnumFacing.EAST || side == EnumFacing.WEST )
{
if( facades.containsKey( EnumFacing.UP ) )
{
max.y -= thickness;
}
if( facades.containsKey( EnumFacing.DOWN ) )
{
min.y += thickness;
}
if( facades.containsKey( EnumFacing.SOUTH ) )
{
max.z -= thickness;
}
if( facades.containsKey( EnumFacing.NORTH ) )
{
min.z += thickness;
}
}
builder.addCube( min.x, min.y, min.z, max.x, max.y, max.z );
}
else
{
Vector3f busMin = new Vector3f( (float) busBounds.minX * 16, (float) busBounds.minY * 16, (float) busBounds.minZ * 16 );
Vector3f busMax = new Vector3f( (float) busBounds.maxX * 16, (float) busBounds.maxY * 16, (float) busBounds.maxZ * 16 );
if( side == EnumFacing.UP || side == EnumFacing.DOWN )
{
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMax.z, 16.0f, 16.0f, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, 16.0f, 16.0f, busMin.z );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMin.z, busMin.x, 16.0f, busMax.z );
this.renderSegmentBlockCurrentBounds( builder, min, max, busMax.x, 0.0f, busMin.z, 16.0f, 16.0f, busMax.z );
}
else if( side == EnumFacing.NORTH || side == EnumFacing.SOUTH )
{
if( facades.get( EnumFacing.UP ) != null )
{
max.y -= thickness;
}
if( facades.get( EnumFacing.DOWN ) != null )
{
min.y += thickness;
}
this.renderSegmentBlockCurrentBounds( builder, min, max, busMax.x, 0.0f, 0.0f, 16.0f, 16.0f, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, busMin.x, 16.0f, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, busMin.x, 0.0f, 0.0f, busMax.x, busMin.y, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, busMin.x, busMax.y, 0.0f, busMax.x, 16.0f, 16.0f );
}
else
{
if( facades.get( EnumFacing.UP ) != null )
{
max.y -= thickness;
}
if( facades.get( EnumFacing.DOWN ) != null )
{
min.y += thickness;
}
if( facades.get( EnumFacing.SOUTH ) != null )
{
max.z -= thickness;
}
if( facades.get( EnumFacing.NORTH ) != null )
{
min.z += thickness;
}
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMax.z, 16.0f, 16.0f, 16.0f );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, 16.0f, 16.0f, busMin.z );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMin.z, 16.0f, busMin.y, busMax.z );
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, busMax.y, busMin.z, 16.0f, 16.0f, busMax.z );
tinter.setTint( Minecraft.getMinecraft().getItemColors().colorMultiplier( textureItem, quad.getTintIndex() ) );
pipeline.enableElement( "tinter" );
}
// Disable elements we don't need for items.
pipeline.disableElement( "face_stripper" );
pipeline.disableElement( "corner_kicker" );
// Setup the clamper
clamper.setClampBounds( THICK_FACADE_BOXES[side.ordinal()] );
// Prepare the pipeline.
pipeline.prepare( collectorQuad );
// Pipe our quad into the pipeline.
quad.pipe( pipeline );
// Check the collector for data and add the quad if there was.
if( collectorQuad.full )
{
facadeQuads.add( collectorQuad.bakeUnpacked() );
}
}
return facadeQuads;
}
private void renderSegmentBlockCurrentBounds( CubeBuilder builder, Vector3f min, Vector3f max, float minX, float minY, float minZ, float maxX, float maxY, float maxZ )
// Helper to gather all quads from a model into a list.
private static List<BakedQuad> gatherQuads( IBakedModel model, IBlockState state, long rand )
{
minX = Math.max( min.x, minX );
minY = Math.max( min.y, minY );
minZ = Math.max( min.z, minZ );
maxX = Math.min( max.x, maxX );
maxY = Math.min( max.y, maxY );
maxZ = Math.min( max.z, maxZ );
// don't draw it if its not at least a pixel wide...
if( maxX - minX >= 1.0 && maxY - minY >= 1.0 && maxZ - minZ >= 1.0 )
List<BakedQuad> modelQuads = new ArrayList<>();
for( EnumFacing face : EnumFacing.VALUES )
{
builder.addCube( minX, minY, minZ, maxX, maxY, maxZ );
modelQuads.addAll( model.getQuads( state, face, rand ) );
}
modelQuads.addAll( model.getQuads( state, null, rand ) );
return modelQuads;
}
/**
* Given the actual facade bounding box, and the bounding boxes of all parts, determine the biggest union of AABB
* that intersect with the
* facade's bounding box. This AABB will need to be "cut out" when the facade is rendered.
* that intersect with the facade's bounding
* box. This AABB will need to be "cut out" when the facade is rendered.
*/
@Nullable
private static AEAxisAlignedBB getCutOutBox( AxisAlignedBB facadeBox, List<AxisAlignedBB> partBoxes )
@@ -411,8 +413,58 @@ public class FacadeBuilder
}
/**
* Determines if any of the part's bounding boxes intersects with the outside 2 voxel wide layer.
* If so, we should use thinner facades (1 voxel deep).
* Generates the box segments around the specified hole. If the specified hole is null, a Singleton of the Facade
* box is returned.
*
* @param fb The Facade's box.
* @param hole The hole to 'cut'.
* @param axis The axis the facade is on.
*
* @return The box segments.
*/
private static List<AxisAlignedBB> getBoxes( AxisAlignedBB fb, AEAxisAlignedBB hole, Axis axis )
{
if( hole == null )
{
return Collections.singletonList( fb );
}
List<AxisAlignedBB> boxes = new ArrayList<>();
switch( axis )
{
case Y:
boxes.add( new AxisAlignedBB( fb.minX, fb.minY, fb.minZ, hole.minX, fb.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( hole.maxX, fb.minY, fb.minZ, fb.maxX, fb.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( hole.minX, fb.minY, fb.minZ, hole.maxX, fb.maxY, hole.minZ ) );
boxes.add( new AxisAlignedBB( hole.minX, fb.minY, hole.maxZ, hole.maxX, fb.maxY, fb.maxZ ) );
break;
case Z:
boxes.add( new AxisAlignedBB( fb.minX, fb.minY, fb.minZ, fb.maxX, hole.minY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.maxY, fb.minZ, fb.maxX, fb.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.minY, fb.minZ, hole.minX, hole.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( hole.maxX, hole.minY, fb.minZ, fb.maxX, hole.maxY, fb.maxZ ) );
break;
case X:
boxes.add( new AxisAlignedBB( fb.minX, fb.minY, fb.minZ, fb.maxX, hole.minY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.maxY, fb.minZ, fb.maxX, fb.maxY, fb.maxZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.minY, fb.minZ, fb.maxX, hole.maxY, hole.minZ ) );
boxes.add( new AxisAlignedBB( fb.minX, hole.minY, hole.maxZ, fb.maxX, hole.maxY, fb.maxZ ) );
break;
default:
// should never happen.
throw new RuntimeException( "switch falloff. " + String.valueOf( axis ) );
}
return boxes;
}
/**
* Determines if any of the part's bounding boxes intersects with the outside 2 voxel wide layer. If so, we should
* use thinner facades (1 voxel deep).
*/
private static boolean isUseThinFacades( List<AxisAlignedBB> partBoxes )
{
@@ -436,57 +488,4 @@ public class FacadeBuilder
}
return false;
}
private static AxisAlignedBB getFacadeBox( EnumFacing side, boolean thinFacades )
{
double thickness = ( thinFacades ? 1 : 2 ) / 16.0;
switch( side )
{
case DOWN:
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, thickness, 1.0 );
case EAST:
return new AxisAlignedBB( 1.0 - thickness, 0.0, 0.0, 1.0, 1.0, 1.0 );
case NORTH:
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, thickness );
case SOUTH:
return new AxisAlignedBB( 0.0, 0.0, 1.0 - thickness, 1.0, 1.0, 1.0 );
case UP:
return new AxisAlignedBB( 0.0, 1.0 - thickness, 0.0, 1.0, 1.0, 1.0 );
case WEST:
return new AxisAlignedBB( 0.0, 0.0, 0.0, thickness, 1.0, 1.0 );
default:
throw new IllegalArgumentException( "Unsupported face: " + side );
}
}
public static class TextureAtlasAndTint
{
private final TextureAtlasSprite sprite;
private final int tint;
private TextureAtlasAndTint( BakedQuad quad )
{
this.sprite = quad.getSprite();
this.tint = quad.getTintIndex();
}
private TextureAtlasAndTint( TextureAtlasSprite sprite, int tint )
{
this.sprite = sprite;
this.tint = tint;
}
public TextureAtlasSprite getSprite()
{
return this.sprite;
}
public int getTint()
{
return this.tint;
}
}
}
@@ -2,12 +2,7 @@
package appeng.client.render.cablebus;
import java.util.EnumSet;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
/**
@@ -19,17 +14,12 @@ public class FacadeRenderState
// The block state to use for rendering this facade
private final IBlockState sourceBlock;
// Which faces of the cube should be rendered for this particular facade
private final EnumSet<EnumFacing> openFaces;
private final boolean transparent;
// For resolving the tint indices of a facade
private final ItemStack textureItem;
public FacadeRenderState( IBlockState sourceBlock, EnumSet<EnumFacing> openFaces, ItemStack textureItem )
public FacadeRenderState( IBlockState sourceBlock, boolean transparent )
{
this.sourceBlock = sourceBlock;
this.openFaces = openFaces;
this.textureItem = textureItem;
this.transparent = transparent;
}
public IBlockState getSourceBlock()
@@ -37,14 +27,8 @@ public class FacadeRenderState
return this.sourceBlock;
}
public EnumSet<EnumFacing> getOpenFaces()
public boolean isTransparent()
{
return this.openFaces;
return this.transparent;
}
public int resolveTintColor( int tintIndex )
{
return Minecraft.getMinecraft().getItemColors().colorMultiplier( this.textureItem, tintIndex );
}
}
@@ -56,7 +56,7 @@ public class P2PTunnelFrequencyBakedModel implements IBakedModel, IPartBakedMode
frequency = (short) ( partFlags.longValue() & 0xffffL );
active = ( partFlags.longValue() & 0x10000L ) != 0;
}
return getQuadsForFrequency( frequency, active );
return this.getQuadsForFrequency( frequency, active );
} );
}
catch( ExecutionException e )
@@ -72,7 +72,7 @@ public class P2PTunnelFrequencyBakedModel implements IBakedModel, IPartBakedMode
{
return Collections.emptyList();
}
return getPartQuads( null, rand );
return this.getPartQuads( null, rand );
}
private List<BakedQuad> getQuadsForFrequency( final short frequency, final boolean active )
@@ -100,7 +100,7 @@ class ItemEncodedPatternBakedModel implements IBakedModel
{
if( this.baseModel instanceof IBakedModel )
{
return ( (IBakedModel) this.baseModel ).handlePerspective( cameraTransformType );
return this.baseModel.handlePerspective( cameraTransformType );
}
return PerspectiveMapWrapper.handlePerspective( this, this.transforms, cameraTransformType );
@@ -150,7 +150,7 @@ class ItemEncodedPatternBakedModel implements IBakedModel
if( selectedModel instanceof IBakedModel )
{
return ( (IBakedModel) selectedModel ).handlePerspective( cameraTransformType );
return selectedModel.handlePerspective( cameraTransformType );
}
return PerspectiveMapWrapper.handlePerspective( this, ItemEncodedPatternBakedModel.this.transforms, cameraTransformType );
@@ -77,7 +77,7 @@ public class AssemblerFX extends Particle implements ICanDie
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -142,7 +142,7 @@ public class CraftingFx extends ParticleBreaking
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -132,7 +132,7 @@ public class EnergyFx extends ParticleBreaking
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -88,7 +88,7 @@ public class LightningFX extends Particle
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -67,7 +67,7 @@ public class MatterCannonFX extends ParticleBreaking
this.setExpired();
}
this.motionY -= 0.04D * (double) this.particleGravity;
this.motionY -= 0.04D * this.particleGravity;
this.move( this.motionX, this.motionY, this.motionZ );
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
@@ -100,15 +100,18 @@ class GlassBakedModel implements IBakedModel
@Override
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
if( !( state instanceof IExtendedBlockState ) || side == null )
{
return Collections.emptyList();
}
IExtendedBlockState extState = (IExtendedBlockState) state;
final IExtendedBlockState extState = (IExtendedBlockState) state;
final GlassState glassState = extState.getValue( BlockQuartzGlass.GLASS_STATE );
GlassState glassState = extState.getValue( BlockQuartzGlass.GLASS_STATE );
if( glassState == null )
{
return Collections.emptyList();
}
final int cx = Math.abs( glassState.getX() % 10 );
final int cy = Math.abs( glassState.getY() % 10 );
@@ -125,12 +128,12 @@ class GlassBakedModel implements IBakedModel
v /= 2;
}
TextureAtlasSprite glassTexture = this.glassTextures[texIdx];
final TextureAtlasSprite glassTexture = this.glassTextures[texIdx];
// Render the glass side
List<BakedQuad> quads = new ArrayList<>( 5 ); // At most 5
final List<BakedQuad> quads = new ArrayList<>( 5 ); // At most 5
List<Vec3d> corners = RenderHelper.getFaceCorners( side );
final List<Vec3d> corners = RenderHelper.getFaceCorners( side );
quads.add( this.createQuad( side, corners, glassTexture, u, v ) );
/*
@@ -143,8 +146,9 @@ class GlassBakedModel implements IBakedModel
* Converted to a number, this bitmask is 5. So the texture at index 5 is used.
* That texture had "0101" in its filename to indicate this.
*/
int edgeBitmask = makeBitmask( glassState, side );
TextureAtlasSprite sideSprite = this.frameTextures[edgeBitmask];
final int edgeBitmask = makeBitmask( glassState, side );
final TextureAtlasSprite sideSprite = this.frameTextures[edgeBitmask];
if( sideSprite != null )
{
quads.add( this.createQuad( side, corners, sideSprite, 0, 0 ) );

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