Compare commits
285 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fc96295a8 | |||
| fd3349614d | |||
| 903f211044 | |||
| 78e1e26a11 | |||
| 2a6de11597 | |||
| cd2b53af85 | |||
| 1c5565491a | |||
| 311cc5c6f6 | |||
| 41796449ed | |||
| 9eef9d3840 | |||
| 13afa6908a | |||
| 103438f805 | |||
| eaa01f7648 | |||
| e81fb09599 | |||
| 94d73aec7c | |||
| b51af43dba | |||
| 85dc8ae7c1 | |||
| c34176f392 | |||
| 76fe2175a0 | |||
| c5d33ed892 | |||
| b423d99879 | |||
| 81156b411d | |||
| 6be1660d41 | |||
| 304f394497 | |||
| 50f21125c8 | |||
| 30b85bd239 | |||
| 9ce00d338f | |||
| 11f5b71089 | |||
| e7da72163b | |||
| 6d7c65dd70 | |||
| 5e21101619 | |||
| 3db8d0185f | |||
| 2f5ecfe638 | |||
| 75843e802d | |||
| e41b6943aa | |||
| 92347ad2f5 | |||
| 517bd77df7 | |||
| 19f928a9a5 | |||
| 73251a0fe5 | |||
| 9335daff7d | |||
| cc5377d53b | |||
| 059f20d801 | |||
| d229570495 | |||
| c284748b6c | |||
| 880a9c8821 | |||
| c68c02ef3b | |||
| 89c4d2736c | |||
| 01778794e5 | |||
| 8f2a06e457 | |||
| 2d71b75019 | |||
| 9f09cd04d4 | |||
| b041fae0d5 | |||
| c466a0e00e | |||
| 618e9390c6 | |||
| 9a71bfb0f0 | |||
| 9680123906 | |||
| 87730894e9 | |||
| 71c944daea | |||
| e96b4a698a | |||
| 1d5465a4b8 | |||
| 09cbfe96d6 | |||
| cbdad7c58e | |||
| 6be96956a9 | |||
| e376e002e9 | |||
| 0b9df31d4e | |||
| cef6dbf0d7 | |||
| e4af7b1947 | |||
| 6eadb8f861 | |||
| b6b6a83563 | |||
| 32ab4c6af4 | |||
| fda8c87410 | |||
| 389e060707 | |||
| 0942a90ef4 | |||
| 8cef06512a | |||
| 8e4658be20 | |||
| 0bd2bd6b5a | |||
| db2c4c4325 | |||
| ac793ee847 | |||
| 6404f26cca | |||
| ced6ad865c | |||
| 24750f00b1 | |||
| df08ce0513 | |||
| f9c274fb48 | |||
| 3582582e3f | |||
| 6de48f8541 | |||
| 5a2c2d06d3 | |||
| 98d3cafdfd | |||
| 904de49543 | |||
| b0772bf94c | |||
| aa5d5e3623 | |||
| 42f4ef2855 | |||
| 3eb2582f29 | |||
| 307f86ded8 | |||
| 56f57e18a5 | |||
| eab695b692 | |||
| 0fb393820b | |||
| 01fe5c7a8b | |||
| 8468b47443 | |||
| 6cb583c918 | |||
| d69395a117 | |||
| 59effe8131 | |||
| 6f42876963 | |||
| 08952b48dd | |||
| e3c9c4ce65 | |||
| 7b91da58c0 | |||
| 26c06bca15 | |||
| 4458bd28ab | |||
| df3f00d978 | |||
| 18ae994ee4 | |||
| 47888b5546 | |||
| e18593feb5 | |||
| af4c3de55e | |||
| bea29331a3 | |||
| 9b9579b358 | |||
| 52da4f9528 | |||
| 50aac2c768 | |||
| 33946438bd | |||
| 9372cb2f14 | |||
| 00037ace77 | |||
| e13af643ba | |||
| ffcfd809d8 | |||
| 7c10a6b883 | |||
| c2bddc30c4 | |||
| 024655f84d | |||
| 589e48ac01 | |||
| 43d3a2c1c0 | |||
| c432fa7200 | |||
| cc744ab8b9 | |||
| 8fe4229a8e | |||
| 3f86884965 | |||
| 1319ec79c9 | |||
| 31a3afc18b | |||
| 9d6026635d | |||
| 39038ac935 | |||
| 4f627b234c | |||
| 6180c188e6 | |||
| 7ada6d18ee | |||
| f493767243 | |||
| ba4cdbcb85 | |||
| f3877aa1ec | |||
| 366b31b3aa | |||
| 533fb5c34b | |||
| 62d1d904c6 | |||
| 03fb43db16 | |||
| 9576bec855 | |||
| b5da6730a1 | |||
| 039bab4811 | |||
| 4b5bdf9893 | |||
| 3c3c23712d | |||
| af91c04ea1 | |||
| 0240a5d76a | |||
| 0c0aafba2f | |||
| b541025738 | |||
| 62f842d4ef | |||
| fc154d8568 | |||
| 4641e48529 | |||
| 0fae87afc7 | |||
| ee1b6bb0d7 | |||
| 36ca8b9f0a | |||
| 9c94c7342b | |||
| 399d67b42c | |||
| 10761a1e9d | |||
| d1ddf53d99 | |||
| f776b4d548 | |||
| 41180792e1 | |||
| 2269c05d98 | |||
| 63616e5730 | |||
| 6ca3e6e696 | |||
| a4b5cfc3b9 | |||
| 38b0a7a153 | |||
| aa4863a979 | |||
| 44c7a46315 | |||
| c3b1dea7c5 | |||
| 40ec517480 | |||
| 2fdc16d3a8 | |||
| 053485a95a | |||
| e910af7734 | |||
| 59d7bd6c16 | |||
| 1a11462ddd | |||
| 77d615559f | |||
| 6878bfa4b0 | |||
| f1d50eca1a | |||
| 4ee32dd0b0 | |||
| 66e589324a | |||
| 362b001cb4 | |||
| b6fd4b3c0f | |||
| e364603a5a | |||
| c58bebc346 | |||
| 97f11f0c61 | |||
| 5c2fa72f95 | |||
| ebd8501301 | |||
| fa07247bd7 | |||
| 95d25ddf47 | |||
| 7a45e1faf4 | |||
| 1f88494832 | |||
| c629b4e0cf | |||
| 65ca607134 | |||
| 898c07ca01 | |||
| 883c267aa8 | |||
| 22cf913708 | |||
| b4ba1af1ec | |||
| 892c919ee2 | |||
| a65b3d2ceb | |||
| c826a3e24f | |||
| fc98505f22 | |||
| ea54ccbcf5 | |||
| 7796c6d4b6 | |||
| e2e6f6e83f | |||
| a7a1a87cd8 | |||
| e50eb7965f | |||
| d25a8a53a2 | |||
| 92b48f01a2 | |||
| 42f0d37c44 | |||
| 088a1827be | |||
| 6a21968dab | |||
| 7c5ff5322a | |||
| 7834028459 | |||
| c43cbbef43 | |||
| ead6274ca4 | |||
| f1c41bab3f | |||
| 12e74dc0de | |||
| c10088d907 | |||
| a12d29c4a0 | |||
| 2227510acf | |||
| 97ae7e1f14 | |||
| fc119070b2 | |||
| 82e3a95f11 | |||
| e6998913e1 | |||
| a3e69ce608 | |||
| ceef176a2a | |||
| c2e2696707 | |||
| 4d6c61dfcb | |||
| 932141cc9e | |||
| adf59774d4 | |||
| 9c6668b0f7 | |||
| 1b7f11a12e | |||
| 3cf4f9122c | |||
| d97996070a | |||
| 8a165bea09 | |||
| f707f95373 | |||
| b2a660ec9b | |||
| d6499c16b0 | |||
| de3e0178a4 | |||
| 203522316c | |||
| 719ea5090b | |||
| 00e19d67a2 | |||
| 169f6393d1 | |||
| 12bf337238 | |||
| 3b544c2486 | |||
| 660e17d167 | |||
| b10246a67b | |||
| 74362bb543 | |||
| 81df58afa5 | |||
| 535289e694 | |||
| d730503378 | |||
| f3349b0a2d | |||
| f667e9a5f0 | |||
| 2c0a2975de | |||
| 2e3d6b721a | |||
| 94e294f4e9 | |||
| 91620a0042 | |||
| ffc79b5494 | |||
| ce7c29d0ac | |||
| 5ac8db41e7 | |||
| 6ece190ac4 | |||
| 00a596ea8f | |||
| 1fc1d5517d | |||
| d5fc7a5b21 | |||
| 1f85d0f607 | |||
| dfe5b82bda | |||
| c7f8f4249e | |||
| 5efa6d6251 | |||
| 4269a66a4b | |||
| df2a7c1858 | |||
| c483bd17f5 | |||
| 92536fceb4 | |||
| ded71cb2bd | |||
| 41a4518c5b | |||
| 87643094c3 | |||
| 8a4c9b58e6 | |||
| 5436e6bf08 | |||
| 078112d97b | |||
| 46355a4e9b | |||
| eb389971a3 | |||
| a38ebf7c4d |
@@ -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'
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
Changes so far :
|
||||
|
||||
Design changes/breakages:
|
||||
- Interfaces no longer spill items of one pattern on other faces
|
||||
- Interfaces now push patterns in round-robin (Interfaces, then sides)
|
||||
|
||||
|
||||
|
||||
|
||||
Fixes:
|
||||
|
||||
- Fix gregtech machines appearing with 'unnamed' or 'draconium lens' on the interface terminal on specific situations.
|
||||
- Add memorycard support for fluid interfaces, import/export/storage busses and level emitters ( this fix was upstreamed to AE2 for MC 1.16)
|
||||
- Storage busses now hide/show inaccessible items as configured.
|
||||
- Exclusive Blocking mode for GTCE ( shapes, molds and configured circuits do not block GTCE machines )
|
||||
- Blocking modes default to block on any item in the iventory the entity exposes
|
||||
- Fuzzy includes items that report that they're damageable, but report a maxDamage of 0 ( auto-crafting of basic capacitors -> resonant capacitors is now possible ) <- Broken item implementation.
|
||||
- Fix CME exceptions on the energy grid
|
||||
- Fix AE going offline even with enough power by extracting from the local buffer always last
|
||||
- Fix IO-Port copying craftable flag into items
|
||||
- Fix NBT of old items not clearing on drives that reached 64 types once
|
||||
|
||||
Performance:
|
||||
|
||||
- Added @talchas fixes for insane channelless AE networks.
|
||||
- Implemented StorageDrawers slotless itemrepository.
|
||||
- Removed CraftedEvent calls (really bad lag with craftweaker versions before CraftTweaker2-1.12-4.1.20.626)
|
||||
- Count items set in interfaces before queuing crafting for them needlessly
|
||||
- Backported b7ca98d ( Avoid copying items on simulated item extraction )
|
||||
- Cache some level emitters functions
|
||||
- Reduced import bus insert simulation to 1 before real insertion (if possible)
|
||||
- Backported itemlist re-implementation along with pattern changes to avoid CraftingManager fallback issues
|
||||
- Instead of recalculating all the content of the network on every change, track the changes properly and apply them to the cached list of items
|
||||
|
||||
QOL:
|
||||
|
||||
- added highlight interface button to interface terminal ("?" button on the left of the interface slots)
|
||||
- Added bar on the interface terminal that search by inputs ( The one on the LEFT, also searchs by interface name )
|
||||
- Shortcut to molecular assemblers with free slots on the terminal interface by @Theisyat
|
||||
- Toggle button on interface terminal to hide full interfaces
|
||||
- JEI "U", "R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
|
||||
- Patterns can now be made with items currently showing on JEI. ( This is overriden by Just Enough Energistics. )
|
||||
- Added multiplier buttons to processing pattern gui
|
||||
- Switched crafting terminal JEI search to fuzzy mode. If the recipe uses a damageable item, AE will try to grab it ( damaged tools )
|
||||
- Encoded patterns stack up to 64 ( holding shift and clicking the encode arrow will transfer the encoded pattern to the player inventory)
|
||||
- Encoded patterns can be draggred on the interface terminal.
|
||||
- Storage Monitor and Conversion Monitor now also ccepts fluids
|
||||
- Draggable JEI ghost items (also works on bookmarked items. SHIFT + Click will move the hovered item into the first free target slot)
|
||||
- JEI auto switches between crafting and processing patterns
|
||||
- GTCE Blocking mode work through phantom itemfaces
|
||||
- Shift-clicking blank patterns into the pattern terminal will try to fill the blank pattern slots first
|
||||
- Mismached simulated/real item count ( most often due to compacting drawers ) will now tell the player wich item cause the failure when trying to start a craft
|
||||
- Added 'pattern expansion' cards that adds an extra row of patterns to interfaces. up to 3 card on an interface. (each card will increase the interface idle power draw by 4 times)
|
||||
|
||||
HOTKEYS:
|
||||
|
||||
- Implemented mousetweaks API. AE2 custom keybinds now work. (Try right clicking and use the scroll-wheel on the terminals)
|
||||
- Holding SHIFT and scrolling UP and DOWN will increase the items set on the configured slots of Interfaces and Pattern Terminal (Processing mode)
|
||||
@@ -1,34 +1,15 @@
|
||||
[](https://travis-ci.org/AppliedEnergistics/Applied-Energistics-2)
|
||||
[](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
|
||||
- [](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
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
version = aeversion + "-" + aechannel + "-" + aebuild
|
||||
version = trousers + "-" + aeversion + "-" + aechannel + "-" + aebuild + "-" + trousersversion
|
||||
group = aegroup
|
||||
archivesBaseName = aebasename
|
||||
|
||||
|
||||
+6
-5
@@ -1,15 +1,16 @@
|
||||
aeversion=rv6
|
||||
aechannel=alpha
|
||||
aebuild=0
|
||||
aechannel=stable
|
||||
aebuild=7
|
||||
aegroup=appeng
|
||||
aebasename=appliedenergistics2
|
||||
|
||||
trousers=trousers_edition
|
||||
trousersversion=v49t
|
||||
#########################################################
|
||||
# Versions #
|
||||
#########################################################
|
||||
minecraft_version=1.12.2
|
||||
mcp_mappings=snapshot_20171003
|
||||
forge_version=14.23.5.2768
|
||||
forge_version=14.23.5.2847
|
||||
|
||||
#########################################################
|
||||
# Installable #
|
||||
@@ -19,7 +20,7 @@ hwyla_version=1.8.26-B41_1.12.2
|
||||
#########################################################
|
||||
# Provided APIs #
|
||||
#########################################################
|
||||
jei_version=4.13.0.219
|
||||
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
|
||||
|
||||
@@ -31,7 +31,12 @@ repositories {
|
||||
|
||||
maven {
|
||||
name = "Tesla repo"
|
||||
url "http://maven.mcmoddev.com"
|
||||
url "https://maven.mcmoddev.com"
|
||||
}
|
||||
|
||||
maven {
|
||||
name "Ellpeck"
|
||||
url "https://maven.ellpeck.de"
|
||||
}
|
||||
|
||||
maven {
|
||||
@@ -54,20 +59,15 @@ 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"
|
||||
@@ -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"
|
||||
@@ -95,6 +97,7 @@ dependencies {
|
||||
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
|
||||
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
|
||||
compileOnly "team.chisel.ctm:CTM:${ctm_version}"
|
||||
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
|
||||
|
||||
// at runtime, use the full JEI jar
|
||||
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -46,7 +46,8 @@ public enum Upgrades
|
||||
*/
|
||||
FUZZY( 1 ),
|
||||
SPEED( 1 ),
|
||||
INVERTER( 1 );
|
||||
INVERTER( 1 ),
|
||||
PATTERN_EXPANSION(1);
|
||||
|
||||
private final int tier;
|
||||
private final Map<ItemStack, Integer> supportedMax = new HashMap<>();
|
||||
|
||||
@@ -89,6 +89,8 @@ public interface IMaterials
|
||||
|
||||
IItemDefinition cardCapacity();
|
||||
|
||||
IItemDefinition cardPatternExpansion();
|
||||
|
||||
IItemDefinition cardFuzzy();
|
||||
|
||||
IItemDefinition cardInverter();
|
||||
|
||||
@@ -58,6 +58,8 @@ public interface IParts
|
||||
|
||||
IItemDefinition storageBus();
|
||||
|
||||
IItemDefinition oreDictStorageBus();
|
||||
|
||||
IItemDefinition importBus();
|
||||
|
||||
IItemDefinition exportBus();
|
||||
@@ -102,6 +104,8 @@ public interface IParts
|
||||
|
||||
IItemDefinition patternTerminal();
|
||||
|
||||
IItemDefinition expandedProcessingPatternTerminal();
|
||||
|
||||
IItemDefinition craftingTerminal();
|
||||
|
||||
IItemDefinition terminal();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,4 +112,17 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
|
||||
* @return definition stack
|
||||
*/
|
||||
ItemStack getDefinition();
|
||||
|
||||
/**
|
||||
* Compare this AE item stack to another item stack, but ignores
|
||||
* the amount. It checks the item type, NBT and damage values.
|
||||
*
|
||||
* @param is An item stack
|
||||
*/
|
||||
boolean equals(ItemStack is);
|
||||
|
||||
ItemStack getCachedItemStack();
|
||||
|
||||
void setCachedItemStack(ItemStack is);
|
||||
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
package com.jaquadro.minecraft.storagedrawers.api.capabilities;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* An interface for treating an inventory as a slotless, central repository of items.
|
||||
*
|
||||
* For all operations that accept a predicate, if a predicate is supplied, a stored ItemStack must pass the predicate
|
||||
* in order to be considered for the given operation.
|
||||
*
|
||||
* An IItemRepository implementation MAY relax or eliminate its own internal tests when a predicate is supplied. If
|
||||
* the predicate is derived from DefaultPredicate, then the implementation MUST apply any tests it would have applied
|
||||
* had no predicate been provided at all, in addition to testing the predicate itself.
|
||||
*/
|
||||
public interface IItemRepository
|
||||
{
|
||||
/**
|
||||
* Gets a list of all items in the inventory. The same item may appear multiple times with varying counts.
|
||||
|
||||
* @return A list of zero or more items in the inventory.
|
||||
*/
|
||||
@Nonnull
|
||||
NonNullList<ItemRecord> getAllItems ();
|
||||
|
||||
/**
|
||||
* Inserts an ItemStack into the inventory and returns the remainder.
|
||||
*
|
||||
* @param stack ItemStack to insert.
|
||||
* @param simulate If true, the insertion is only simulated
|
||||
* @param predicate See interface notes about predicates. Passing null specifies default matching.
|
||||
* @return The remaining ItemStack that was not inserted. If the entire stack was accepted, returns
|
||||
* ItemStack.EMPTY instead.
|
||||
*/
|
||||
@Nonnull
|
||||
ItemStack insertItem (@Nonnull ItemStack stack, boolean simulate, Predicate<ItemStack> predicate);
|
||||
|
||||
@Nonnull
|
||||
default ItemStack insertItem (@Nonnull ItemStack stack, boolean simulate) {
|
||||
return insertItem(stack, simulate, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to extract the given ItemStack from the inventory. The returned value will be a matching ItemStack
|
||||
* with a stack size equal to or less than amount, or the empty ItemStack if the item could not be found at all.
|
||||
* The returned stack size may exceed the ItemStack's getMaxStackSize() value.
|
||||
|
||||
* @param stack The item to extract. The stack size is ignored.
|
||||
* @param amount Amount to extract (may be greater than the stacks max limit)
|
||||
* @param simulate If true, the extraction is only simulated
|
||||
* @param predicate See interface notes about predicates. Passing null specifies default matching.
|
||||
* @return ItemStack extracted from the inventory, or ItemStack.EMPTY if nothing could be extracted.
|
||||
*/
|
||||
@Nonnull
|
||||
ItemStack extractItem (@Nonnull ItemStack stack, int amount, boolean simulate, Predicate<ItemStack> predicate);
|
||||
|
||||
@Nonnull
|
||||
default ItemStack extractItem (@Nonnull ItemStack stack, int amount, boolean simulate) {
|
||||
return extractItem(stack, amount, simulate, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of items matching the given ItemStack stored by the inventory.
|
||||
|
||||
* @param stack ItemStack to query.
|
||||
* @param predicate See interface notes about predicates. Passing null specifies default matching.
|
||||
* @return The number of stored matching items. A value of Integer.MAX_VALUE may indicate an infinite item source.
|
||||
*/
|
||||
default int getStoredItemCount (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
|
||||
ItemStack amount = extractItem(stack, Integer.MAX_VALUE, true, predicate);
|
||||
return amount.getCount();
|
||||
}
|
||||
|
||||
default int getStoredItemCount (@Nonnull ItemStack stack) {
|
||||
return getStoredItemCount(stack, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number items matching the given ItemStack that additionally still be stored by the inventory.
|
||||
* Remaining capacity may include space that is internally empty or unassigned to any given item.
|
||||
*
|
||||
* @param stack ItemStack to query.
|
||||
* @param predicate See interface notes about predicates. Passing null specifies default matching.
|
||||
* @return The available remaining space for matching items.
|
||||
*/
|
||||
default int getRemainingItemCapacity (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
|
||||
stack = stack.copy();
|
||||
stack.setCount(Integer.MAX_VALUE);
|
||||
ItemStack remainder = insertItem(stack, true, predicate);
|
||||
return Integer.MAX_VALUE - remainder.getCount();
|
||||
}
|
||||
|
||||
default int getRemainingItemCapacity (@Nonnull ItemStack stack) {
|
||||
return getRemainingItemCapacity(stack, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total inventory capacity for items matching the given ItemStack.
|
||||
* Total capacity may include space that is internally empty or unassigned to any given item.
|
||||
*
|
||||
* @param stack ItemStack to query.
|
||||
* @param predicate See interface notes about predicates. Passing null specifies default matching.
|
||||
* @return The total capacity for matching items.
|
||||
*/
|
||||
default int getItemCapacity (@Nonnull ItemStack stack, Predicate<ItemStack> predicate) {
|
||||
long capacity = getStoredItemCount(stack, predicate) + getRemainingItemCapacity(stack, predicate);
|
||||
if (capacity > Integer.MAX_VALUE)
|
||||
return Integer.MAX_VALUE;
|
||||
return (int)capacity;
|
||||
}
|
||||
|
||||
default int getItemCapacity (@Nonnull ItemStack stack) {
|
||||
return getItemCapacity(stack, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* An item record representing an item and the amount stored.
|
||||
*
|
||||
* The ItemStack held by itemPrototype always reports a stack size of 1.
|
||||
* IT IS IMPORTANT THAT YOU NEVER MODIFY itemPrototype.
|
||||
*/
|
||||
class ItemRecord
|
||||
{
|
||||
@Nonnull
|
||||
public final ItemStack itemPrototype;
|
||||
public final int count;
|
||||
|
||||
public ItemRecord (@Nonnull ItemStack itemPrototype, int count) {
|
||||
this.itemPrototype = itemPrototype;
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A variant of the standard Predicate interface that when passed to IItemRepository functions, will ask the
|
||||
* internal default predicate to be tested in addition to the custom predicate. An IItemRepository function
|
||||
* may choose to enforce its own predicate regardless.
|
||||
*/
|
||||
interface DefaultPredicate<T> extends Predicate<T> { }
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -25,7 +25,11 @@ import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import appeng.client.gui.AEBaseGui;
|
||||
import appeng.container.interfaces.IJEIGhostIngredients;
|
||||
import appeng.helpers.HighlighterHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -35,9 +39,7 @@ import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.MouseEvent;
|
||||
import net.minecraftforge.client.event.RenderLivingEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.client.event.*;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.ForgeModContainer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -73,6 +75,7 @@ import appeng.hooks.TickHandler;
|
||||
import appeng.hooks.TickHandler.PlayerColor;
|
||||
import appeng.server.ServerHelper;
|
||||
import appeng.util.Platform;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
|
||||
public class ClientHelper extends ServerHelper
|
||||
@@ -106,6 +109,11 @@ public class ClientHelper extends ServerHelper
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void renderWorldLastEvent( RenderWorldLastEvent event) {
|
||||
HighlighterHandler.tick(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld()
|
||||
{
|
||||
@@ -308,6 +316,28 @@ public class ClientHelper extends ServerHelper
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect( fx );
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void MouseClickEvent( final GuiScreenEvent.MouseInputEvent.Pre me )
|
||||
{
|
||||
final Minecraft mc = Minecraft.getMinecraft();
|
||||
if( mc.currentScreen instanceof IJEIGhostIngredients )
|
||||
{
|
||||
AEBaseGui gui = ( (AEBaseGui) mc.currentScreen );
|
||||
Object ingredient = gui.getBookmarkedIngredient();
|
||||
if( ingredient != null )
|
||||
{
|
||||
if( GuiScreen.isShiftKeyDown() )
|
||||
{
|
||||
me.setCanceled( true );
|
||||
}
|
||||
else if( Mouse.isButtonDown( 0 ) )
|
||||
{
|
||||
me.setCanceled( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void wheelEvent( final MouseEvent me )
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package appeng.client.gui;
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
@@ -31,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 )
|
||||
@@ -183,6 +207,65 @@ public abstract class AEBaseGui extends GuiContainer
|
||||
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 || gui instanceof GuiExpandedProcessingPatternTerm )
|
||||
{
|
||||
IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui );
|
||||
for( Target<I> target : targets )
|
||||
{
|
||||
if( ghostGui.getFakeSlotTargetMap().get( target ) instanceof SlotFake )
|
||||
{
|
||||
if( ( (SlotFake) ghostGui.getFakeSlotTargetMap().get( target ) ).getStack().isEmpty() )
|
||||
{
|
||||
target.accept( ingredient );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( ghostGui.getFakeSlotTargetMap().get( target ) instanceof GuiFluidSlot )
|
||||
{
|
||||
if( ( (GuiFluidSlot) ghostGui.getFakeSlotTargetMap().get( target ) ).getFluidStack() == null )
|
||||
{
|
||||
target.accept( ingredient );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(){
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldHighlightTargets()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ package appeng.client.gui.implementations;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -123,6 +124,12 @@ public class GuiCraftAmount extends AEBaseGui
|
||||
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( target instanceof PartExpandedProcessingPatternTerminal )
|
||||
{
|
||||
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( this.originalGui != null && !myIcon.isEmpty() )
|
||||
{
|
||||
this.buttonList.add( this.originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender ) );
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import org.lwjgl.input.Mouse;
|
||||
@@ -104,6 +105,11 @@ public class GuiCraftConfirm extends AEBaseGui
|
||||
{
|
||||
this.OriginalGui = GuiBridge.GUI_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( te instanceof PartExpandedProcessingPatternTerminal )
|
||||
{
|
||||
this.OriginalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAutoStart()
|
||||
@@ -582,4 +588,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ package appeng.client.gui.implementations;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
@@ -95,6 +96,12 @@ public class GuiCraftingStatus extends GuiCraftingCPU
|
||||
|
||||
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( target instanceof PartExpandedProcessingPatternTerminal )
|
||||
{
|
||||
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
|
||||
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import appeng.api.config.ActionItems;
|
||||
import appeng.api.config.ItemSubstitution;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.storage.ITerminalHost;
|
||||
import appeng.client.gui.widgets.GuiImgButton;
|
||||
import appeng.client.gui.widgets.GuiTabButton;
|
||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
||||
import appeng.container.interfaces.IJEIGhostIngredients;
|
||||
import appeng.container.slot.AppEngSlot;
|
||||
import appeng.container.slot.SlotFake;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketInventoryAction;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import mezz.jei.api.gui.IGhostIngredientHandler;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class GuiExpandedProcessingPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
|
||||
{
|
||||
private static final String BACKGROUND_EXPANDED_PROCESSING_MODE = "guis/pattern_processing_expanded.png";
|
||||
|
||||
private static final String SUBSITUTION_DISABLE = "0";
|
||||
private static final String SUBSITUTION_ENABLE = "1";
|
||||
|
||||
private static final String CRAFTMODE_CRFTING = "1";
|
||||
private static final String CRAFTMODE_PROCESSING = "0";
|
||||
|
||||
private GuiTabButton tabCraftButton;
|
||||
private GuiTabButton tabProcessButton;
|
||||
private GuiImgButton substitutionsEnabledBtn;
|
||||
private GuiImgButton substitutionsDisabledBtn;
|
||||
private GuiImgButton encodeBtn;
|
||||
private GuiImgButton clearBtn;
|
||||
private GuiImgButton x2Btn;
|
||||
private GuiImgButton x3Btn;
|
||||
private GuiImgButton plusOneBtn;
|
||||
private GuiImgButton divTwoBtn;
|
||||
private GuiImgButton divThreeBtn;
|
||||
private GuiImgButton minusOneBtn;
|
||||
private GuiImgButton maxCountBtn;
|
||||
public Map<IGhostIngredientHandler.Target<?>, Object> mapTargetSlot = new HashMap<>();
|
||||
|
||||
public GuiExpandedProcessingPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
|
||||
{
|
||||
super( inventoryPlayer, te, new ContainerExpandedProcessingPatternTerm( inventoryPlayer, te ) );
|
||||
this.setReservedSpace( 81 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed( final GuiButton btn )
|
||||
{
|
||||
super.actionPerformed( btn );
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if( this.tabCraftButton == btn || this.tabProcessButton == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
|
||||
}
|
||||
|
||||
if( this.encodeBtn == btn )
|
||||
{
|
||||
if( isShiftKeyDown() )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "2" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "1" ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( this.clearBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Clear", "1" ) );
|
||||
}
|
||||
|
||||
if( this.x2Btn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByTwo", "1" ) );
|
||||
}
|
||||
|
||||
if( this.x3Btn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByThree", "1" ) );
|
||||
}
|
||||
|
||||
if( this.divTwoBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByTwo", "1" ) );
|
||||
}
|
||||
|
||||
if( this.divThreeBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByThree", "1" ) );
|
||||
}
|
||||
|
||||
if( this.plusOneBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.IncreaseByOne", "1" ) );
|
||||
}
|
||||
|
||||
if( this.minusOneBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DecreaseByOne", "1" ) );
|
||||
}
|
||||
|
||||
if( this.maxCountBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MaximizeCount", "1" ) );
|
||||
}
|
||||
|
||||
if( this.substitutionsEnabledBtn == btn || this.substitutionsDisabledBtn == btn )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
|
||||
}
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.error( e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
|
||||
this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.CRAFTING_TABLE ), GuiText.CraftingPattern.getLocal(), this.itemRender );
|
||||
this.buttonList.add( this.tabCraftButton );
|
||||
|
||||
this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.FURNACE ), GuiText.ProcessingPattern.getLocal(), this.itemRender );
|
||||
this.buttonList.add( this.tabProcessButton );
|
||||
|
||||
this.substitutionsEnabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.ENABLED );
|
||||
this.substitutionsEnabledBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.substitutionsEnabledBtn );
|
||||
|
||||
this.substitutionsDisabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.DISABLED );
|
||||
this.substitutionsDisabledBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.substitutionsDisabledBtn );
|
||||
|
||||
this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE );
|
||||
this.clearBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.clearBtn );
|
||||
|
||||
this.x3Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.MULTIPLY_BY_THREE );
|
||||
this.x3Btn.setHalfSize( true );
|
||||
this.buttonList.add( this.x3Btn );
|
||||
|
||||
this.x2Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.MULTIPLY_BY_TWO );
|
||||
this.x2Btn.setHalfSize( true );
|
||||
this.buttonList.add( this.x2Btn );
|
||||
|
||||
this.plusOneBtn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.INCREASE_BY_ONE );
|
||||
this.plusOneBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.plusOneBtn );
|
||||
|
||||
this.divThreeBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.DIVIDE_BY_THREE );
|
||||
this.divThreeBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.divThreeBtn );
|
||||
|
||||
this.divTwoBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.DIVIDE_BY_TWO );
|
||||
this.divTwoBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.divTwoBtn );
|
||||
|
||||
this.minusOneBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.DECREASE_BY_ONE );
|
||||
this.minusOneBtn.setHalfSize( true );
|
||||
this.buttonList.add( this.minusOneBtn );
|
||||
|
||||
//this.maxCountBtn = new GuiImgButton( this.guiLeft + 128, this.guiTop + this.ySize - 108, Settings.ACTIONS, ActionItems.MAX_COUNT );
|
||||
//this.maxCountBtn.setHalfSize( true );
|
||||
//this.buttonList.add( this.maxCountBtn );
|
||||
|
||||
this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE );
|
||||
this.buttonList.add( this.encodeBtn );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
|
||||
{
|
||||
this.tabCraftButton.visible = false;
|
||||
this.tabProcessButton.visible = true;
|
||||
this.substitutionsEnabledBtn.visible = false;
|
||||
this.substitutionsDisabledBtn.visible = false;
|
||||
this.x2Btn.visible = true;
|
||||
this.x3Btn.visible = true;
|
||||
this.divTwoBtn.visible = true;
|
||||
this.divThreeBtn.visible = true;
|
||||
this.plusOneBtn.visible = true;
|
||||
this.minusOneBtn.visible = true;
|
||||
//this.maxCountBtn.visible = true;
|
||||
|
||||
super.drawFG( offsetX, offsetY, mouseX, mouseY );
|
||||
this.fontRenderer.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.getReservedSpace(), 4210752 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBackground()
|
||||
{
|
||||
return BACKGROUND_EXPANDED_PROCESSING_MODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repositionSlot( final AppEngSlot s )
|
||||
{
|
||||
final int offsetPlayerSide = s.isPlayerSide() ? 5 : 3;
|
||||
|
||||
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IGhostIngredientHandler.Target<?>> getPhantomTargets( Object ingredient )
|
||||
{
|
||||
if( !( ingredient instanceof ItemStack ) )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<IGhostIngredientHandler.Target<?>> targets = new ArrayList<>();
|
||||
for( Slot slot : this.inventorySlots.inventorySlots )
|
||||
{
|
||||
if( slot instanceof SlotFake )
|
||||
{
|
||||
ItemStack itemStack = (ItemStack) ingredient;
|
||||
IGhostIngredientHandler.Target<Object> target = new IGhostIngredientHandler.Target<Object>()
|
||||
{
|
||||
@Override
|
||||
public Rectangle getArea()
|
||||
{
|
||||
return new Rectangle( getGuiLeft() + slot.xPos, getGuiTop() + slot.yPos, 16, 16 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept( Object ingredient )
|
||||
{
|
||||
final PacketInventoryAction p;
|
||||
try
|
||||
{
|
||||
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (SlotFake) slot, AEItemStack.fromItemStack( itemStack ) );
|
||||
NetworkHandler.instance().sendToServer( p );
|
||||
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
targets.add( target );
|
||||
mapTargetSlot.putIfAbsent( target, slot );
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<IGhostIngredientHandler.Target<?>, Object> getFakeSlotTargetMap()
|
||||
{
|
||||
return mapTargetSlot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class GuiInterface extends GuiUpgradeable
|
||||
public GuiInterface( final InventoryPlayer inventoryPlayer, final IInterfaceHost te )
|
||||
{
|
||||
super( new ContainerInterface( inventoryPlayer, te ) );
|
||||
this.ySize = 211;
|
||||
this.ySize = 256;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,8 +62,7 @@ public class GuiInterface extends GuiUpgradeable
|
||||
this.BlockMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO );
|
||||
this.buttonList.add( this.BlockMode );
|
||||
|
||||
this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal
|
||||
.getLocal(), GuiText.InterfaceTerminalHint.getLocal() );
|
||||
this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal() );
|
||||
this.buttonList.add( this.interfaceMode );
|
||||
}
|
||||
|
||||
@@ -86,13 +85,20 @@ public class GuiInterface extends GuiUpgradeable
|
||||
this.fontRenderer.drawString( GuiText.StoredItems.getLocal(), 8, 6 + 60 + 7, 4210752 );
|
||||
this.fontRenderer.drawString( GuiText.Patterns.getLocal(), 8, 6 + 73 + 7, 4210752 );
|
||||
|
||||
this.fontRenderer.drawString( GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBackground()
|
||||
{
|
||||
return "guis/interface.png";
|
||||
int upgrades = ( (ContainerInterface) this.cvb ).getPatternUpgrades();
|
||||
if( upgrades == 0 )
|
||||
{
|
||||
return "guis/newinterface.png";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "guis/newinterface" + upgrades + ".png";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,4 +123,5 @@ public class GuiInterface extends GuiUpgradeable
|
||||
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.BlockMode.getSetting(), backwards ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import appeng.api.config.ActionItems;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.client.gui.AEBaseGui;
|
||||
import appeng.client.gui.widgets.GuiImgButton;
|
||||
import appeng.client.gui.widgets.GuiTabButton;
|
||||
import appeng.client.gui.widgets.MEGuiTextField;
|
||||
import appeng.container.implementations.ContainerPartOreDictStorageBus;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.GuiBridge;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketSwitchGuis;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
import appeng.parts.misc.PartOreDicStorageBus;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class GuiPartOreDictStorageBus extends AEBaseGui
|
||||
{
|
||||
PartOreDicStorageBus part;
|
||||
private GuiTabButton priority;
|
||||
private GuiImgButton partition;
|
||||
|
||||
private static final Pattern ORE_DICTIONARY_FILTER = Pattern.compile( "\\*?[a-zA-Z0-9_|\\\\+(){,}?!=\\-\\[:\\]&^$]*\\*?" );
|
||||
private MEGuiTextField searchFieldInputs;
|
||||
|
||||
public GuiPartOreDictStorageBus( final InventoryPlayer inventoryPlayer, final PartOreDicStorageBus te )
|
||||
{
|
||||
super( new ContainerPartOreDictStorageBus( inventoryPlayer, te ) );
|
||||
part = te;
|
||||
this.ySize = 84;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
|
||||
this.searchFieldInputs = new MEGuiTextField( this.fontRenderer, this.guiLeft + 3, this.guiTop + 22, 170, 12 );
|
||||
this.searchFieldInputs.setEnableBackgroundDrawing( false );
|
||||
this.searchFieldInputs.setMaxStringLength( 512 );
|
||||
this.searchFieldInputs.setTextColor( 0xFFFFFF );
|
||||
this.searchFieldInputs.setVisible( true );
|
||||
this.searchFieldInputs.setFocused( false );
|
||||
this.searchFieldInputs.setValidator( str -> ORE_DICTIONARY_FILTER.matcher( str ).matches() );
|
||||
|
||||
this.buttonList.add( this.priority = new GuiTabButton( this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender ) );
|
||||
this.buttonList.add( this.partition = new GuiImgButton( this.guiLeft - 18, this.guiTop + 28, Settings.ACTIONS, ActionItems.WRENCH ) );
|
||||
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.getRegex", "1" ) );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void fillRegex( String regex )
|
||||
{
|
||||
this.searchFieldInputs.setText( regex );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed( final GuiButton btn ) throws IOException
|
||||
{
|
||||
super.actionPerformed( btn );
|
||||
if( btn == this.priority )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketSwitchGuis( GuiBridge.GUI_PRIORITY ) );
|
||||
}
|
||||
if( btn == this.partition )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "StorageBus.Action", "Partition" ) );
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.getRegex", "1" ) );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked( final int xCoord, final int yCoord, final int btn ) throws IOException
|
||||
{
|
||||
boolean wasFocused = this.searchFieldInputs.isFocused();
|
||||
this.searchFieldInputs.mouseClicked( xCoord, yCoord, btn );
|
||||
|
||||
if( btn == 1 && this.searchFieldInputs.isMouseIn( xCoord, yCoord ) )
|
||||
{
|
||||
this.searchFieldInputs.setText( "" );
|
||||
}
|
||||
|
||||
if( !searchFieldInputs.isFocused() && wasFocused )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.save", searchFieldInputs.getText() ) );
|
||||
}
|
||||
|
||||
super.mouseClicked( xCoord, yCoord, btn );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped( final char character, final int key ) throws IOException
|
||||
{
|
||||
if( !this.checkHotbarKeys( key ) )
|
||||
{
|
||||
if( !this.searchFieldInputs.textboxKeyTyped( character, key ) )
|
||||
{
|
||||
super.keyTyped( character, key );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG( int offsetX, int offsetY, int mouseX, int mouseY )
|
||||
{
|
||||
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.OreDictStorageBus.getLocal() ), 8, 6, 4210752 );
|
||||
this.fontRenderer.drawString( this.searchFieldInputs.getText().length() + " / " + this.searchFieldInputs.getMaxStringLength(), 8, 36, 4210752 );
|
||||
this.fontRenderer.drawSplitString( "Supports regex. Or use * as a wildcard", 6, 48, 174, 4210752 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBG( int offsetX, int offsetY, int mouseX, int mouseY )
|
||||
{
|
||||
this.bindTexture( "guis/oredictstoragebus.png" );
|
||||
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, 175, 85 );
|
||||
|
||||
if( this.searchFieldInputs != null )
|
||||
{
|
||||
this.searchFieldInputs.drawTextBox();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,11 +19,21 @@
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.container.interfaces.IJEIGhostIngredients;
|
||||
import appeng.container.slot.SlotFake;
|
||||
import appeng.core.sync.packets.PacketInventoryAction;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import mezz.jei.api.gui.IGhostIngredientHandler.Target;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.config.ActionItems;
|
||||
@@ -40,7 +50,7 @@ import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
|
||||
|
||||
public class GuiPatternTerm extends GuiMEMonitorable
|
||||
public class GuiPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
|
||||
{
|
||||
|
||||
private static final String BACKGROUND_CRAFTING_MODE = "guis/pattern.png";
|
||||
@@ -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 )
|
||||
{
|
||||
@@ -85,7 +103,13 @@ public class GuiPatternTerm extends GuiMEMonitorable
|
||||
|
||||
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 )
|
||||
@@ -93,6 +117,41 @@ 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()
|
||||
@@ -131,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 );
|
||||
}
|
||||
@@ -142,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 )
|
||||
{
|
||||
@@ -160,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 );
|
||||
@@ -184,4 +285,52 @@ public class GuiPatternTerm extends GuiMEMonitorable
|
||||
|
||||
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Target<?>> getPhantomTargets(Object ingredient) {
|
||||
if (!(ingredient instanceof ItemStack )) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Target<?>> targets = new ArrayList<>();
|
||||
for( Slot slot : this.inventorySlots.inventorySlots )
|
||||
{
|
||||
if( slot instanceof SlotFake )
|
||||
{
|
||||
ItemStack itemStack = (ItemStack) ingredient;
|
||||
Target<Object> target = new Target<Object>()
|
||||
{
|
||||
@Override
|
||||
public Rectangle getArea()
|
||||
{
|
||||
return new Rectangle( getGuiLeft() + slot.xPos, getGuiTop() + slot.yPos, 16, 16 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept( Object ingredient )
|
||||
{
|
||||
final PacketInventoryAction p;
|
||||
try
|
||||
{
|
||||
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (SlotFake) slot, AEItemStack.fromItemStack( itemStack ) );
|
||||
NetworkHandler.instance().sendToServer( p );
|
||||
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
targets.add( target );
|
||||
mapTargetSlot.putIfAbsent( target, slot );
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Target<?>, Object> getFakeSlotTargetMap()
|
||||
{
|
||||
return mapTargetSlot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,24 @@
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.client.gui.widgets.GuiCustomSlot;
|
||||
import appeng.container.interfaces.IJEIGhostIngredients;
|
||||
import appeng.container.slot.IJEITargetSlot;
|
||||
import appeng.container.slot.SlotFake;
|
||||
import appeng.core.sync.packets.PacketInventoryAction;
|
||||
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import mezz.jei.api.gui.IGhostIngredientHandler.Target;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fluids.*;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
@@ -43,9 +59,9 @@ import appeng.parts.automation.PartExportBus;
|
||||
import appeng.parts.automation.PartImportBus;
|
||||
|
||||
|
||||
public class GuiUpgradeable extends AEBaseGui
|
||||
public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
|
||||
{
|
||||
|
||||
private final Map<Target<?>,Object> mapTargetSlot = new HashMap<>();
|
||||
protected final ContainerUpgradeable cvb;
|
||||
protected final IUpgradeableHost bc;
|
||||
|
||||
@@ -200,4 +216,111 @@ public class GuiUpgradeable extends AEBaseGui
|
||||
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.schedulingMode.getSetting(), backwards ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Target<?>> getPhantomTargets(Object ingredient)
|
||||
{
|
||||
mapTargetSlot.clear();
|
||||
|
||||
FluidStack fluidStack = null;
|
||||
ItemStack itemStack = ItemStack.EMPTY;
|
||||
|
||||
if( ingredient instanceof ItemStack )
|
||||
{
|
||||
itemStack = (ItemStack) ingredient;
|
||||
fluidStack = FluidUtil.getFluidContained( itemStack );
|
||||
}
|
||||
else if( ingredient instanceof FluidStack )
|
||||
{
|
||||
fluidStack = (FluidStack) ingredient;
|
||||
}
|
||||
|
||||
if( !( ingredient instanceof ItemStack ) && !( ingredient instanceof FluidStack ) )
|
||||
return Collections.emptyList();
|
||||
|
||||
List<Target<?>> targets = new ArrayList<>();
|
||||
|
||||
List<IJEITargetSlot> slots = new ArrayList<>();
|
||||
if( this.inventorySlots.inventorySlots.size() > 0 )
|
||||
{
|
||||
for( Slot slot : this.inventorySlots.inventorySlots )
|
||||
{
|
||||
if( slot instanceof SlotFake && ( !itemStack.isEmpty() || this instanceof GuiCellWorkbench && fluidStack != null ) )
|
||||
{
|
||||
slots.add( (IJEITargetSlot) slot );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( this.getGuiSlots().size() > 0 )
|
||||
{
|
||||
for( GuiCustomSlot slot : this.getGuiSlots() )
|
||||
{
|
||||
if( slot instanceof GuiFluidSlot && fluidStack != null )
|
||||
{
|
||||
slots.add( (IJEITargetSlot) slot );
|
||||
}
|
||||
}
|
||||
}
|
||||
for( Object slot : slots )
|
||||
{
|
||||
ItemStack finalItemStack = itemStack;
|
||||
FluidStack finalFluidStack = fluidStack;
|
||||
Target<Object> targetItem = new Target<Object>()
|
||||
{
|
||||
@Override
|
||||
public Rectangle getArea()
|
||||
{
|
||||
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
|
||||
{
|
||||
return new Rectangle( getGuiLeft() + ( (SlotFake) slot ).xPos, getGuiTop() + ( (SlotFake) slot ).yPos, 16, 16 );
|
||||
}
|
||||
else if( slot instanceof GuiFluidSlot && ( (GuiFluidSlot) slot ).isSlotEnabled() )
|
||||
{
|
||||
return new Rectangle( getGuiLeft() + ( (GuiFluidSlot) slot ).xPos(), getGuiTop() + ( (GuiFluidSlot) slot ).yPos(), 16, 16 );
|
||||
}
|
||||
return new Rectangle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept( Object ingredient )
|
||||
{
|
||||
PacketInventoryAction p = null;
|
||||
try
|
||||
{
|
||||
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
|
||||
{
|
||||
if( finalItemStack.isEmpty() && finalFluidStack != null )
|
||||
{
|
||||
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( FluidUtil.getFilledBucket( finalFluidStack ) ) );
|
||||
}
|
||||
else if( !finalItemStack.isEmpty() )
|
||||
{
|
||||
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( finalItemStack ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( finalFluidStack == null ) return;
|
||||
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack( AEFluidStack.fromFluidStack( finalFluidStack ).asItemStackRepresentation() ) );
|
||||
}
|
||||
NetworkHandler.instance().sendToServer( p );
|
||||
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
targets.add( targetItem );
|
||||
mapTargetSlot.putIfAbsent( targetItem, slot );
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Target<?>, Object> getFakeSlotTargetMap()
|
||||
{
|
||||
return mapTargetSlot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import net.minecraft.item.ItemStack;
|
||||
|
||||
public abstract class GuiCustomSlot extends Gui implements ITooltip
|
||||
{
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int id;
|
||||
protected final int x;
|
||||
protected final int y;
|
||||
protected final int id;
|
||||
|
||||
public GuiCustomSlot( final int id, final int x, final int y )
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -172,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 )
|
||||
|
||||
@@ -19,14 +19,9 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
import appeng.block.storage.BlockDrive;
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
@@ -37,9 +32,12 @@ import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
|
||||
import appeng.block.storage.BlockDrive;
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class DriveBakedModel implements IBakedModel
|
||||
@@ -57,13 +55,17 @@ public class DriveBakedModel implements IBakedModel
|
||||
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
|
||||
{
|
||||
|
||||
List<BakedQuad> result = new ArrayList<>();
|
||||
|
||||
result.addAll( this.bakedBase.getQuads( state, side, rand ) );
|
||||
List<BakedQuad> result = new ArrayList<>( this.bakedBase.getQuads( state, side, rand ) );
|
||||
|
||||
if( side == null && state instanceof IExtendedBlockState )
|
||||
{
|
||||
IExtendedBlockState extState = (IExtendedBlockState) state;
|
||||
|
||||
if (!extState.getUnlistedNames().contains( BlockDrive.SLOTS_STATE ))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
DriveSlotsState slotsState = extState.getValue( BlockDrive.SLOTS_STATE );
|
||||
|
||||
for( int row = 0; row < 5; row++ )
|
||||
|
||||
@@ -699,8 +699,23 @@ public abstract class AEBaseContainer extends Container
|
||||
is.setCount( 1 );
|
||||
s.putStack( is );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
final ItemStack is = s.getStack().copy();
|
||||
if (is.getCount() < is.getMaxStackSize())
|
||||
is.grow( 1 );
|
||||
s.putStack( is );
|
||||
}
|
||||
break;
|
||||
case PICKUP_SINGLE:
|
||||
if( hand.isEmpty() )
|
||||
{
|
||||
final ItemStack is = s.getStack().copy();
|
||||
if (is.getCount() > 1)
|
||||
is.shrink( 1 );
|
||||
s.putStack( is );
|
||||
}
|
||||
break;
|
||||
case SPLIT_OR_PLACE_SINGLE:
|
||||
|
||||
ItemStack is = s.getStack();
|
||||
|
||||
@@ -51,6 +51,12 @@ public class ContainerCraftAmount extends AEBaseContainer
|
||||
this.addSlotToContainer( this.getCraftingItem() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slot getSlot( int slotId )
|
||||
{
|
||||
return super.getSlot( 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.concurrent.Future;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -345,11 +346,15 @@ public class ContainerCraftConfirm extends AEBaseContainer
|
||||
originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( ah instanceof PartExpandedProcessingPatternTerminal )
|
||||
{
|
||||
originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
|
||||
}
|
||||
|
||||
if( this.result != null && !this.isSimulation() )
|
||||
{
|
||||
final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class );
|
||||
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true,
|
||||
this.getActionSrc() );
|
||||
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true, this.getActionSrc() );
|
||||
this.setAutoStart( false );
|
||||
if( g != null && originalGui != null && this.getOpenContext() != null )
|
||||
{
|
||||
|
||||
@@ -159,56 +159,58 @@ public class ContainerCraftingCPU extends AEBaseContainer implements IMEMonitorH
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
if( Platform.isServer() && this.getMonitor() != null && !this.list.isEmpty() )
|
||||
if( Platform.isServer() && this.getMonitor() != null )
|
||||
{
|
||||
try
|
||||
if( this.getEstimatedTime() >= 0 )
|
||||
{
|
||||
if( this.getEstimatedTime() >= 0 )
|
||||
final long elapsedTime = this.getMonitor().getElapsedTime();
|
||||
final double remainingItems = this.getMonitor().getRemainingItemCount();
|
||||
final double startItems = this.getMonitor().getStartItemCount();
|
||||
final long eta = (long) ( elapsedTime / Math.max( 1d, ( startItems - remainingItems ) ) * remainingItems );
|
||||
this.setEstimatedTime( eta );
|
||||
}
|
||||
if( !this.list.isEmpty() )
|
||||
{
|
||||
try
|
||||
{
|
||||
final long elapsedTime = this.getMonitor().getElapsedTime();
|
||||
final double remainingItems = this.getMonitor().getRemainingItemCount();
|
||||
final double startItems = this.getMonitor().getStartItemCount();
|
||||
final long eta = (long) ( elapsedTime / Math.max( 1d, ( startItems - remainingItems ) ) * remainingItems );
|
||||
this.setEstimatedTime( eta );
|
||||
}
|
||||
final PacketMEInventoryUpdate a = new PacketMEInventoryUpdate( (byte) 0 );
|
||||
final PacketMEInventoryUpdate b = new PacketMEInventoryUpdate( (byte) 1 );
|
||||
final PacketMEInventoryUpdate c = new PacketMEInventoryUpdate( (byte) 2 );
|
||||
|
||||
final PacketMEInventoryUpdate a = new PacketMEInventoryUpdate( (byte) 0 );
|
||||
final PacketMEInventoryUpdate b = new PacketMEInventoryUpdate( (byte) 1 );
|
||||
final PacketMEInventoryUpdate c = new PacketMEInventoryUpdate( (byte) 2 );
|
||||
|
||||
for( final IAEItemStack out : this.list )
|
||||
{
|
||||
a.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.STORAGE ) );
|
||||
b.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.ACTIVE ) );
|
||||
c.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.PENDING ) );
|
||||
}
|
||||
|
||||
this.list.resetStatus();
|
||||
|
||||
for( final Object g : this.listeners )
|
||||
{
|
||||
if( g instanceof EntityPlayer )
|
||||
for( final IAEItemStack out : this.list )
|
||||
{
|
||||
if( !a.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( a, (EntityPlayerMP) g );
|
||||
}
|
||||
a.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.STORAGE ) );
|
||||
b.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.ACTIVE ) );
|
||||
c.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.PENDING ) );
|
||||
}
|
||||
|
||||
if( !b.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( b, (EntityPlayerMP) g );
|
||||
}
|
||||
this.list.resetStatus();
|
||||
|
||||
if( !c.isEmpty() )
|
||||
for( final Object g : this.listeners )
|
||||
{
|
||||
if( g instanceof EntityPlayer )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( c, (EntityPlayerMP) g );
|
||||
if( !a.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( a, (EntityPlayerMP) g );
|
||||
}
|
||||
|
||||
if( !b.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( b, (EntityPlayerMP) g );
|
||||
}
|
||||
|
||||
if( !c.isEmpty() )
|
||||
{
|
||||
NetworkHandler.instance().sendTo( c, (EntityPlayerMP) g );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
// :P
|
||||
catch( final IOException e )
|
||||
{
|
||||
// :P
|
||||
}
|
||||
}
|
||||
}
|
||||
super.detectAndSendChanges();
|
||||
|
||||
+528
@@ -0,0 +1,528 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.definitions.IDefinitions;
|
||||
import appeng.api.storage.ITerminalHost;
|
||||
import appeng.container.slot.*;
|
||||
import appeng.helpers.IContainerCraftingPacket;
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.IAEAppEngInventory;
|
||||
import appeng.util.inv.InvOperation;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.PlayerInvWrapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static appeng.helpers.PatternHelper.PROCESSING_INPUT_LIMIT;
|
||||
import static appeng.helpers.PatternHelper.PROCESSING_OUTPUT_LIMIT;
|
||||
|
||||
|
||||
public class ContainerExpandedProcessingPatternTerm extends ContainerMEMonitorable implements IAEAppEngInventory, IOptionalSlotHost, IContainerCraftingPacket
|
||||
{
|
||||
private final IItemHandler crafting;
|
||||
private final SlotFakeCraftingMatrix[] gridSlots = new SlotFakeCraftingMatrix[PROCESSING_INPUT_LIMIT];
|
||||
private final OptionalSlotFake[] outputSlots = new OptionalSlotFake[PROCESSING_OUTPUT_LIMIT];
|
||||
private final SlotRestrictedInput patternSlotIN;
|
||||
private final SlotRestrictedInput patternSlotOUT;
|
||||
private final PartExpandedProcessingPatternTerminal expandedProcessingPatternTerminal;
|
||||
|
||||
public ContainerExpandedProcessingPatternTerm( InventoryPlayer ip, ITerminalHost monitorable )
|
||||
{
|
||||
super( ip, monitorable, false );
|
||||
|
||||
this.expandedProcessingPatternTerminal = (PartExpandedProcessingPatternTerminal) monitorable;
|
||||
|
||||
final IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
|
||||
final IItemHandler output = this.getExpandedPatternTerminal().getInventoryByName( "output" );
|
||||
|
||||
this.crafting = this.getExpandedPatternTerminal().getInventoryByName( "crafting" );
|
||||
|
||||
for( int y = 0; y < 4; y++ )
|
||||
{
|
||||
for( int x = 0; x < 4; x++ )
|
||||
{
|
||||
this.addSlotToContainer( this.gridSlots[x + y * 4] = new SlotFakeCraftingMatrix( this.crafting, x + y * 4, 4 + x * 18, -85 + y * 18 ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( int y = 0; y < 3; y++ )
|
||||
{
|
||||
for( int x = 0; x < 2; x++ )
|
||||
{
|
||||
this.addSlotToContainer( this.outputSlots[x + y * 2] = new SlotPatternOutputs( output, this, x + y * 2, 96 + x * 18, -76 + y * 18, 0, 0, 1 ) );
|
||||
this.outputSlots[x + y * 2].setRenderDisabled( false );
|
||||
this.outputSlots[x + y * 2].setIIcon( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
this.addSlotToContainer( this.patternSlotIN = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.BLANK_PATTERN, patternInv, 0, 147, -72 - 9, this.getInventoryPlayer() ) );
|
||||
this.addSlotToContainer( this.patternSlotOUT = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, patternInv, 1, 147, -72 + 34, this.getInventoryPlayer() ) );
|
||||
|
||||
this.patternSlotOUT.setStackLimit( 1 );
|
||||
|
||||
this.bindPlayerInventory( ip, 0, 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
|
||||
{
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
if( this.inventorySlots.get( idx ) instanceof SlotPlayerInv || this.inventorySlots.get( idx ) instanceof SlotPlayerHotBar )
|
||||
{
|
||||
final AppEngSlot clickSlot = (AppEngSlot) this.inventorySlots.get( idx ); // require AE SLots!
|
||||
ItemStack itemStack = clickSlot.getStack();
|
||||
if( AEApi.instance().definitions().materials().blankPattern().isSameAs( itemStack ) )
|
||||
{
|
||||
IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
|
||||
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
|
||||
clickSlot.putStack( remainder );
|
||||
}
|
||||
}
|
||||
return super.transferStackInSlot( p, idx );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChanges()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeInventory( final IItemHandler inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void encodeAndMoveToInventory()
|
||||
{
|
||||
encode();
|
||||
ItemStack output = this.patternSlotOUT.getStack();
|
||||
if( !output.isEmpty() )
|
||||
{
|
||||
if( !getPlayerInv().addItemStackToInventory( output ) )
|
||||
{
|
||||
getPlayerInv().player.dropItem( output, false );
|
||||
}
|
||||
this.patternSlotOUT.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
}
|
||||
|
||||
public void encode()
|
||||
{
|
||||
ItemStack output = this.patternSlotOUT.getStack();
|
||||
|
||||
final ItemStack[] in = this.getInputs();
|
||||
final ItemStack[] out = this.getOutputs();
|
||||
|
||||
// if there is no input, this would be silly.
|
||||
if( in == null || out == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// first check the output slots, should either be null, or a pattern
|
||||
if( !output.isEmpty() && !this.isPattern( output ) )
|
||||
{
|
||||
return;
|
||||
} // if nothing is there we should snag a new pattern.
|
||||
else if( output.isEmpty() )
|
||||
{
|
||||
output = this.patternSlotIN.getStack();
|
||||
if( output.isEmpty() || !this.isPattern( output ) )
|
||||
{
|
||||
return; // no blanks.
|
||||
}
|
||||
|
||||
// remove one, and clear the input slot.
|
||||
output.setCount( output.getCount() - 1 );
|
||||
if( output.getCount() == 0 )
|
||||
{
|
||||
this.patternSlotIN.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
|
||||
// add a new encoded pattern.
|
||||
Optional<ItemStack> maybePattern = AEApi.instance().definitions().items().encodedPattern().maybeStack( 1 );
|
||||
if( maybePattern.isPresent() )
|
||||
{
|
||||
output = maybePattern.get();
|
||||
this.patternSlotOUT.putStack( output );
|
||||
}
|
||||
}
|
||||
|
||||
// encode the slot.
|
||||
final NBTTagCompound encodedValue = new NBTTagCompound();
|
||||
|
||||
final NBTTagList tagIn = new NBTTagList();
|
||||
final NBTTagList tagOut = new NBTTagList();
|
||||
|
||||
for( final ItemStack i : in )
|
||||
{
|
||||
tagIn.appendTag( this.createItemTag( i ) );
|
||||
}
|
||||
|
||||
for( final ItemStack i : out )
|
||||
{
|
||||
tagOut.appendTag( this.createItemTag( i ) );
|
||||
}
|
||||
|
||||
encodedValue.setTag( "in", tagIn );
|
||||
encodedValue.setTag( "out", tagOut );
|
||||
encodedValue.setBoolean( "crafting", false );
|
||||
encodedValue.setBoolean( "substitute", false );
|
||||
|
||||
output.setTagCompound( encodedValue );
|
||||
}
|
||||
|
||||
boolean isPattern( final ItemStack output )
|
||||
{
|
||||
if( output.isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final IDefinitions definitions = AEApi.instance().definitions();
|
||||
|
||||
boolean isPattern = definitions.items().encodedPattern().isSameAs( output );
|
||||
isPattern |= definitions.materials().blankPattern().isSameAs( output );
|
||||
|
||||
return isPattern;
|
||||
}
|
||||
|
||||
NBTBase createItemTag( final ItemStack i )
|
||||
{
|
||||
final NBTTagCompound c = new NBTTagCompound();
|
||||
|
||||
if( !i.isEmpty() )
|
||||
{
|
||||
i.writeToNBT( c );
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlotEnabled( final int idx )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ItemStack[] getInputs()
|
||||
{
|
||||
final ItemStack[] input = new ItemStack[16];
|
||||
boolean hasValue = false;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() )
|
||||
{
|
||||
hasValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( hasValue )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ItemStack[] getOutputs()
|
||||
{
|
||||
final List<ItemStack> list = new ArrayList<>( 3 );
|
||||
boolean hasValue = false;
|
||||
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
|
||||
if( !out.isEmpty() && out.getCount() > 0 )
|
||||
{
|
||||
list.add( out );
|
||||
hasValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( hasValue )
|
||||
{
|
||||
return list.toArray( new ItemStack[0] );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
for( final Slot s : this.gridSlots )
|
||||
{
|
||||
s.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
|
||||
for( final Slot s : this.outputSlots )
|
||||
{
|
||||
s.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
|
||||
this.detectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getInventoryByName( final String name )
|
||||
{
|
||||
if( name.equals( "player" ) )
|
||||
{
|
||||
return new PlayerInvWrapper( this.getInventoryPlayer() );
|
||||
}
|
||||
return this.getExpandedPatternTerminal().getInventoryByName( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useRealItems()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public PartExpandedProcessingPatternTerminal getExpandedPatternTerminal()
|
||||
{
|
||||
return this.expandedProcessingPatternTerminal;
|
||||
}
|
||||
|
||||
public void multiply( int multiple )
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canMultiplyInputs = true;
|
||||
boolean canMultiplyOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() * multiple > input[x].getMaxStackSize() )
|
||||
{
|
||||
canMultiplyInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() * multiple > out.getMaxStackSize() )
|
||||
{
|
||||
canMultiplyOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canMultiplyInputs && canMultiplyOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() * multiple );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() * multiple );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void divide( int divide )
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canDivideInputs = true;
|
||||
boolean canDivideOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() % divide != 0 )
|
||||
{
|
||||
canDivideInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() % divide != 0 )
|
||||
{
|
||||
canDivideOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canDivideInputs && canDivideOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() / divide );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() / divide );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void increase( int increase )
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canIncreaseInputs = true;
|
||||
boolean canIncreaseOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() + increase > input[x].getMaxStackSize() )
|
||||
{
|
||||
canIncreaseInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() + increase > out.getMaxStackSize() )
|
||||
{
|
||||
canIncreaseOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canIncreaseInputs && canIncreaseOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() + increase );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() + increase );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void decrease( int decrease )
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canDecreaseInputs = true;
|
||||
boolean canDecreaseOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() - decrease < 1 )
|
||||
{
|
||||
canDecreaseInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() - decrease < 1 )
|
||||
{
|
||||
canDecreaseOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canDecreaseInputs && canDecreaseOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() - decrease );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() - decrease );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void maximizeCount()
|
||||
{
|
||||
ItemStack[] input = new ItemStack[gridSlots.length];
|
||||
boolean canGrowInputs = true;
|
||||
boolean canGrowOutputs = true;
|
||||
int maxInputStackGrowth = 0;
|
||||
int maxOutputStackGrowth = 0;
|
||||
|
||||
for( int x = 0; x < this.gridSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.gridSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getMaxStackSize() - input[x].getCount() > maxInputStackGrowth )
|
||||
{
|
||||
maxInputStackGrowth = input[x].getMaxStackSize() - input[x].getCount();
|
||||
}
|
||||
if( !input[x].isEmpty() && input[x].getCount() + maxInputStackGrowth > input[x].getMaxStackSize() )
|
||||
{
|
||||
canGrowInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
{
|
||||
maxOutputStackGrowth = out.getMaxStackSize() - out.getCount();
|
||||
}
|
||||
if( !out.isEmpty() && out.getCount() + maxOutputStackGrowth > out.getMaxStackSize() )
|
||||
{
|
||||
canGrowOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canGrowInputs && canGrowOutputs )
|
||||
{
|
||||
int maxStackGrowth = Math.min( maxInputStackGrowth, maxOutputStackGrowth );
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
craftingSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
|
||||
}
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
outputSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,9 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
|
||||
import appeng.api.config.Upgrades;
|
||||
import appeng.container.slot.*;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
@@ -26,14 +29,11 @@ import appeng.api.config.Settings;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.api.util.IConfigManager;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.SlotFake;
|
||||
import appeng.container.slot.SlotNormal;
|
||||
import appeng.container.slot.SlotRestrictedInput;
|
||||
import appeng.helpers.DualityInterface;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
|
||||
|
||||
public class ContainerInterface extends ContainerUpgradeable
|
||||
public class ContainerInterface extends ContainerUpgradeable implements IOptionalSlotHost
|
||||
{
|
||||
|
||||
private final DualityInterface myDuality;
|
||||
@@ -44,16 +44,22 @@ public class ContainerInterface extends ContainerUpgradeable
|
||||
@GuiSync( 4 )
|
||||
public YesNo iTermMode = YesNo.YES;
|
||||
|
||||
@GuiSync( 7 )
|
||||
public int patternExpansions = 0;
|
||||
|
||||
public ContainerInterface( final InventoryPlayer ip, final IInterfaceHost te )
|
||||
{
|
||||
super( ip, te.getInterfaceDuality().getHost() );
|
||||
|
||||
this.myDuality = te.getInterfaceDuality();
|
||||
|
||||
for( int x = 0; x < DualityInterface.NUMBER_OF_PATTERN_SLOTS; x++ )
|
||||
for (int row = 0 ; row < 4 ; ++row)
|
||||
{
|
||||
this.addSlotToContainer( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, this.myDuality
|
||||
.getPatterns(), x, 8 + 18 * x, 90 + 7, this.getInventoryPlayer() ) );
|
||||
for( int x = 0; x < 9; x++ )
|
||||
{
|
||||
this.addSlotToContainer( new OptionalSlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, this.myDuality
|
||||
.getPatterns(), this, x + row * 9, 8 + 18 * x, 97 + ( 18 * row ), row, this.getInventoryPlayer() ).setStackLimit( 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( int x = 0; x < DualityInterface.NUMBER_OF_CONFIG_SLOTS; x++ )
|
||||
@@ -70,7 +76,7 @@ public class ContainerInterface extends ContainerUpgradeable
|
||||
@Override
|
||||
protected int getHeight()
|
||||
{
|
||||
return 211;
|
||||
return 256;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,16 +88,35 @@ public class ContainerInterface extends ContainerUpgradeable
|
||||
@Override
|
||||
public int availableUpgrades()
|
||||
{
|
||||
return 1;
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlotEnabled( final int idx )
|
||||
{
|
||||
return myDuality.getInstalledUpgrades(Upgrades.PATTERN_EXPANSION) >= idx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
this.verifyPermissions( SecurityPermissions.BUILD, false );
|
||||
|
||||
if (patternExpansions != getPatternUpgrades())
|
||||
{
|
||||
patternExpansions = getPatternUpgrades();
|
||||
this.myDuality.dropExcessPatterns();
|
||||
}
|
||||
super.detectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate( final String field, final Object oldValue, final Object newValue ) {
|
||||
super.onUpdate(field, oldValue, newValue);
|
||||
if ( Platform.isClient() && field.equals("patternExpansions"))
|
||||
this.myDuality.dropExcessPatterns();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadSettingsFromHost( final IConfigManager cm )
|
||||
{
|
||||
@@ -118,4 +143,9 @@ public class ContainerInterface extends ContainerUpgradeable
|
||||
{
|
||||
this.iTermMode = iTermMode;
|
||||
}
|
||||
|
||||
public int getPatternUpgrades()
|
||||
{
|
||||
return this.myDuality.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,13 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import appeng.api.config.Upgrades;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.config.Settings;
|
||||
@@ -78,7 +81,7 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
||||
this.grid = anchor.getActionableNode().getGrid();
|
||||
}
|
||||
|
||||
this.bindPlayerInventory( ip, 0, 222 - /* height of player inventory */82 );
|
||||
this.bindPlayerInventory( ip, 14, 256 - /* height of player inventory */82 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -213,35 +216,48 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
||||
final IItemHandler theSlot = new WrapperFilteredItemHandler( new WrapperRangeItemHandler( inv.server, slot, slot + 1 ), new PatternSlotFilter() );
|
||||
final InventoryAdaptor interfaceSlot = new AdaptorItemHandler( theSlot );
|
||||
|
||||
switch( action )
|
||||
IItemHandler interfaceHandler = inv.server;
|
||||
boolean canInsert = true;
|
||||
|
||||
switch ( action )
|
||||
{
|
||||
case PICKUP_OR_SET_DOWN:
|
||||
|
||||
if( hasItemInHand )
|
||||
{
|
||||
ItemStack inSlot = theSlot.getStackInSlot( 0 );
|
||||
if( inSlot.isEmpty() )
|
||||
for( int s = 0; s < interfaceHandler.getSlots(); s++ )
|
||||
{
|
||||
player.inventory.setItemStack( interfaceSlot.addItems( player.inventory.getItemStack() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
inSlot = inSlot.copy();
|
||||
final ItemStack inHand = player.inventory.getItemStack().copy();
|
||||
|
||||
ItemHandlerUtil.setStackInSlot( theSlot, 0, ItemStack.EMPTY );
|
||||
player.inventory.setItemStack( ItemStack.EMPTY );
|
||||
|
||||
player.inventory.setItemStack( interfaceSlot.addItems( inHand.copy() ) );
|
||||
|
||||
if( player.inventory.getItemStack().isEmpty() )
|
||||
if( Platform.itemComparisons().isSameItem( interfaceHandler.getStackInSlot( s ), player.inventory.getItemStack() ) )
|
||||
{
|
||||
player.inventory.setItemStack( inSlot );
|
||||
canInsert = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( canInsert )
|
||||
{
|
||||
ItemStack inSlot = theSlot.getStackInSlot( 0 );
|
||||
if( inSlot.isEmpty() )
|
||||
{
|
||||
player.inventory.setItemStack( interfaceSlot.addItems( player.inventory.getItemStack() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.inventory.setItemStack( inHand );
|
||||
ItemHandlerUtil.setStackInSlot( theSlot, 0, inSlot );
|
||||
inSlot = inSlot.copy();
|
||||
final ItemStack inHand = player.inventory.getItemStack().copy();
|
||||
|
||||
ItemHandlerUtil.setStackInSlot( theSlot, 0, ItemStack.EMPTY );
|
||||
player.inventory.setItemStack( ItemStack.EMPTY );
|
||||
|
||||
player.inventory.setItemStack( interfaceSlot.addItems( inHand.copy() ) );
|
||||
|
||||
if( player.inventory.getItemStack().isEmpty() )
|
||||
{
|
||||
player.inventory.setItemStack( inSlot );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.inventory.setItemStack( inHand );
|
||||
ItemHandlerUtil.setStackInSlot( theSlot, 0, inSlot );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,17 +268,27 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
||||
|
||||
break;
|
||||
case SPLIT_OR_PLACE_SINGLE:
|
||||
|
||||
if( hasItemInHand )
|
||||
{
|
||||
ItemStack extra = playerHand.removeItems( 1, ItemStack.EMPTY, null );
|
||||
if( !extra.isEmpty() )
|
||||
for( int s = 0; s < interfaceHandler.getSlots(); s++ )
|
||||
{
|
||||
extra = interfaceSlot.addItems( extra );
|
||||
if( Platform.itemComparisons().isSameItem( interfaceHandler.getStackInSlot( s ), player.inventory.getItemStack() ) )
|
||||
{
|
||||
canInsert = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !extra.isEmpty() )
|
||||
if( canInsert )
|
||||
{
|
||||
playerHand.addItems( extra );
|
||||
ItemStack extra = playerHand.removeItems( 1, ItemStack.EMPTY, null );
|
||||
if( !extra.isEmpty() && !interfaceSlot.containsItems() )
|
||||
{
|
||||
extra = interfaceSlot.addItems( extra );
|
||||
}
|
||||
if( !extra.isEmpty() )
|
||||
{
|
||||
playerHand.addItems( extra );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( !is.isEmpty() )
|
||||
@@ -378,6 +404,9 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
||||
{
|
||||
tag.setLong( "sortBy", inv.sortBy );
|
||||
tag.setString( "un", inv.unlocalizedName );
|
||||
tag.setTag( "pos", NBTUtil.createPosTag( inv.pos ) );
|
||||
tag.setInteger( "dim", inv.dim );
|
||||
tag.setInteger( "numUpgrades", inv.numUpgrades );
|
||||
}
|
||||
|
||||
for( int x = 0; x < length; x++ )
|
||||
@@ -408,6 +437,9 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
||||
private final String unlocalizedName;
|
||||
private final IItemHandler client;
|
||||
private final IItemHandler server;
|
||||
private final BlockPos pos;
|
||||
private final int dim;
|
||||
private final int numUpgrades;
|
||||
|
||||
public InvTracker( final DualityInterface dual, final IItemHandler patterns, final String unlocalizedName )
|
||||
{
|
||||
@@ -415,6 +447,9 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
||||
this.client = new AppEngInternalInventory( null, this.server.getSlots() );
|
||||
this.unlocalizedName = unlocalizedName;
|
||||
this.sortBy = dual.getSortValue();
|
||||
this.pos = dual.getLocation().getPos();
|
||||
this.dim = dual.getLocation().getWorld().provider.getDimension();
|
||||
this.numUpgrades = dual.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,31 +60,21 @@ public class ContainerMEPortableCell extends ContainerMEMonitorable
|
||||
{
|
||||
final ItemStack currentItem = this.slot < 0 ? this.getPlayerInv().getCurrentItem() : this.getPlayerInv().getStackInSlot( this.slot );
|
||||
|
||||
if( this.civ != null )
|
||||
{
|
||||
if( currentItem != this.civ.getItemStack() )
|
||||
{
|
||||
if( !currentItem.isEmpty() )
|
||||
{
|
||||
if( ItemStack.areItemsEqual( this.civ.getItemStack(), currentItem ) )
|
||||
{
|
||||
this.getPlayerInv().setInventorySlotContents( this.getPlayerInv().currentItem, this.civ.getItemStack() );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setValidContainer( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setValidContainer( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if( this.civ == null || currentItem.isEmpty() )
|
||||
{
|
||||
this.setValidContainer( false );
|
||||
}
|
||||
else if( this.civ != null && !this.civ.getItemStack().isEmpty() && currentItem != this.civ.getItemStack() )
|
||||
{
|
||||
if( ItemStack.areItemsEqual( this.civ.getItemStack(), currentItem ) )
|
||||
{
|
||||
this.getPlayerInv().setInventorySlotContents( this.getPlayerInv().currentItem, this.civ.getItemStack() );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setValidContainer( false );
|
||||
}
|
||||
}
|
||||
|
||||
// drain 1 ae t
|
||||
this.ticks++;
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.StorageFilter;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
import appeng.parts.misc.PartOreDicStorageBus;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import appeng.util.item.OreReference;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class ContainerPartOreDictStorageBus extends AEBaseContainer
|
||||
{
|
||||
private final PartOreDicStorageBus part;
|
||||
|
||||
public ContainerPartOreDictStorageBus( final InventoryPlayer ip, final PartOreDicStorageBus anchor )
|
||||
{
|
||||
super( ip, anchor );
|
||||
this.part = anchor;
|
||||
|
||||
this.bindPlayerInventory( ip, 14, 256 - /* height of player inventory */82 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
super.detectAndSendChanges();
|
||||
}
|
||||
|
||||
public void partition()
|
||||
{
|
||||
final IMEInventory<IAEItemStack> cellInv = this.part.getInternalHandler();
|
||||
|
||||
Set<Integer> oreIDs = new HashSet<>();
|
||||
|
||||
for( IAEItemStack itemStack : cellInv.getAvailableItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) )
|
||||
{
|
||||
OreReference ref = ( (AEItemStack) itemStack ).getOre().orElse( null );
|
||||
if( ref != null )
|
||||
{
|
||||
oreIDs.addAll( ref.getOres() );
|
||||
}
|
||||
}
|
||||
|
||||
String oreMatch = "(";
|
||||
String append = "";
|
||||
|
||||
for( Iterator<Integer> it = oreIDs.iterator(); it.hasNext(); )
|
||||
{
|
||||
int oreID = it.next();
|
||||
if( it.hasNext() )
|
||||
{
|
||||
append = ")|(";
|
||||
}
|
||||
else
|
||||
{
|
||||
append = ")";
|
||||
}
|
||||
oreMatch = oreMatch.concat( OreDictionary.getOreName( oreID ) + append );
|
||||
}
|
||||
|
||||
if( oreMatch.equals( "(" ) )
|
||||
{
|
||||
oreMatch = "";
|
||||
}
|
||||
part.saveOreMatch( oreMatch );
|
||||
|
||||
this.detectAndSendChanges();
|
||||
}
|
||||
|
||||
public void saveOreMatch( String value )
|
||||
{
|
||||
part.saveOreMatch( value );
|
||||
}
|
||||
|
||||
public void sendRegex()
|
||||
{
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendTo( new PacketValueConfig( "OreDictStorageBus.sendRegex", part.getOreMatch() ), (EntityPlayerMP) getInventoryPlayer().player );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import appeng.container.slot.*;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
@@ -51,12 +52,6 @@ import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.container.ContainerNull;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.IOptionalSlotHost;
|
||||
import appeng.container.slot.OptionalSlotFake;
|
||||
import appeng.container.slot.SlotFakeCraftingMatrix;
|
||||
import appeng.container.slot.SlotPatternOutputs;
|
||||
import appeng.container.slot.SlotPatternTerm;
|
||||
import appeng.container.slot.SlotRestrictedInput;
|
||||
import appeng.core.sync.packets.PacketPatternSlot;
|
||||
import appeng.helpers.IContainerCraftingPacket;
|
||||
import appeng.items.storage.ItemViewCell;
|
||||
@@ -132,6 +127,28 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
this.updateOrderOfOutputSlots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
|
||||
{
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
if( this.inventorySlots.get( idx ) instanceof SlotPlayerInv || this.inventorySlots.get( idx ) instanceof SlotPlayerHotBar )
|
||||
{
|
||||
final AppEngSlot clickSlot = ( AppEngSlot ) this.inventorySlots.get( idx ); // require AE SLots!
|
||||
ItemStack itemStack = clickSlot.getStack();
|
||||
if( AEApi.instance().definitions().materials().blankPattern().isSameAs( itemStack ) )
|
||||
{
|
||||
IItemHandler patternInv = this.getPatternTerminal().getInventoryByName( "pattern" );
|
||||
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
|
||||
clickSlot.putStack( remainder );
|
||||
}
|
||||
}
|
||||
return super.transferStackInSlot( p, idx );
|
||||
}
|
||||
|
||||
|
||||
private void updateOrderOfOutputSlots()
|
||||
{
|
||||
if( !this.isCraftingMode() )
|
||||
@@ -161,7 +178,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
this.getAndUpdateOutput();
|
||||
}
|
||||
|
||||
private ItemStack getAndUpdateOutput()
|
||||
protected ItemStack getAndUpdateOutput()
|
||||
{
|
||||
final World world = this.getPlayerInv().player.world;
|
||||
final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 );
|
||||
@@ -203,6 +220,19 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
|
||||
}
|
||||
|
||||
public void encodeAndMoveToInventory()
|
||||
{
|
||||
encode();
|
||||
ItemStack output = this.patternSlotOUT.getStack();
|
||||
if ( !output.isEmpty() )
|
||||
{
|
||||
if (!getPlayerInv().addItemStackToInventory( output )){
|
||||
getPlayerInv().player.dropItem( output , false );
|
||||
}
|
||||
this.patternSlotOUT.putStack( ItemStack.EMPTY );
|
||||
}
|
||||
}
|
||||
|
||||
public void encode()
|
||||
{
|
||||
ItemStack output = this.patternSlotOUT.getStack();
|
||||
@@ -269,7 +299,213 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
output.setTagCompound( encodedValue );
|
||||
}
|
||||
|
||||
private ItemStack[] getInputs()
|
||||
public void multiply(int multiple)
|
||||
{
|
||||
ItemStack[] input = new ItemStack[9];
|
||||
boolean canMultiplyInputs = true;
|
||||
boolean canMultiplyOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.craftingSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.craftingSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() * multiple > input[x].getMaxStackSize() )
|
||||
{
|
||||
canMultiplyInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() * multiple > out.getMaxStackSize() )
|
||||
{
|
||||
canMultiplyOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canMultiplyInputs && canMultiplyOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.craftingSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
craftingSlot.getStack().setCount( stack.getCount() * multiple );
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
outputSlot.getStack().setCount( stack.getCount() * multiple );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void divide(int divide)
|
||||
{
|
||||
ItemStack[] input = new ItemStack[9];
|
||||
boolean canDivideInputs = true;
|
||||
boolean canDivideOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.craftingSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.craftingSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() % divide != 0 )
|
||||
{
|
||||
canDivideInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() % divide != 0 )
|
||||
{
|
||||
canDivideOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canDivideInputs && canDivideOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.craftingSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
craftingSlot.getStack().setCount( stack.getCount() / divide );
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
outputSlot.getStack().setCount( stack.getCount() / divide );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void increase(int increase)
|
||||
{
|
||||
ItemStack[] input = new ItemStack[9];
|
||||
boolean canIncreaseInputs = true;
|
||||
boolean canIncreaseOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.craftingSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.craftingSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() + increase > input[x].getMaxStackSize() )
|
||||
{
|
||||
canIncreaseInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() + increase > out.getMaxStackSize() )
|
||||
{
|
||||
canIncreaseOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canIncreaseInputs && canIncreaseOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.craftingSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
craftingSlot.getStack().setCount( stack.getCount() + increase );
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
outputSlot.getStack().setCount( stack.getCount() + increase );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void decrease(int decrease)
|
||||
{
|
||||
ItemStack[] input = new ItemStack[9];
|
||||
boolean canDecreaseInputs = true;
|
||||
boolean canDecreaseOutputs = true;
|
||||
|
||||
for( int x = 0; x < this.craftingSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.craftingSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getCount() - decrease < 1 )
|
||||
{
|
||||
canDecreaseInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
if( !out.isEmpty() && out.getCount() - decrease < 1 )
|
||||
{
|
||||
canDecreaseOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canDecreaseInputs && canDecreaseOutputs )
|
||||
{
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.craftingSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
craftingSlot.getStack().setCount( stack.getCount() - decrease );
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
outputSlot.getStack().setCount( stack.getCount() - decrease );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void maximizeCount()
|
||||
{
|
||||
ItemStack[] input = new ItemStack[9];
|
||||
boolean canGrowInputs = true;
|
||||
boolean canGrowOutputs = true;
|
||||
int maxInputStackGrowth = 0;
|
||||
int maxOutputStackGrowth = 0;
|
||||
|
||||
|
||||
for( int x = 0; x < this.craftingSlots.length; x++ )
|
||||
{
|
||||
input[x] = this.craftingSlots[x].getStack();
|
||||
if( !input[x].isEmpty() && input[x].getMaxStackSize() - input[x].getCount() > maxInputStackGrowth )
|
||||
{
|
||||
maxInputStackGrowth = input[x].getMaxStackSize() - input[x].getCount();
|
||||
}
|
||||
if( !input[x].isEmpty() && input[x].getCount() + maxInputStackGrowth > input[x].getMaxStackSize() )
|
||||
{
|
||||
canGrowInputs = false;
|
||||
}
|
||||
}
|
||||
for( final OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
final ItemStack out = outputSlot.getStack();
|
||||
{
|
||||
maxOutputStackGrowth = out.getMaxStackSize() - out.getCount();
|
||||
}
|
||||
if( !out.isEmpty() && out.getCount() + maxOutputStackGrowth > out.getMaxStackSize() )
|
||||
{
|
||||
canGrowOutputs = false;
|
||||
}
|
||||
}
|
||||
if( canGrowInputs && canGrowOutputs )
|
||||
{
|
||||
int maxStackGrowth = Math.min(maxInputStackGrowth,maxOutputStackGrowth);
|
||||
for( SlotFakeCraftingMatrix craftingSlot : this.craftingSlots )
|
||||
{
|
||||
ItemStack stack = craftingSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
craftingSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
|
||||
}
|
||||
for( OptionalSlotFake outputSlot : this.outputSlots )
|
||||
{
|
||||
ItemStack stack = outputSlot.getStack();
|
||||
if( !stack.isEmpty() )
|
||||
outputSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ItemStack[] getInputs()
|
||||
{
|
||||
final ItemStack[] input = new ItemStack[9];
|
||||
boolean hasValue = false;
|
||||
@@ -291,7 +527,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
return null;
|
||||
}
|
||||
|
||||
private ItemStack[] getOutputs()
|
||||
protected ItemStack[] getOutputs()
|
||||
{
|
||||
if( this.isCraftingMode() )
|
||||
{
|
||||
@@ -299,7 +535,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
|
||||
if( !out.isEmpty() && out.getCount() > 0 )
|
||||
{
|
||||
return new ItemStack[] { out };
|
||||
return new ItemStack[]{out};
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -327,7 +563,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isPattern( final ItemStack output )
|
||||
boolean isPattern( final ItemStack output )
|
||||
{
|
||||
if( output.isEmpty() )
|
||||
{
|
||||
@@ -342,7 +578,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
return isPattern;
|
||||
}
|
||||
|
||||
private NBTBase createItemTag( final ItemStack i )
|
||||
NBTBase createItemTag( final ItemStack i )
|
||||
{
|
||||
final NBTTagCompound c = new NBTTagCompound();
|
||||
|
||||
@@ -588,7 +824,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
||||
return this.patternTerminal;
|
||||
}
|
||||
|
||||
private boolean isSubstitute()
|
||||
boolean isSubstitute()
|
||||
{
|
||||
return this.substitute;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package appeng.container.interfaces;
|
||||
|
||||
import mezz.jei.api.gui.IGhostIngredientHandler.Target;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public interface IJEIGhostIngredients
|
||||
{
|
||||
List<Target<?>> getPhantomTargets( Object ingredient );
|
||||
|
||||
default Map<Target<?>, Object> getFakeSlotTargetMap(){
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -157,7 +157,7 @@ public class AppEngSlot extends Slot
|
||||
{
|
||||
if( this.isSlotEnabled() )
|
||||
{
|
||||
return !this.itemHandler.extractItem( this.index, 1, true ).isEmpty();
|
||||
return !this.itemHandler.extractItem( this.index, Integer.MAX_VALUE, true ).isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package appeng.container.slot;
|
||||
|
||||
public interface IJEITargetSlot {
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
|
||||
public class SlotFake extends AppEngSlot
|
||||
public class SlotFake extends AppEngSlot implements IJEITargetSlot
|
||||
{
|
||||
|
||||
public SlotFake( final IItemHandler inv, final int idx, final int x, final int y )
|
||||
|
||||
@@ -363,6 +363,8 @@ final class Registration
|
||||
// Interface
|
||||
Upgrades.CRAFTING.registerItem( parts.iface(), 1 );
|
||||
Upgrades.CRAFTING.registerItem( blocks.iface(), 1 );
|
||||
Upgrades.PATTERN_EXPANSION.registerItem( parts.iface(), 3 );
|
||||
Upgrades.PATTERN_EXPANSION.registerItem( blocks.iface(), 3 );
|
||||
|
||||
// IO Port!
|
||||
Upgrades.SPEED.registerItem( blocks.iOPort(), 3 );
|
||||
|
||||
@@ -175,7 +175,7 @@ public class ApiStorage implements IStorageHelper
|
||||
@Override
|
||||
public int transferFactor()
|
||||
{
|
||||
return 125;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -616,7 +616,12 @@ public final class ApiBlocks implements IBlocks
|
||||
|
||||
private static IBlockDefinition makeStairs( String registryName, FeatureFactory registry, IBlockDefinition block )
|
||||
{
|
||||
return registry.block( registryName, () -> new BlockStairCommon( block.maybeBlock().get(), block.identifier() ) )
|
||||
if( !block.maybeBlock().isPresent() )
|
||||
{
|
||||
return new BlockDefinition( registryName, null, null );
|
||||
}
|
||||
|
||||
IBlockDefinition stairs = registry.block( registryName, () -> new BlockStairCommon( block.maybeBlock().get(), block.identifier() ) )
|
||||
.features( AEFeature.DECORATIVE_BLOCKS )
|
||||
.rendering( new BlockRenderingCustomizer()
|
||||
{
|
||||
@@ -629,6 +634,10 @@ public final class ApiBlocks implements IBlocks
|
||||
}
|
||||
} )
|
||||
.build();
|
||||
|
||||
Verify.verify(stairs.maybeBlock().isPresent());
|
||||
|
||||
return stairs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -86,6 +86,7 @@ public final class ApiMaterials implements IMaterials
|
||||
private final IItemDefinition cardRedstone;
|
||||
private final IItemDefinition cardSpeed;
|
||||
private final IItemDefinition cardCapacity;
|
||||
private final IItemDefinition cardPatternExpansion;
|
||||
private final IItemDefinition cardFuzzy;
|
||||
private final IItemDefinition cardInverter;
|
||||
private final IItemDefinition cardCrafting;
|
||||
@@ -204,6 +205,7 @@ public final class ApiMaterials implements IMaterials
|
||||
this.cardRedstone = new DamagedItemDefinition( "material.card.redstone", materials.createMaterial( MaterialType.CARD_REDSTONE ) );
|
||||
this.cardSpeed = new DamagedItemDefinition( "material.card.acceleration", materials.createMaterial( MaterialType.CARD_SPEED ) );
|
||||
this.cardCapacity = new DamagedItemDefinition( "material.card.capacity", materials.createMaterial( MaterialType.CARD_CAPACITY ) );
|
||||
this.cardPatternExpansion = new DamagedItemDefinition( "material.card.pattern.expansion", materials.createMaterial(MaterialType.CARD_PATTERN_EXPANSION) );
|
||||
this.cardFuzzy = new DamagedItemDefinition( "material.card.fuzzy", materials.createMaterial( MaterialType.CARD_FUZZY ) );
|
||||
this.cardInverter = new DamagedItemDefinition( "material.card.inverter", materials.createMaterial( MaterialType.CARD_INVERTER ) );
|
||||
this.cardCrafting = new DamagedItemDefinition( "material.card.crafting", materials.createMaterial( MaterialType.CARD_CRAFTING ) );
|
||||
@@ -424,6 +426,9 @@ public final class ApiMaterials implements IMaterials
|
||||
return this.cardCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition cardPatternExpansion(){ return this.cardPatternExpansion;}
|
||||
|
||||
@Override
|
||||
public IItemDefinition cardFuzzy()
|
||||
{
|
||||
|
||||
@@ -52,6 +52,7 @@ public final class ApiParts implements IParts
|
||||
private final IItemDefinition toggleBus;
|
||||
private final IItemDefinition invertedToggleBus;
|
||||
private final IItemDefinition storageBus;
|
||||
private final IItemDefinition oreDictStorageBus;
|
||||
private final IItemDefinition importBus;
|
||||
private final IItemDefinition exportBus;
|
||||
private final IItemDefinition iface;
|
||||
@@ -77,6 +78,7 @@ public final class ApiParts implements IParts
|
||||
private final IItemDefinition darkMonitor;
|
||||
private final IItemDefinition interfaceTerminal;
|
||||
private final IItemDefinition patternTerminal;
|
||||
private final IItemDefinition expandedProcessingPatternTerminal;
|
||||
private final IItemDefinition craftingTerminal;
|
||||
private final IItemDefinition terminal;
|
||||
private final IItemDefinition storageMonitor;
|
||||
@@ -112,6 +114,7 @@ public final class ApiParts implements IParts
|
||||
this.toggleBus = new DamagedItemDefinition( "part.toggle_bus", itemPart.createPart( PartType.TOGGLE_BUS ) );
|
||||
this.invertedToggleBus = new DamagedItemDefinition( "part.toggle_bus.inverted", itemPart.createPart( PartType.INVERTED_TOGGLE_BUS ) );
|
||||
this.storageBus = new DamagedItemDefinition( "part.bus.storage", itemPart.createPart( PartType.STORAGE_BUS ) );
|
||||
this.oreDictStorageBus = new DamagedItemDefinition( "part.bus.oredict_storage", itemPart.createPart( PartType.OREDICT_STORAGE_BUS ) );
|
||||
this.importBus = new DamagedItemDefinition( "part.bus.import", itemPart.createPart( PartType.IMPORT_BUS ) );
|
||||
this.exportBus = new DamagedItemDefinition( "part.bus.export", itemPart.createPart( PartType.EXPORT_BUS ) );
|
||||
this.iface = new DamagedItemDefinition( "part.interface", itemPart.createPart( PartType.INTERFACE ) );
|
||||
@@ -139,6 +142,7 @@ public final class ApiParts implements IParts
|
||||
this.darkMonitor = new DamagedItemDefinition( "part.monitor.dark", itemPart.createPart( PartType.DARK_MONITOR ) );
|
||||
this.interfaceTerminal = new DamagedItemDefinition( "part.terminal.interface", itemPart.createPart( PartType.INTERFACE_TERMINAL ) );
|
||||
this.patternTerminal = new DamagedItemDefinition( "part.terminal.pattern", itemPart.createPart( PartType.PATTERN_TERMINAL ) );
|
||||
this.expandedProcessingPatternTerminal = new DamagedItemDefinition( "part.terminal.expanded_processing_pattern", itemPart.createPart( PartType.EXPANDED_PROCESSING_PATTERN_TERMINAL ) );
|
||||
this.craftingTerminal = new DamagedItemDefinition( "part.terminal.crafting", itemPart.createPart( PartType.CRAFTING_TERMINAL ) );
|
||||
this.terminal = new DamagedItemDefinition( "part.terminal", itemPart.createPart( PartType.TERMINAL ) );
|
||||
this.storageMonitor = new DamagedItemDefinition( "part.monitor.storage", itemPart.createPart( PartType.STORAGE_MONITOR ) );
|
||||
@@ -245,6 +249,12 @@ public final class ApiParts implements IParts
|
||||
return this.storageBus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition oreDictStorageBus()
|
||||
{
|
||||
return this.oreDictStorageBus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition importBus()
|
||||
{
|
||||
@@ -379,6 +389,12 @@ public final class ApiParts implements IParts
|
||||
return this.patternTerminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition expandedProcessingPatternTerminal()
|
||||
{
|
||||
return this.expandedProcessingPatternTerminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDefinition craftingTerminal()
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package appeng.core.localization;
|
||||
|
||||
|
||||
import appeng.api.config.SchedulingMode;
|
||||
import net.minecraft.util.text.translation.I18n;
|
||||
|
||||
|
||||
@@ -137,6 +138,28 @@ public enum ButtonToolTips
|
||||
BlockPlacementYes,
|
||||
BlockPlacementNo,
|
||||
|
||||
MultiplyByTwo,
|
||||
MultiplyByTwoDesc,
|
||||
MultiplyByThree,
|
||||
MultiplyByThreeDesc,
|
||||
IncreaseByOne,
|
||||
IncreaseByOneDesc,
|
||||
DivideByTwo,
|
||||
DivideByTwoDesc,
|
||||
DivideByThree,
|
||||
DivideByThreeDesc,
|
||||
DecreaseByOne,
|
||||
DecreaseByOneDesc,
|
||||
MaxCount,
|
||||
MaxCountDesc,
|
||||
FreeMolecularSlotShortcut,
|
||||
FreeMolecularSlotShortcutDesc,
|
||||
ToggleShowFullInterfaces,
|
||||
ToggleShowFullInterfacesOnDesc,
|
||||
ToggleShowFullInterfacesOffDesc,
|
||||
HighlightInterface,
|
||||
HighlightInterfaceDesc,
|
||||
|
||||
// Used in the tooltips of the items in the terminal, when moused over
|
||||
ItemsStored,
|
||||
ItemsRequestable,
|
||||
|
||||
@@ -70,6 +70,7 @@ public enum GuiText
|
||||
EnergyDrain,
|
||||
|
||||
StorageBus,
|
||||
OreDictStorageBus,
|
||||
StorageBusFluids,
|
||||
Priority,
|
||||
Security,
|
||||
|
||||
@@ -31,8 +31,10 @@ public enum WailaText
|
||||
DeviceMissingChannel,
|
||||
|
||||
P2PUnlinked,
|
||||
P2PInputOneOutput,
|
||||
P2PInputManyOutputs,
|
||||
P2P_INPUT_ONE_OUTPUT,
|
||||
P2P_INPUT_MANY_OUTPUTS,
|
||||
P2P_OUTPUT_ONE_INPUT,
|
||||
P2P_OUTPUT_MANY_INPUTS,
|
||||
P2POutput,
|
||||
|
||||
Locked,
|
||||
|
||||
@@ -21,6 +21,9 @@ package appeng.core.sync;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import appeng.container.implementations.*;
|
||||
import appeng.parts.misc.PartOreDicStorageBus;
|
||||
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -53,39 +56,6 @@ import appeng.client.gui.GuiNull;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.ContainerNull;
|
||||
import appeng.container.ContainerOpenContext;
|
||||
import appeng.container.implementations.ContainerCellWorkbench;
|
||||
import appeng.container.implementations.ContainerChest;
|
||||
import appeng.container.implementations.ContainerCondenser;
|
||||
import appeng.container.implementations.ContainerCraftAmount;
|
||||
import appeng.container.implementations.ContainerCraftConfirm;
|
||||
import appeng.container.implementations.ContainerCraftingCPU;
|
||||
import appeng.container.implementations.ContainerCraftingStatus;
|
||||
import appeng.container.implementations.ContainerCraftingTerm;
|
||||
import appeng.container.implementations.ContainerDrive;
|
||||
import appeng.container.implementations.ContainerFormationPlane;
|
||||
import appeng.container.implementations.ContainerGrinder;
|
||||
import appeng.container.implementations.ContainerIOPort;
|
||||
import appeng.container.implementations.ContainerInscriber;
|
||||
import appeng.container.implementations.ContainerInterface;
|
||||
import appeng.container.implementations.ContainerInterfaceTerminal;
|
||||
import appeng.container.implementations.ContainerLevelEmitter;
|
||||
import appeng.container.implementations.ContainerMAC;
|
||||
import appeng.container.implementations.ContainerMEMonitorable;
|
||||
import appeng.container.implementations.ContainerMEPortableCell;
|
||||
import appeng.container.implementations.ContainerNetworkStatus;
|
||||
import appeng.container.implementations.ContainerNetworkTool;
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
import appeng.container.implementations.ContainerPriority;
|
||||
import appeng.container.implementations.ContainerQNB;
|
||||
import appeng.container.implementations.ContainerQuartzKnife;
|
||||
import appeng.container.implementations.ContainerSecurityStation;
|
||||
import appeng.container.implementations.ContainerSkyChest;
|
||||
import appeng.container.implementations.ContainerSpatialIOPort;
|
||||
import appeng.container.implementations.ContainerStorageBus;
|
||||
import appeng.container.implementations.ContainerUpgradeable;
|
||||
import appeng.container.implementations.ContainerVibrationChamber;
|
||||
import appeng.container.implementations.ContainerWireless;
|
||||
import appeng.container.implementations.ContainerWirelessTerm;
|
||||
import appeng.fluids.container.ContainerFluidFormationPlane;
|
||||
import appeng.fluids.container.ContainerFluidIO;
|
||||
import appeng.fluids.container.ContainerFluidInterface;
|
||||
@@ -171,6 +141,8 @@ public enum GuiBridge implements IGuiHandler
|
||||
|
||||
GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_OREDICTSTORAGEBUS( ContainerPartOreDictStorageBus.class, PartOreDicStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_STORAGEBUS_FLUID( ContainerFluidStorageBus.class, PartFluidStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
@@ -185,6 +157,8 @@ public enum GuiBridge implements IGuiHandler
|
||||
|
||||
GUI_PATTERN_TERMINAL( ContainerPatternTerm.class, PartPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
|
||||
|
||||
GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL( ContainerExpandedProcessingPatternTerm.class, PartExpandedProcessingPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
|
||||
|
||||
GUI_FLUID_TERMINAL( ContainerFluidTerminal.class, ITerminalHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
// extends (Container/Gui) + Bus
|
||||
|
||||
@@ -20,7 +20,16 @@ package appeng.core.sync.packets;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.container.slot.IJEITargetSlot;
|
||||
import appeng.container.slot.SlotFake;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
|
||||
import appeng.fluids.container.ContainerFluidConfigurable;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
@@ -40,6 +49,7 @@ import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
|
||||
public class PacketInventoryAction extends AppEngPacket
|
||||
@@ -57,6 +67,7 @@ public class PacketInventoryAction extends AppEngPacket
|
||||
this.slot = stream.readInt();
|
||||
this.id = stream.readLong();
|
||||
final boolean hasItem = stream.readBoolean();
|
||||
|
||||
if( hasItem )
|
||||
{
|
||||
this.slotItem = AEItemStack.fromPacket( stream );
|
||||
@@ -70,7 +81,6 @@ public class PacketInventoryAction extends AppEngPacket
|
||||
// api
|
||||
public PacketInventoryAction( final InventoryAction action, final int slot, final IAEItemStack slotItem ) throws IOException
|
||||
{
|
||||
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
throw new IllegalStateException( "invalid packet, client cannot post inv actions with stacks." );
|
||||
@@ -101,6 +111,36 @@ public class PacketInventoryAction extends AppEngPacket
|
||||
this.configureWrite( data );
|
||||
}
|
||||
|
||||
public PacketInventoryAction(final InventoryAction action, final IJEITargetSlot slot, final IAEItemStack slotItem ) throws IOException
|
||||
{
|
||||
|
||||
this.action = action;
|
||||
if (slot instanceof SlotFake)
|
||||
this.slot = ((SlotFake) slot).slotNumber;
|
||||
else this.slot = ((GuiFluidSlot) slot).getId();
|
||||
this.id = 0;
|
||||
this.slotItem = slotItem;
|
||||
|
||||
final ByteBuf data = Unpooled.buffer();
|
||||
|
||||
data.writeInt( this.getPacketID() );
|
||||
data.writeInt( action.ordinal() );
|
||||
data.writeInt( this.slot );
|
||||
data.writeLong( this.id );
|
||||
|
||||
if( slotItem == null )
|
||||
{
|
||||
data.writeBoolean( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
data.writeBoolean( true );
|
||||
slotItem.writeToPacket( data );
|
||||
}
|
||||
|
||||
this.configureWrite( data );
|
||||
}
|
||||
|
||||
// api
|
||||
public PacketInventoryAction( final InventoryAction action, final int slot, final long id )
|
||||
{
|
||||
@@ -150,6 +190,47 @@ public class PacketInventoryAction extends AppEngPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM )
|
||||
{
|
||||
if( sender.openContainer instanceof ContainerFluidConfigurable )
|
||||
{
|
||||
if( this.slotItem != null )
|
||||
{
|
||||
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
|
||||
if( aefs != null )
|
||||
{
|
||||
aefs.setStackSize( 1000 );
|
||||
( (ContainerFluidConfigurable) sender.openContainer ).getFluidConfigInventory().setFluidInSlot( this.slot, aefs );
|
||||
NetworkHandler.instance().sendToServer( new PacketFluidSlot( Collections.singletonMap( this.slot, aefs ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.slot < sender.openContainer.inventorySlots.size() && sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake )
|
||||
{
|
||||
if( this.slotItem != null )
|
||||
{
|
||||
sender.openContainer.inventorySlots.get( this.slot ).putStack( this.slotItem.createItemStack() );
|
||||
if( sender.openContainer.inventorySlots.get( this.slot ).getStack().isEmpty() )
|
||||
{
|
||||
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
|
||||
if( aefs != null )
|
||||
{
|
||||
FluidStack fluid = aefs.getFluidStack();
|
||||
sender.openContainer.inventorySlots.get( this.slot ).putStack( AEFluidStack.fromFluidStack( fluid ).asItemStackRepresentation() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else sender.openContainer.inventorySlots.get( this.slot ).putStack( ItemStack.EMPTY );
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendTo( new PacketInventoryAction( InventoryAction.UPDATE_HAND, 0, AEItemStack.fromItemStack( ItemStack.EMPTY ) ), sender );
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
baseContainer.doAction( sender, this.action, this.slot, this.id );
|
||||
|
||||
@@ -23,7 +23,14 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
import gregtech.common.items.MetaTool;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
@@ -63,7 +70,10 @@ import appeng.util.prioritylist.IPartitionList;
|
||||
public class PacketJEIRecipe extends AppEngPacket
|
||||
{
|
||||
|
||||
private ItemStack[][] recipe;
|
||||
private List<ItemStack[]> recipe;
|
||||
private List<ItemStack> output;
|
||||
static ItemStack[] emptyArray = {ItemStack.EMPTY};
|
||||
|
||||
|
||||
// automatic.
|
||||
public PacketJEIRecipe( final ByteBuf stream ) throws IOException
|
||||
@@ -73,20 +83,39 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
final NBTTagCompound comp = CompressedStreamTools.readCompressed( bytes );
|
||||
if( comp != null )
|
||||
{
|
||||
this.recipe = new ItemStack[9][];
|
||||
for( int x = 0; x < this.recipe.length; x++ )
|
||||
this.recipe = new ArrayList<>();
|
||||
|
||||
for( int x = 0; x < comp.getKeySet().size(); x++ )
|
||||
{
|
||||
final NBTTagList list = comp.getTagList( "#" + x, 10 );
|
||||
if( list.tagCount() > 0 )
|
||||
if( comp.hasKey( "#" + x ) )
|
||||
{
|
||||
this.recipe[x] = new ItemStack[list.tagCount()];
|
||||
for( int y = 0; y < list.tagCount(); y++ )
|
||||
final NBTTagList list = comp.getTagList( "#" + x, 10 );
|
||||
if( list.tagCount() > 0 )
|
||||
{
|
||||
this.recipe[x][y] = new ItemStack( list.getCompoundTagAt( y ) );
|
||||
this.recipe.add( new ItemStack[list.tagCount()] );
|
||||
for( int y = 0; y < list.tagCount(); y++ )
|
||||
{
|
||||
this.recipe.get( x )[y] = new ItemStack( list.getCompoundTagAt( y ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.recipe.add( emptyArray );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( comp.hasKey( "outputs" ) )
|
||||
{
|
||||
final NBTTagList outputList = comp.getTagList( "outputs", 10 );
|
||||
this.output = new ArrayList<>();
|
||||
for( int z = 0; z < outputList.tagCount(); z++ )
|
||||
{
|
||||
this.output.add( new ItemStack( outputList.getCompoundTagAt( z ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// api
|
||||
@@ -146,12 +175,24 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
{
|
||||
ItemStack currentItem = craftMatrix.getStackInSlot( x );
|
||||
|
||||
if (x >= this.recipe.size()) {
|
||||
currentItem = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
// prepare slots
|
||||
if( !currentItem.isEmpty() )
|
||||
{
|
||||
// already the correct item?
|
||||
ItemStack newItem = this.canUseInSlot( x, currentItem );
|
||||
|
||||
if( !cct.useRealItems() && this.recipe.get( x ) != null )
|
||||
{
|
||||
if( this.recipe.get( x ).length > 0 )
|
||||
{
|
||||
currentItem.setCount( recipe.get( x )[0].getCount() );
|
||||
}
|
||||
}
|
||||
|
||||
// put away old item
|
||||
if( newItem != currentItem && security.hasPermission( player, SecurityPermissions.INJECT ) )
|
||||
{
|
||||
@@ -168,12 +209,12 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
}
|
||||
}
|
||||
|
||||
if( currentItem.isEmpty() && this.recipe[x] != null )
|
||||
if( currentItem.isEmpty() && recipe.size() > x && recipe.get( x ) != null )
|
||||
{
|
||||
// for each variant
|
||||
for( int y = 0; y < this.recipe[x].length && currentItem.isEmpty(); y++ )
|
||||
for( int y = 0; y < this.recipe.get( x ).length && currentItem.isEmpty(); y++ )
|
||||
{
|
||||
final IAEItemStack request = AEItemStack.fromItemStack( this.recipe[x][y] );
|
||||
final IAEItemStack request = AEItemStack.fromItemStack( this.recipe.get( x )[y] );
|
||||
if( request != null )
|
||||
{
|
||||
// try ae
|
||||
@@ -185,6 +226,24 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
if( cct.useRealItems() )
|
||||
{
|
||||
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
||||
if( out == null )
|
||||
{
|
||||
if( request.getItem().isDamageable() || ( Platform.isModLoaded( "gregtech" ) && request.getItem() instanceof MetaTool ) )
|
||||
{
|
||||
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
|
||||
for( IAEItemStack is : outList )
|
||||
{
|
||||
if( is.getDefinition().getMetadata() == request.getDefinition().getMetadata() )
|
||||
{
|
||||
out = Platform.poweredExtraction( energy, storage, is.copy().setStackSize( 1 ), cct.getActionSource() );
|
||||
}
|
||||
if( out != null )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -202,6 +261,10 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
|
||||
if( out != null )
|
||||
{
|
||||
if (!cct.useRealItems())
|
||||
{
|
||||
out.setStackSize( recipe.get( x )[y].getCount() );
|
||||
}
|
||||
currentItem = out.createItemStack();
|
||||
}
|
||||
}
|
||||
@@ -213,19 +276,42 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
|
||||
if( cct.useRealItems() )
|
||||
{
|
||||
currentItem = ad.removeItems( 1, this.recipe[x][y], null );
|
||||
currentItem = ad.removeSimilarItems( 1, this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentItem = ad.simulateRemove( 1, this.recipe[x][y], null );
|
||||
currentItem = ad.simulateSimilarRemove( recipe.get( x )[y].getCount(), this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cct.useRealItems())
|
||||
{
|
||||
if( currentItem.isEmpty() && recipe.size() > x && this.recipe.get( x ) != null )
|
||||
{
|
||||
currentItem = this.recipe.get( x )[0].copy();
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemHandlerUtil.setStackInSlot( craftMatrix, x, currentItem );
|
||||
}
|
||||
|
||||
con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) );
|
||||
|
||||
if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) )
|
||||
{
|
||||
IItemHandler outputSlots = cct.getInventoryByName( "output" );
|
||||
|
||||
for( int i = 0; i < this.output.size(); ++i )
|
||||
{
|
||||
if( this.output.get( i ) == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output.get( i ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,11 +323,11 @@ public class PacketJEIRecipe extends AppEngPacket
|
||||
*/
|
||||
private ItemStack canUseInSlot( int slot, ItemStack is )
|
||||
{
|
||||
if( this.recipe[slot] != null )
|
||||
if( this.recipe.get( slot ) != null )
|
||||
{
|
||||
for( ItemStack option : this.recipe[slot] )
|
||||
for( ItemStack option : this.recipe.get( slot ) )
|
||||
{
|
||||
if( is.isItemEqual( option ) )
|
||||
if( ItemStack.areItemStacksEqual( is, option ) )
|
||||
{
|
||||
return is;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package appeng.core.sync.packets;
|
||||
|
||||
|
||||
import appeng.fluids.container.ContainerFluidInterface;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
@@ -90,5 +91,9 @@ public class PacketTargetFluidStack extends AppEngPacket
|
||||
{
|
||||
( (ContainerFluidTerminal) player.openContainer ).setTargetStack( this.stack );
|
||||
}
|
||||
else if( player.openContainer instanceof ContainerFluidInterface )
|
||||
{
|
||||
( (ContainerFluidInterface) player.openContainer ).setTargetStack( this.stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.client.gui.implementations.GuiPartOreDictStorageBus;
|
||||
import appeng.container.implementations.*;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
@@ -40,17 +42,6 @@ import appeng.api.util.IConfigManager;
|
||||
import appeng.api.util.IConfigurableObject;
|
||||
import appeng.client.gui.implementations.GuiCraftingCPU;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.implementations.ContainerCellWorkbench;
|
||||
import appeng.container.implementations.ContainerCraftConfirm;
|
||||
import appeng.container.implementations.ContainerCraftingCPU;
|
||||
import appeng.container.implementations.ContainerCraftingStatus;
|
||||
import appeng.container.implementations.ContainerLevelEmitter;
|
||||
import appeng.container.implementations.ContainerNetworkTool;
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
import appeng.container.implementations.ContainerPriority;
|
||||
import appeng.container.implementations.ContainerQuartzKnife;
|
||||
import appeng.container.implementations.ContainerSecurityStation;
|
||||
import appeng.container.implementations.ContainerStorageBus;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.fluids.container.ContainerFluidLevelEmitter;
|
||||
@@ -166,24 +157,109 @@ public class PacketValueConfig extends AppEngPacket
|
||||
final ContainerFluidLevelEmitter lvc = (ContainerFluidLevelEmitter) c;
|
||||
lvc.setLevel( Long.parseLong( this.Value ), player );
|
||||
}
|
||||
else if( this.Name.startsWith( "PatternTerminal." ) && c instanceof ContainerPatternTerm )
|
||||
else if( this.Name.startsWith( "PatternTerminal." ) )
|
||||
{
|
||||
final ContainerPatternTerm cpt = (ContainerPatternTerm) c;
|
||||
if( this.Name.equals( "PatternTerminal.CraftMode" ) )
|
||||
if( c instanceof ContainerPatternTerm )
|
||||
{
|
||||
cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) );
|
||||
final ContainerPatternTerm cpt = (ContainerPatternTerm) c;
|
||||
if( this.Name.equals( "PatternTerminal.CraftMode" ) )
|
||||
{
|
||||
cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Encode" ) )
|
||||
{
|
||||
if( this.Value.equals( "2" ) )
|
||||
{
|
||||
cpt.encodeAndMoveToInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
cpt.encode();
|
||||
}
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Clear" ) )
|
||||
{
|
||||
cpt.clear();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
|
||||
{
|
||||
cpt.multiply( 2 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
|
||||
{
|
||||
cpt.multiply( 3 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
|
||||
{
|
||||
cpt.divide( 2 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
|
||||
{
|
||||
cpt.divide( 3 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
|
||||
{
|
||||
cpt.increase( 1 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
|
||||
{
|
||||
cpt.decrease( 1 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
|
||||
{
|
||||
cpt.maximizeCount();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
|
||||
{
|
||||
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
|
||||
}
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Encode" ) )
|
||||
else if( c instanceof ContainerExpandedProcessingPatternTerm )
|
||||
{
|
||||
cpt.encode();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Clear" ) )
|
||||
{
|
||||
cpt.clear();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
|
||||
{
|
||||
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
|
||||
final ContainerExpandedProcessingPatternTerm cept = (ContainerExpandedProcessingPatternTerm) c;
|
||||
if( this.Name.equals( "PatternTerminal.Encode" ) )
|
||||
{
|
||||
if( this.Value.equals( "2" ) )
|
||||
{
|
||||
cept.encodeAndMoveToInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
cept.encode();
|
||||
}
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.Clear" ) )
|
||||
{
|
||||
cept.clear();
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
|
||||
{
|
||||
cept.multiply( 2 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
|
||||
{
|
||||
cept.multiply( 3 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
|
||||
{
|
||||
cept.divide( 2 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
|
||||
{
|
||||
cept.divide( 3 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
|
||||
{
|
||||
cept.increase( 1 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
|
||||
{
|
||||
cept.decrease( 1 );
|
||||
}
|
||||
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
|
||||
{
|
||||
cept.maximizeCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.Name.startsWith( "StorageBus." ) )
|
||||
@@ -200,6 +276,10 @@ public class PacketValueConfig extends AppEngPacket
|
||||
{
|
||||
( (ContainerFluidStorageBus) c ).partition();
|
||||
}
|
||||
else if( c instanceof ContainerPartOreDictStorageBus )
|
||||
{
|
||||
( (ContainerPartOreDictStorageBus) c ).partition();
|
||||
}
|
||||
}
|
||||
else if( this.Value.equals( "Clear" ) )
|
||||
{
|
||||
@@ -214,6 +294,20 @@ public class PacketValueConfig extends AppEngPacket
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.Name.startsWith( "OreDictStorageBus" ) )
|
||||
{
|
||||
if( c instanceof ContainerPartOreDictStorageBus )
|
||||
{
|
||||
if( this.Name.equals( "OreDictStorageBus.save" ) )
|
||||
{
|
||||
( (ContainerPartOreDictStorageBus) c ).saveOreMatch( this.Value );
|
||||
}
|
||||
if( this.Name.equals( "OreDictStorageBus.getRegex" ) )
|
||||
{
|
||||
( (ContainerPartOreDictStorageBus) c ).sendRegex();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.Name.startsWith( "CellWorkbench." ) && c instanceof ContainerCellWorkbench )
|
||||
{
|
||||
final ContainerCellWorkbench ccw = (ContainerCellWorkbench) c;
|
||||
@@ -290,6 +384,14 @@ public class PacketValueConfig extends AppEngPacket
|
||||
( (GuiCraftingCPU) gs ).clearItems();
|
||||
}
|
||||
}
|
||||
else if( this.Name.equals( "OreDictStorageBus.sendRegex" ) )
|
||||
{
|
||||
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
|
||||
if( gs instanceof GuiPartOreDictStorageBus )
|
||||
{
|
||||
( (GuiPartOreDictStorageBus) gs ).fillRegex( this.Value );
|
||||
}
|
||||
}
|
||||
else if( c instanceof IConfigurableObject )
|
||||
{
|
||||
final IConfigManager cm = ( (IConfigurableObject) c ).getConfigManager();
|
||||
|
||||
@@ -69,8 +69,8 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
private final ICraftingCallback callback;
|
||||
private boolean running = false;
|
||||
private boolean done = false;
|
||||
private int time = 5;
|
||||
private int incTime = Integer.MAX_VALUE;
|
||||
private int time;
|
||||
private int incTime;
|
||||
|
||||
private World wrapWorld( final World w )
|
||||
{
|
||||
@@ -221,11 +221,10 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
|
||||
void handlePausing() throws InterruptedException
|
||||
{
|
||||
if( this.incTime > 100 )
|
||||
if( !this.actionSrc.player().isPresent() && this.incTime > 100 )
|
||||
{
|
||||
this.incTime = 0;
|
||||
|
||||
synchronized( this.monitor )
|
||||
synchronized ( this.monitor )
|
||||
{
|
||||
if( this.watch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
|
||||
{
|
||||
@@ -238,7 +237,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
{
|
||||
AELog.craftingDebug( "crafting job will now sleep" );
|
||||
|
||||
while( !this.running )
|
||||
while ( !this.running )
|
||||
{
|
||||
this.monitor.wait();
|
||||
}
|
||||
@@ -310,43 +309,25 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if this needs more simulation.
|
||||
*
|
||||
* @param milli milliseconds of simulation
|
||||
*
|
||||
* @return true if this needs more simulation
|
||||
*/
|
||||
public boolean simulateFor( final int milli )
|
||||
public boolean simulateFor(final int milli)
|
||||
{
|
||||
this.time = milli;
|
||||
|
||||
synchronized( this.monitor )
|
||||
synchronized ( this.monitor )
|
||||
{
|
||||
if( this.done )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this.watch.reset();
|
||||
this.watch.start();
|
||||
this.running = true;
|
||||
|
||||
AELog.craftingDebug( "main thread is now going to sleep" );
|
||||
|
||||
this.monitor.notify();
|
||||
|
||||
while( this.running )
|
||||
if( !this.actionSrc.player().isPresent() )
|
||||
{
|
||||
try
|
||||
{
|
||||
this.monitor.wait();
|
||||
}
|
||||
catch( final InterruptedException ignored )
|
||||
{
|
||||
}
|
||||
this.watch.reset();
|
||||
this.watch.start();
|
||||
this.monitor.notify();
|
||||
}
|
||||
|
||||
AELog.craftingDebug( "main thread is now active" );
|
||||
this.running = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -120,18 +121,47 @@ public class CraftingTreeNode
|
||||
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
{
|
||||
this.job.handlePausing();
|
||||
|
||||
final List<IAEItemStack> thingsUsed = new ArrayList<>();
|
||||
|
||||
this.what.setStackSize( l );
|
||||
if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
|
||||
IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
if( !this.exhausted )
|
||||
{
|
||||
final IAEItemStack is = this.job.checkUse( available );
|
||||
|
||||
if( is != null )
|
||||
{
|
||||
thingsUsed.add( is.copy() );
|
||||
this.used.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
this.bytes += available.getStackSize();
|
||||
l -= available.getStackSize();
|
||||
|
||||
if( l == 0 )
|
||||
{
|
||||
return available;
|
||||
}
|
||||
}
|
||||
|
||||
else if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
|
||||
{
|
||||
final Collection<IAEItemStack> itemList;
|
||||
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
|
||||
|
||||
if( this.parent.details.canSubstitute() )
|
||||
{
|
||||
itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL );
|
||||
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs( this.slot );
|
||||
itemList = new ArrayList<>( substitutes.size() );
|
||||
|
||||
for( IAEItemStack stack : substitutes )
|
||||
{
|
||||
itemList.addAll( inventoryList.findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -147,12 +177,12 @@ public class CraftingTreeNode
|
||||
|
||||
for( IAEItemStack fuzz : itemList )
|
||||
{
|
||||
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.createItemStack(), this.world ) )
|
||||
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().setStackSize( 1 ).createItemStack(), this.world ) )
|
||||
{
|
||||
fuzz = fuzz.copy();
|
||||
fuzz.setStackSize( l );
|
||||
|
||||
final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
||||
available = inv.extractItems( fuzz, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
@@ -178,32 +208,6 @@ public class CraftingTreeNode
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
if( !this.exhausted )
|
||||
{
|
||||
final IAEItemStack is = this.job.checkUse( available );
|
||||
|
||||
if( is != null )
|
||||
{
|
||||
thingsUsed.add( is.copy() );
|
||||
this.used.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
this.bytes += available.getStackSize();
|
||||
l -= available.getStackSize();
|
||||
|
||||
if( l == 0 )
|
||||
{
|
||||
return available;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( this.canEmit )
|
||||
{
|
||||
@@ -222,7 +226,7 @@ public class CraftingTreeNode
|
||||
{
|
||||
final CraftingTreeProcess pro = this.nodes.get( 0 );
|
||||
|
||||
while( pro.possible && l > 0 )
|
||||
while ( pro.possible && l > 0 )
|
||||
{
|
||||
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
|
||||
|
||||
@@ -230,7 +234,7 @@ public class CraftingTreeNode
|
||||
|
||||
madeWhat.setStackSize( l );
|
||||
|
||||
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
|
||||
available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
@@ -254,13 +258,13 @@ public class CraftingTreeNode
|
||||
{
|
||||
try
|
||||
{
|
||||
while( pro.possible && l > 0 )
|
||||
while ( pro.possible && l > 0 )
|
||||
{
|
||||
final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true );
|
||||
pro.request( subInv, 1, src );
|
||||
|
||||
this.what.setStackSize( l );
|
||||
final IAEItemStack available = subInv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
available = subInv.extractItems( this.what, Actionable.MODULATE, src );
|
||||
|
||||
if( available != null )
|
||||
{
|
||||
@@ -317,7 +321,7 @@ public class CraftingTreeNode
|
||||
}
|
||||
// missing = 0;
|
||||
|
||||
job.addBytes( 8 + this.bytes );
|
||||
job.addBytes( this.bytes );
|
||||
|
||||
for( final CraftingTreeProcess pro : this.nodes )
|
||||
{
|
||||
@@ -354,6 +358,10 @@ public class CraftingTreeNode
|
||||
|
||||
if( ex == null || ex.getStackSize() != i.getStackSize() )
|
||||
{
|
||||
if( src.player().isPresent() )
|
||||
{
|
||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + i.getStackSize() + " " + i.getDefinition().getItem().getItemStackDisplayName( i.getDefinition() ) + " available but could not extract anything" ), false );
|
||||
}
|
||||
throw new CraftBranchFailure( i, i.getStackSize() );
|
||||
}
|
||||
|
||||
|
||||
@@ -77,8 +77,6 @@ public class CraftingTreeProcess
|
||||
ic.setInventorySlotContents( x, is[x] == null ? ItemStack.EMPTY : is[x].createItemStack() );
|
||||
}
|
||||
|
||||
FMLCommonHandler.instance().firePlayerCraftingEvent( Platform.getPlayer( (WorldServer) world ), details.getOutput( ic, world ), ic );
|
||||
|
||||
for( int x = 0; x < ic.getSizeInventory(); x++ )
|
||||
{
|
||||
final ItemStack g = ic.getStackInSlot( x );
|
||||
@@ -188,7 +186,6 @@ public class CraftingTreeProcess
|
||||
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
{
|
||||
this.job.handlePausing();
|
||||
|
||||
if( this.fullSimulation )
|
||||
{
|
||||
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
@@ -201,8 +198,6 @@ public class CraftingTreeProcess
|
||||
ic.setInventorySlotContents( entry.getKey().getSlot(), stack.createItemStack() );
|
||||
}
|
||||
|
||||
FMLCommonHandler.instance().firePlayerCraftingEvent( Platform.getPlayer( (WorldServer) this.world ), this.details.getOutput( ic, this.world ), ic );
|
||||
|
||||
for( int x = 0; x < ic.getSizeInventory(); x++ )
|
||||
{
|
||||
ItemStack is = ic.getStackInSlot( x );
|
||||
@@ -246,7 +241,6 @@ public class CraftingTreeProcess
|
||||
o.setStackSize( o.getStackSize() * i );
|
||||
inv.injectItems( o, Actionable.MODULATE, src );
|
||||
}
|
||||
|
||||
this.crafts += i;
|
||||
}
|
||||
|
||||
@@ -258,14 +252,14 @@ public class CraftingTreeProcess
|
||||
pro.dive( job );
|
||||
}
|
||||
|
||||
job.addBytes( 8 + this.crafts + this.bytes );
|
||||
job.addBytes( this.crafts + 8 + this.bytes );
|
||||
}
|
||||
|
||||
IAEItemStack getAmountCrafted( IAEItemStack what2 )
|
||||
{
|
||||
for( final IAEItemStack is : this.details.getCondensedOutputs() )
|
||||
{
|
||||
if( is.equals( what2 ) )
|
||||
if( is.isSameType( what2 ) )
|
||||
{
|
||||
what2 = what2.copy();
|
||||
what2.setStackSize( is.getStackSize() );
|
||||
|
||||
@@ -28,7 +28,9 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.helpers.PlayerSource;
|
||||
import appeng.util.inv.ItemListIgnoreCrafting;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
|
||||
|
||||
public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
@@ -307,8 +309,19 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||
|
||||
if( result == null || result.getStackSize() != extra.getStackSize() )
|
||||
{
|
||||
if( src.player().isPresent() )
|
||||
{
|
||||
if( result == null )
|
||||
{
|
||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could not extract anything" ), false );
|
||||
}
|
||||
else
|
||||
{
|
||||
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could only extract " + result.getStackSize() ), false );
|
||||
}
|
||||
}
|
||||
failed = true;
|
||||
break;
|
||||
if( !src.player().isPresent() ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class BlockQuartzGlass extends AEBaseBlock
|
||||
}
|
||||
}
|
||||
|
||||
return w.getBlockState( pos ).shouldSideBeRendered( w, adjacentPos, side );
|
||||
return super.shouldSideBeRendered( state, w, pos, side );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,9 @@ package appeng.fluids.client.gui;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.api.util.IConfigManager;
|
||||
import appeng.client.gui.widgets.GuiCustomSlot;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
|
||||
@@ -38,11 +41,12 @@ import appeng.fluids.helper.IFluidInterfaceHost;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
|
||||
|
||||
public class GuiFluidInterface extends GuiUpgradeable
|
||||
public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerHost
|
||||
{
|
||||
public final static int ID_BUTTON_TANK = 222;
|
||||
|
||||
private final IFluidInterfaceHost host;
|
||||
private final ContainerFluidInterface container;
|
||||
private GuiTabButton priority;
|
||||
|
||||
public GuiFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
|
||||
@@ -50,6 +54,8 @@ public class GuiFluidInterface extends GuiUpgradeable
|
||||
super( new ContainerFluidInterface( ip, te ) );
|
||||
this.ySize = 231;
|
||||
this.host = te;
|
||||
( this.container = (ContainerFluidInterface) this.inventorySlots ).setGui( this );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,9 +68,7 @@ public class GuiFluidInterface extends GuiUpgradeable
|
||||
|
||||
for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i )
|
||||
{
|
||||
final GuiFluidTank guiTank = new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, this.getGuiLeft() + 35 + 18 * i, this
|
||||
.getGuiTop() + 53, 16, 68 );
|
||||
this.buttonList.add( guiTank );
|
||||
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 53, 16, 68 ) );
|
||||
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
|
||||
}
|
||||
|
||||
@@ -104,9 +108,33 @@ public class GuiFluidInterface extends GuiUpgradeable
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked( int xCoord, int yCoord, int btn ) throws IOException
|
||||
{
|
||||
for( GuiCustomSlot slot : this.guiSlots )
|
||||
{
|
||||
if( slot instanceof GuiFluidTank )
|
||||
{
|
||||
if( this.isPointInRegion( slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord ) && slot.canClick( this.mc.player ) )
|
||||
{
|
||||
this.container.setTargetStack( ( (GuiFluidTank) slot ).getFluidStack() );
|
||||
slot.slotClicked( this.mc.player.inventory.getItemStack(), btn );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
super.mouseClicked( xCoord, yCoord, btn );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean drawUpgrades()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,13 @@ public class GuiFluidLevelEmitter extends GuiUpgradeable
|
||||
this.level.drawTextBox();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG( int offsetX, int offsetY, int mouseX, int mouseY )
|
||||
{
|
||||
if( isPointInRegion( 24, 43,89,this.fontRenderer.FONT_HEIGHT,mouseX,mouseY ) ) drawTooltip( mouseX - guiLeft - 7, mouseY - guiTop + 25, "Amount in millibuckets" );
|
||||
super.drawFG( offsetX, offsetY, mouseX, mouseY );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean drawUpgrades()
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ package appeng.fluids.client.gui.widgets;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import appeng.container.slot.IJEITargetSlot;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
@@ -23,7 +24,7 @@ import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
|
||||
|
||||
public class GuiFluidSlot extends GuiCustomSlot
|
||||
public class GuiFluidSlot extends GuiCustomSlot implements IJEITargetSlot
|
||||
{
|
||||
private final IAEFluidTank fluids;
|
||||
private final int slot;
|
||||
|
||||
@@ -19,42 +19,50 @@
|
||||
package appeng.fluids.client.gui.widgets;
|
||||
|
||||
|
||||
import appeng.client.gui.widgets.GuiCustomSlot;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketInventoryAction;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.util.AEColor;
|
||||
import appeng.client.gui.widgets.ITooltip;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
|
||||
|
||||
@SideOnly( Side.CLIENT )
|
||||
public class GuiFluidTank extends GuiButton implements ITooltip
|
||||
public class GuiFluidTank extends GuiCustomSlot implements ITooltip
|
||||
{
|
||||
private final IAEFluidTank tank;
|
||||
private final int slot;
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
public GuiFluidTank( IAEFluidTank tank, int slot, int id, int x, int y, int w, int h )
|
||||
{
|
||||
super( id, x, y, w, h, "" );
|
||||
super( id, x, y );
|
||||
this.tank = tank;
|
||||
this.slot = slot;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton( final Minecraft mc, final int mouseX, final int mouseY, final float partialTicks )
|
||||
public void drawContent( Minecraft mc, int mouseX, int mouseY, float partialTicks )
|
||||
{
|
||||
if( this.visible )
|
||||
final IAEFluidStack fs = this.getFluidStack();
|
||||
if( fs != null )
|
||||
{
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.disableLighting();
|
||||
|
||||
drawRect( this.x, this.y, this.x + this.width, this.y + this.height, AEColor.GRAY.blackVariant | 0xFF000000 );
|
||||
//drawRect( this.x, this.y, this.x + this.width, this.y + this.height, AEColor.GRAY.blackVariant | 0xFF000000 );
|
||||
|
||||
final IAEFluidStack fluid = this.tank.getFluidInSlot( this.slot );
|
||||
if( fluid != null && fluid.getStackSize() > 0 )
|
||||
@@ -69,17 +77,16 @@ public class GuiFluidTank extends GuiButton implements ITooltip
|
||||
TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite( fluid.getFluid().getStill().toString() );
|
||||
final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) );
|
||||
|
||||
int iconHeightRemainder = scaledHeight % 16;
|
||||
int iconHeightRemainder = scaledHeight % this.getHeight();
|
||||
if( iconHeightRemainder > 0 )
|
||||
{
|
||||
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder, sprite, 16, iconHeightRemainder );
|
||||
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, this.getWidth(), iconHeightRemainder );
|
||||
}
|
||||
for( int i = 0; i < scaledHeight / 16; i++ )
|
||||
for( int i = 0; i < scaledHeight / this.getHeight(); i++ )
|
||||
{
|
||||
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
|
||||
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, this.getWidth(), this.getHeight() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,25 +107,25 @@ public class GuiFluidTank extends GuiButton implements ITooltip
|
||||
@Override
|
||||
public int xPos()
|
||||
{
|
||||
return this.x - 2;
|
||||
return this.x - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos()
|
||||
{
|
||||
return this.y - 2;
|
||||
return this.y - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth()
|
||||
{
|
||||
return this.width + 4;
|
||||
return this.width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
return this.height + 4;
|
||||
return this.height + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,4 +134,24 @@ public class GuiFluidTank extends GuiButton implements ITooltip
|
||||
return true;
|
||||
}
|
||||
|
||||
public IAEFluidStack getFluidStack()
|
||||
{
|
||||
return this.tank.getFluidInSlot( this.slot );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void slotClicked( ItemStack clickStack, final int mouseButton )
|
||||
{
|
||||
|
||||
if( getFluidStack() != null )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketInventoryAction( InventoryAction.FILL_ITEM, slot, 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketInventoryAction( InventoryAction.EMPTY_ITEM, slot, 0 ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public class FluidStackSizeRenderer
|
||||
format.setDecimalFormatSymbols( symbols );
|
||||
format.setRoundingMode( RoundingMode.DOWN );
|
||||
|
||||
return format.format( originalSize / 1000f );
|
||||
return format.format( originalSize / 1000d );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,17 @@
|
||||
package appeng.fluids.container;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketTargetFluidStack;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.IContainerListener;
|
||||
|
||||
@@ -33,12 +41,19 @@ import appeng.fluids.helper.FluidSyncHelper;
|
||||
import appeng.fluids.helper.IFluidInterfaceHost;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidUtil;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
|
||||
|
||||
|
||||
public class ContainerFluidInterface extends ContainerFluidConfigurable
|
||||
public class ContainerFluidInterface extends ContainerFluidConfigurable implements IConfigManagerHost
|
||||
{
|
||||
private final DualityFluidInterface myDuality;
|
||||
private final FluidSyncHelper tankSync;
|
||||
private IConfigManagerHost gui;
|
||||
// Holds the fluid the client wishes to extract, or null for insert
|
||||
private IAEFluidStack clientRequestedTargetFluid = null;
|
||||
|
||||
public ContainerFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
|
||||
{
|
||||
@@ -60,6 +75,15 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable
|
||||
return this.myDuality.getConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue )
|
||||
{
|
||||
if( this.getGui() != null )
|
||||
{
|
||||
this.getGui().updateSetting( manager, settingName, newValue );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
@@ -97,6 +121,126 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable
|
||||
this.tankSync.readPacket( fluids );
|
||||
}
|
||||
|
||||
private IConfigManagerHost getGui()
|
||||
{
|
||||
return this.gui;
|
||||
}
|
||||
|
||||
public void setGui( @Nonnull final IConfigManagerHost gui )
|
||||
{
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
public void doAction( EntityPlayerMP player, InventoryAction action, int slot, long id )
|
||||
{
|
||||
if( action != InventoryAction.FILL_ITEM && action != InventoryAction.EMPTY_ITEM )
|
||||
{
|
||||
super.doAction( player, action, slot, id );
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack held = player.inventory.getItemStack();
|
||||
ItemStack heldCopy = held.copy();
|
||||
heldCopy.setCount( 1 );
|
||||
IFluidHandlerItem fh = FluidUtil.getFluidHandler( heldCopy );
|
||||
if( fh == null )
|
||||
{
|
||||
// only fluid handlers items
|
||||
return;
|
||||
}
|
||||
|
||||
if( action == InventoryAction.FILL_ITEM && this.clientRequestedTargetFluid != null )
|
||||
{
|
||||
final IAEFluidStack stack = this.clientRequestedTargetFluid.copy();
|
||||
|
||||
// Check how much we can store in the item
|
||||
stack.setStackSize( Integer.MAX_VALUE );
|
||||
int amountAllowed = fh.fill( stack.getFluidStack(), false );
|
||||
int heldAmount = held.getCount();
|
||||
for( int i = 0; i < heldAmount; i++ )
|
||||
{
|
||||
ItemStack copiedFluidContainer = held.copy();
|
||||
copiedFluidContainer.setCount( 1 );
|
||||
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||
|
||||
FluidStack extractableFluid = this.myDuality.getTanks().drain( stack.setStackSize( amountAllowed ).getFluidStack(), false );
|
||||
if( extractableFluid == null || extractableFluid.amount == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
int fillableAmount = fh.fill( extractableFluid, false );
|
||||
if( fillableAmount > 0 )
|
||||
{
|
||||
FluidStack extractedFluid = this.myDuality.getTanks().drain( extractableFluid, true );
|
||||
fh.fill( extractedFluid, true );
|
||||
}
|
||||
|
||||
if( held.getCount() == 1 )
|
||||
{
|
||||
player.inventory.setItemStack( fh.getContainer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.inventory.getItemStack().shrink( 1 );
|
||||
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||
{
|
||||
player.dropItem( fh.getContainer(), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( action == InventoryAction.EMPTY_ITEM )
|
||||
{
|
||||
int heldAmount = held.getCount();
|
||||
for( int i = 0; i < heldAmount; i++ )
|
||||
{
|
||||
ItemStack copiedFluidContainer = held.copy();
|
||||
copiedFluidContainer.setCount( 1 );
|
||||
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||
|
||||
FluidStack drainable = fh.drain( this.myDuality.getTanks().getTankProperties()[slot].getCapacity(), false );
|
||||
if( drainable != null )
|
||||
{
|
||||
fh.drain( drainable, true );
|
||||
this.myDuality.getTanks().fill( drainable, true );
|
||||
}
|
||||
|
||||
if( held.getCount() == 1 )
|
||||
{
|
||||
player.inventory.setItemStack( fh.getContainer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.inventory.getItemStack().shrink( 1 );
|
||||
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||
{
|
||||
player.dropItem( fh.getContainer(), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.updateHeld( player );
|
||||
}
|
||||
|
||||
public void setTargetStack( final IAEFluidStack stack )
|
||||
{
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
if( stack == null && this.clientRequestedTargetFluid == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if( stack != null && this.clientRequestedTargetFluid != null && stack.getFluidStack().isFluidEqual( this.clientRequestedTargetFluid.getFluidStack() ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
NetworkHandler.instance().sendToServer( new PacketTargetFluidStack( (AEFluidStack) stack ) );
|
||||
}
|
||||
|
||||
this.clientRequestedTargetFluid = stack == null ? null : stack.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportCapacity()
|
||||
{
|
||||
|
||||
@@ -24,14 +24,14 @@ import java.nio.BufferOverflowException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.container.slot.AppEngSlot;
|
||||
import appeng.container.slot.SlotPlayerHotBar;
|
||||
import appeng.container.slot.SlotPlayerInv;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.IContainerListener;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.ForgeModContainer;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidUtil;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
|
||||
@@ -73,6 +73,7 @@ import appeng.me.helpers.ChannelPowerSrc;
|
||||
import appeng.util.ConfigManager;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
|
||||
/**
|
||||
@@ -345,6 +346,89 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
|
||||
{
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
EntityPlayerMP player = (EntityPlayerMP) p;
|
||||
if( this.inventorySlots.get( idx ) instanceof SlotPlayerInv || this.inventorySlots.get( idx ) instanceof SlotPlayerHotBar )
|
||||
{
|
||||
final AppEngSlot clickSlot = (AppEngSlot) this.inventorySlots.get( idx ); // require AE SLots!
|
||||
ItemStack itemStack = clickSlot.getStack();
|
||||
|
||||
ItemStack copy = itemStack.copy();
|
||||
copy.setCount( 1 );
|
||||
IFluidHandlerItem fh = FluidUtil.getFluidHandler( copy );
|
||||
if( fh == null )
|
||||
{
|
||||
// only fluid handlers items
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
int heldAmount = itemStack.getCount();
|
||||
for( int i = 0; i < heldAmount; i++ )
|
||||
{
|
||||
copy = itemStack.copy();
|
||||
copy.setCount( 1 );
|
||||
fh = FluidUtil.getFluidHandler( copy );
|
||||
|
||||
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
|
||||
if( extract == null || extract.amount < 1 )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
// Check if we can push into the system
|
||||
final IAEFluidStack notStorable = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource(), Actionable.SIMULATE );
|
||||
|
||||
if( notStorable != null && notStorable.getStackSize() > 0 )
|
||||
{
|
||||
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
|
||||
final FluidStack storable = fh.drain( toStore, false );
|
||||
|
||||
if( storable == null || storable.amount == 0 )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
extract.amount = storable.amount;
|
||||
}
|
||||
}
|
||||
|
||||
// Actually drain
|
||||
final FluidStack drained = fh.drain( extract, true );
|
||||
extract.amount = drained.amount;
|
||||
|
||||
final IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource() );
|
||||
|
||||
if( notInserted != null && notInserted.getStackSize() > 0 )
|
||||
{
|
||||
IAEFluidStack spill = this.monitor.injectItems( notInserted, Actionable.MODULATE, this.getActionSource() );
|
||||
if( spill != null && spill.getStackSize() > 0 )
|
||||
{
|
||||
fh.fill( spill.getFluidStack(), true );
|
||||
}
|
||||
}
|
||||
|
||||
if( notInserted == null )
|
||||
{
|
||||
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||
{
|
||||
player.dropItem( fh.getContainer(), false );
|
||||
}
|
||||
clickSlot.decrStackSize( 1 );
|
||||
}
|
||||
}
|
||||
this.detectAndSendChanges();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
return super.transferStackInSlot( p, idx );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAction( EntityPlayerMP player, InventoryAction action, int slot, long id )
|
||||
{
|
||||
@@ -353,95 +437,140 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
|
||||
super.doAction( player, action, slot, id );
|
||||
return;
|
||||
}
|
||||
ItemStack held = player.inventory.getItemStack();
|
||||
if( held.getCount() != 1 )
|
||||
{
|
||||
// only support stacksize 1 for now
|
||||
return;
|
||||
}
|
||||
IFluidHandlerItem fh = FluidUtil.getFluidHandler( held );
|
||||
|
||||
final ItemStack held = player.inventory.getItemStack();
|
||||
ItemStack heldCopy = held.copy();
|
||||
heldCopy.setCount( 1 );
|
||||
IFluidHandlerItem fh = FluidUtil.getFluidHandler( heldCopy );
|
||||
if( fh == null )
|
||||
{
|
||||
// only fluid handlers items
|
||||
return;
|
||||
}
|
||||
boolean isBucket = held.getItem() == Items.BUCKET || held.getItem() == Items.WATER_BUCKET || held.getItem() == Items.LAVA_BUCKET || held
|
||||
.getItem() == Items.MILK_BUCKET || held.getItem() == ForgeModContainer.getInstance().universalBucket;
|
||||
|
||||
if( action == InventoryAction.FILL_ITEM && this.clientRequestedTargetFluid != null )
|
||||
{
|
||||
AEFluidStack stack = (AEFluidStack) this.clientRequestedTargetFluid.copy();
|
||||
|
||||
AELog.debug( "Filling %s with %s, %s mb", held.getDisplayName(), this.clientRequestedTargetFluid.getFluidStack().getLocalizedName(),
|
||||
stack.getStackSize() );
|
||||
|
||||
if( isBucket && stack.getStackSize() < Fluid.BUCKET_VOLUME )
|
||||
{ // Although buckets support less than a buckets worth of fluid, it does not display how much it holds
|
||||
return;
|
||||
}
|
||||
final IAEFluidStack stack = this.clientRequestedTargetFluid.copy();
|
||||
|
||||
// Check how much we can store in the item
|
||||
stack.setStackSize( Integer.MAX_VALUE );
|
||||
int amountAllowed = fh.fill( stack.getFluidStack(), false );
|
||||
stack.setStackSize( amountAllowed );
|
||||
|
||||
// Check if we can pull out of the system
|
||||
IAEFluidStack canPull = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack, this.getActionSource(), Actionable.SIMULATE );
|
||||
if( canPull == null || canPull.getStackSize() < 1 || ( isBucket && canPull.getStackSize() != Fluid.BUCKET_VOLUME ) )
|
||||
int heldAmount = held.getCount();
|
||||
for( int i = 0; i < heldAmount; i++ )
|
||||
{
|
||||
// Either we couldn't pull out of the system,
|
||||
// or we are using a bucket and can only pull out less than a buckets worth of fluid
|
||||
return;
|
||||
ItemStack copiedFluidContainer = held.copy();
|
||||
copiedFluidContainer.setCount( 1 );
|
||||
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||
|
||||
// Check if we can pull out of the system
|
||||
final IAEFluidStack canPull = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack.setStackSize( amountAllowed ), this.getActionSource(), Actionable.SIMULATE );
|
||||
if( canPull == null || canPull.getStackSize() < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// How much could fit into the container
|
||||
final int canFill = fh.fill( canPull.getFluidStack(), false );
|
||||
if( canFill == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Now actually pull out of the system
|
||||
final IAEFluidStack pulled = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack.setStackSize( canFill ), this.getActionSource() );
|
||||
if( pulled == null || pulled.getStackSize() < 1 )
|
||||
{
|
||||
// Something went wrong
|
||||
AELog.error( "Unable to pull fluid out of the ME system even though the simulation said yes " );
|
||||
return;
|
||||
}
|
||||
|
||||
// Actually fill
|
||||
final int used = fh.fill( pulled.getFluidStack(), true );
|
||||
|
||||
if( used != canFill )
|
||||
{
|
||||
AELog.error( "Fluid item [%s] reported a different possible amount than it actually accepted.", held.getDisplayName() );
|
||||
}
|
||||
|
||||
if( held.getCount() == 1 )
|
||||
{
|
||||
player.inventory.setItemStack( fh.getContainer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.inventory.getItemStack().shrink( 1 );
|
||||
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||
{
|
||||
player.dropItem( fh.getContainer(), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now actually pull out of the system
|
||||
IAEFluidStack pulled = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack, this.getActionSource() );
|
||||
if( pulled == null || pulled.getStackSize() < 1 )
|
||||
{
|
||||
// Something went wrong
|
||||
AELog.error( "Unable to pull fluid out of the ME system even though the simulation said yes " );
|
||||
return;
|
||||
}
|
||||
|
||||
// Actually fill
|
||||
fh.fill( pulled.getFluidStack(), true );
|
||||
|
||||
player.inventory.setItemStack( fh.getContainer() );
|
||||
this.updateHeld( player );
|
||||
|
||||
}
|
||||
else if( action == InventoryAction.EMPTY_ITEM )
|
||||
{
|
||||
// Empty held item
|
||||
AELog.debug( "Emptying %s", held.getDisplayName() );
|
||||
|
||||
// See how much we can drain from the item
|
||||
FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
|
||||
if( extract == null || extract.amount < 1 )
|
||||
int heldAmount = held.getCount();
|
||||
for( int i = 0; i < heldAmount; i++ )
|
||||
{
|
||||
return;
|
||||
ItemStack copiedFluidContainer = held.copy();
|
||||
copiedFluidContainer.setCount( 1 );
|
||||
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||
|
||||
// See how much we can drain from the item
|
||||
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
|
||||
if( extract == null || extract.amount < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we can push into the system
|
||||
final IAEFluidStack notStorable = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource(), Actionable.SIMULATE );
|
||||
|
||||
if( notStorable != null && notStorable.getStackSize() > 0 )
|
||||
{
|
||||
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
|
||||
final FluidStack storable = fh.drain( toStore, false );
|
||||
|
||||
if( storable == null || storable.amount == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
extract.amount = storable.amount;
|
||||
}
|
||||
}
|
||||
|
||||
// Actually drain
|
||||
final FluidStack drained = fh.drain( extract, true );
|
||||
extract.amount = drained.amount;
|
||||
|
||||
final IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource() );
|
||||
|
||||
if( notInserted != null && notInserted.getStackSize() > 0 )
|
||||
{
|
||||
IAEFluidStack spill = this.monitor.injectItems( notInserted, Actionable.MODULATE, this.getActionSource() );
|
||||
if( spill != null && spill.getStackSize() > 0 )
|
||||
{
|
||||
fh.fill( spill.getFluidStack(), true );
|
||||
}
|
||||
}
|
||||
|
||||
if( held.getCount() == 1 )
|
||||
{
|
||||
player.inventory.setItemStack( fh.getContainer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.inventory.getItemStack().shrink( 1 );
|
||||
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||
{
|
||||
player.dropItem( fh.getContainer(), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we can push into the system
|
||||
IAEFluidStack notPushed = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ),
|
||||
this.getActionSource(), Actionable.SIMULATE );
|
||||
if( isBucket && notPushed != null && notPushed.getStackSize() > 0 )
|
||||
{
|
||||
// We can't push enough for the bucket
|
||||
return;
|
||||
}
|
||||
|
||||
IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ),
|
||||
this.getActionSource() );
|
||||
if( notInserted != null && notInserted.getStackSize() > 0 )
|
||||
{
|
||||
// Only try to extract the amount we DID insert
|
||||
extract.amount -= Math.toIntExact( notInserted.getStackSize() );
|
||||
}
|
||||
|
||||
// Actually drain
|
||||
fh.drain( extract, true );
|
||||
|
||||
player.inventory.setItemStack( fh.getContainer() );
|
||||
this.updateHeld( player );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -72,7 +73,7 @@ import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
public class DualityFluidInterface implements IGridTickable, IStorageMonitorable, IAEFluidInventory, IUpgradeableHost, IConfigManagerHost
|
||||
public class DualityFluidInterface implements IGridTickable, IStorageMonitorable, IAEFluidInventory, IUpgradeableHost, IConfigManagerHost, IConfigurableFluidInventory
|
||||
{
|
||||
public static final int NUMBER_OF_TANKS = 6;
|
||||
public static final int TANK_CAPACITY = Fluid.BUCKET_VOLUME * 4;
|
||||
@@ -90,12 +91,10 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
private int isWorking = -1;
|
||||
private int priority;
|
||||
|
||||
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance()
|
||||
.storage()
|
||||
.getStorageChannel( IItemStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance()
|
||||
.storage()
|
||||
.getStorageChannel( IFluidStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
|
||||
private boolean resetConfigCache = true;
|
||||
private IMEMonitor<IAEFluidStack> configCachedHandler;
|
||||
|
||||
public DualityFluidInterface( final AENetworkProxy networkProxy, final IFluidInterfaceHost ih )
|
||||
{
|
||||
@@ -118,15 +117,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
|
||||
public IUpgradeableHost getHost()
|
||||
{
|
||||
if( this.iHost instanceof IUpgradeableHost )
|
||||
{
|
||||
return this.iHost;
|
||||
}
|
||||
if( this.iHost instanceof IUpgradeableHost )
|
||||
{
|
||||
return this.iHost;
|
||||
}
|
||||
return null;
|
||||
return this.iHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,7 +136,12 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
{
|
||||
if( this.hasConfig() )
|
||||
{
|
||||
return (IMEMonitor<T>) new InterfaceInventory( this );
|
||||
if( resetConfigCache )
|
||||
{
|
||||
resetConfigCache = false;
|
||||
configCachedHandler = new InterfaceInventory( this );
|
||||
}
|
||||
return (IMEMonitor<T>) configCachedHandler;
|
||||
}
|
||||
|
||||
return (IMEMonitor<T>) this.fluids;
|
||||
@@ -255,6 +251,17 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
|
||||
private void readConfig()
|
||||
{
|
||||
this.hasConfig = false;
|
||||
|
||||
for( int i = 0; i < this.config.getSlots(); i++ )
|
||||
{
|
||||
if( this.config.getFluidInSlot( i ) != null )
|
||||
{
|
||||
this.hasConfig = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean had = this.hasWorkToDo();
|
||||
|
||||
for( int x = 0; x < NUMBER_OF_TANKS; x++ )
|
||||
@@ -371,7 +378,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
else if( this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ).getStorageList().findPrecise( work ) != null )
|
||||
{
|
||||
final IAEFluidStack acquired = Platform.poweredExtraction( src, dest, work, this.interfaceRequestSource );
|
||||
if( acquired != null )
|
||||
@@ -438,7 +445,13 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
|
||||
if( inventory == this.config )
|
||||
{
|
||||
boolean cfg = hasConfig();
|
||||
this.readConfig();
|
||||
if( cfg != hasConfig )
|
||||
{
|
||||
resetConfigCache = true;
|
||||
this.notifyNeighbors();
|
||||
}
|
||||
}
|
||||
else if( inventory == this.tanks )
|
||||
{
|
||||
@@ -543,7 +556,6 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
InterfaceInventory( final DualityFluidInterface tileInterface )
|
||||
{
|
||||
super( tileInterface.tanks );
|
||||
this.setActionSource( new MachineSource( tileInterface.iHost ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -592,6 +604,14 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidHandler getFluidInventoryByName( final String name) {
|
||||
if (name.equals("config")) {
|
||||
return this.config;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInstalledUpgrades( Upgrades u )
|
||||
{
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package appeng.fluids.helper;
|
||||
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
public interface IConfigurableFluidInventory
|
||||
{
|
||||
default IFluidHandler getFluidInventoryByName( String name )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,15 @@
|
||||
package appeng.fluids.parts;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.StorageFilter;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
||||
@@ -42,7 +44,6 @@ import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.IGridProxyable;
|
||||
import appeng.me.storage.ITickingMonitor;
|
||||
|
||||
@@ -61,12 +62,21 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
private final IFluidHandler fluidHandler;
|
||||
private final IGridProxyable proxyable;
|
||||
private final FluidHandlerAdapter.InventoryCache cache;
|
||||
private StorageFilter mode;
|
||||
private AccessRestriction access;
|
||||
|
||||
FluidHandlerAdapter( IFluidHandler fluidHandler, IGridProxyable proxy )
|
||||
{
|
||||
this.fluidHandler = fluidHandler;
|
||||
this.proxyable = proxy;
|
||||
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler );
|
||||
if( this.proxyable instanceof PartFluidStorageBus )
|
||||
{
|
||||
PartFluidStorageBus partFluidStorageBus = (PartFluidStorageBus) this.proxyable;
|
||||
this.mode = ( (StorageFilter) partFluidStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
||||
this.access = ( (AccessRestriction) partFluidStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||
}
|
||||
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode );
|
||||
this.cache.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,11 +95,14 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEFluidStack added = input.copy().setStackSize( input.getStackSize() - remaining );
|
||||
this.cache.currentlyCached.add( added );
|
||||
this.postDifference( Collections.singletonList( added ) );
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ignore )
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
@@ -114,25 +127,32 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
return null;
|
||||
}
|
||||
|
||||
IAEFluidStack gatheredAEFluidstack = AEFluidStack.fromFluidStack( gathered );
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
IAEFluidStack cachedStack = this.cache.currentlyCached.findPrecise( request );
|
||||
if( cachedStack != null )
|
||||
{
|
||||
cachedStack.decStackSize( gatheredAEFluidstack.getStackSize() );
|
||||
this.postDifference( Collections.singletonList( gatheredAEFluidstack.copy().setStackSize( -gatheredAEFluidstack.getStackSize() ) ) );
|
||||
}
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ignore )
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
return AEFluidStack.fromFluidStack( gathered );
|
||||
return gatheredAEFluidstack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
List<IAEFluidStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() )
|
||||
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
return TickRateModulation.URGENT;
|
||||
@@ -193,11 +213,13 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
|
||||
private static class InventoryCache
|
||||
{
|
||||
private IAEFluidStack[] cachedAeStacks = new IAEFluidStack[0];
|
||||
private final IFluidHandler fluidHandler;
|
||||
private final StorageFilter mode;
|
||||
IItemList<IAEFluidStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
|
||||
public InventoryCache( IFluidHandler fluidHandler )
|
||||
public InventoryCache( IFluidHandler fluidHandler, StorageFilter mode )
|
||||
{
|
||||
this.mode = mode;
|
||||
this.fluidHandler = fluidHandler;
|
||||
}
|
||||
|
||||
@@ -205,96 +227,46 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
{
|
||||
final List<IAEFluidStack> changes = new ArrayList<>();
|
||||
final IFluidTankProperties[] tankProperties = this.fluidHandler.getTankProperties();
|
||||
final int slots = tankProperties.length;
|
||||
|
||||
// Make room for new slots
|
||||
if( slots > this.cachedAeStacks.length )
|
||||
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
|
||||
for( IFluidTankProperties tankProperty : tankProperties )
|
||||
{
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
|
||||
for( int slot = 0; slot < slots; slot++ )
|
||||
{
|
||||
// Save the old stuff
|
||||
final IAEFluidStack oldAEFS = this.cachedAeStacks[slot];
|
||||
final FluidStack newFS = tankProperties[slot].getContents();
|
||||
|
||||
this.handlePossibleSlotChanges( slot, oldAEFS, newFS, changes );
|
||||
}
|
||||
|
||||
// Handle cases where the number of slots actually is lower now than before
|
||||
if( slots < this.cachedAeStacks.length )
|
||||
{
|
||||
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
|
||||
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain( 1, false ) == null )
|
||||
{
|
||||
final IAEFluidStack aeStack = this.cachedAeStacks[slot];
|
||||
|
||||
if( aeStack != null )
|
||||
{
|
||||
final IAEFluidStack a = aeStack.copy();
|
||||
a.setStackSize( -a.getStackSize() );
|
||||
changes.add( a );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
|
||||
}
|
||||
|
||||
for ( final IAEFluidStack is : currentlyCached )
|
||||
{
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
|
||||
for ( final IAEFluidStack is : currentlyOnStorage )
|
||||
{
|
||||
currentlyCached.add( is );
|
||||
}
|
||||
|
||||
for ( final IAEFluidStack is : currentlyCached )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
changes.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
currentlyCached = currentlyOnStorage;
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public IItemList<IAEFluidStack> getAvailableItems( IItemList<IAEFluidStack> out )
|
||||
{
|
||||
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
|
||||
currentlyCached.iterator().forEachRemaining( out::add );
|
||||
return out;
|
||||
}
|
||||
|
||||
private void handlePossibleSlotChanges( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
||||
{
|
||||
if( oldAeFS != null && oldAeFS.getFluidStack().isFluidEqual( newFS ) )
|
||||
{
|
||||
this.handleStackSizeChanged( slot, oldAeFS, newFS, changes );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.handleFluidChanged( slot, oldAeFS, newFS, changes );
|
||||
}
|
||||
}
|
||||
|
||||
private void handleStackSizeChanged( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
||||
{
|
||||
// Still the same fluid, but amount might have changed
|
||||
final long diff = newFS.amount - oldAeFS.getStackSize();
|
||||
|
||||
if( diff != 0 )
|
||||
{
|
||||
final IAEFluidStack stack = oldAeFS.copy();
|
||||
stack.setStackSize( newFS.amount );
|
||||
|
||||
this.cachedAeStacks[slot] = stack;
|
||||
|
||||
final IAEFluidStack a = stack.copy();
|
||||
a.setStackSize( diff );
|
||||
changes.add( a );
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFluidChanged( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
||||
{
|
||||
// Completely different fluid
|
||||
this.cachedAeStacks[slot] = AEFluidStack.fromFluidStack( newFS );
|
||||
|
||||
// If we had a stack previously in this slot, notify the network about its disappearance
|
||||
if( oldAeFS != null )
|
||||
{
|
||||
oldAeFS.setStackSize( -oldAeFS.getStackSize() );
|
||||
changes.add( oldAeFS );
|
||||
}
|
||||
|
||||
// Notify the network about the new stack. Note that this is null if newFS was null
|
||||
if( this.cachedAeStacks[slot] != null )
|
||||
{
|
||||
changes.add( this.cachedAeStacks[slot] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
@@ -51,9 +52,10 @@ import appeng.parts.automation.PartAbstractFormationPlane;
|
||||
import appeng.parts.automation.PlaneModels;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.prioritylist.PrecisePriorityList;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
|
||||
public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluidStack> implements IAEFluidInventory
|
||||
public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluidStack> implements IAEFluidInventory, IConfigurableFluidInventory
|
||||
{
|
||||
private static final PlaneModels MODELS = new PlaneModels( "part/fluid_formation_plane_", "part/fluid_formation_plane_on_" );
|
||||
|
||||
@@ -176,8 +178,9 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
|
||||
this.stateChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void updateChannels( final MENetworkChannelsChanged changedChannels )
|
||||
public void chanRender( final MENetworkChannelsChanged changedChannels )
|
||||
{
|
||||
this.stateChanged();
|
||||
}
|
||||
@@ -202,7 +205,7 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
|
||||
@Override
|
||||
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
|
||||
{
|
||||
if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||
if( channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||
{
|
||||
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
|
||||
handler.add( this.myHandler );
|
||||
@@ -222,6 +225,14 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
|
||||
return this.config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidHandler getFluidInventoryByName( final String name) {
|
||||
if (name.equals("config")) {
|
||||
return this.config;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStackRepresentation()
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@ package appeng.fluids.parts;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -30,6 +31,7 @@ import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -61,7 +63,7 @@ import appeng.parts.PartModel;
|
||||
import appeng.util.Platform;
|
||||
|
||||
|
||||
public class PartFluidInterface extends PartBasicState implements IGridTickable, IStorageMonitorable, IFluidInterfaceHost, IPriorityHost
|
||||
public class PartFluidInterface extends PartBasicState implements IGridTickable, IStorageMonitorable, IFluidInterfaceHost, IPriorityHost, IConfigurableFluidInventory
|
||||
{
|
||||
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/fluid_interface_base" );
|
||||
|
||||
@@ -88,14 +90,16 @@ public class PartFluidInterface extends PartBasicState implements IGridTickable,
|
||||
return this.duality;
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void stateChange( final MENetworkChannelsChanged c )
|
||||
public void chanRender( final MENetworkChannelsChanged c )
|
||||
{
|
||||
this.duality.notifyNeighbors();
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void stateChange( final MENetworkPowerStatusChange c )
|
||||
public void powerRender( final MENetworkPowerStatusChange c )
|
||||
{
|
||||
this.duality.notifyNeighbors();
|
||||
}
|
||||
@@ -233,6 +237,11 @@ public class PartFluidInterface extends PartBasicState implements IGridTickable,
|
||||
return this.duality.getInventoryByName( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidHandler getFluidInventoryByName( final String name) {
|
||||
return this.duality.getFluidInventoryByName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStackRepresentation()
|
||||
{
|
||||
|
||||
@@ -4,6 +4,9 @@ package appeng.fluids.parts;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||
import appeng.me.cache.NetworkMonitor;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -33,7 +36,6 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.api.util.AECableType;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.IConfigManager;
|
||||
@@ -48,9 +50,10 @@ import appeng.parts.PartModel;
|
||||
import appeng.parts.automation.PartUpgradeable;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
|
||||
public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatcherHost, IConfigManagerHost, IAEFluidInventory, IMEMonitorHandlerReceiver<IAEFluidStack>
|
||||
public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatcherHost, IConfigManagerHost, IAEFluidInventory, IMEMonitorHandlerReceiver<IAEFluidStack>, IConfigurableFluidInventory
|
||||
{
|
||||
@PartModels
|
||||
public static final ResourceLocation MODEL_BASE_OFF = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_base_off" );
|
||||
@@ -125,15 +128,25 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
||||
this.configureWatchers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void channelChanged( final MENetworkChannelsChanged c )
|
||||
public void powerRender( final MENetworkPowerStatusChange powerEvent )
|
||||
{
|
||||
if (this.getProxy().isActive())
|
||||
{
|
||||
onListUpdate();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void powerChanged( final MENetworkPowerStatusChange c )
|
||||
public void chanRender( final MENetworkChannelsChanged c )
|
||||
{
|
||||
if (this.getProxy().isActive())
|
||||
{
|
||||
onListUpdate();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
@@ -245,10 +258,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
||||
|
||||
if( myStack == null )
|
||||
{
|
||||
this.lastReportedValue = 0;
|
||||
for( final IAEFluidStack st : monitor.getStorageList() )
|
||||
if( monitor instanceof NetworkMonitor )
|
||||
{
|
||||
this.lastReportedValue += st.getStackSize();
|
||||
this.lastReportedValue = ( (NetworkMonitor<IAEFluidStack>) monitor ).getGridCurrentCount();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -354,6 +366,14 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
||||
return this.config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidHandler getFluidInventoryByName( final String name) {
|
||||
if (name.equals("config")) {
|
||||
return this.config;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT( final NBTTagCompound data )
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@
|
||||
package appeng.fluids.parts;
|
||||
|
||||
|
||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -44,6 +45,7 @@ import appeng.fluids.util.IAEFluidTank;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.parts.automation.PartUpgradeable;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
|
||||
/**
|
||||
@@ -51,7 +53,7 @@ import appeng.util.Platform;
|
||||
* @version rv6 - 30/04/2018
|
||||
* @since rv6 30/04/2018
|
||||
*/
|
||||
public abstract class PartSharedFluidBus extends PartUpgradeable implements IGridTickable
|
||||
public abstract class PartSharedFluidBus extends PartUpgradeable implements IGridTickable, IConfigurableFluidInventory
|
||||
{
|
||||
|
||||
private final AEFluidInventory config = new AEFluidInventory( null, 9 );
|
||||
@@ -176,6 +178,14 @@ public abstract class PartSharedFluidBus extends PartUpgradeable implements IGri
|
||||
return this.config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidHandler getFluidInventoryByName( final String name) {
|
||||
if (name.equals("config")) {
|
||||
return this.config;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected IFluidStorageChannel getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class );
|
||||
|
||||
@@ -23,11 +23,13 @@ import java.util.EnumSet;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -50,7 +52,7 @@ import appeng.helpers.IPriorityHost;
|
||||
import appeng.tile.grid.AENetworkTile;
|
||||
|
||||
|
||||
public class TileFluidInterface extends AENetworkTile implements IGridTickable, IFluidInterfaceHost, IPriorityHost
|
||||
public class TileFluidInterface extends AENetworkTile implements IGridTickable, IFluidInterfaceHost, IPriorityHost, IConfigurableFluidInventory
|
||||
{
|
||||
private final DualityFluidInterface duality = new DualityFluidInterface( this.getProxy(), this );
|
||||
|
||||
@@ -176,6 +178,11 @@ public class TileFluidInterface extends AENetworkTile implements IGridTickable,
|
||||
return this.duality.getInventoryByName( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidHandler getFluidInventoryByName(final String name) {
|
||||
return this.duality.getFluidInventoryByName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStackRepresentation()
|
||||
{
|
||||
|
||||
@@ -19,18 +19,19 @@
|
||||
package appeng.helpers;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
|
||||
import appeng.util.*;
|
||||
import appeng.util.inv.*;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
|
||||
import gregtech.api.block.machines.BlockMachine;
|
||||
import gregtech.api.metatileentity.MetaTileEntity;
|
||||
import gregtech.api.metatileentity.MetaTileEntityHolder;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Items;
|
||||
@@ -46,6 +47,7 @@ import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.RangedWrapper;
|
||||
@@ -99,23 +101,18 @@ import appeng.parts.automation.StackUpgradeInventory;
|
||||
import appeng.parts.automation.UpgradeInventory;
|
||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.util.ConfigManager;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.AdaptorItemHandler;
|
||||
import appeng.util.inv.IAEAppEngInventory;
|
||||
import appeng.util.inv.IInventoryDestination;
|
||||
import appeng.util.inv.InvOperation;
|
||||
import appeng.util.item.AEItemStack;
|
||||
|
||||
import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
|
||||
|
||||
|
||||
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost
|
||||
{
|
||||
private int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
|
||||
|
||||
public static final int NUMBER_OF_STORAGE_SLOTS = 9;
|
||||
public static final int NUMBER_OF_CONFIG_SLOTS = 9;
|
||||
public static final int NUMBER_OF_PATTERN_SLOTS = 9;
|
||||
public static final int NUMBER_OF_PATTERN_SLOTS = 36;
|
||||
|
||||
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
|
||||
private final IAEItemStack[] requireWork = { null, null, null, null, null, null, null, null, null };
|
||||
@@ -129,11 +126,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
private final AppEngInternalInventory storage = new AppEngInternalInventory( this, NUMBER_OF_STORAGE_SLOTS );
|
||||
private final AppEngInternalInventory patterns = new AppEngInternalInventory( this, NUMBER_OF_PATTERN_SLOTS );
|
||||
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance()
|
||||
.storage()
|
||||
.getStorageChannel( IItemStorageChannel.class ) );
|
||||
.storage()
|
||||
.getStorageChannel( IItemStorageChannel.class ) );
|
||||
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance()
|
||||
.storage()
|
||||
.getStorageChannel( IFluidStorageChannel.class ) );
|
||||
.storage()
|
||||
.getStorageChannel( IFluidStorageChannel.class ) );
|
||||
private final UpgradeInventory upgrades;
|
||||
private boolean hasConfig = false;
|
||||
private int priority;
|
||||
@@ -142,13 +139,18 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
private IMEInventory<IAEItemStack> destination;
|
||||
private int isWorking = -1;
|
||||
private final Accessor accessor = new Accessor();
|
||||
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
|
||||
private EnumMap<EnumFacing, List<ItemStack>> waitingToSendFacing = new EnumMap<>( EnumFacing.class );
|
||||
private GTCEInventoryAdaptor GTad;
|
||||
private boolean resetConfigCache = true;
|
||||
private IMEMonitor<IAEItemStack> configCachedHandler;
|
||||
|
||||
public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih )
|
||||
{
|
||||
this.gridProxy = networkProxy;
|
||||
this.gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
|
||||
|
||||
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 1 );
|
||||
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4 );
|
||||
this.cm.registerSetting( Settings.BLOCK, YesNo.NO );
|
||||
this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES );
|
||||
|
||||
@@ -176,10 +178,15 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( inv == this.config )
|
||||
if( inv == this.config && ( !removed.isEmpty() || !added.isEmpty() ) )
|
||||
{
|
||||
boolean cfg = hasConfig();
|
||||
this.readConfig();
|
||||
if( cfg != hasConfig )
|
||||
{
|
||||
resetConfigCache = true;
|
||||
this.notifyNeighbors();
|
||||
}
|
||||
}
|
||||
else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) )
|
||||
{
|
||||
@@ -235,6 +242,27 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
data.setTag( "waitingToSend", waitingToSend );
|
||||
|
||||
NBTTagCompound sidedWaitList = new NBTTagCompound();
|
||||
|
||||
if (this.waitingToSendFacing != null)
|
||||
{
|
||||
for( EnumFacing s : this.iHost.getTargets() )
|
||||
{
|
||||
NBTTagList waitingListSided = new NBTTagList();
|
||||
if (this.waitingToSendFacing.containsKey( s ))
|
||||
{
|
||||
for( final ItemStack is : this.waitingToSendFacing.get( s ) )
|
||||
{
|
||||
final NBTTagCompound item = new NBTTagCompound();
|
||||
is.writeToNBT( item );
|
||||
waitingListSided.appendTag( item );
|
||||
}
|
||||
sidedWaitList.setTag( s.name(), waitingListSided );
|
||||
}
|
||||
}
|
||||
}
|
||||
data.setTag( "sidedWaitList", sidedWaitList );
|
||||
}
|
||||
|
||||
public void readFromNBT( final NBTTagCompound data )
|
||||
@@ -254,9 +282,44 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
this.waitingToSendFacing = null;
|
||||
final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" );
|
||||
|
||||
for( EnumFacing s : EnumFacing.values() )
|
||||
if( waitingListSided.hasKey( s.name() ) )
|
||||
{
|
||||
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
|
||||
for( int x = 0; x < w.tagCount(); x++ )
|
||||
{
|
||||
final NBTTagCompound c = w.getCompoundTagAt( x );
|
||||
if( c != null )
|
||||
{
|
||||
final ItemStack is = new ItemStack( c );
|
||||
this.addToSendListFacing( is, EnumFacing.getFront( s.getIndex() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.craftingTracker.readFromNBT( data );
|
||||
|
||||
// fix upgrade slot size mismatch
|
||||
NBTTagCompound up = data.getCompoundTag( "upgrades" );
|
||||
if( up.hasKey( "Size" ) && up.getInteger( "Size" ) != this.upgrades.getSlots() )
|
||||
{
|
||||
up.setInteger( "Size", this.upgrades.getSlots() );
|
||||
this.upgrades.writeToNBT( up, "upgrades" );
|
||||
}
|
||||
|
||||
this.upgrades.readFromNBT( data, "upgrades" );
|
||||
this.config.readFromNBT( data, "config" );
|
||||
|
||||
NBTTagCompound pa = data.getCompoundTag( "patterns" );
|
||||
if( pa.hasKey( "Size" ) && pa.getInteger( "Size" ) != this.patterns.getSlots() )
|
||||
{
|
||||
pa.setInteger( "Size", this.patterns.getSlots() );
|
||||
this.upgrades.writeToNBT( pa, "patterns" );
|
||||
}
|
||||
|
||||
this.patterns.readFromNBT( data, "patterns" );
|
||||
this.storage.readFromNBT( data, "storage" );
|
||||
this.priority = data.getInteger( "priority" );
|
||||
@@ -289,6 +352,30 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
private void addToSendListFacing( final ItemStack is, EnumFacing f )
|
||||
{
|
||||
if( is.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.waitingToSendFacing == null){
|
||||
this.waitingToSendFacing = new EnumMap<>(EnumFacing.class);
|
||||
}
|
||||
|
||||
this.waitingToSendFacing.computeIfAbsent( f, k -> new ArrayList<>() );
|
||||
|
||||
this.waitingToSendFacing.get( f ).add( is );
|
||||
|
||||
try
|
||||
{
|
||||
this.gridProxy.getTick().wakeDevice( this.gridProxy.getNode() );
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
// :P
|
||||
}
|
||||
}
|
||||
|
||||
private void readConfig()
|
||||
{
|
||||
this.hasConfig = false;
|
||||
@@ -335,9 +422,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
private void updateCraftingList()
|
||||
{
|
||||
final Boolean[] accountedFor = { false, false, false, false, false, false, false, false, false }; // 9...
|
||||
|
||||
assert ( accountedFor.length == this.patterns.getSlots() );
|
||||
final Boolean[] accountedFor = new Boolean[this.patterns.getSlots()];
|
||||
Arrays.fill( accountedFor, false );
|
||||
|
||||
if( !this.gridProxy.isReady() )
|
||||
{
|
||||
@@ -352,7 +438,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final ICraftingPatternDetails details = i.next();
|
||||
boolean found = false;
|
||||
|
||||
for( int x = 0; x < accountedFor.length; x++ )
|
||||
for( int x = 0; x < accountedFor.length ; x++ )
|
||||
{
|
||||
final ItemStack is = this.patterns.getStackInSlot( x );
|
||||
if( details.getPattern() == is )
|
||||
@@ -368,7 +454,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
for( int x = 0; x < accountedFor.length; x++ )
|
||||
for( int x = 0; x < accountedFor.length ; x++ )
|
||||
{
|
||||
if( !accountedFor[x] )
|
||||
{
|
||||
@@ -386,24 +472,22 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasWorkToDo()
|
||||
{
|
||||
if( this.hasItemsToSend() )
|
||||
{
|
||||
private boolean hasWorkToDo() {
|
||||
|
||||
if (hasItemsToSend()){
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( final IAEItemStack requiredWork : this.requireWork )
|
||||
{
|
||||
if( requiredWork != null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if(hasItemsToSendFacing()){
|
||||
return true;
|
||||
}
|
||||
|
||||
for (final IAEItemStack requiredWork : this.requireWork) {
|
||||
if (requiredWork != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updatePlan( final int slot )
|
||||
@@ -430,14 +514,18 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
this.requireWork[slot] = req.copy();
|
||||
return;
|
||||
}
|
||||
else if( req.isSameType( stored ) ) // same type ( qty different? )!
|
||||
else if( req.isSameType( stored ) ) // same type and quantity )!
|
||||
{
|
||||
if( req.getStackSize() != stored.getCount() )
|
||||
if( req.getStackSize() == stored.getCount() )
|
||||
{
|
||||
this.requireWork[slot] = null;
|
||||
}
|
||||
else // same type ( qty different? )!
|
||||
{
|
||||
this.requireWork[slot] = req.copy();
|
||||
this.requireWork[slot].setStackSize( req.getStackSize() - stored.getCount() );
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
// Stored != null; dispose!
|
||||
@@ -504,6 +592,45 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return this.waitingToSend != null && !this.waitingToSend.isEmpty();
|
||||
}
|
||||
|
||||
private boolean hasItemsToSendFacing()
|
||||
{
|
||||
if (waitingToSendFacing != null)
|
||||
{
|
||||
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
|
||||
{
|
||||
if( !waitingToSendFacing.get( enumFacing ).isEmpty() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dropExcessPatterns()
|
||||
{
|
||||
IItemHandler patterns = getPatterns();
|
||||
|
||||
List<ItemStack> dropList = new ArrayList<>();
|
||||
for( int invSlot = 0; invSlot < patterns.getSlots(); invSlot++ )
|
||||
{
|
||||
if( invSlot > 8 + this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) * 9 )
|
||||
{
|
||||
ItemStack is = patterns.getStackInSlot( invSlot );
|
||||
if( is.isEmpty() ) continue;
|
||||
dropList.add( patterns.extractItem( invSlot, Integer.MAX_VALUE, false ) );
|
||||
}
|
||||
}
|
||||
if( dropList.size() > 0 )
|
||||
{
|
||||
World world = this.getLocation().getWorld();
|
||||
BlockPos blockPos = this.getLocation().getPos();
|
||||
Platform.spawnDrops( world, blockPos, dropList );
|
||||
}
|
||||
|
||||
this.gridProxy.setIdlePowerUsage( Math.pow( 4, ( this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) ) ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsert( final ItemStack stack )
|
||||
{
|
||||
@@ -575,11 +702,21 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return TickRateModulation.SLEEP;
|
||||
}
|
||||
|
||||
//Previous version might have items saved in this list
|
||||
//recover them
|
||||
if( this.hasItemsToSend() )
|
||||
{
|
||||
this.pushItemsOut( this.iHost.getTargets() );
|
||||
}
|
||||
|
||||
if (hasItemsToSendFacing())
|
||||
{
|
||||
for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
|
||||
{
|
||||
this.pushItemsOut( enumFacing );
|
||||
}
|
||||
}
|
||||
|
||||
final boolean couldDoWork = this.updateStorage();
|
||||
return this.hasWorkToDo() ? ( couldDoWork ? TickRateModulation.URGENT : TickRateModulation.SLOWER ) : TickRateModulation.SLEEP;
|
||||
}
|
||||
@@ -640,6 +777,47 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
private void pushItemsOut( final EnumFacing s )
|
||||
{
|
||||
if (!this.waitingToSendFacing.containsKey(s) ||
|
||||
(this.waitingToSendFacing.containsKey(s) && this.waitingToSendFacing.get( s ).isEmpty())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TileEntity tile = this.iHost.getTileEntity();
|
||||
final World w = tile.getWorld();
|
||||
|
||||
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
|
||||
if( te == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator();
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
ItemStack whatToSend = i.next();
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( ad != null )
|
||||
{
|
||||
final ItemStack result = ad.addItems( whatToSend );
|
||||
if( !result.isEmpty() )
|
||||
{
|
||||
whatToSend.setCount( whatToSend.getCount() - ( whatToSend.getCount() - result.getCount() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( this.waitingToSendFacing.get( s ).isEmpty() )
|
||||
{
|
||||
this.waitingToSendFacing.remove( s );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateStorage()
|
||||
{
|
||||
boolean didSomething = false;
|
||||
@@ -679,19 +857,26 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
|
||||
if( acquired != null )
|
||||
IAEItemStack storedStack = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findPrecise( itemStack );
|
||||
if( storedStack != null )
|
||||
{
|
||||
changed = true;
|
||||
final ItemStack issue = adaptor.addItems( acquired.createItemStack() );
|
||||
if( !issue.isEmpty() )
|
||||
if( storedStack.getStackSize() > 0 )
|
||||
{
|
||||
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
|
||||
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
|
||||
if( acquired != null )
|
||||
{
|
||||
changed = true;
|
||||
final ItemStack issue = adaptor.addItems( acquired.createItemStack() );
|
||||
if( !issue.isEmpty() )
|
||||
{
|
||||
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( storedStack.isCraftable() )
|
||||
{
|
||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
|
||||
}
|
||||
}
|
||||
else if( itemStack.getStackSize() < 0 )
|
||||
@@ -759,8 +944,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null )
|
||||
{
|
||||
return this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
|
||||
if (this.failedCraftTriesSlot[x] <= 0)
|
||||
{
|
||||
boolean crafted = this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
|
||||
this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
|
||||
|
||||
if (crafted) this.failedCraftTriesSlot[x] = 0;
|
||||
else{
|
||||
this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
@@ -794,7 +988,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.hasConfig() )
|
||||
{
|
||||
return (IMEMonitor<T>) new InterfaceInventory( this );
|
||||
if( resetConfigCache )
|
||||
{
|
||||
resetConfigCache = false;
|
||||
configCachedHandler = new InterfaceInventory( this );
|
||||
}
|
||||
return (IMEMonitor<T>) configCachedHandler;
|
||||
}
|
||||
|
||||
return (IMEMonitor<T>) this.items;
|
||||
@@ -893,10 +1092,20 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
};
|
||||
}
|
||||
|
||||
private boolean invIsBlocked( InventoryAdaptor inv )
|
||||
{
|
||||
return (inv.containsItems());
|
||||
}
|
||||
|
||||
private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv )
|
||||
{
|
||||
return ( !inv.canRemoveAllExceptCircuits() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pushPattern( final ICraftingPatternDetails patternDetails, final InventoryCrafting table )
|
||||
{
|
||||
if( this.hasItemsToSend() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
|
||||
if( this.hasItemsToSend() || this.hasItemsToSendFacing() || !this.gridProxy.isActive() || !this.craftingList.contains( patternDetails ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -904,8 +1113,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final TileEntity tile = this.iHost.getTileEntity();
|
||||
final World w = tile.getWorld();
|
||||
|
||||
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
|
||||
for( final EnumFacing s : possibleDirections )
|
||||
if( this.visitedFaces.isEmpty() )
|
||||
{
|
||||
this.visitedFaces = this.iHost.getTargets();
|
||||
}
|
||||
|
||||
for( final EnumFacing s : visitedFaces )
|
||||
{
|
||||
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
|
||||
if( te instanceof IInterfaceHost )
|
||||
@@ -914,6 +1127,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( ( (IInterfaceHost) te ).getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -928,6 +1142,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final ICraftingMachine cm = (ICraftingMachine) te;
|
||||
if( cm.acceptsPlans() )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
if( cm.pushPattern( patternDetails, table, s.getOpposite() ) )
|
||||
{
|
||||
return true;
|
||||
@@ -941,42 +1156,67 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.isBlocking() )
|
||||
{
|
||||
if( !ad.simulateRemove( 1, ItemStack.EMPTY, null ).isEmpty() )
|
||||
IPhantomTile phantomTE = null;
|
||||
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
|
||||
{
|
||||
phantomTE = ( (IPhantomTile) te );
|
||||
if( phantomTE.hasBoundPosition() )
|
||||
{
|
||||
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
||||
if( phantom instanceof MetaTileEntityHolder && isGTCEblocked( phantom, s ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
|
||||
{
|
||||
if( isGTCEblocked( te, s ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
else if( invIsBlocked( ad ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( this.acceptsItems( ad, table ) )
|
||||
{
|
||||
visitedFaces.remove( s );
|
||||
for( int x = 0; x < table.getSizeInventory(); x++ )
|
||||
{
|
||||
final ItemStack is = table.getStackInSlot( x );
|
||||
if( !is.isEmpty() )
|
||||
{
|
||||
final ItemStack added = ad.addItems( is );
|
||||
this.addToSendList( added );
|
||||
addToSendListFacing( is, s );
|
||||
}
|
||||
}
|
||||
this.pushItemsOut( possibleDirections );
|
||||
pushItemsOut( s );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
visitedFaces.remove( s );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy()
|
||||
{
|
||||
if( this.hasItemsToSend() )
|
||||
boolean busy = false;
|
||||
|
||||
if( this.hasItemsToSend() || hasItemsToSendFacing() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean busy = false;
|
||||
|
||||
if( this.isBlocking() )
|
||||
{
|
||||
final EnumSet<EnumFacing> possibleDirections = this.iHost.getTargets();
|
||||
@@ -988,24 +1228,52 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
for( final EnumFacing s : possibleDirections )
|
||||
{
|
||||
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
|
||||
IPhantomTile phantomTE = null;
|
||||
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
if( ad != null )
|
||||
{
|
||||
if( ad.simulateRemove( 1, ItemStack.EMPTY, null ).isEmpty() )
|
||||
if( Loader.isModLoaded( "actuallyadditions") && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
|
||||
{
|
||||
phantomTE = ( (IPhantomTile) te );
|
||||
if( phantomTE.hasBoundPosition() )
|
||||
{
|
||||
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
|
||||
if( phantom instanceof MetaTileEntityHolder && !isGTCEblocked( phantom, s ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
|
||||
{
|
||||
if( !isGTCEblocked( te, s ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if( !invIsBlocked( ad ) )
|
||||
{
|
||||
allAreBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
busy = allAreBusy;
|
||||
}
|
||||
|
||||
return busy;
|
||||
}
|
||||
|
||||
boolean isGTCEblocked(TileEntity te, EnumFacing s)
|
||||
{
|
||||
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
|
||||
return invIsBlockedGTCE( GTad );
|
||||
}
|
||||
|
||||
private boolean sameGrid( final IGrid grid ) throws GridAccessException
|
||||
{
|
||||
return grid == this.gridProxy.getGrid();
|
||||
@@ -1061,6 +1329,20 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
}
|
||||
}
|
||||
|
||||
if( this.waitingToSendFacing != null )
|
||||
{
|
||||
for (List<ItemStack> itemList : waitingToSendFacing.values())
|
||||
{
|
||||
for (final ItemStack is : itemList)
|
||||
{
|
||||
if (!is.isEmpty())
|
||||
{
|
||||
drops.add(is);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( final ItemStack is : this.upgrades )
|
||||
{
|
||||
if( !is.isEmpty() )
|
||||
@@ -1184,6 +1466,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
final IBlockState directedBlockState = hostWorld.getBlockState( targ );
|
||||
final Block directedBlock = directedBlockState.getBlock();
|
||||
ItemStack what = new ItemStack( directedBlock, 1, directedBlock.getMetaFromState( directedBlockState ) );
|
||||
|
||||
if ( Loader.isModLoaded("gregtech") && directedBlock instanceof BlockMachine )
|
||||
{
|
||||
MetaTileEntity metaTileEntity = getMetaTileEntity(hostWorld, targ);
|
||||
return metaTileEntity.getMetaFullName();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Vec3d from = new Vec3d( hostTile.getPos().getX() + 0.5, hostTile.getPos().getY() + 0.5, hostTile.getPos().getZ() + 0.5 );
|
||||
@@ -1312,7 +1601,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
public InterfaceInventory( final DualityInterface tileInterface )
|
||||
{
|
||||
super( new AdaptorItemHandler( tileInterface.storage ) );
|
||||
this.setActionSource( new MachineSource( DualityInterface.this.iHost ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package appeng.helpers;
|
||||
|
||||
import appeng.client.render.BlockPosHighlighter;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
// taken from McJty's McJtyLib
|
||||
|
||||
public class HighlighterHandler
|
||||
{
|
||||
|
||||
public static void tick( RenderWorldLastEvent event ) {
|
||||
renderHilightedBlock(event);
|
||||
}
|
||||
|
||||
private static void renderHilightedBlock( RenderWorldLastEvent event ) {
|
||||
BlockPos c = BlockPosHighlighter.getHilightedBlock();
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
int dimension = mc.world.provider.getDimension();
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
if (time > BlockPosHighlighter.getExpireHilight() || dimension != BlockPosHighlighter.getDimension()) {
|
||||
BlockPosHighlighter.hilightBlock(null, -1, BlockPosHighlighter.getDimension() );
|
||||
return;
|
||||
}
|
||||
|
||||
if (((time / 500) & 1) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
EntityPlayerSP p = mc.player;
|
||||
double doubleX = p.lastTickPosX + (p.posX - p.lastTickPosX) * event.getPartialTicks();
|
||||
double doubleY = p.lastTickPosY + (p.posY - p.lastTickPosY) * event.getPartialTicks();
|
||||
double doubleZ = p.lastTickPosZ + (p.posZ - p.lastTickPosZ) * event.getPartialTicks();
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.color(1.0f, 0, 0);
|
||||
GlStateManager.glLineWidth(3);
|
||||
GlStateManager.translate(-doubleX, -doubleY, -doubleZ);
|
||||
|
||||
GlStateManager.disableDepth();
|
||||
GlStateManager.disableTexture2D();
|
||||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder buffer = tessellator.getBuffer();
|
||||
float mx = c.getX();
|
||||
float my = c.getY();
|
||||
float mz = c.getZ();
|
||||
buffer.begin( GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
|
||||
renderHighLightedBlocksOutline(buffer, mx, my, mz, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
tessellator.draw();
|
||||
|
||||
GlStateManager.enableTexture2D();
|
||||
GlStateManager.enableDepth();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
public static void renderHighLightedBlocksOutline(BufferBuilder buffer, float mx, float my, float mz, float r, float g, float b, float a) {
|
||||
buffer.pos(mx, my, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my + 1, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my + 1, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my + 1, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my + 1, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my + 1, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my + 1, mz).color(r, g, b, a).endVertex();
|
||||
|
||||
buffer.pos(mx, my + 1, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my + 1, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my + 1, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my + 1, mz).color(r, g, b, a).endVertex();
|
||||
|
||||
buffer.pos(mx + 1, my, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my, mz).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my + 1, mz).color(r, g, b, a).endVertex();
|
||||
|
||||
buffer.pos(mx, my, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx + 1, my, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my, mz + 1).color(r, g, b, a).endVertex();
|
||||
buffer.pos(mx, my + 1, mz + 1).color(r, g, b, a).endVertex();
|
||||
}
|
||||
}
|
||||
@@ -43,5 +43,6 @@ public enum InventoryAction
|
||||
ROLL_UP,
|
||||
ROLL_DOWN,
|
||||
AUTO_CRAFT,
|
||||
PLACE_SINGLE
|
||||
PLACE_SINGLE,
|
||||
PLACE_JEI_GHOST_ITEM
|
||||
}
|
||||
|
||||
@@ -19,21 +19,17 @@
|
||||
package appeng.helpers;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.*;
|
||||
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.CraftingManager;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -41,25 +37,32 @@ import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.container.ContainerNull;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.features.AEFeature;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import net.minecraftforge.common.crafting.IShapedRecipe;
|
||||
|
||||
|
||||
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
|
||||
{
|
||||
|
||||
private static final int CRAFTING_GRID_DIMENSION = 3;
|
||||
private static final int CRAFTING_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION;
|
||||
public static final int PROCESSING_INPUT_HEIGHT = 4;
|
||||
public static final int PROCESSING_INPUT_WIDTH = 4;
|
||||
public static final int PROCESSING_INPUT_LIMIT = PROCESSING_INPUT_HEIGHT * PROCESSING_INPUT_WIDTH;
|
||||
private static final int CRAFTING_OUTPUT_LIMIT = 1;
|
||||
public static final int PROCESSING_OUTPUT_LIMIT = 6;
|
||||
|
||||
private final ItemStack patternItem;
|
||||
private final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
private final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||
private final InventoryCrafting crafting;
|
||||
private final InventoryCrafting testFrame;
|
||||
private final ItemStack correctOutput;
|
||||
private final IRecipe standardRecipe;
|
||||
private final IAEItemStack[] condensedInputs;
|
||||
private final IAEItemStack[] condensedOutputs;
|
||||
private final IAEItemStack[] inputs;
|
||||
private final IAEItemStack[] outputs;
|
||||
private final Map<Integer, List<IAEItemStack>> substituteInputs;
|
||||
private final boolean isCrafting;
|
||||
private final boolean canSubstitute;
|
||||
private final Set<TestLookup> failCache = new HashSet<>();
|
||||
@@ -80,6 +83,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
final NBTTagList outTag = encodedValue.getTagList( "out", 10 );
|
||||
this.isCrafting = encodedValue.getBoolean( "crafting" );
|
||||
|
||||
crafting = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
|
||||
testFrame = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
|
||||
|
||||
this.canSubstitute = this.isCrafting && encodedValue.getBoolean( "substitute" );
|
||||
this.patternItem = is;
|
||||
this.pattern = AEItemStack.fromItemStack( is );
|
||||
@@ -143,9 +149,11 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
}
|
||||
}
|
||||
}
|
||||
final int outputLength = out.size();
|
||||
|
||||
this.outputs = out.toArray( new IAEItemStack[out.size()] );
|
||||
this.inputs = in.toArray( new IAEItemStack[in.size()] );
|
||||
this.inputs = in.toArray( new IAEItemStack[isCrafting ? CRAFTING_INPUT_LIMIT : PROCESSING_INPUT_LIMIT] );
|
||||
this.outputs = out.toArray( new IAEItemStack[outputLength] );
|
||||
this.substituteInputs = new HashMap<>( CRAFTING_INPUT_LIMIT );
|
||||
|
||||
final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>();
|
||||
|
||||
@@ -257,6 +265,14 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
|
||||
this.testFrame.setInventorySlotContents( slotIndex, i );
|
||||
|
||||
// If we cannot substitute, the items must match exactly
|
||||
if (!canSubstitute && slotIndex < inputs.length) {
|
||||
if (!inputs[slotIndex].isSameType(i)) {
|
||||
this.markItemAs(slotIndex, i, TestStatus.DECLINE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( this.standardRecipe.matches( this.testFrame, w ) )
|
||||
{
|
||||
final ItemStack testOutput = this.standardRecipe.getCraftingResult( this.testFrame );
|
||||
@@ -268,25 +284,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( AEConfig.instance().isFeatureEnabled( AEFeature.CRAFTING_MANAGER_FALLBACK ) )
|
||||
{
|
||||
final ItemStack testOutput = CraftingManager.findMatchingResult( this.testFrame, w );
|
||||
|
||||
if( Platform.itemComparisons().isSameItem( this.correctOutput, testOutput ) )
|
||||
{
|
||||
this.testFrame.setInventorySlotContents( slotIndex, this.crafting.getStackInSlot( slotIndex ) );
|
||||
this.markItemAs( slotIndex, i, TestStatus.ACCEPT );
|
||||
|
||||
if( AELog.isCraftingDebugLogEnabled() )
|
||||
{
|
||||
this.warnAboutCraftingManager( true );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
this.warnAboutCraftingManager( false );
|
||||
}
|
||||
|
||||
this.markItemAs( slotIndex, i, TestStatus.DECLINE );
|
||||
return false;
|
||||
@@ -328,6 +325,97 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
return this.canSubstitute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IAEItemStack> getSubstituteInputs(int slot) {
|
||||
if (this.inputs[slot] == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return this.substituteInputs.computeIfAbsent(slot, value -> {
|
||||
ItemStack[] matchingStacks = getRecipeIngredient(slot).getMatchingStacks();
|
||||
List<IAEItemStack> itemList = new ArrayList<>(matchingStacks.length + 1);
|
||||
for (ItemStack matchingStack : matchingStacks) {
|
||||
itemList.add(AEItemStack.fromItemStack(matchingStack));
|
||||
}
|
||||
|
||||
// Ensure that the specific item put in by the user is at the beginning,
|
||||
// so that it takes precedence over substitutions
|
||||
itemList.add(0, this.inputs[slot]);
|
||||
return itemList;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Ingredient} from the actual used recipe for a given slot-index into {@link #getInputs()}.
|
||||
* <p/>
|
||||
* Conversion is needed for two reasons: our sparse ingredients are always organized in a 3x3 grid, while Vanilla's
|
||||
* ingredient list will be condensed to the actual recipe's grid size. In addition, in our 3x3 grid, the user can
|
||||
* shift the actual recipe input to the right and down.
|
||||
*/
|
||||
private Ingredient getRecipeIngredient(int slot) {
|
||||
|
||||
if (standardRecipe instanceof IShapedRecipe ) {
|
||||
IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe;
|
||||
|
||||
return getShapedRecipeIngredient(slot, shapedRecipe.getRecipeWidth());
|
||||
} else {
|
||||
return getShapelessRecipeIngredient(slot);
|
||||
}
|
||||
}
|
||||
|
||||
private Ingredient getShapedRecipeIngredient(int slot, int recipeWidth) {
|
||||
// Compute the offset of the user's input vs. crafting grid origin
|
||||
// Which is >0 if they have empty rows above or to the left of their input
|
||||
int topOffset = 0;
|
||||
if (inputs[0] == null && inputs[1] == null && inputs[2] == null) {
|
||||
topOffset++; // First row is fully empty
|
||||
if (inputs[3] == null && inputs[4] == null && inputs[5] == null) {
|
||||
topOffset++; // Second row is fully empty
|
||||
}
|
||||
}
|
||||
int leftOffset = 0;
|
||||
if (inputs[0] == null && inputs[3] == null && inputs[6] == null) {
|
||||
leftOffset++; // First column is fully empty
|
||||
if (inputs[1] == null && inputs[4] == null && inputs[7] == null) {
|
||||
leftOffset++; // Second column is fully empty
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the x,y of the slot, as-if the recipe was anchored to 0,0
|
||||
int slotX = slot % CRAFTING_GRID_DIMENSION - leftOffset;
|
||||
int slotY = slot / CRAFTING_GRID_DIMENSION - topOffset;
|
||||
|
||||
// Compute the index into the recipe's ingredient list now
|
||||
int ingredientIndex = slotY * recipeWidth + slotX;
|
||||
|
||||
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
|
||||
|
||||
if (ingredientIndex < 0 || ingredientIndex > ingredients.size()) {
|
||||
return Ingredient.EMPTY;
|
||||
}
|
||||
|
||||
return ingredients.get(ingredientIndex);
|
||||
}
|
||||
|
||||
private Ingredient getShapelessRecipeIngredient(int slot) {
|
||||
// We map the list of *filled* sparse inputs to the shapeless (ergo unordered)
|
||||
// ingredients. While these do not actually correspond to each other,
|
||||
// since both lists have the same length, the mapping is at least stable.
|
||||
int ingredientIndex = 0;
|
||||
for (int i = 0; i < slot; i++) {
|
||||
if (inputs[i] != null) {
|
||||
ingredientIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
|
||||
if (ingredientIndex < ingredients.size()) {
|
||||
return ingredients.get(ingredientIndex);
|
||||
}
|
||||
|
||||
return Ingredient.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getOutput( final InventoryCrafting craftingInv, final World w )
|
||||
{
|
||||
@@ -406,24 +494,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
return this.pattern.hashCode();
|
||||
}
|
||||
|
||||
private void warnAboutCraftingManager( boolean foundAlternative )
|
||||
{
|
||||
final String foundAlternativeRecipe = foundAlternative ? "Found alternative recipe." : "NOT FOUND, please report.";
|
||||
|
||||
final StringJoiner joinActualInputs = new StringJoiner( ", " );
|
||||
for( int j = 0; j < this.testFrame.getSizeInventory(); j++ )
|
||||
{
|
||||
final ItemStack stack = this.testFrame.getStackInSlot( j );
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
joinActualInputs.add( stack.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
AELog.warn( "Using CraftingManager fallback: Recipe <%s> for output <%s> rejected inputs [%s]. %s",
|
||||
this.standardRecipe.getRegistryName(), this.standardRecipe.getRecipeOutput(), joinActualInputs, foundAlternativeRecipe );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( final Object obj )
|
||||
{
|
||||
|
||||
@@ -187,21 +187,15 @@ public class TickHandler
|
||||
if( ev.type == Type.WORLD && ev.phase == Phase.END )
|
||||
{
|
||||
final WorldTickEvent wte = (WorldTickEvent) ev;
|
||||
synchronized( this.craftingJobs )
|
||||
synchronized ( this.craftingJobs )
|
||||
{
|
||||
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
|
||||
if( !jobSet.isEmpty() )
|
||||
{
|
||||
final int simTime = Math.max( 1, AEConfig.instance().getCraftingCalculationTimePerTick() / jobSet.size() );
|
||||
final Iterator<CraftingJob> i = jobSet.iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final CraftingJob cj = i.next();
|
||||
if( !cj.simulateFor( simTime ) )
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
if (!jobSet.isEmpty()) {
|
||||
final int jobSize = jobSet.size();
|
||||
final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000;
|
||||
final int simTime = Math.max(1, microSecondsPerTick / jobSize);
|
||||
|
||||
jobSet.removeIf( cj -> !cj.simulateFor( simTime ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class GrinderRecipes
|
||||
final ItemStack s2 = CTModule.toStack( secondary2Output );
|
||||
if( !s2.isEmpty() )
|
||||
{
|
||||
builder.withFirstOptional( s2, secondary2Chance == null ? 1.0f : secondary2Chance );
|
||||
builder.withSecondOptional( s2, secondary2Chance == null ? 1.0f : secondary2Chance );
|
||||
}
|
||||
CTModule.MODIFICATIONS.add( new Add( builder.build() ) );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package appeng.integration.modules.gregtech;
|
||||
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
|
||||
{
|
||||
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
|
||||
{
|
||||
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
|
||||
{
|
||||
// Attempt getting an IItemHandler for the given side via caps
|
||||
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
|
||||
if (itemHandler != null)
|
||||
{
|
||||
return new GTCEItemHandler(itemHandler);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract boolean canRemoveAllExceptCircuits();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package appeng.integration.modules.gregtech;
|
||||
|
||||
import appeng.util.inv.ItemHandlerIterator;
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class GTCEItemHandler extends GTCEInventoryAdaptor
|
||||
{
|
||||
ArrayList<Integer> GTCElenses = new ArrayList<>(Arrays.asList(15085,15214,15092,15111,15113,15219,15218,15243,15244,15209,15117,15206,15216,15331,15212,15213,15154,15122,15157,15190,15247));
|
||||
ArrayList<Integer> GTCEmolds = new ArrayList<>(Arrays.asList(32301,32303,32304,32305,32306,32307,32308,32309,32313,32314,32315,32317,32350,32351,32352,32353,32354,32355,32356,32358,32359,32360,32361,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373));
|
||||
Item smallGearExtruderShape = Item.getByNameOrId("contenttweaker:smallgearextrudershape");
|
||||
Item creativePortableTankMold = Item.getByNameOrId("contenttweaker:creativeportabletankmold");
|
||||
|
||||
protected final IItemHandler itemHandler;
|
||||
|
||||
public GTCEItemHandler(IItemHandler itemHandler)
|
||||
{
|
||||
this.itemHandler = itemHandler;
|
||||
}
|
||||
|
||||
boolean isBlockableItem(ItemStack stack)
|
||||
{
|
||||
if ( stack.getItem() == Item.getByNameOrId("gregtech:meta_item_1") ) {
|
||||
int metadata = stack.getItemDamage();
|
||||
if ( metadata == 32766 || GTCElenses.contains(metadata) || GTCEmolds.contains(metadata)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( stack.getItem() == smallGearExtruderShape ) return false;
|
||||
if ( stack.getItem() == creativePortableTankMold) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRemoveAllExceptCircuits()
|
||||
{
|
||||
int slots = this.itemHandler.getSlots();
|
||||
for ( int slot = 0; slot < slots; slot++ ) {
|
||||
ItemStack is = this.itemHandler.getStackInSlot(slot);
|
||||
if ( is.isEmpty() || !isBlockableItem(is) ) continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ItemSlot> iterator()
|
||||
{
|
||||
return new ItemHandlerIterator( this.itemHandler );
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ class GrinderRecipeCategory implements IRecipeCategory<GrinderRecipeWrapper>, IR
|
||||
this.localizedName = I18n.format( "tile.appliedenergistics2.grindstone.name" );
|
||||
|
||||
ResourceLocation location = new ResourceLocation( AppEng.MOD_ID, "textures/guis/grinder.png" );
|
||||
this.background = guiHelper.createDrawable( location, 11, 16, 154, 64 );
|
||||
this.background = guiHelper.createDrawable( location, 11, 16, 154, 70 );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,20 +19,22 @@
|
||||
package appeng.integration.modules.jei;
|
||||
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import appeng.client.gui.AEGuiHandler;
|
||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import mezz.jei.api.*;
|
||||
import mezz.jei.config.Constants;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import mezz.jei.api.IJeiRuntime;
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.IModRegistry;
|
||||
import mezz.jei.api.ISubtypeRegistry;
|
||||
import mezz.jei.api.recipe.IRecipeCategoryRegistration;
|
||||
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
|
||||
|
||||
@@ -55,6 +57,9 @@ import appeng.items.parts.ItemFacade;
|
||||
@mezz.jei.api.JEIPlugin
|
||||
public class JEIPlugin implements IModPlugin
|
||||
{
|
||||
public static IJeiRuntime runtime;
|
||||
public static AEGuiHandler aeGuiHandler;
|
||||
|
||||
@Override
|
||||
public void registerItemSubtypes( ISubtypeRegistry subtypeRegistry )
|
||||
{
|
||||
@@ -86,12 +91,13 @@ public class JEIPlugin implements IModPlugin
|
||||
this.registerDescriptions( definitions, registry );
|
||||
|
||||
// Allow recipe transfer from JEI to crafting and pattern terminal
|
||||
registry.getRecipeTransferRegistry()
|
||||
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ),
|
||||
VanillaRecipeCategoryUid.CRAFTING );
|
||||
registry.getRecipeTransferRegistry()
|
||||
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ),
|
||||
VanillaRecipeCategoryUid.CRAFTING );
|
||||
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), VanillaRecipeCategoryUid.CRAFTING );
|
||||
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
|
||||
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerExpandedProcessingPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
|
||||
|
||||
aeGuiHandler = new AEGuiHandler();
|
||||
registry.addAdvancedGuiHandlers( aeGuiHandler );
|
||||
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler );
|
||||
}
|
||||
|
||||
private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
|
||||
@@ -203,7 +209,7 @@ public class JEIPlugin implements IModPlugin
|
||||
{
|
||||
Optional<Item> itemFacade = definitions.items().facade().maybeItem();
|
||||
Optional<ItemStack> cableAnchor = definitions.parts().cableAnchor().maybeStack( 1 );
|
||||
if( itemFacade.isPresent() && cableAnchor.isPresent() )
|
||||
if( itemFacade.isPresent() && cableAnchor.isPresent() && AEConfig.instance().isFeatureEnabled( AEFeature.ENABLE_FACADE_CRAFTING ) )
|
||||
{
|
||||
registry.addRecipeRegistryPlugin( new FacadeRegistryPlugin( (ItemFacade) itemFacade.get(), cableAnchor.get() ) );
|
||||
}
|
||||
@@ -214,5 +220,6 @@ public class JEIPlugin implements IModPlugin
|
||||
{
|
||||
JEIModule jeiModule = (JEIModule) Integrations.jei();
|
||||
jeiModule.setJei( new JeiRuntimeAdapter( jeiRuntime ) );
|
||||
runtime = jeiRuntime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
|
||||
import mezz.jei.transfer.RecipeTransferErrorInternal;
|
||||
import mezz.jei.transfer.RecipeTransferErrorTooltip;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.Slot;
|
||||
@@ -66,15 +72,47 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
@Override
|
||||
public IRecipeTransferError transferRecipe( T container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer, boolean doTransfer )
|
||||
{
|
||||
final String recipeType = recipeLayout.getRecipeCategory().getUid();
|
||||
|
||||
if (recipeType.equals( VanillaRecipeCategoryUid.INFORMATION) || recipeType.equals(VanillaRecipeCategoryUid.FUEL))
|
||||
{
|
||||
return RecipeTransferErrorInternal.INSTANCE;
|
||||
}
|
||||
|
||||
if( !doTransfer )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if( container instanceof ContainerPatternTerm )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( !( (ContainerPatternTerm) container ).isCraftingMode() )
|
||||
{
|
||||
if( recipeType.equals( VanillaRecipeCategoryUid.CRAFTING ) )
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", "1" ) );
|
||||
}
|
||||
}
|
||||
else if( !recipeType.equals( VanillaRecipeCategoryUid.CRAFTING ) )
|
||||
{
|
||||
|
||||
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", "0" ) );
|
||||
}
|
||||
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Map<Integer, ? extends IGuiIngredient<ItemStack>> ingredients = recipeLayout.getItemStacks().getGuiIngredients();
|
||||
|
||||
final NBTTagCompound recipe = new NBTTagCompound();
|
||||
final NBTTagList outputs = new NBTTagList();
|
||||
|
||||
|
||||
int slotIndex = 0;
|
||||
for( Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> ingredientEntry : ingredients.entrySet() )
|
||||
@@ -82,6 +120,13 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
IGuiIngredient<ItemStack> ingredient = ingredientEntry.getValue();
|
||||
if( !ingredient.isInput() )
|
||||
{
|
||||
ItemStack output = ingredient.getDisplayedIngredient();
|
||||
if( output != null )
|
||||
{
|
||||
final NBTTagCompound tag = new NBTTagCompound();
|
||||
output.writeToNBT( tag );
|
||||
outputs.appendTag( tag );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -102,8 +147,12 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
}
|
||||
|
||||
// prefer pure crystals.
|
||||
for( ItemStack stack : ingredient.getAllIngredients() )
|
||||
for ( ItemStack stack : ingredient.getAllIngredients() )
|
||||
{
|
||||
if( stack == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( Platform.isRecipePrioritized( stack ) )
|
||||
{
|
||||
list.add( 0, stack );
|
||||
@@ -114,7 +163,7 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
}
|
||||
}
|
||||
|
||||
for( final ItemStack is : list )
|
||||
for ( final ItemStack is : list )
|
||||
{
|
||||
final NBTTagCompound tag = new NBTTagCompound();
|
||||
is.writeToNBT( tag );
|
||||
@@ -130,6 +179,8 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
slotIndex++;
|
||||
}
|
||||
|
||||
recipe.setTag( "outputs", outputs );
|
||||
|
||||
try
|
||||
{
|
||||
NetworkHandler.instance().sendToServer( new PacketJEIRecipe( recipe ) );
|
||||
|
||||
@@ -35,6 +35,8 @@ public enum TheOneProbeText
|
||||
P2P_UNLINKED,
|
||||
P2P_INPUT_ONE_OUTPUT,
|
||||
P2P_INPUT_MANY_OUTPUTS,
|
||||
P2P_OUTPUT_ONE_INPUT,
|
||||
P2P_OUTPUT_MANY_INPUTS,
|
||||
P2P_OUTPUT,
|
||||
P2P_FREQUENCY,
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user