Compare commits

...

110 Commits

Author SHA1 Message Date
A. Regnander 83d661ab2a Create sv_se.json (#4485) 2020-07-20 21:33:44 +02:00
shartte a537bcf0ee Merge pull request #4486 from AppliedEnergistics/number-entry-dialogs
Number Entry Dialogs
2020-07-20 20:13:04 +02:00
Sebastian Hartte 590e435ad6 Formatting fixes 2020-07-19 23:51:57 +02:00
Sebastian Hartte 8d92a51e4f Formatting fixes 2020-07-19 23:50:47 +02:00
Sebastian Hartte 4322910614 Added labels that specify the unit of power (AE) and the unit of fluid (mB) for the level emitters. 2020-07-19 23:50:18 +02:00
Sebastian Hartte ebe589a714 Ported the other number entry dialogs over to the shared widget. 2020-07-19 23:25:11 +02:00
Sebastian Hartte 6187e6a7bb Started refactoring number entry dialogs to use shared code. 2020-07-19 20:04:08 +02:00
shartte d5f113eb35 Merge pull request #4484 from AppliedEnergistics/energy-grid-failfast
Guard Against Concurrent EnergyGrid Modifications
2020-07-19 17:56:22 +02:00
shartte 9ad5bb21c0 Merge pull request #4480 from AppliedEnergistics/mb-fixes
Fix more MultiBlock issues
2020-07-19 17:31:06 +02:00
Sebastian Hartte 1c88ea7b78 Fail faster when something modifies the list of energy providers/requesters while an extract/inject operation is ongoing, since this would lead to ConcurrentModificationExceptions later, without a way of tracking down what caused the modification in the first place. 2020-07-19 16:39:37 +02:00
shartte 5a976ebfae Merge pull request #4483 from AppliedEnergistics/texture-cleanup
Texture Cleanup
2020-07-19 16:20:32 +02:00
Sebastian Hartte b45669bb82 Removed several unchecked casts. 2020-07-19 16:01:19 +02:00
Sebastian Hartte e52cc40dbf JSON Formatting Fix 2020-07-19 16:00:01 +02:00
Sebastian Hartte 8a20d3c1d7 Consolidated fluid models to reuse the item counterparts with different textures. 2020-07-19 15:00:46 +02:00
Sebastian Hartte 749ebeb91d Moved part textures from parts to part to be consistent with singular naming used in Minecraft (and for the model directory). 2020-07-19 14:14:18 +02:00
Sebastian Hartte 82586732e3 Removed unused crafting and fluid terminal models and associated textures.
Unified naming for textures used by the fluid terminal.
2020-07-19 14:09:57 +02:00
Sebastian Hartte e023d83e62 Deleted unused matrix frame related documentation images. 2020-07-19 13:40:42 +02:00
Sebastian Hartte de7cbc4949 Moved part-related textures from textures/item/part to textures/parts/ and adapted the level emitter item models to use the normal part texture. 2020-07-19 13:37:23 +02:00
Sebastian Hartte 71a91e51fb Naming improvements 2020-07-19 13:16:50 +02:00
yueh 223163aa0a Fixes #4330: Avoid mutating the input stack (#4481) 2020-07-19 13:13:20 +02:00
Sebastian Hartte bdd22093c3 Account for empty messages when drawing tooltips. 2020-07-19 12:05:26 +02:00
Sebastian Hartte 0367b35ce0 Never return null from Widget#getMessage since the
narrator will always dereference it, leading to a crash.
2020-07-19 12:04:15 +02:00
yueh 755ac12b8a Fix SortedSet using compare for equals (#4479)
Fix SortedSet using compare for equals
2020-07-19 11:43:20 +02:00
Sebastian Hartte e1f9e01404 Force cluster-rebuilds on the first detected change, if their bounds do not match.
Also use a client-side method to update connected textures
for crafting cubes if two previously distinct clusters are connected.
Refactored MBCalculator to use generics for type checks and remove more casts.
2020-07-19 00:16:33 +02:00
Sebastian Hartte 7121426fc9 Disable AO for the Spatial Pylon due to artifacts. 2020-07-19 00:12:35 +02:00
yueh a94e8504f8 Correctly convert milliseconds to microseconds (#4478) 2020-07-18 20:51:30 +02:00
yueh 9275bfe001 Split TickHandler#onTick into more specific event handlers (#4477) 2020-07-18 19:35:33 +02:00
shartte 5b3c4aef79 When blocks adjacent to multiblock-capable blocks are updated, (#4474)
do not always recalculate existing multiblocks. Only do so,
if the adjacent block is either part of the multiblock's bounding
box, or if the adjacent block would be a valid part of the multiblock.
2020-07-18 18:18:24 +02:00
yueh 4a289470e2 Added a priority to IAEPowerStorage (#4473)
Added a priority to IAEPowerStorage
2020-07-18 18:06:05 +02:00
shartte d79c0f642c Do not allow recursive creation of multiblocks. (#4472) 2020-07-18 18:00:40 +02:00
aoisensi 9ecad8749f Added new japanese translate (#4475)
* Added new japanese translate
2020-07-18 12:38:23 +02:00
shartte e8b57c6dc5 Multiblocks sometimes can't be broken because during removal, (#4469)
they update their own block-state to display the disconnected
state, effectively reversing their own removal. This occurs
because the cached block state in the tile entity base class is
outdated and doesn't reflect the removal.
2020-07-17 22:35:49 +02:00
shartte 8142eb90a6 Added new Cell Rendering to ME Chest (#4464)
Moved cell models to origin 0,0,0.
Implemented a TER to render cell models/LED in the ME chest as they are rendered in the drive.
2020-07-17 20:37:07 +02:00
Sebastian Hartte 08abd4a770 Fixed formatting. 2020-07-17 20:26:17 +02:00
Sebastian Hartte b8722dbbc0 Do not rely on exceptions for control flow, when the
cell has no fuzzy mode.
2020-07-17 19:51:59 +02:00
Sebastian Hartte 1ac6d5d967 Fixes creation of entangled singularities. 2020-07-17 15:27:03 +02:00
Sebastian Hartte 5c290789e0 Fixes #4467: Private methods also need to be annotated with @OnlyIn(Dist.CLIENT)
if they use client-side classes.
2020-07-17 12:45:17 +02:00
yueh 38f6bf16f2 Updated dependencies (#4466)
Changed forge to 31.2.31 and also marked it as required version.
Changed JEI to 6.0.2.12 for dev usage.
2020-07-15 23:25:35 +02:00
Sebastian Hartte 4953509255 P2P Fluid Tunnel Fix 2020-07-13 17:45:40 +02:00
Sebastian Hartte 188f105730 Fix the alive check for the matter cannon. 2020-07-12 17:20:42 +02:00
yueh 9bb23bcac8 Refactored crafting patterns (#4458)
* Deduplicate crafting patterns internals

This should save a bit memory for duplicate patterns as well as speed up
loading new patterns on reloading chunks.

* Encode recipe id in pattern
* Use the recipe id directly for looking it up
* Slightly refactored how patterns encode whether they are crafting patterns or not.
* Renamed PatternHelper.
* Added APIs to encode patterns. (#4463)
* Removed ICraftingPatternItem.
* Renamed isCrafting to isCraftable

Co-authored-by: shartte <shartte@users.noreply.github.com>
2020-07-12 16:21:30 +02:00
yueh 06735f5c39 Rewrite drive model to support custom cell models (#4459)
* Rewrite driver model to support custom cell models

Each cell can now register a mapping Item -> ResourceLocation for a
custom cell model. Fallback will always be a 1k item cell.
2020-07-11 23:07:20 +02:00
shartte e8143d3618 Merge pull request #4462 from AppliedEnergistics/aeplugin-loader
Restored the old PluginLoader as AddonLoader
2020-07-11 21:00:58 +02:00
yueh 0d43ca15be Removed AEApi
Moved all internal access to the internal `Api` class using a new static
getter.
2020-07-11 19:40:34 +02:00
yueh d18eabe1fc Restored the old PluginLoader as AddonLoader
Introduce a new `IAEAddon` interface, which has to be implemented and
annotated wit `@AEAddon` to obtain access to our public API.
2020-07-11 18:40:51 +02:00
yueh d9d491d51c Removed deprecated API parts (#4457) 2020-07-10 19:35:29 +02:00
yueh 9a5bd114a4 Updated IStorageCell docs to mention int limitations. 2020-07-10 16:04:30 +02:00
Sebastian Hartte 30cc8c8abc Changed Javadoc for Upgrade tooltip group 2020-07-07 20:43:56 +02:00
shartte 815094e5bf Merge pull request #4454 from AppliedEnergistics/fix-4453
Fixes #4453: Avoid using clientside methods serverside.
2020-07-07 20:23:54 +02:00
yueh 1eaddef694 Fixes #4453: Avoid using clientside methods serverside. 2020-07-07 18:13:32 +02:00
yueh 450299cb67 Updated README.md
Removed crafttweaker info. Will be moved to a wiki page when necessary
again.
Updated API part with the info about github packages and also moved it
higher.
2020-07-07 12:39:37 +02:00
yueh 235fc2e81f Removed superfluous IAEStack methods 2020-07-07 12:12:48 +02:00
yueh 92fb39d53a Added curseforge task 2020-07-07 10:21:58 +02:00
Sebastian Hartte eb0e4289b3 Unify the client/server-side shared itemstack registry to avoid over-dependence on the current thread
when this class is used. Otherwise if a thread is not correctly detected to be part of the server or client
thread groups, a shared item stack from the wrong domain is returned.
2020-07-05 12:23:16 +02:00
Sebastian Hartte ebbb5b1059 Removed unused storage dimension cap. 2020-07-05 12:22:06 +02:00
yueh d4a1590b51 Added a blocktag for movable tile entities with spatial IO. (#4448)
`#spatial/whitelist` needs to be explicitly enabled through a config
value.
`#spatial/blacklist` will always be consider on top of the normal
blacklist.
2020-07-03 20:34:53 +02:00
yueh bd1d9701a9 Try to fail with missing assets (#4449) 2020-07-03 20:31:41 +02:00
yueh 4b3a232add Fix formatting 2020-07-03 20:07:51 +02:00
Sebastian Hartte b8aa810a5f Add equals(ItemStack) to IAEItemStack contract. 2020-07-03 14:32:48 +02:00
yueh 22facb9748 Don't tick debug energy tileentity clientside 2020-07-03 13:56:22 +02:00
yueh ef3cc8a0a0 Enables replicator card to place multiple instances at once. (#4447) 2020-07-03 13:04:12 +02:00
Sebastian Hartte 55b3dc0823 Removed unused class. 2020-07-02 23:22:40 +02:00
shartte 9445fad5a6 Merge pull request #4446 from AppliedEnergistics/removed-part-type
Part type's gone!
2020-07-02 13:49:46 +02:00
shartte 1a7bac1fcc Merge pull request #4438 from AppliedEnergistics/drive-state-sync
Refactored drive state sync
2020-07-02 12:18:40 +02:00
shartte 19dee8d339 Merge pull request #4443 from AppliedEnergistics/cable-bus-redstone-connections
Refactored CableBus to pass the direction directly.
2020-07-02 12:17:54 +02:00
shartte a4f66c5923 Merge pull request #4444 from AppliedEnergistics/update-mappings
Update MCP mappings
2020-07-02 12:17:21 +02:00
Sebastian Hartte fe439bfb23 Part type's gone! 2020-07-02 12:05:34 +02:00
yueh 25da0b7357 Removed unused code from DriveLedTER 2020-07-02 11:37:59 +02:00
shartte a2344f52e1 Merge pull request #4445 from AppliedEnergistics/materials-rework
Changed AEGlassMaterial to Materials
2020-07-02 10:55:32 +02:00
yueh bafc65d3a8 Changed AEGlassMaterial to Materials
Preparation in case we need more to support custom non solid, non
opaque, or similar blocks.
Removed custom fullSize/opaque blocks in favour of Material
2020-07-02 09:57:47 +02:00
shartte 4e8296d3e7 Merge pull request #4442 from AppliedEnergistics/cleanups
Reduce Importance of PartType and Fix Upgrade Card Tooltip Grouping
2020-07-02 09:41:00 +02:00
Sebastian Hartte 26eeeb4c75 Fix player id logging. 2020-07-02 09:25:38 +02:00
Sebastian Hartte f573b52b1b Be more lenient with the return value of BlockItem.tryPlace (it might be CONSUME in future versions). 2020-07-02 01:12:53 +02:00
Sebastian Hartte a1042384e3 Minor simplification of PartPlacement. 2020-07-02 01:09:17 +02:00
yueh 1ce82cc3b9 Update MCP mappings 2020-07-01 20:23:27 +02:00
yueh 7dffbf78ce Refactored CableBus to pass the direction directly. 2020-07-01 19:56:39 +02:00
yueh 0f11c1e0a4 Hide debug tools from JEI when disabled via config (#4439) 2020-07-01 14:29:43 +02:00
yueh 77b544ce4f Refactored drive state sync
Removed blinking state for now
2020-07-01 14:22:07 +02:00
Sebastian Hartte c67dba2f13 Removed reliance on PartType from code outside of Bootstrapping,
and restored ability to group different supported items on
Upgrade Card tooltips.
2020-07-01 00:56:17 +02:00
Sebastian Hartte 400fcdb633 Formatting fix 2020-07-01 00:50:37 +02:00
Sebastian Hartte fba157a707 Removed unused ItemPredicate 2020-07-01 00:44:48 +02:00
Sebastian Hartte 538965e74a Crash when someone tries to overwrite existing grid cache implementations. 2020-07-01 00:44:48 +02:00
shartte 0a56c724ed Merge pull request #4441 from AppliedEnergistics/cleanups
Minor Cleanups / Refactoring
2020-07-01 00:30:25 +02:00
Sebastian Hartte 8d8d3dd2d7 Minor refactoring.
Replaced use of reflection with use of functional factory interface (API change).
2020-06-30 18:58:30 +02:00
Sebastian Hartte d17f8cec92 Removed unused fields. 2020-06-30 18:39:34 +02:00
Sebastian Hartte d0acc9ccf1 Removed reliance of TickTracker on implementation detail to generate additional crash information. 2020-06-30 18:34:36 +02:00
yueh 17b919a171 Mark CableBusBlock as variableOpacity. 2020-06-30 15:37:34 +02:00
yueh 003ef8672c Added cullface to drive cell models. 2020-06-30 10:27:22 +02:00
Sebastian Hartte eaf2873649 Render all sides of the cell models regardless of cullface. 2020-06-29 22:39:34 +02:00
yueh 66d00a4600 Use our own TransparencyState.
ObfuscationReflectionHelper is a massive performance issue.
2020-06-29 22:17:39 +02:00
yueh d79d284690 Fix formatting 2020-06-29 22:17:25 +02:00
Sebastian Hartte 7233b11284 Fix TinyTNT not spawning the correct entity client-side (and the renderer using the wrong shadow). 2020-06-29 21:14:58 +02:00
Sebastian Hartte d5491549eb Fixes TinyTNT not being primable with flint & steel. 2020-06-29 21:01:30 +02:00
Sebastian Hartte f943106419 Fix serialization of 0-amount fluidstacks which is required for properly updating an ME inventory where an existing fluid stack should be fully removed. (I.e. Taking out the last amount of a given fluid via a terminal). 2020-06-29 17:13:04 +02:00
Sebastian Hartte 57fa5576af Fix rendering of the dummy fluid item (i.e. in cell workbenches, fluid terminals are unaffected). 2020-06-29 15:32:49 +02:00
Sebastian Hartte 346e58ff25 Remove duplicate registration of disassembly recipes. 2020-06-29 02:58:52 +02:00
Sebastian Hartte 42c2be5c05 Add version constraint on Forge. 2020-06-29 02:57:38 +02:00
Sebastian Hartte 312abce956 Removed unused interface. 2020-06-28 23:58:36 +02:00
Sebastian Hartte 6379cfe3a2 Removed unused interface. 2020-06-28 23:57:19 +02:00
yueh 208cd70725 Readded cullface to drive model.
Also fixed a debug machine
2020-06-28 20:59:51 +02:00
yueh 130fc74768 Render cells in offline drives as offline. 2020-06-28 20:01:22 +02:00
yueh 6bbea481b8 Grid connections to the front of a drive are no longer valid. 2020-06-28 19:35:19 +02:00
yueh 55d7ac82e5 Removed no channels pathing.
Also use default values for features without a config option
2020-06-28 19:19:05 +02:00
yueh 4ee44970b6 Forgot github token 2020-06-27 16:28:45 +02:00
yueh e323e08192 Merge build and publish steps 2020-06-27 16:17:45 +02:00
yueh 3faab6ae25 Reenable maven publish 2020-06-27 16:03:46 +02:00
yueh 3c53fddd8e Added content type for release assets 2020-06-27 15:53:12 +02:00
yueh f3233d948b Sign jars (#4435) 2020-06-27 15:30:07 +02:00
yueh d5eb16a6b0 Updated README.md 2020-06-25 22:27:55 +02:00
yueh 200ca8d9cc Publish api, sources, and javadoc artifacts 2020-06-25 22:21:11 +02:00
860 changed files with 6135 additions and 5702 deletions
+4
View File
@@ -21,9 +21,13 @@ jobs:
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Validate no assets
run: test ! -d ./src/generated
- name: Generate assets
uses: GabrielBB/xvfb-action@v1.2
with:
run: ./gradlew runData --no-daemon
- name: Validate assets
run: test -d ./src/generated
- name: Build with Gradle
run: ./gradlew build --no-daemon
+4
View File
@@ -21,9 +21,13 @@ jobs:
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Validate no assets
run: test ! -d ./src/generated
- name: Generate assets
uses: GabrielBB/xvfb-action@v1.2
with:
run: ./gradlew runData --no-daemon
- name: Validate assets
run: test -d ./src/generated
- name: Build with Gradle
run: ./gradlew build --no-daemon
+4
View File
@@ -21,10 +21,14 @@ jobs:
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Validate no assets
run: test ! -d ./src/generated
- name: Generate assets
uses: GabrielBB/xvfb-action@v1.2
with:
run: ./gradlew runData --no-daemon
- name: Validate assets
run: test -d ./src/generated
- name: Build with Gradle
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
+46 -14
View File
@@ -2,7 +2,7 @@ name: 'Release'
on:
release:
types: [created]
types: [published]
jobs:
build:
@@ -11,8 +11,16 @@ jobs:
steps:
- name: Validate semver
env:
RELEASE: ${{ github.event.release.tag_name }}
run: echo $RELEASE | grep -oP '^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
TAG: ${{ github.event.release.tag_name }}
run: |
echo $TAG | grep -oP '^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
echo "::set-env name=RELEASE::${TAG:1}"
- name: Export keystore
env:
KEY_STORE: ${{ secrets.KEY_STORE }}
run: |
echo $KEY_STORE | base64 -d > $HOME/keystore.jks
echo "::set-env name=KEY_STORE_FILE::$HOME/keystore.jks"
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
@@ -20,23 +28,47 @@ jobs:
java-version: 1.8
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Use gradle cache for faster builds
uses: actions/cache@v1
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Validate no assets
run: test ! -d ./src/generated
- name: Generate assets
uses: GabrielBB/xvfb-action@v1.2
env:
RELEASE: ${{ github.event.release.tag_name }}
with:
run: ./gradlew runData --no-daemon
- name: Validate assets
run: test -d ./src/generated
- name: Build with Gradle
env:
RELEASE: ${{ github.event.release.tag_name }}
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build --no-daemon
- name: Publish package
- name: Upload to curseforge
env:
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
CHANGELOG: ${{ github.event.release.body }}
CURSEFORGE: ${{ secrets.CURSEFORGE }}
run: ./gradlew curseforge --no-daemon
- name: Publish to github packages
env:
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew publish --no-daemon
- name: Prepare artifact metadata
id: prepare_artifact_metadata
run: |
echo ::set-output name=ARTIFACT_PATH::./build/libs/appliedenergistics2-${RELEASE}.jar
echo ::set-output name=ARTIFACT_NAME::appliedenergistics2-${RELEASE}.jar
- name: Upload Release Artifact
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE: ${{ github.event.release.tag_name }}
run: ./gradlew publish --no-daemon
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ${{ steps.prepare_artifact_metadata.outputs.ARTIFACT_PATH }}
asset_name: ${{ steps.prepare_artifact_metadata.outputs.ARTIFACT_NAME }}
asset_content_type: application/zip
+35 -63
View File
@@ -1,5 +1,6 @@
[![Build master](https://img.shields.io/github/workflow/status/AppliedEnergistics/Applied-Energistics-2/Build%20master?style=flat-square)](https://github.com/AppliedEnergistics/Applied-Energistics-2/actions?query=workflow%3A%22Build+master%22)
[![Latest Release](https://img.shields.io/github/v/release/AppliedEnergistics/Applied-Energistics-2?label=Latest%20Release&style=flat-square)](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases)
[![Latest Release](https://img.shields.io/github/v/release/AppliedEnergistics/Applied-Energistics-2?style=flat-square&label=Release)](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases)
[![Latest PreRelease](https://img.shields.io/github/v/release/AppliedEnergistics/Applied-Energistics-2?include_prereleases&style=flat-square&label=Pre)](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases)
# Applied Energistics 2
@@ -11,10 +12,9 @@
* [Downloads](#downloads)
* [Installation](#installation)
* [Issues](#issues)
* [API](#applied-energistics-2-api)
* [Building](#building)
* [Contribution](#contribution)
* [API](#applied-energistics-2-api)
* [CraftTweaker](#applied-energistics-2-crafttweaker)
* [Localization](#applied-energistics-2-localization)
* [Credits](#credits)
@@ -66,6 +66,38 @@ Providing as many details as possible does help us to find and resolve the issue
Please note that we might close any issue not matching these requirements.
## 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.
### Maven
We use Github Packages as maven repository now. You can use the following snippet as example on how to add a repository to your gradle build file.
repositories {
maven {
name "AE2"
url "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2"
}
}
When compiling against the AE2 API you can use gradle dependencies, just add
dependencies {
compileOnly "appeng:appliedenergistics2:VERSION:api"
}
or add the `compileOnly` line to your existing dependencies task to your build.gradle.
Replace `VERSION` with the desired one. With 1.15+ we switched to using [semver](https://semver.org/).
It is highly recommended following its specification and further considering an upper bound for the dependency version.
A change of the `MAJOR` version will be an API break and can lead to various crashes. Better to inform a player about the addon not supporting the new version until it could be tested or updated.
An example string would be `appeng:appliedenergistics2:7.0.0-alpha.6:api` for the API only or `appeng:appliedenergistics2:7.0.0-alpha.6` for the whole mod.
Builds obtained [here](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases) or via [maven](https://github.com/AppliedEnergistics/Applied-Energistics-2/packages) should work in a development environment.
However the dependency might need to be wrapped in `fg.deobf()` like `runtimeOnly fg.deobf("appeng:appliedenergistics2:VERSION:api")`
## Building
1. Clone this repository via
@@ -109,66 +141,6 @@ Here are a few things to keep in mind that will help get your PR approved.
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
The inscriber uses the vanilla recipe system with a custom `type` of `appliedenergistics2:inscriber`.
See the [inscriber recipe folder](src/main/resources/data/appliedenergistics2/recipes/inscriber) for some examples.
### Grindstone
The grindstone uses the vanilla recipe system with a custom `type` of `appliedenergistics2:grinder`.
See the [grinder recipe folder](src/main/resources/data/appliedenergistics2/recipes/grinder) for some examples.
### 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
+28 -1
View File
@@ -30,6 +30,7 @@ buildscript {
plugins {
id "maven-publish"
id "com.diffplug.gradle.spotless" version "4.3.0"
id "com.matthewprenger.cursegradle" version "1.4.0"
id "org.sonarqube" version "2.8"
id "jacoco"
}
@@ -69,7 +70,7 @@ if (ext.branch) {
ext.release = System.getenv('RELEASE') ?: ""
if (ext.release) {
version = ext.release.substring(1)
version = ext.release
}
@@ -142,7 +143,30 @@ minecraft {
}
}
def signProps = [:]
if (System.getenv("KEY_STORE_FILE")) {
signProps['keyStore'] = System.getenv("KEY_STORE_FILE")
signProps['storePass'] = System.getenv("KEY_STORE_PASS")
signProps['alias'] = System.getenv("KEY_STORE_ALIAS")
signProps['keyPass'] = System.getenv("KEY_STORE_KEY_PASS")
}
task signJar(type: net.minecraftforge.gradle.common.task.SignJar, dependsOn: 'reobfJar') {
onlyIf { !signProps.isEmpty() }
if (!signProps.isEmpty()) {
keyStore = signProps.keyStore
alias = signProps.alias
storePass = signProps.storePass
keyPass = signProps.keyPass
inputFile = jar.archivePath
outputFile = jar.archivePath
}
}
apply from: 'gradle/scripts/artifacts.gradle'
apply from: 'gradle/scripts/curseforge.gradle'
publishing {
publications {
@@ -151,6 +175,9 @@ publishing {
artifactId = project.archivesBaseName
version = project.version
from components.java
artifact sourcesJar
artifact javadocJar
artifact apiJar
}
}
repositories {
+4 -3
View File
@@ -10,13 +10,13 @@ artifact_basename=appliedenergistics2
#########################################################
minecraft_release=1.15
minecraft_version=1.15.2
mcp_mappings=20200613-1.15.1
forge_version=31.2.20
mcp_mappings=20200715-1.15.1
forge_version=31.2.31
#########################################################
# Provided APIs #
#########################################################
jei_version=6.0.0.4
jei_version=6.0.2.12
top_version=2.0.4-5
hwyla_version=1.10.8-B72_1.15.2
ctm_version=MC1.15.2-1.1.0.9
@@ -26,6 +26,7 @@ ctm_version=MC1.15.2-1.1.0.9
#########################################################
website_version=1.15.2
curse_versions=1.15.2
curseforge_project=223794
#########################################################
# Gradle #
+3
View File
@@ -21,6 +21,9 @@ processResources {
}
jar {
finalizedBy 'reobfJar'
finalizedBy 'signJar'
from sourceSets.main.output.classesDirs
from sourceSets.api.output.classesDirs
from sourceSets.main.output.resourcesDir
+39
View File
@@ -0,0 +1,39 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2020, TeamAppliedEnergistics, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*g GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
def isAlpha = project.version.contains("alpha")
def isBeta = project.version.contains("beta")
def cfReleaseType = "release"
if (isAlpha) {
cfReleaseType = "alpha"
} else if (isBeta) {
cfReleaseType = "beta"
}
if (System.getenv("CURSEFORGE")) {
curseforge {
apiKey = System.getenv("CURSEFORGE")
project {
id = project.curseforge_project
changelogType = "markdown"
changelog = System.getenv("CHANGELOG") ?: "Please visit our [releases](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases) for a changelog"
releaseType = cfReleaseType
}
}
}
@@ -26,12 +26,16 @@ import java.lang.annotation.Target;
/**
* Use this annotation on a class in your Mod to have it instantiated during the
* initialization phase of Applied Energistics. AE expects your class to have a
* single constructor and can supply certain arguments to your constructor using
* dependency injection.
* initialization phase of Applied Energistics.
*
* The class also needs to implement {@link IAEAddon}.
*
* AE expects your class to have a single constructor without any parameters.
*
* This is the only way to get access to the public {@link IAppEngApi} instance.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.CLASS)
@Documented
public @interface AEPlugin {
public @interface AEAddon {
}
-67
View File
@@ -1,67 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api;
import java.lang.reflect.Field;
import appeng.api.exceptions.CoreInaccessibleException;
/**
* Entry point for api.
*/
public enum AEApi {
;
private static final String CORE_API_FQN = "appeng.core.Api";
private static final String CORE_API_FIELD = "INSTANCE";
private static final IAppEngApi HELD_API;
static {
try {
final Class<?> apiClass = Class.forName(CORE_API_FQN);
final Field apiField = apiClass.getField(CORE_API_FIELD);
HELD_API = (IAppEngApi) apiField.get(apiClass);
} catch (final ClassNotFoundException e) {
throw new CoreInaccessibleException(
"AE2 API tried to access the " + CORE_API_FQN + " class, without it being declared.");
} catch (final NoSuchFieldException e) {
throw new CoreInaccessibleException("AE2 API tried to access the " + CORE_API_FIELD + " field in "
+ CORE_API_FQN + " without it being declared.");
} catch (final IllegalAccessException e) {
throw new CoreInaccessibleException("AE2 API tried to access the " + CORE_API_FIELD + " field in "
+ CORE_API_FQN + " without enough access permissions.");
}
}
/**
* API Entry Point.
*
* @return the {@link IAppEngApi}
*/
public static IAppEngApi instance() {
return HELD_API;
}
}
-33
View File
@@ -1,33 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks interfaces that can be used as injectable constructor arguments for an
* {@link AEPlugin}.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AEInjectable {
}
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
* Copyright (c) 2020 TeamAppliedEnergistics
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -21,23 +21,30 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.implementations.items;
package appeng.api;
import java.util.Set;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
/**
* Lets you specify the name of the group of items this falls under.
* Every AE2 addon requiring access to {@link IAppEngApi}, needs to provide at
* least one class implementing this interface.
*
* Further it requires the class to be annotated with {@link AEAddon}.
*
*/
public interface IItemGroup {
public interface IAEAddon {
/**
* returning null, is the same as not implementing the interface at all.
*
* @param is item
*
* @return an unlocalized string to use for the items group name.
* This gets called once the API is successfully constructed and ready to be
* used.
*
* For now this happens during {@link FMLCommonSetupEvent}.
*
* Each addon is responsible to maintain a reference to {@link IAppEngApi} for
* future use. Otherwise there is no alternative to access it later.
*
* @param api The API instance when ready.
*/
String getUnlocalizedGroupName(Set<ItemStack> otherItems, ItemStack is);
void onAPIAvailable(IAppEngApi api);
}
+13 -7
View File
@@ -23,16 +23,22 @@
package appeng.api;
import appeng.api.client.IClientHelper;
import appeng.api.crafting.ICraftingHelper;
import appeng.api.definitions.IDefinitions;
import appeng.api.features.IRegistryContainer;
import appeng.api.networking.IGridHelper;
import appeng.api.networking.IGridNode;
import appeng.api.parts.IPartHelper;
import appeng.api.storage.IStorageHelper;
import appeng.api.util.IClientHelper;
@AEInjectable
public interface IAppEngApi {
/**
* @return An accessible list of all AE definitions
*/
IDefinitions definitions();
/**
* @return Registry Container for the numerous registries in AE2.
*/
@@ -43,6 +49,11 @@ public interface IAppEngApi {
*/
IStorageHelper storage();
/**
* @return A helper for working with crafting related tasks.
*/
ICraftingHelper crafting();
/**
* @return A helper to create {@link IGridNode} and other grid related objects.
*/
@@ -53,11 +64,6 @@ public interface IAppEngApi {
*/
IPartHelper partHelper();
/**
* @return An accessible list of all AE definitions
*/
IDefinitions definitions();
/**
* @return Utility methods primarily useful for client side stuff
*/
@@ -0,0 +1,88 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 TeamAppliedEnergistics
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.client;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
/**
* A registry for 3D models used to render storage cells in the world, when they
* are inserted into a drive or similar machines.
*/
public interface ICellModelRegistry {
/**
* Register a new model for a storage cell item.
*
* <p>
* You are responsible for ensuring that the given model is actually loaded by
* the game. See
* {@see net.minecraftforge.client.model.ModelLoader#addSpecialModel}.
*
* This method only maps an {@link Item} to a {@link ResourceLocation} which can
* be looked up from the {@link ModelBakery}. No validation about missing models
* will be done.
*
* Will throw an exception in case a model is already registered for an item.
*
* For examples look at our cell part models within the drive model directory.
*
* @param item The cell item
* @param model The {@link ResourceLocation} representing the model.
* @return
*/
void registerModel(@Nonnull Item item, @Nonnull ResourceLocation model);
/**
* The {@link ResourceLocation} of the model used to render the given storage
* cell {@link Item} when inserted into a drive or similar.
*
* @param item
* @return null, if no model is registered.
*/
@Nullable
ResourceLocation model(@Nonnull Item item);
/**
* An unmodifiable map of all registered mappings.
*
* @return
*/
@Nonnull
Map<Item, ResourceLocation> models();
/**
* Returns the default model, which can be used when no explicit model is
* registered.
*/
@Nonnull
ResourceLocation getDefaultModel();
}
@@ -21,7 +21,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.util;
package appeng.api.client;
import java.util.List;
@@ -39,4 +39,11 @@ public interface IClientHelper {
*/
<T extends IAEStack<T>> void addCellInformation(ICellInventoryHandler<T> handler, List<ITextComponent> lines);
/**
* A helper to work with clientside related tasks for cells.
*
* @return
*/
ICellModelRegistry cells();
}
+107 -18
View File
@@ -23,12 +23,22 @@
package appeng.api.config;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.item.ItemStack;
import javax.annotation.Nullable;
import appeng.api.definitions.IItemDefinition;
import com.google.common.base.Preconditions;
import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.util.IItemProvider;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
public enum Upgrades {
/**
@@ -42,7 +52,8 @@ public enum Upgrades {
FUZZY(1), SPEED(1), INVERTER(1);
private final int tier;
private final Map<ItemStack, Integer> supportedMax = new HashMap<>();
private final List<Supported> supported = new ArrayList<>();
private List<ITextComponent> supportedTooltipLines;
Upgrades(final int tier) {
this.tier = tier;
@@ -52,8 +63,12 @@ public enum Upgrades {
* @return list of Items/Blocks that support this upgrade, and how many it
* supports.
*/
public Map<ItemStack, Integer> getSupported() {
return this.supportedMax;
public List<Supported> getSupported() {
return this.supported;
}
public void registerItem(final IItemProvider item, final int maxSupported) {
this.registerItem(item, maxSupported, null);
}
/**
@@ -61,24 +76,98 @@ public enum Upgrades {
*
* @param item machine in which this upgrade can be installed
* @param maxSupported amount how many upgrades can be installed
* @param tooltipGroup If more than one item of the same group are supported,
* the tooltip will show this translation key instead. If
* the items have different maxSupported values, the highest
* will be shown.
*/
public void registerItem(final IItemDefinition item, final int maxSupported) {
item.maybeStack(1).ifPresent(is -> this.registerItem(is, maxSupported));
public void registerItem(final IItemProvider item, final int maxSupported, @Nullable String tooltipGroup) {
Preconditions.checkNotNull(item);
this.supported.add(new Supported(item.asItem(), maxSupported, tooltipGroup));
supportedTooltipLines = null; // Reset tooltip
}
/**
* Registers a specific amount of this upgrade into a specific machine
*
* @param stack machine in which this upgrade can be installed
* @param maxSupported amount how many upgrades can be installed
*/
public void registerItem(final ItemStack stack, final int maxSupported) {
if (stack != null) {
this.supportedMax.put(stack, maxSupported);
public List<ITextComponent> getTooltipLines() {
if (supportedTooltipLines == null) {
supported.sort(Comparator.comparingInt(o -> o.maxCount));
supportedTooltipLines = new ArrayList<>(supported.size());
// Use a separate set because the final text will include numbers
Set<ITextComponent> namesAdded = new HashSet<>();
for (int i = 0; i < supported.size(); i++) {
Supported supported = this.supported.get(i);
ITextComponent name = supported.item.getName();
// If the group was already added by a previous item, skip this
if (supported.getTooltipGroup() != null && namesAdded.contains(supported.getTooltipGroup())) {
continue;
}
// If any of the following items would be of the same group, use the group name
// instead
if (supported.getTooltipGroup() != null) {
for (int j = i + 1; j < this.supported.size(); j++) {
ITextComponent otherGroup = this.supported.get(j).getTooltipGroup();
if (supported.getTooltipGroup().equals(otherGroup)) {
name = supported.getTooltipGroup();
break;
}
}
}
if (namesAdded.add(name)) {
// append the supported count only if its > 1
if (supported.maxCount > 1) {
name = name.deepCopy().appendText(" (" + supported.maxCount + ")");
}
supportedTooltipLines.add(name);
}
}
}
return supportedTooltipLines;
}
public int getTier() {
return this.tier;
}
public static class Supported {
private final Item item;
private final Block block;
private final int maxCount;
// Translation key of the tooltip group
@Nullable
private final String tooltipGroup;
public Supported(Item item, int maxCount, @Nullable String tooltipGroup) {
this.item = item;
if (item.getItem() instanceof BlockItem) {
this.block = ((BlockItem) item.getItem()).getBlock();
} else {
this.block = null;
}
this.maxCount = maxCount;
this.tooltipGroup = tooltipGroup;
}
public int getMaxCount() {
return maxCount;
}
public boolean isSupported(Block block) {
return block != null && this.block == block;
}
public boolean isSupported(Item item) {
return item != null && this.item == item;
}
public ITextComponent getTooltipGroup() {
return this.tooltipGroup != null ? new TranslationTextComponent(this.tooltipGroup) : null;
}
}
}
@@ -0,0 +1,108 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 TeamAppliedEnergistics
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.crafting;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.ICraftingRecipe;
import net.minecraft.world.World;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.storage.data.IAEItemStack;
public interface ICraftingHelper {
/**
* Checks that the given item stack is an encoded pattern.
*/
boolean isEncodedPattern(@Nullable IAEItemStack item);
/**
* Checks that the given item stack is an encoded pattern.
*/
boolean isEncodedPattern(ItemStack item);
/**
* Encodes a processing pattern which represents the ability to convert the
* given inputs into the given outputs using some process external to the ME
* system.
*
* @param stack If null, a new item will be created to hold the encoded pattern.
* Otherwise the given item must already contains an encoded
* pattern that will be overwritten.
* @return A new encoded pattern, or the given stack with the pattern encoded in
* it.
*/
ItemStack encodeProcessingPattern(@Nullable ItemStack stack, ItemStack[] in, ItemStack[] out);
/**
* Encodes a crafting pattern which represents a Vanilla crafting recipe.
*
* @param stack If null, a new item will be created to hold the
* encoded pattern. Otherwise the given item must
* already contains an encoded pattern that will be
* overwritten.
* @param recipe The Vanilla crafting recipe to be encoded.
* @param in The items in the crafting grid, which are used to
* determine what items are supplied from the ME system
* to craft using this pattern.
* @param out What is to be expected as the result of this crafting
* operation by the ME system.
* @param allowSubstitutes Controls whether the ME system will allow the use of
* equivalent items to craft this recipe.
*/
ItemStack encodeCraftingPattern(@Nullable ItemStack stack, ICraftingRecipe recipe, ItemStack[] in, ItemStack out,
boolean allowSubstitutes);
/**
* Same as {@link #decodePattern(ItemStack, World, boolean)} with no auto
* recovery of changed recipe ids.
*/
@Nullable
default ICraftingPatternDetails decodePattern(@Nonnull ItemStack itemStack, @Nonnull World world) {
return decodePattern(itemStack, world, false);
}
/**
* Decodes an encoded crafting pattern and returns the pattern details.
* <p>
* The item backing the {@link ItemStack} needs to be an item returned by the
* encode methods of this class.
*
* @param itemStack pattern
* @param world world used to access the
* {@link net.minecraft.item.crafting.RecipeManager}.
* @param autoRecovery If true, the method will try to recover from changed
* recipe ids by searching the entire recipe manager for a
* recipe matching the inputs. If this is successful, the
* given item stack will be changed to reflect the new
* recipe id.
* @return The pattern details if the pattern could be decoded. Otherwise null.
*/
@Nullable
ICraftingPatternDetails decodePattern(@Nonnull ItemStack itemStack, @Nonnull World world, boolean autoRecovery);
}
@@ -30,10 +30,11 @@ import javax.annotation.Nonnull;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IItemProvider;
import appeng.api.features.AEFeature;
public interface IItemDefinition extends IComparableDefinition {
public interface IItemDefinition extends IComparableDefinition, IItemProvider {
/**
* @return the unique name of the definition which will be used to register the
* underlying structure. Will never be null
@@ -63,4 +64,10 @@ public interface IItemDefinition extends IComparableDefinition {
* @return an immutable set of the features of this item
*/
Set<AEFeature> features();
@Override
default Item asItem() {
return item();
}
}
@@ -23,7 +23,6 @@
package appeng.api.features;
import appeng.api.AEInjectable;
import appeng.api.movable.IMovableRegistry;
import appeng.api.networking.IGridCacheRegistry;
import appeng.api.parts.IPartModels;
@@ -36,7 +35,6 @@ import appeng.api.storage.ICellRegistry;
* @version 7
* @since rv0
*/
@AEInjectable
public interface IRegistryContainer {
/**
@@ -1,46 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.implementations;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import appeng.api.networking.crafting.ICraftingPatternDetails;
/**
* Implemented on {@link Item}
*/
public interface ICraftingPatternItem {
/**
* Access Details about a pattern
*
* @param is pattern
* @param w crafting world
*
* @return details of pattern
*/
ICraftingPatternDetails getPatternForItem(ItemStack is, World w);
}
@@ -28,18 +28,25 @@ import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.cells.ICellHandler;
import appeng.api.storage.cells.ICellInventory;
import appeng.api.storage.cells.ICellWorkbenchItem;
import appeng.api.storage.data.IAEStack;
/**
* Any item which implements this can be treated as an IMEInventory via
* Util.getCell / Util.isCell It automatically handles the internals and NBT
* data, which is both nice, and bad for you!
* {@link ICellHandler#getCellInventory(ItemStack, appeng.api.storage.cells.ISaveProvider, IStorageChannel)}
* or {@link ICellHandler#isCell(ItemStack)}. It automatically handles the
* internals and NBT data, which is both nice, and bad for you!
*
* Good cause it means you don't have to do anything, bad because you have
* little to no control over it.
*
* The standard AE implementation only provides 1-63 Types
*
* Limited to {@link Integer} internally for most calculations. E.g. if the used
* or remaining bytes would overflow {@link Integer#MAX_VALUE} the behaviour is
* no longer specified. Even if {@link ICellInventory} is using {@link Long}.
*
* The standard AE implementation also only provides 1-63 Types.
*/
public interface IStorageCell<T extends IAEStack<T>> extends ICellWorkbenchItem {
@@ -91,16 +91,6 @@ public interface IGridBlock {
*/
void onGridNotification(@Nonnull GridNotification notification);
/**
* Update Blocks network/connection/booting status. grid,
*
* @param grid grid
* @param channelsInUse used channels
* @deprecated to be removed in rv7
*/
@Deprecated
void setNetworkStatus(IGrid grid, int channelsInUse);
/**
* Determine which sides of the block can be connected too, only used when
* isWorldAccessible returns true, not used for {@link IPart} implementations.
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 - 2015 AlgorithmX2
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
@@ -21,20 +21,23 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.recipes;
import java.io.BufferedReader;
package appeng.api.networking;
import javax.annotation.Nonnull;
@Deprecated
public interface IRecipeLoader {
/**
* A factory for grid cache implementations.
*/
@FunctionalInterface
public interface IGridCacheFactory<T extends IGridCache> {
/**
* @param filePath the path to the to be loaded file
* Creates a grid cache for the given grid.
*
* @return reader handler of the file
*
* @throws Exception if reading goes wrong
* @param grid The grid for which the cache should be created.
* @return A new grid cache instance.
*/
BufferedReader getFile(@Nonnull String filePath) throws Exception;
@Nonnull
T createCache(IGrid grid);
}
@@ -36,10 +36,10 @@ public interface IGridCacheRegistry {
* Register a new grid cache for use during operation, must be called during the
* loading phase.
*
* @param iface grid cache class
* @param iface grid cache class
* @param factory Factory for creating a new instance for each constructed grid
*/
void registerGridCache(@Nonnull Class<? extends IGridCache> iface,
@Nonnull Class<? extends IGridCache> implementation);
<T extends IGridCache> void registerGridCache(@Nonnull Class<T> iface, @Nonnull IGridCacheFactory<T> factory);
/**
* requests a new INSTANCE of a grid cache for use, used internally
@@ -27,18 +27,19 @@ import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.storage.data.IAEItemStack;
/**
* do not implement provided by {@link ICraftingPatternItem}
*
* caching this INSTANCE will increase performance of validation and checks.
* Describes a crafting or processing pattern decoded by
* {@link appeng.api.crafting.ICraftingHelper}.
* <p>
* Do not cache instances of this class unless you handle recipe reloads on the
* server and client correctly.
*/
public interface ICraftingPatternDetails {
/**
* @return source item.
* @return encodes this crafting pattern into a new item stack.
*/
ItemStack getPattern();
@@ -52,7 +53,9 @@ public interface ICraftingPatternDetails {
boolean isValidItemForSlot(int slotIndex, ItemStack itemStack, World world);
/**
* @return if this pattern is a crafting pattern ( work bench )
* @return if this pattern is for a Vanilla
* {@link net.minecraft.item.crafting.IRecipeType#CRAFTING crafting
* recipe}.
*/
boolean isCraftable();
@@ -23,6 +23,7 @@
package appeng.api.networking.crafting;
import appeng.api.crafting.ICraftingHelper;
import appeng.api.storage.data.IAEItemStack;
/**
@@ -33,6 +34,9 @@ public interface ICraftingProviderHelper {
/**
* Add new Pattern to AE's crafting cache.
*
* This will only accept instances created by
* {@link ICraftingHelper#decodePattern(net.minecraft.item.ItemStack, net.minecraft.world.World)}
*/
void addCraftingOption(ICraftingMedium medium, ICraftingPatternDetails api);
@@ -27,6 +27,7 @@ import javax.annotation.Nonnull;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.IGrid;
/**
* Used to access information about AE's various power accepting blocks for
@@ -71,4 +72,22 @@ public interface IAEPowerStorage extends IEnergySource {
*/
@Nonnull
AccessRestriction getPowerFlow();
}
/**
* The priority to use this energy storage.
*
* A higher value means it is more likely to be extracted from first, and less
* likely to be inserted into first.
*
* The value needs to be constant once added to a {@link IGrid}. Should it ever
* need to be changed, it has to be removed from the grid, then update the
* value, and finally added back to the grid.
*
* This should never use {@link Integer#MIN_VALUE} or {@link Integer#MAX_VALUE}.
*
* @return the priority for this storage
*/
default int getPriority() {
return 0;
}
}
@@ -23,7 +23,6 @@
package appeng.api.networking.security;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.api.networking.IGridNode;
@@ -31,6 +31,6 @@ public interface ICustomCableConnection {
* @return This controls the cable connection to the node. -1 to render
* connection yourself.
*/
public float getCableConnectionLength(AECableType cable);
float getCableConnectionLength(AECableType cable);
}
@@ -24,7 +24,6 @@
package appeng.api.parts;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
+12 -1
View File
@@ -32,6 +32,7 @@ import javax.annotation.Nonnull;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
@@ -278,7 +279,7 @@ public interface IPart extends ICustomCableConnection {
* the node. -1 to render connection yourself.
*/
@Override
public float getCableConnectionLength(AECableType cable);
float getCableConnectionLength(AECableType cable);
/**
* same as Block.animateTick, for but parts.
@@ -371,4 +372,14 @@ public interface IPart extends ICustomCableConnection {
*/
void getBoxes(final IPartCollisionHelper bch);
/**
* This will be used by the core to add information about this part to a crash
* report if it is attached to a host that caused a crash during tick
* processing.
*
* @param section The crash report section the information will be added to.
*/
default void addEntityCrashInfo(final CrashReportCategory section) {
}
}
@@ -23,13 +23,10 @@ import java.util.Collection;
import net.minecraft.util.ResourceLocation;
import appeng.api.AEInjectable;
/**
* Allows registration of part models that can then be used in
* {@link IPart#getStaticModels()}.
*/
@AEInjectable
public interface IPartModels {
/**
@@ -1,54 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.recipes;
import java.util.List;
import appeng.api.exceptions.MissingIngredientException;
import appeng.api.exceptions.RecipeException;
import appeng.api.exceptions.RegistrationException;
@Deprecated
public interface ICraftHandler {
/**
* Called when your recipe handler receives a newly parsed list of
* inputs/outputs.
*
* @param input parsed inputs
* @param output parsed outputs
*
* @throws RecipeException
*/
void setup(List<List<IIngredient>> input, List<List<IIngredient>> output) throws RecipeException;
/**
* called when all recipes are parsed, and your required to register your
* recipe.
*
* @throws RegistrationException
* @throws MissingIngredientException
*/
void register() throws RegistrationException, MissingIngredientException;
}
@@ -1,92 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.recipes;
import net.minecraft.item.ItemStack;
import appeng.api.exceptions.MissingIngredientException;
import appeng.api.exceptions.RegistrationException;
@Deprecated
public interface IIngredient {
/**
* Acquire a single input stack for the current recipe, if more then one
* ItemStack is possible a RegistrationError exception will be thrown, ignore
* these and let the system handle the error.
*
* @return a single ItemStack for the recipe handler.
*
* @throws RegistrationException
* @throws MissingIngredientException
*/
ItemStack getItemStack() throws RegistrationException, MissingIngredientException;
/**
* Acquire a list of all the input stacks for the current recipe, this is for
* handlers that support multiple inputs per slot.
*
* @return an array of ItemStacks for the recipe handler.
*
* @throws RegistrationException
* @throws MissingIngredientException
*/
ItemStack[] getItemStackSet() throws RegistrationException, MissingIngredientException;
/**
* If you wish to support air, you must test before getting the ItemStack, or
* ItemStackSet
*
* @return true if this slot contains no ItemStack, this is passed as "_"
*/
boolean isAir();
/**
* @return The Name Space of the item. Prefer getItemStack or getItemStackSet
*/
String getNameSpace();
/**
* @return The Name of the item. Prefer getItemStack or getItemStackSet
*/
String getItemName();
/**
* @return The Damage Value of the item. Prefer getItemStack or getItemStackSet
*/
int getDamageValue();
/**
* @return The Damage Value of the item. Prefer getItemStack or getItemStackSet
*/
int getQty();
/**
* Bakes the lists in for faster runtime look-ups.
*
* @throws MissingIngredientException
* @throws RegistrationException
*/
void bake() throws RegistrationException, MissingIngredientException;
}
@@ -1,44 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.recipes;
/**
* Represents the AE2 Recipe Loading/Reading Class
*/
@Deprecated
public interface IRecipeHandler {
/**
* Call when you want to read recipes in from a file based on a loader
*
* @param loader recipe loader
* @param path path of file
*/
void parseRecipes(IRecipeLoader loader, String path);
/**
* this loads the read recipes into minecraft, should be called in Init.
*/
void injectRecipes();
}
@@ -1,45 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.recipes;
import net.minecraft.nbt.CompoundNBT;
public class ResolverResult {
public final String itemName;
public final int damageValue;
public final CompoundNBT compound;
public ResolverResult(final String name, final int damage) {
this.itemName = name;
this.damageValue = damage;
this.compound = null;
}
public ResolverResult(final String name, final int damage, final CompoundNBT data) {
this.itemName = name;
this.damageValue = damage;
this.compound = data;
}
}
@@ -1,40 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.recipes;
import java.util.Arrays;
import java.util.List;
import net.minecraft.item.ItemStack;
public class ResolverResultSet {
public final String name;
public final List<ItemStack> results;
public ResolverResultSet(final String myName, final ItemStack... set) {
this.results = Arrays.asList(set);
this.name = myName;
}
}
@@ -50,5 +50,5 @@ public enum CellState {
/**
* Full cell, technically could have free types
*/
FULL,
FULL;
}
@@ -106,4 +106,13 @@ public interface IAEItemStack extends IAEStack<IAEItemStack> {
* @return definition stack
*/
ItemStack getDefinition();
/**
* Compare this AE item stack to another item stack, but ignores the amount. It
* checks the item type, NBT and damage values.
*
* @param is An item stack
*/
boolean equals(ItemStack is);
}
@@ -179,17 +179,7 @@ public interface IAEStack<T extends IAEStack<T>> {
T empty();
/**
* @return true if the stack is a {@link IAEItemStack}
*/
boolean isItem();
/**
* @return true if the stack is a {@link IAEFluidStack}
*/
boolean isFluid();
/**
* @return ITEM or FLUID
* @return The {@link IStorageChannel} backing this stack.
*/
IStorageChannel<T> getChannel();
+2 -40
View File
@@ -18,22 +18,14 @@
package appeng.block;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.material.MaterialColor;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
@@ -41,13 +33,11 @@ import net.minecraftforge.common.ToolType;
import appeng.api.util.IOrientable;
import appeng.api.util.IOrientableBlock;
import appeng.helpers.AEGlassMaterial;
import appeng.helpers.AEMaterials;
import appeng.util.Platform;
public abstract class AEBaseBlock extends Block {
private boolean isOpaque = true;
private boolean isFullSize = true;
private boolean isInventory = false;
protected AEBaseBlock(final Block.Properties props) {
@@ -74,7 +64,7 @@ public abstract class AEBaseBlock extends Block {
}
private static SoundType getDefaultSoundByMaterial(Material mat) {
if (mat == AEGlassMaterial.INSTANCE || mat == Material.GLASS) {
if (mat == AEMaterials.GLASS || mat == Material.GLASS) {
return SoundType.GLASS;
} else if (mat == Material.ROCK) {
return SoundType.STONE;
@@ -85,11 +75,6 @@ public abstract class AEBaseBlock extends Block {
}
}
@Override
public boolean isNormalCube(BlockState state, IBlockReader worldIn, BlockPos pos) {
return this.isFullSize() && this.isOpaque();
}
@Override
public boolean hasComparatorInputOverride(BlockState state) {
return this.isInventory();
@@ -129,11 +114,6 @@ public abstract class AEBaseBlock extends Block {
return false;
}
public ActionResultType onActivated(final World w, final BlockPos pos, final PlayerEntity player, final Hand hand,
final @Nullable ItemStack heldItem, final BlockRayTraceResult hit) {
return ActionResultType.PASS;
}
public final Direction mapRotation(final IOrientable ori, final Direction dir) {
// case DOWN: return bottomIcon;
// case UP: return blockIcon;
@@ -219,24 +199,6 @@ public abstract class AEBaseBlock extends Block {
return true;
}
protected boolean isOpaque() {
return this.isOpaque;
}
protected boolean setOpaque(final boolean isOpaque) {
this.isOpaque = isOpaque;
return isOpaque;
}
protected boolean isFullSize() {
return this.isFullSize;
}
protected boolean setFullSize(final boolean isFullSize) {
this.isFullSize = isFullSize;
return isFullSize;
}
protected boolean isInventory() {
return this.isInventory;
}
@@ -129,7 +129,7 @@ public class AEBaseBlockItem extends BlockItem {
}
ActionResultType result = super.tryPlace(context);
if (result != ActionResultType.SUCCESS) {
if (!result.isSuccessOrConsume()) {
return result;
}
@@ -139,7 +139,7 @@ public class AEBaseBlockItem extends BlockItem {
ori = tile;
if (tile == null) {
return ActionResultType.SUCCESS;
return result;
}
if (ori.canBeRotated() && !this.blockType.hasCustomRotation()) {
@@ -155,7 +155,7 @@ public class AEBaseBlockItem extends BlockItem {
ori.setOrientation(forward, up);
}
return ActionResultType.SUCCESS;
return result;
}
}
@@ -32,12 +32,12 @@ import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerUnits;
import appeng.api.definitions.IBlockDefinition;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.core.Api;
import appeng.core.localization.GuiText;
public class AEBaseBlockItemChargeable extends AEBaseBlockItem implements IAEItemPowerStorage {
@@ -123,7 +123,7 @@ public class AEBaseBlockItemChargeable extends AEBaseBlockItem implements IAEIte
private double getMaxEnergyCapacity() {
final Block blockID = Block.getBlockFromItem(this);
final IBlockDefinition energyCell = AEApi.instance().definitions().blocks().energyCell();
final IBlockDefinition energyCell = Api.instance().definitions().blocks().energyCell();
return energyCell.maybeBlock().map(block -> {
if (blockID == block) {
@@ -278,6 +278,11 @@ public abstract class AEBaseTileBlock<T extends AEBaseTileEntity> extends AEBase
return this.onActivated(world, pos, player, hand, player.getHeldItem(hand), hit);
}
public ActionResultType onActivated(final World w, final BlockPos pos, final PlayerEntity player, final Hand hand,
final @Nullable ItemStack heldItem, final BlockRayTraceResult hit) {
return ActionResultType.PASS;
}
@Override
public IOrientable getOrientable(final IBlockReader w, final BlockPos pos) {
return this.getTileEntity(w, pos);
@@ -23,10 +23,13 @@ import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
@@ -54,12 +57,22 @@ public abstract class AbstractCraftingUnitBlock<T extends CraftingTileEntity> ex
builder.add(FORMED);
}
@Override
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
BlockPos currentPos, BlockPos facingPos) {
TileEntity te = worldIn.getTileEntity(currentPos);
if (te != null) {
te.requestModelDataUpdate();
}
return super.updatePostPlacement(stateIn, facing, facingState, worldIn, currentPos, facingPos);
}
@Override
public void neighborChanged(final BlockState state, final World worldIn, final BlockPos pos, final Block blockIn,
final BlockPos fromPos, boolean isMoving) {
final CraftingTileEntity cp = this.getTileEntity(worldIn, pos);
if (cp != null) {
cp.updateMultiBlock();
cp.updateMultiBlock(fromPos);
}
}
@@ -21,10 +21,10 @@ package appeng.block.crafting;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlockItem;
import appeng.core.AEConfig;
import appeng.core.Api;
public class CraftingStorageItem extends AEBaseBlockItem {
@@ -34,7 +34,7 @@ public class CraftingStorageItem extends AEBaseBlockItem {
@Override
public ItemStack getContainerItem(final ItemStack itemStack) {
return AEApi.instance().definitions().blocks().craftingUnit().maybeStack(1).orElse(ItemStack.EMPTY);
return Api.instance().definitions().blocks().craftingUnit().maybeStack(1).orElse(ItemStack.EMPTY);
}
@Override
@@ -49,13 +49,13 @@ import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.AEApi;
import appeng.api.util.AEAxisAlignedBB;
import appeng.block.AEBaseTileBlock;
import appeng.client.render.effects.ParticleTypes;
import appeng.client.render.renderable.ItemRenderable;
import appeng.client.render.tesr.ModularTESR;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
import appeng.tile.misc.ChargerTileEntity;
import appeng.util.Platform;
@@ -64,8 +64,6 @@ public class ChargerBlock extends AEBaseTileBlock<ChargerTileEntity> {
public ChargerBlock() {
super(defaultProps(Material.IRON).notSolid());
this.setFullSize(this.setOpaque(false));
}
@Override
@@ -103,7 +101,7 @@ public class ChargerBlock extends AEBaseTileBlock<ChargerTileEntity> {
final ChargerTileEntity tile = this.getTileEntity(w, pos);
if (tile != null) {
if (AEApi.instance().definitions().materials().certusQuartzCrystalCharged()
if (Api.instance().definitions().materials().certusQuartzCrystalCharged()
.isSameAs(tile.getInternalInventory().getStackInSlot(0))) {
final double xOff = 0.0;
final double yOff = 0.0;
@@ -81,7 +81,7 @@ public class QuartzFixtureBlock extends AEBaseBlock implements IOrientableBlock
public QuartzFixtureBlock() {
super(defaultProps(Material.MISCELLANEOUS).doesNotBlockMovement().hardnessAndResistance(0).lightValue(14)
.sound(SoundType.GLASS));
.sound(SoundType.GLASS).notSolid());
this.setDefaultState(getDefaultState().with(FACING, Direction.UP).with(ODD, false));
}
@@ -199,9 +199,4 @@ public class QuartzFixtureBlock extends AEBaseBlock implements IOrientableBlock
return new MetaRotation(w, pos, FACING);
}
@Override
public boolean isOpaque() {
return false;
}
}
@@ -18,10 +18,9 @@
package appeng.block.misc;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
@@ -52,8 +51,7 @@ public class TinyTNTBlock extends AEBaseBlock {
.create(new AxisAlignedBB(0.25f, 0.0f, 0.25f, 0.75f, 0.5f, 0.75f));
public TinyTNTBlock(Block.Properties props) {
super(props);
setFullSize(setOpaque(false));
super(defaultProps(Material.TNT).notSolid());
}
@Override
@@ -67,17 +65,18 @@ public class TinyTNTBlock extends AEBaseBlock {
}
@Override
public ActionResultType onActivated(final World w, final BlockPos pos, final PlayerEntity player, final Hand hand,
final @Nullable ItemStack heldItem, final BlockRayTraceResult hit) {
if (heldItem != null && heldItem.getItem() == Items.FLINT_AND_STEEL) {
this.startFuse(w, pos, player);
w.removeBlock(pos, false);
public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player,
Hand handIn, BlockRayTraceResult hit) {
ItemStack heldItem = player.getHeldItem(handIn);
if (!heldItem.isEmpty() && heldItem.getItem() == Items.FLINT_AND_STEEL) {
this.startFuse(world, pos, player);
world.removeBlock(pos, false);
heldItem.damageItem(1, player, p -> {
p.sendBreakAnimation(hand);
p.sendBreakAnimation(handIn);
}); // FIXME Check if onBroken is equivalent
return ActionResultType.SUCCESS;
} else {
return super.onActivated(w, pos, player, hand, heldItem, hit);
return super.onBlockActivated(state, world, pos, player, handIn, hit);
}
}
@@ -18,7 +18,6 @@
package appeng.block.networking;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
@@ -44,8 +43,11 @@ import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.RayTraceResult.Type;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
@@ -68,7 +70,7 @@ import appeng.client.render.cablebus.CableBusBreakingParticle;
import appeng.client.render.cablebus.CableBusRenderState;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ClickPacket;
import appeng.helpers.AEGlassMaterial;
import appeng.helpers.AEMaterials;
import appeng.integration.abstraction.IAEFacade;
import appeng.parts.ICableBusContainer;
import appeng.parts.NullCableBusContainer;
@@ -81,7 +83,7 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
public CableBusBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE).notSolid().noDrops());
super(defaultProps(AEMaterials.GLASS).notSolid().noDrops().variableOpacity());
}
@Override
@@ -158,11 +160,12 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
@Override
public boolean canConnectRedstone(final BlockState state, final IBlockReader w, final BlockPos pos,
Direction side) {
// TODO: Verify this.
if (side == null) {
side = Direction.UP;
return false;
}
return this.cb(w, pos).canConnectRedstone(EnumSet.of(side));
return this.cb(w, pos).canConnectRedstone(side.getOpposite());
}
@Override
@@ -19,12 +19,12 @@
package appeng.block.networking;
import appeng.block.AEBaseTileBlock;
import appeng.helpers.AEGlassMaterial;
import appeng.helpers.AEMaterials;
import appeng.tile.networking.CreativeEnergyCellTileEntity;
public class CreativeEnergyCellBlock extends AEBaseTileBlock<CreativeEnergyCellTileEntity> {
public CreativeEnergyCellBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE));
super(defaultProps(AEMaterials.GLASS));
}
}
@@ -30,7 +30,7 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.block.AEBaseTileBlock;
import appeng.helpers.AEGlassMaterial;
import appeng.helpers.AEMaterials;
import appeng.tile.networking.EnergyCellTileEntity;
public class EnergyCellBlock extends AEBaseTileBlock<EnergyCellTileEntity> {
@@ -38,7 +38,7 @@ public class EnergyCellBlock extends AEBaseTileBlock<EnergyCellTileEntity> {
public static final IntegerProperty ENERGY_STORAGE = IntegerProperty.create("fullness", 0, 7);
public EnergyCellBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE));
super(defaultProps(AEMaterials.GLASS));
}
@Override
@@ -40,7 +40,7 @@ import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.WirelessContainer;
import appeng.helpers.AEGlassMaterial;
import appeng.helpers.AEMaterials;
import appeng.tile.networking.WirelessTileEntity;
import appeng.util.Platform;
@@ -58,9 +58,7 @@ public class WirelessBlock extends AEBaseTileBlock<WirelessTileEntity> {
public static final EnumProperty<State> STATE = EnumProperty.create("state", State.class);
public WirelessBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE).notSolid());
this.setFullSize(false);
this.setOpaque(false);
super(defaultProps(AEMaterials.GLASS).notSolid());
this.setDefaultState(this.getDefaultState().with(STATE, State.OFF));
}
@@ -42,9 +42,7 @@ import appeng.util.Platform;
public class PaintSplotchesBlock extends AEBaseTileBlock<PaintSplotchesTileEntity> {
public PaintSplotchesBlock() {
super(defaultProps(Material.WATER, MaterialColor.AIR));
this.setFullSize(false);
this.setOpaque(false);
super(defaultProps(Material.WATER, MaterialColor.AIR).notSolid());
}
@Override
@@ -25,8 +25,8 @@ import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.data.IDynamicBakedModel;
import net.minecraftforge.client.model.data.IModelData;
import appeng.api.AEApi;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.core.Api;
import appeng.core.AppEng;
import appeng.tile.qnb.QuantumBridgeTileEntity;
@@ -41,9 +41,9 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
private static final Material TEXTURE_RING_LIGHT_CORNER = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "block/quantum_ring_light_corner"));
private static final Material TEXTURE_CABLE_GLASS = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "parts/cable/glass/transparent"));
new ResourceLocation(AppEng.MOD_ID, "part/cable/glass/transparent"));
private static final Material TEXTURE_COVERED_CABLE = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "parts/cable/covered/transparent"));
new ResourceLocation(AppEng.MOD_ID, "part/cable/covered/transparent"));
private static final float DEFAULT_RENDER_MIN = 2.0f;
private static final float DEFAULT_RENDER_MAX = 14.0f;
@@ -73,7 +73,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
this.coveredCableTexture = bakedTextureGetter.apply(TEXTURE_COVERED_CABLE);
this.lightTexture = bakedTextureGetter.apply(TEXTURE_RING_LIGHT);
this.lightCornerTexture = bakedTextureGetter.apply(TEXTURE_RING_LIGHT_CORNER);
this.linkBlock = AEApi.instance().definitions().blocks().quantumLink().maybeBlock().orElse(null);
this.linkBlock = Api.instance().definitions().blocks().quantumLink().maybeBlock().orElse(null);
}
@Override
@@ -46,7 +46,6 @@ public abstract class QuantumBaseBlock extends AEBaseTileBlock<QuantumBridgeTile
public QuantumBaseBlock(Block.Properties props) {
super(props);
this.setFullSize(this.setOpaque(false));
this.setDefaultState(this.getDefaultState().with(FORMED, false));
}
@@ -71,7 +70,7 @@ public abstract class QuantumBaseBlock extends AEBaseTileBlock<QuantumBridgeTile
boolean isMoving) {
final QuantumBridgeTileEntity bridge = this.getTileEntity(world, pos);
if (bridge != null) {
bridge.neighborUpdate();
bridge.neighborUpdate(fromPos);
}
}
@@ -41,7 +41,7 @@ import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.QNBContainer;
import appeng.core.AppEng;
import appeng.helpers.AEGlassMaterial;
import appeng.helpers.AEMaterials;
import appeng.tile.qnb.QuantumBridgeTileEntity;
import appeng.util.Platform;
@@ -56,7 +56,7 @@ public class QuantumLinkChamberBlock extends QuantumBaseBlock {
}
public QuantumLinkChamberBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE));
super(defaultProps(AEMaterials.GLASS));
}
@Override
@@ -25,13 +25,13 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.helpers.AEGlassMaterial;
import appeng.helpers.AEMaterials;
import appeng.tile.spatial.SpatialPylonTileEntity;
public class SpatialPylonBlock extends AEBaseTileBlock<SpatialPylonTileEntity> {
public SpatialPylonBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE));
super(defaultProps(AEMaterials.GLASS));
}
@Override
@@ -39,7 +39,7 @@ public class SpatialPylonBlock extends AEBaseTileBlock<SpatialPylonTileEntity> {
boolean isMoving) {
final SpatialPylonTileEntity tsp = this.getTileEntity(world, pos);
if (tsp != null) {
tsp.neighborChanged();
tsp.neighborChanged(fromPos);
}
}
@@ -25,7 +25,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
@@ -42,18 +42,17 @@ import appeng.tile.storage.ChestTileEntity;
public class ChestBlock extends AEBaseTileBlock<ChestTileEntity> {
private final static EnumProperty<DriveSlotState> SLOT_STATE = EnumProperty.create("slot_state",
DriveSlotState.class);
private final static BooleanProperty LIGHTS_ON = BooleanProperty.create("lights_on");
public ChestBlock() {
super(defaultProps(Material.IRON));
this.setDefaultState(this.getDefaultState().with(SLOT_STATE, DriveSlotState.EMPTY));
this.setDefaultState(this.getDefaultState().with(LIGHTS_ON, false));
}
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
super.fillStateContainer(builder);
builder.add(SLOT_STATE);
builder.add(LIGHTS_ON);
}
@Override
@@ -68,7 +67,7 @@ public class ChestBlock extends AEBaseTileBlock<ChestTileEntity> {
slotState = DriveSlotState.OFFLINE;
}
return currentState.with(SLOT_STATE, slotState);
return currentState.with(LIGHTS_ON, slotState != DriveSlotState.EMPTY && slotState != DriveSlotState.OFFLINE);
}
@Override
@@ -1,45 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import net.minecraft.util.IStringSerializable;
/**
* Describes the type of cell present in a slot.
*/
public enum DriveSlotCellType implements IStringSerializable {
EMPTY("empty"),
ITEM("item"),
FLUID("fluid");
private final String name;
DriveSlotCellType(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name;
}
}
@@ -37,6 +37,9 @@ public enum DriveSlotState implements IStringSerializable {
// Online and free space
ONLINE("online"),
// Online and not space
NOT_EMPTY("not_empty"),
// Types full, space left
TYPES_FULL("types_full"),
@@ -60,8 +63,9 @@ public enum DriveSlotState implements IStringSerializable {
case ABSENT:
return DriveSlotState.EMPTY;
case EMPTY:
case NOT_EMPTY:
return DriveSlotState.ONLINE;
case NOT_EMPTY:
return DriveSlotState.NOT_EMPTY;
case TYPES_FULL:
return DriveSlotState.TYPES_FULL;
case FULL:
@@ -25,7 +25,6 @@ import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.energy.IEnergyStorage;
import appeng.api.storage.ISpatialDimension;
import appeng.api.storage.IStorageMonitorableAccessor;
/**
@@ -38,8 +37,6 @@ public final class Capabilities {
public static Capability<IStorageMonitorableAccessor> STORAGE_MONITORABLE_ACCESSOR;
public static Capability<ISpatialDimension> SPATIAL_DIMENSION;
public static Capability<IEnergyStorage> FORGE_ENERGY;
/**
@@ -48,7 +45,6 @@ public final class Capabilities {
public static void register() {
CapabilityManager.INSTANCE.register(IStorageMonitorableAccessor.class, createNullStorage(),
NullMENetworkAccessor::new);
CapabilityManager.INSTANCE.register(ISpatialDimension.class, createNullStorage(), NullSpatialDimension::new);
}
@CapabilityInject(IStorageMonitorableAccessor.class)
@@ -56,11 +52,6 @@ public final class Capabilities {
STORAGE_MONITORABLE_ACCESSOR = cap;
}
@CapabilityInject(ISpatialDimension.class)
private static void capISpatialDimensionRegistered(Capability<ISpatialDimension> cap) {
SPATIAL_DIMENSION = cap;
}
@CapabilityInject(IEnergyStorage.class)
private static void capIEnergyStorageRegistered(Capability<IEnergyStorage> cap) {
FORGE_ENERGY = cap;
@@ -1,63 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.capabilities;
import java.util.List;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.server.ServerWorld;
import appeng.api.storage.ISpatialDimension;
class NullSpatialDimension implements ISpatialDimension {
@Override
public DimensionType createNewCellDimension(BlockPos size) {
return null;
}
@Override
public void deleteCellDimension(DimensionType cellStorageId) {
}
@Override
public BlockPos getCellDimensionOrigin(DimensionType cellStorageId) {
return null;
}
@Override
public BlockPos getCellDimensionSize(DimensionType cellDim) {
return BlockPos.ZERO;
}
@Override
public void addCellDimensionTooltip(DimensionType cellDim, List<ITextComponent> tooltip) {
}
@Override
public ServerWorld getWorld(DimensionType cellStorageId) {
return null;
}
@Override
public boolean isCellDimension(DimensionType cellDimID) {
return false;
}
}
@@ -39,7 +39,10 @@ import net.minecraftforge.fml.client.registry.ClientRegistry;
import appeng.api.parts.CableRenderMode;
import appeng.block.AEBaseBlock;
import appeng.client.render.effects.*;
import appeng.client.render.effects.EnergyParticleData;
import appeng.client.render.effects.LightningArcFX;
import appeng.client.render.effects.LightningFX;
import appeng.client.render.effects.ParticleTypes;
import appeng.core.AEConfig;
import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
@@ -35,6 +35,7 @@ import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.renderer.BufferBuilder;
@@ -60,6 +61,7 @@ import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.widgets.CustomSlotWidget;
import appeng.client.gui.widgets.ITickingWidget;
import appeng.client.gui.widgets.ITooltip;
import appeng.client.gui.widgets.Scrollbar;
import appeng.client.me.InternalSlotME;
@@ -88,6 +90,9 @@ import appeng.fluids.container.slots.IMEFluidSlot;
import appeng.helpers.InventoryAction;
public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerScreen<T> {
public static final int COLOR_DARK_GRAY = 4210752;
private final List<InternalSlotME> meSlots = new ArrayList<>();
// drag y
private final Set<Slot> drag_click = new HashSet<>();
@@ -176,7 +181,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
}
final String msg = tooltip.getMessage();
if (msg != null) {
if (msg != null && !msg.isEmpty()) {
this.drawTooltip(x + 11, y + 4, msg);
}
}
@@ -781,4 +786,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
protected List<InternalSlotME> getMeSlots() {
return this.meSlots;
}
public void tick() {
super.tick();
for (IGuiEventListener child : children) {
if (child instanceof ITickingWidget) {
((ITickingWidget) child).tick();
}
}
}
}
@@ -0,0 +1,16 @@
package appeng.client.gui;
public enum NumberEntryType {
CRAFT_ITEM_COUNT(Long.class), PRIORITY(Long.class), LEVEL_ITEM_COUNT(Long.class), LEVEL_FLUID_VOLUME(Long.class);
private final Class<? extends Number> inputType;
NumberEntryType(Class<? extends Number> inputType) {
this.inputType = inputType;
}
public Class<? extends Number> getInputType() {
return inputType;
}
}
@@ -8,7 +8,6 @@ import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.definitions.IParts;
import appeng.client.gui.AEBaseScreen;
@@ -18,6 +17,7 @@ import appeng.container.implementations.CraftingTermContainer;
import appeng.container.implementations.MEMonitorableContainer;
import appeng.container.implementations.PatternTermContainer;
import appeng.container.implementations.WirelessTermContainer;
import appeng.core.Api;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.SwitchGuisPacket;
import appeng.helpers.IPriorityHost;
@@ -44,7 +44,7 @@ final class AESubScreen {
public AESubScreen(AEBaseScreen<?> gui, Object containerTarget) {
this.gui = gui;
final IDefinitions definitions = AEApi.instance().definitions();
final IDefinitions definitions = Api.instance().definitions();
final IParts parts = definitions.parts();
if (containerTarget instanceof ChestTileEntity) {
@@ -19,15 +19,13 @@
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.NumberBox;
import appeng.client.gui.NumberEntryType;
import appeng.container.implementations.CraftAmountContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.CraftRequestPacket;
@@ -35,7 +33,7 @@ import appeng.core.sync.packets.CraftRequestPacket;
public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
private final AESubScreen subGui;
private NumberBox amountToCraft;
private NumberEntryWidget amountToCraft;
private Button next;
@@ -48,39 +46,22 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
public void init() {
super.init();
final int a = AEConfig.instance().craftItemsByStackAmounts(0);
final int b = AEConfig.instance().craftItemsByStackAmounts(1);
final int c = AEConfig.instance().craftItemsByStackAmounts(2);
final int d = AEConfig.instance().craftItemsByStackAmounts(3);
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 26, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 26, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 26, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 26, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 75, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 75, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 75, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 75, 38, 20, "-" + d, btn -> addQty(-d)));
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT, value -> {
});
this.amountToCraft.setValue(1);
this.amountToCraft.setTextFieldBounds(62, 57, 50);
this.amountToCraft.setMinValue(1);
this.amountToCraft.addButtons(children::add, this::addButton);
this.next = this.addButton(
new Button(this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.getLocal(), this::confirm));
subGui.addBackButton(this::addButton, 154, 0);
this.amountToCraft = new NumberBox(this.font, this.guiLeft + 62, this.guiTop + 57, 59, this.font.FONT_HEIGHT,
Integer.class);
this.amountToCraft.setEnableBackgroundDrawing(false);
this.amountToCraft.setMaxStringLength(16);
this.amountToCraft.setTextColor(0xFFFFFF);
this.amountToCraft.setVisible(true);
this.amountToCraft.setFocused2(true);
this.amountToCraft.setText("1");
}
private void confirm(Button button) {
NetworkHandler.instance()
.sendToServer(new CraftRequestPacket(Integer.parseInt(this.amountToCraft.getText()), hasShiftDown()));
.sendToServer(new CraftRequestPacket((int) this.amountToCraft.getValue(), hasShiftDown()));
}
@Override
@@ -95,99 +76,23 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
this.bindTexture("guis/craft_amt.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
try {
Long.parseLong(this.amountToCraft.getText());
this.next.active = !this.amountToCraft.getText().isEmpty();
} catch (final NumberFormatException e) {
this.next.active = false;
}
this.next.active = this.amountToCraft.getValue() > 0;
this.amountToCraft.render(offsetX, offsetY, partialTicks);
}
@Override
public boolean charTyped(char ch, int p_charTyped_2_) {
// Forward entered text to the craft amount text-field
return this.amountToCraft.charTyped(ch, p_charTyped_2_);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == 28) {
this.next.onPress();
}
if ((keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14)
&& this.amountToCraft.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
try {
String out = this.amountToCraft.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.amountToCraft.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
final long result = Long.parseLong(out);
if (result < 0) {
this.amountToCraft.setText("1");
}
} catch (final NumberFormatException e) {
// :P
}
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
private void addQty(final int i) {
try {
String out = this.amountToCraft.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.amountToCraft.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
long result = Integer.parseInt(out);
if (result == 1 && i > 1) {
result = 0;
}
result += i;
if (result < 1) {
result = 1;
}
out = Long.toString(result);
Integer.parseInt(out);
this.amountToCraft.setText(out);
} catch (final NumberFormatException e) {
// :P
if (keyCode == 28) {
this.next.onPress();
return true;
} else {
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
}
protected String getBackground() {
return "guis/craftAmt.png";
}
}
@@ -33,13 +33,13 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.AEApi;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.Scrollbar;
import appeng.container.implementations.CraftConfirmContainer;
import appeng.core.Api;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
@@ -51,11 +51,11 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
private final int rows = 5;
private final IItemList<IAEItemStack> storage = AEApi.instance().storage()
private final IItemList<IAEItemStack> storage = Api.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final IItemList<IAEItemStack> pending = AEApi.instance().storage()
private final IItemList<IAEItemStack> pending = Api.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final IItemList<IAEItemStack> missing = AEApi.instance().storage()
private final IItemList<IAEItemStack> missing = Api.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final List<IAEItemStack> visual = new ArrayList<>();
@@ -34,7 +34,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.AEApi;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
@@ -47,6 +46,7 @@ import appeng.client.gui.widgets.ISortSource;
import appeng.client.gui.widgets.Scrollbar;
import appeng.container.implementations.CraftingCPUContainer;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
@@ -79,11 +79,11 @@ public class CraftingCPUScreen<T extends CraftingCPUContainer> extends AEBaseScr
private static final int ITEMSTACK_LEFT_OFFSET = 9;
private static final int ITEMSTACK_TOP_OFFSET = 22;
private IItemList<IAEItemStack> storage = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
private IItemList<IAEItemStack> storage = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private IItemList<IAEItemStack> active = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
private IItemList<IAEItemStack> active = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private IItemList<IAEItemStack> pending = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
private IItemList<IAEItemStack> pending = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private List<IAEItemStack> visual = new ArrayList<>();
@@ -100,9 +100,9 @@ public class CraftingCPUScreen<T extends CraftingCPUContainer> extends AEBaseScr
}
public void clearItems() {
this.storage = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.active = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.pending = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.storage = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.active = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.pending = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.visual = new ArrayList<>();
}
@@ -21,7 +21,6 @@ package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import appeng.api.AEApi;
import appeng.api.config.FullnessMode;
import appeng.api.config.OperationMode;
import appeng.api.config.RedstoneMode;
@@ -30,6 +29,7 @@ import appeng.api.definitions.IDefinitions;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.IOPortContainer;
import appeng.core.Api;
import appeng.core.localization.GuiText;
public class IOPortScreen extends UpgradeableScreen<IOPortContainer> {
@@ -78,7 +78,7 @@ public class IOPortScreen extends UpgradeableScreen<IOPortContainer> {
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
super.drawBG(offsetX, offsetY, mouseX, mouseY, partialTicks);
final IDefinitions definitions = AEApi.instance().definitions();
final IDefinitions definitions = Api.instance().definitions();
definitions.items().cell1k().maybeStack(1)
.ifPresent(cell1kStack -> this.drawItem(offsetX + 66 - 8, offsetY + 17, cell1kStack));
@@ -40,7 +40,6 @@ import net.minecraft.nbt.ListNBT;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.AEApi;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseScreen;
@@ -49,6 +48,7 @@ import appeng.client.gui.widgets.Scrollbar;
import appeng.client.me.ClientDCInternalInv;
import appeng.client.me.SlotDisconnected;
import appeng.container.implementations.InterfaceTerminalContainer;
import appeng.core.Api;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
@@ -321,7 +321,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
final ItemStack parsedItemStack = ItemStack.read(outTag.getCompound(i));
if (!parsedItemStack.isEmpty()) {
final String displayName = Platform.getItemDisplayName(AEApi.instance().storage()
final String displayName = Platform.getItemDisplayName(Api.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createStack(parsedItemStack)).getString()
.toLowerCase();
if (displayName.contains(searchTerm)) {
@@ -18,39 +18,27 @@
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.PowerUnits;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.client.gui.widgets.NumberBox;
import appeng.client.gui.NumberEntryType;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.LevelEmitterContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> {
private NumberBox level;
private Button plus1;
private Button plus10;
private Button plus100;
private Button plus1000;
private Button minus1;
private Button minus10;
private Button minus100;
private Button minus1000;
private NumberEntryWidget level;
private SettingToggleButton<LevelType> levelMode;
private SettingToggleButton<YesNo> craftingMode;
@@ -62,16 +50,17 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
public void init() {
super.init();
this.level = new NumberBox(this.font, this.guiLeft + 24, this.guiTop + 43, 79, this.font.FONT_HEIGHT,
Long.class);
this.level.setEnableBackgroundDrawing(false);
this.level.setMaxStringLength(16);
this.level.setTextColor(0xFFFFFF);
this.level.setVisible(true);
this.level.setFocused2(true);
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT,
this::onLevelChange);
this.level.setTextFieldBounds(25, 44, 75);
this.level.addButtons(children::add, this::addButton);
container.setTextField(this.level);
}
private void onLevelChange(long level) {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(level)));
}
@Override
protected void addButtons() {
this.levelMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 8, Settings.LEVEL_TYPE,
@@ -82,29 +71,6 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
FuzzyMode.IGNORE_ALL);
this.craftingMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 48,
Settings.CRAFT_VIA_REDSTONE, YesNo.NO);
final int a = AEConfig.instance().levelByStackAmounts(0);
final int b = AEConfig.instance().levelByStackAmounts(1);
final int c = AEConfig.instance().levelByStackAmounts(2);
final int d = AEConfig.instance().levelByStackAmounts(3);
this.addButton(this.plus1 = new Button(this.guiLeft + 20, this.guiTop + 17, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(
this.plus10 = new Button(this.guiLeft + 48, this.guiTop + 17, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(
this.plus100 = new Button(this.guiLeft + 82, this.guiTop + 17, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(
this.plus1000 = new Button(this.guiLeft + 120, this.guiTop + 17, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(
this.minus1 = new Button(this.guiLeft + 20, this.guiTop + 59, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(
this.minus10 = new Button(this.guiLeft + 48, this.guiTop + 59, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(
this.minus100 = new Button(this.guiLeft + 82, this.guiTop + 59, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(
this.minus1000 = new Button(this.guiLeft + 120, this.guiTop + 59, 38, 20, "-" + d, btn -> addQty(-d)));
this.addButton(this.levelMode);
this.addButton(this.redstoneMode);
this.addButton(this.craftingMode);
@@ -115,15 +81,7 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
final boolean notCraftingMode = this.bc.getInstalledUpgrades(Upgrades.CRAFTING) == 0;
// configure enabled status...
this.level.setEnabled(notCraftingMode);
this.plus1.active = notCraftingMode;
this.plus10.active = notCraftingMode;
this.plus100.active = notCraftingMode;
this.plus1000.active = notCraftingMode;
this.minus1.active = notCraftingMode;
this.minus10.active = notCraftingMode;
this.minus100.active = notCraftingMode;
this.minus1000.active = notCraftingMode;
this.level.setActive(notCraftingMode);
this.levelMode.active = notCraftingMode;
this.redstoneMode.active = notCraftingMode;
@@ -134,7 +92,14 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
}
if (this.levelMode != null) {
this.levelMode.set(((LevelEmitterContainer) this.cvb).getLevelMode());
LevelType currentLevelMode = ((LevelEmitterContainer) this.cvb).getLevelMode();
this.levelMode.set(currentLevelMode);
if (notCraftingMode) {
if (currentLevelMode == LevelType.ENERGY_LEVEL) {
this.font.drawString(PowerUnits.AE.textComponent().getString(), 110, 44, COLOR_DARK_GRAY);
}
}
}
}
@@ -160,70 +125,4 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
return GuiText.LevelEmitter;
}
private void addQty(final long i) {
try {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
long result = Long.parseLong(Out);
result += i;
if (result < 0) {
result = 0;
}
this.level.setText(Out = Long.toString(result));
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", Out));
} catch (final NumberFormatException e) {
// nope..
this.level.setText("0");
}
}
@Override
public boolean charTyped(char character, int key) {
// Forward entered characters to the number-text-field
return level.charTyped(character, key);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14) {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", Out));
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
}
@@ -28,7 +28,12 @@ import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import appeng.api.config.*;
import appeng.api.config.SearchBoxMode;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.TerminalStyle;
import appeng.api.config.ViewItems;
import appeng.api.implementations.guiobjects.IPortableCell;
import appeng.api.implementations.tiles.IMEChest;
import appeng.api.implementations.tiles.IViewCellStorage;
@@ -37,7 +42,11 @@ import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseMEScreen;
import appeng.client.gui.widgets.*;
import appeng.client.gui.widgets.AETextField;
import appeng.client.gui.widgets.ISortSource;
import appeng.client.gui.widgets.Scrollbar;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.client.gui.widgets.TabButton;
import appeng.client.me.InternalSlotME;
import appeng.client.me.ItemRepo;
import appeng.container.implementations.CraftingStatusContainer;
@@ -0,0 +1,130 @@
package appeng.client.gui.implementations;
import java.util.function.Consumer;
import java.util.function.LongConsumer;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.widget.button.Button;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.NumberEntryType;
import appeng.client.gui.widgets.ITickingWidget;
import appeng.client.gui.widgets.NumberBox;
import appeng.core.AEConfig;
/**
* A utility widget that consists of a text-field to enter a number with
* attached buttons to increment/decrement the number in fixed intervals.
*/
public class NumberEntryWidget implements ITickingWidget {
private final AEBaseScreen<?> parent;
private final int x;
private final int y;
private final NumberBox level;
private final NumberEntryType type;
private Button plus1;
private Button plus10;
private Button plus100;
private Button plus1000;
private Button minus1;
private Button minus10;
private Button minus100;
private Button minus1000;
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type,
LongConsumer changeListener) {
this.parent = parent;
this.x = x;
this.y = y;
this.type = type;
FontRenderer font = parent.getMinecraft().fontRenderer;
int inputX = parent.getGuiLeft() + x;
int inputY = parent.getGuiTop() + y;
this.level = new NumberBox(font, inputX, inputY, width, font.FONT_HEIGHT, type.getInputType(), changeListener);
this.level.setEnableBackgroundDrawing(false);
this.level.setMaxStringLength(16);
this.level.setTextColor(0xFFFFFF);
this.level.setVisible(true);
this.level.setFocused2(true);
parent.setFocusedDefault(this.level);
}
public void setActive(boolean active) {
this.level.setEnabled(active);
this.plus1.active = active;
this.plus10.active = active;
this.plus100.active = active;
this.plus1000.active = active;
this.minus1.active = active;
this.minus10.active = active;
this.minus100.active = active;
this.minus1000.active = active;
}
public void setTextFieldBounds(int x, int y, int width) {
this.level.x = parent.getGuiLeft() + x;
this.level.y = parent.getGuiTop() + y;
this.level.setWidth(width);
}
public void setMinValue(long minValue) {
this.level.setMinValue(minValue);
}
public void addButtons(Consumer<IGuiEventListener> addChildren, Consumer<Button> addButton) {
final int[] steps = AEConfig.instance().getNumberEntrySteps(type);
int a = steps[0];
int b = steps[1];
int c = steps[2];
int d = steps[3];
int left = parent.getGuiLeft() + x;
int top = parent.getGuiTop() + y;
addButton.accept(this.plus1 = new Button(left, top, 22, 20, "+" + a, btn -> addQty(a)));
addButton.accept(this.plus10 = new Button(left + 28, top, 28, 20, "+" + b, btn -> addQty(b)));
addButton.accept(this.plus100 = new Button(left + 62, top, 32, 20, "+" + c, btn -> addQty(c)));
addButton.accept(this.plus1000 = new Button(left + 100, top, 38, 20, "+" + d, btn -> addQty(d)));
// Placing this here will give a sensible tab order
addChildren.accept(this.level);
addButton.accept(this.minus1 = new Button(left, top + 42, 22, 20, "-" + a, btn -> addQty(-a)));
addButton.accept(this.minus10 = new Button(left + 28, top + 42, 28, 20, "-" + b, btn -> addQty(-b)));
addButton.accept(this.minus100 = new Button(left + 62, top + 42, 32, 20, "-" + c, btn -> addQty(-c)));
addButton.accept(this.minus1000 = new Button(left + 100, top + 42, 38, 20, "-" + d, btn -> addQty(-d)));
}
private void addQty(final long i) {
long currentValue = this.level.getValue();
long minValue = this.level.getMinValue();
this.level.setText(String.valueOf(Math.max(minValue, currentValue + i)));
}
public void render(int mouseX, int mouseY, float partialTicks) {
this.level.render(mouseX, mouseY, partialTicks);
}
public void setValue(long value, boolean skipNotify) {
this.level.setValue(value, skipNotify);
}
public void setValue(long value) {
setValue(value, false);
}
public long getValue() {
return level.getValue();
}
@Override
public void tick() {
this.level.tick();
}
}
@@ -18,15 +18,12 @@
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.NumberBox;
import appeng.client.gui.NumberEntryType;
import appeng.container.implementations.PriorityContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
@@ -35,7 +32,7 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
private final AESubScreen subGui;
private NumberBox priority;
private NumberEntryWidget priority;
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, ITextComponent title) {
super(container, playerInventory, title);
@@ -46,31 +43,18 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
public void init() {
super.init();
final int a = AEConfig.instance().priorityByStacksAmounts(0);
final int b = AEConfig.instance().priorityByStacksAmounts(1);
final int c = AEConfig.instance().priorityByStacksAmounts(2);
final int d = AEConfig.instance().priorityByStacksAmounts(3);
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 32, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 32, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 32, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 32, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 69, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 69, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 69, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 69, 38, 20, "-" + d, btn -> addQty(-d)));
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY, this::onPriorityChange);
this.priority.setTextFieldBounds(62, 57, 50);
this.priority.setMinValue(Integer.MIN_VALUE);
container.setTextField(this.priority);
this.priority.addButtons(children::add, this::addButton);
this.subGui.addBackButton(this::addButton, 154, 0);
}
this.priority = new NumberBox(this.font, this.guiLeft + 62, this.guiTop + 57, 59, this.font.FONT_HEIGHT,
Long.class);
this.priority.setEnableBackgroundDrawing(false);
this.priority.setMaxStringLength(16);
this.priority.setTextColor(0xFFFFFF);
this.priority.setVisible(true);
this.priority.setFocused2(true);
container.setTextField(this.priority);
private void onPriorityChange(long priority) {
NetworkHandler.instance()
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(priority)));
}
@Override
@@ -86,90 +70,6 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
this.priority.render(mouseX, mouseY, partialTicks);
}
private void addQty(final int i) {
try {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
long result = Long.parseLong(out);
result += i;
this.priority.setText(out = Long.toString(result));
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
} catch (final NumberFormatException e) {
// nope..
this.priority.setText("0");
}
}
@Override
public boolean charTyped(char character, int key) {
if (priority.charTyped(character, key)) {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
return true;
}
return false;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if ((keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14)
&& this.priority.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
protected String getBackground() {
return "guis/priority.png";
}
@@ -0,0 +1,13 @@
package appeng.client.gui.widgets;
import net.minecraft.client.gui.screen.Screen;
/**
* Indicates that a widget (anything that is in the {@link Screen#children()}
* list) should receive callbacks every tick.
*/
public interface ITickingWidget {
void tick();
}
@@ -18,35 +18,131 @@
package appeng.client.gui.widgets;
import java.util.function.LongConsumer;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
// FIXME: Fix this piece of crap (i.e. onChange listener)
public class NumberBox extends TextFieldWidget {
private final Class type;
private final LongConsumer changeListener;
private long lastValue;
private long minValue = 0;
private long maxValue;
public NumberBox(final FontRenderer fontRenderer, final int x, final int y, final int width, final int height,
final Class type) {
final Class<?> type, LongConsumer changeListener) {
super(fontRenderer, x, y, width, height, "0");
this.type = type;
this.setText("0");
setResponder(this::onTextChanged);
this.lastValue = 0;
this.changeListener = changeListener;
if (type == int.class || type == Integer.class) {
maxValue = Integer.MAX_VALUE;
} else {
maxValue = Long.MAX_VALUE;
}
}
private void onTextChanged(String text) {
if (text.isEmpty()) {
setText("0"); // Will call onTextChanged recursively
return;
}
boolean canBeNegative = canBeNegative();
if (canBeNegative && text.equals("-")) {
// Allow this as a special case to make typing in a negative number easier
return;
}
StringBuilder sanitized = new StringBuilder(text);
boolean encounteredNonZero = false;
for (int i = 0; i < sanitized.length(); i++) {
char ch = sanitized.charAt(i);
if (canBeNegative && i == 0 && ch == '-') {
continue; // Allow leading minus sign
}
if (ch >= '1' && ch <= '9') {
encounteredNonZero = true;
continue;
}
if (ch != '0' || !encounteredNonZero) {
sanitized.deleteCharAt(i--);
}
}
if (sanitized.length() == 0) {
sanitized.append('0');
}
String sanitizedStr = sanitized.toString();
if (!sanitizedStr.equals(text)) {
setText(sanitizedStr); // Will call onTextChanged recursively
return;
}
if (getValue() < minValue) {
setText(String.valueOf(minValue)); // Will call onTextChanged recursively
return;
}
if (getValue() > maxValue) {
setText(String.valueOf(maxValue)); // Will call onTextChanged recursively
return;
}
reportChange();
}
private void reportChange() {
long value = getValue();
if (value != lastValue) {
lastValue = value;
changeListener.accept(value);
}
}
public void setValue(long value, boolean skipNotify) {
// This check avoid changing the cursor position needlessly
if (value == this.getValue()) {
return;
}
if (skipNotify) {
lastValue = value;
}
setText(String.valueOf(value));
}
public long getValue() {
if (getText().equals("-") && canBeNegative()) {
return lastValue; // Allow this as a special case to type in a negative number more easily
}
return Long.parseLong(getText());
}
@Override
public void writeText(final String selectedText) {
final String original = this.getText();
super.writeText(selectedText);
try {
if (this.type == int.class || this.type == Integer.class) {
Integer.parseInt(this.getText());
} else if (this.type == long.class || this.type == Long.class) {
Long.parseLong(this.getText());
} else if (this.type == double.class || this.type == Double.class) {
Double.parseDouble(this.getText());
}
} catch (final NumberFormatException e) {
this.setText(original);
public boolean keyPressed(int p_keyPressed_1_, int p_keyPressed_2_, int p_keyPressed_3_) {
if (super.keyPressed(p_keyPressed_1_, p_keyPressed_2_, p_keyPressed_3_)) {
return true;
}
// Swallow key presses for numbers because they would otherwise trigger the
// hotbar swapping unintentionally
return isFocused() && p_keyPressed_1_ >= '0' && p_keyPressed_1_ <= '9';
}
public void setMinValue(long minValue) {
this.minValue = minValue;
}
public long getMinValue() {
return minValue;
}
private boolean canBeNegative() {
return minValue < 0;
}
}
@@ -314,7 +314,7 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
return name + '\n' + sb;
}
return null;
return "";
}
public String getFillVar() {
@@ -99,7 +99,7 @@ public class ToggleButton extends Button implements ITooltip {
return name + '\n' + sb;
}
return null;
return "";
}
@Override
@@ -27,8 +27,6 @@ import javax.annotation.Nonnull;
import net.minecraft.util.text.ITextComponent;
import appeng.api.AEApi;
import appeng.api.config.Settings;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
import appeng.api.config.YesNo;
@@ -38,6 +36,7 @@ import appeng.api.storage.data.IItemList;
import appeng.client.gui.widgets.IScrollSource;
import appeng.client.gui.widgets.ISortSource;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.fluids.util.FluidSorters;
import appeng.util.Platform;
import appeng.util.prioritylist.IPartitionList;
@@ -48,8 +47,8 @@ import appeng.util.prioritylist.IPartitionList;
* @since rv6 22/05/2018
*/
public class FluidRepo {
private final IItemList<IAEFluidStack> list = AEApi.instance().storage()
.getStorageChannel(IFluidStorageChannel.class).createList();
private final IItemList<IAEFluidStack> list = Api.instance().storage().getStorageChannel(IFluidStorageChannel.class)
.createList();
private final ArrayList<IAEFluidStack> view = new ArrayList<>();
private final IScrollSource src;
private final ISortSource sortSrc;
+2 -2
View File
@@ -28,7 +28,6 @@ import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import appeng.api.AEApi;
import appeng.api.config.SearchBoxMode;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
@@ -39,6 +38,7 @@ import appeng.api.storage.data.IItemList;
import appeng.client.gui.widgets.IScrollSource;
import appeng.client.gui.widgets.ISortSource;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.integration.abstraction.JEIFacade;
import appeng.items.storage.ViewCellItem;
import appeng.util.ItemSorters;
@@ -47,7 +47,7 @@ import appeng.util.prioritylist.IPartitionList;
public class ItemRepo {
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
private final IItemList<IAEItemStack> list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private final ArrayList<IAEItemStack> view = new ArrayList<>();
private final IScrollSource src;
@@ -24,7 +24,12 @@ import java.util.function.Function;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.IModelTransform;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.model.Material;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.IModelConfiguration;
@@ -81,19 +81,19 @@ class CableBuilder {
String textureFolder;
switch (cableType) {
case GLASS:
textureFolder = "parts/cable/glass/";
textureFolder = "part/cable/glass/";
break;
case COVERED:
textureFolder = "parts/cable/covered/";
textureFolder = "part/cable/covered/";
break;
case SMART:
textureFolder = "parts/cable/smart/";
textureFolder = "part/cable/smart/";
break;
case DENSE_COVERED:
textureFolder = "parts/cable/dense_covered/";
textureFolder = "part/cable/dense_covered/";
break;
case DENSE_SMART:
textureFolder = "parts/cable/dense_smart/";
textureFolder = "part/cable/dense_smart/";
break;
default:
throw new IllegalStateException("Cable type " + cableType + " does not support connections.");
@@ -37,7 +37,7 @@ import appeng.core.AppEng;
* Covered (also used by the Smart Cable) - Dense
*/
public enum CableCoreType {
GLASS("parts/cable/core/glass"), COVERED("parts/cable/core/covered"), DENSE("parts/cable/core/dense_smart");
GLASS("part/cable/core/glass"), COVERED("part/cable/core/covered"), DENSE("part/cable/core/dense_smart");
private static final Map<AECableType, CableCoreType> cableMapping = generateCableMapping();
@@ -49,8 +49,8 @@ import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import appeng.api.AEApi;
import appeng.api.util.AEAxisAlignedBB;
import appeng.core.Api;
import appeng.parts.misc.CableAnchorPart;
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
import appeng.thirdparty.codechicken.lib.model.Quad;
@@ -108,7 +108,7 @@ public class FacadeBuilder {
Function<ResourceLocation, IBakedModel> modelLookup) {
BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get();
boolean transparent = AEApi.instance().partHelper().getCableRenderMode().transparentFacades;
boolean transparent = Api.instance().partHelper().getCableRenderMode().transparentFacades;
Map<Direction, FacadeRenderState> facadeStates = renderState.getFacades();
List<AxisAlignedBB> partBoxes = renderState.getBoundingBoxes();
Set<Direction> sidesWithParts = renderState.getAttachments().keySet();
@@ -23,7 +23,7 @@ import appeng.core.AppEng;
public class P2PTunnelFrequencyModel implements IModelGeometry<P2PTunnelFrequencyModel> {
private static final Material TEXTURE = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "parts/p2p_tunnel_frequency"));
new ResourceLocation(AppEng.MOD_ID, "part/p2p_tunnel_frequency"));
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery,
@@ -34,16 +34,16 @@ import appeng.core.AppEng;
public class SmartCableTextures {
public static final Material[] SMART_CHANNELS_TEXTURES = Arrays
.stream(new ResourceLocation[] { new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_00"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_01"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_02"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_03"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_04"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_10"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_11"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_12"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_13"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_14")//
.stream(new ResourceLocation[] { new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_00"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_01"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_02"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_03"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_04"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_10"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_11"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_12"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_13"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_14")//
}).map(e -> new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, e)).toArray(Material[]::new);
// Textures used to display channels on smart cables. There's two sets of 5
@@ -28,8 +28,6 @@ import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.core.AppEng;
@OnlyIn(Dist.CLIENT)
public class ChargedOreFX extends RedstoneParticle {
@@ -34,8 +34,6 @@ import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.core.AppEng;
@OnlyIn(Dist.CLIENT)
public class CraftingFx extends SpriteTexturedParticle {
@@ -20,15 +20,17 @@ package appeng.client.render.effects;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.particle.*;
import net.minecraft.client.particle.IAnimatedSprite;
import net.minecraft.client.particle.IParticleFactory;
import net.minecraft.client.particle.IParticleRenderType;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.SpriteTexturedParticle;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.core.AppEng;
@OnlyIn(Dist.CLIENT)
public class EnergyFx extends SpriteTexturedParticle {
@@ -28,8 +28,6 @@ import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.core.AppEng;
@OnlyIn(Dist.CLIENT)
public class LightningArcFX extends LightningFX {
@@ -37,8 +37,6 @@ import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.core.AppEng;
@OnlyIn(Dist.CLIENT)
public class LightningFX extends SpriteTexturedParticle {
@@ -18,14 +18,17 @@
package appeng.client.render.effects;
import net.minecraft.client.particle.*;
import net.minecraft.client.particle.IAnimatedSprite;
import net.minecraft.client.particle.IParticleFactory;
import net.minecraft.client.particle.IParticleRenderType;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.SpriteTexturedParticle;
import net.minecraft.particles.BasicParticleType;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.util.AEPartLocation;
import appeng.core.AppEng;
public class MatterCannonFX extends SpriteTexturedParticle {
@@ -28,8 +28,6 @@ import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.core.AppEng;
@OnlyIn(Dist.CLIENT)
public class VibrantFX extends SpriteTexturedParticle {
@@ -28,25 +28,39 @@ import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.util.Direction;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import appeng.api.definitions.IItems;
import appeng.block.storage.DriveSlotCellType;
import appeng.block.storage.DriveSlotsState;
import appeng.client.render.DelegateBakedModel;
import appeng.core.Api;
public class DriveBakedModel extends DelegateBakedModel {
private final Map<DriveSlotCellType, IBakedModel> bakedCells;
private final Map<Item, IBakedModel> bakedCells;
private final IBakedModel defaultCell;
public DriveBakedModel(IBakedModel bakedBase, Map<DriveSlotCellType, IBakedModel> bakedCells) {
public DriveBakedModel(IBakedModel bakedBase, Map<Item, IBakedModel> cellModels, IBakedModel defaultCell) {
super(bakedBase);
this.bakedCells = bakedCells;
this.bakedCells = cellModels;
this.defaultCell = defaultCell;
}
/**
* Calculates the origin of a drive slot for positioning a cell model into it.
*/
public static void getSlotOrigin(int row, int col, Vector3f translation) {
// Position this drive model copy at the correct slot. The transform is based on
// the cell-model being in slot 0,0,0 while the upper left slot's origin is at
// 9,13,1
float xOffset = (9 - col * 8) / 16.0f;
float yOffset = (13 - row * 3) / 16.0f;
float zOffset = 1 / 16.0f;
translation.set(xOffset, yOffset, zOffset);
}
@Nonnull
@@ -63,24 +77,21 @@ public class DriveBakedModel extends DelegateBakedModel {
DriveSlotsState slotsState = driveModelData.getSlotsState();
if (side == null && slotsState != null) {
Vector3f slotTranslation = new Vector3f();
if (slotsState != null) {
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 2; col++) {
Matrix4f transform = new Matrix4f();
// Position this drive model copy at the correct slot. The transform is based on
// the
// cell-model being in slot 0,0 at the top left of the drive.
float xOffset = -col * 8 / 16.0f;
float yOffset = -row * 3 / 16.0f;
transform.setTranslation(xOffset, yOffset, 0);
getSlotOrigin(row, col, slotTranslation);
transform.setTranslation(slotTranslation.getX(), slotTranslation.getY(), slotTranslation.getZ());
int slot = row * 2 + col;
// Add the drive chassis
Item cell = slotsState.getCell(slot);
IBakedModel cellChassisModel = getCellChassisModel(cell);
addModel(state, rand, extraData, result, cellChassisModel, transform);
addModel(state, rand, extraData, result, side, cellChassisModel, transform);
}
}
}
@@ -92,29 +103,24 @@ public class DriveBakedModel extends DelegateBakedModel {
public boolean isAmbientOcclusion() {
// We have faces inside the chassis that are facing east, but should not receive
// ambient occlusion from the east-side, but sadly this cannot be fine-tuned on
// a
// face-by-face basis.
// a face-by-face basis.
return false;
}
// Determine which drive chassis to show based on the used cell
private IBakedModel getCellChassisModel(Item cell) {
IItems items = Api.INSTANCE.definitions().items();
if (cell == null) {
return bakedCells.get(DriveSlotCellType.EMPTY);
} else if (items.fluidCell1k().item() == cell || items.fluidCell4k().item() == cell
|| items.fluidCell16k().item() == cell || items.fluidCell64k().item() == cell) {
return bakedCells.get(DriveSlotCellType.FLUID);
} else {
// Fall back to an item model
return bakedCells.get(DriveSlotCellType.ITEM);
return bakedCells.get(Items.AIR);
}
final IBakedModel model = bakedCells.get(cell);
return model != null ? model : defaultCell;
}
private static void addModel(@Nullable BlockState state, @Nonnull Random rand, @Nonnull IModelData extraData,
List<BakedQuad> result, IBakedModel bakedCell, Matrix4f transform) {
List<BakedQuad> result, Direction side, IBakedModel bakedCell, Matrix4f transform) {
MatrixVertexTransformer transformer = new MatrixVertexTransformer(transform);
for (BakedQuad bakedQuad : bakedCell.getQuads(state, null, rand, extraData)) {
for (BakedQuad bakedQuad : bakedCell.getQuads(state, side, rand, extraData)) {
BakedQuadBuilder builder = new BakedQuadBuilder();
transformer.setParent(builder);
transformer.setVertexFormat(builder.getVertexFormat());
@@ -20,13 +20,12 @@ package appeng.client.render.model;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.model.IBakedModel;
@@ -36,39 +35,41 @@ import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.model.Material;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import appeng.block.storage.DriveSlotCellType;
import appeng.api.client.ICellModelRegistry;
import appeng.core.Api;
public class DriveModel implements IModelGeometry<DriveModel> {
private static final ResourceLocation MODEL_BASE = new ResourceLocation(
"appliedenergistics2:block/drive/drive_base");
private static final Map<DriveSlotCellType, ResourceLocation> MODELS_CELLS = ImmutableMap.of(
DriveSlotCellType.EMPTY, new ResourceLocation("appliedenergistics2:block/drive/drive_cell_empty"),
DriveSlotCellType.ITEM, new ResourceLocation("appliedenergistics2:block/drive/drive_cell_items"),
DriveSlotCellType.FLUID, new ResourceLocation("appliedenergistics2:block/drive/drive_cell_fluids"));
public static final Set<ResourceLocation> DEPENDENCIES = ImmutableSet.<ResourceLocation>builder()
.addAll(MODELS_CELLS.values()).add(MODEL_BASE).build();
private static final ResourceLocation MODEL_CELL_EMPTY = new ResourceLocation(
"appliedenergistics2:block/drive/drive_cell_empty");
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery,
Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform,
ItemOverrideList overrides, ResourceLocation modelLocation) {
EnumMap<DriveSlotCellType, IBakedModel> cellModels = new EnumMap<>(DriveSlotCellType.class);
final ICellModelRegistry cellRegistry = Api.instance().client().cells();
final Map<Item, IBakedModel> cellModels = new IdentityHashMap<>();
// Load the base model and the model for each cell state.
for (DriveSlotCellType cellType : MODELS_CELLS.keySet()) {
IBakedModel cellModel = bakery.getBakedModel(MODELS_CELLS.get(cellType), modelTransform, spriteGetter);
cellModels.put(cellType, cellModel);
// Load the base model and the model for each cell model.
for (Entry<Item, ResourceLocation> entry : cellRegistry.models().entrySet()) {
IBakedModel cellModel = bakery.getBakedModel(entry.getValue(), modelTransform, spriteGetter);
cellModels.put(entry.getKey(), cellModel);
}
IBakedModel baseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
return new DriveBakedModel(baseModel, cellModels);
final IBakedModel baseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
final IBakedModel defaultCell = bakery.getBakedModel(cellRegistry.getDefaultModel(), modelTransform,
spriteGetter);
cellModels.put(Items.AIR, bakery.getBakedModel(MODEL_CELL_EMPTY, modelTransform, spriteGetter));
return new DriveBakedModel(baseModel, cellModels, defaultCell);
}
@Override
@@ -184,7 +184,7 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
@Override
public boolean isAmbientOcclusion() {
return true;
return false;
}
@Override
@@ -19,14 +19,12 @@
package appeng.client.render.spatial;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
import appeng.core.AppEng;
public class SpatialPylonRendering extends BlockRenderingCustomizer {

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