Compare commits

..

70 Commits

Author SHA1 Message Date
Ghzdude 6425ef6ecd Fix NPE when posting changes for storage busses (#405) 2024-02-24 10:25:51 +08:00
Yang Xizhi 7ebb2a0fbb allow custom slot jei check and fix fluid color in cell workbanch (#401) 2024-02-18 23:06:07 -06:00
Neeve 20a1fec6fb Recache OreDict Buses on RegEx changes & adjust visibility logic (#395) 2024-02-05 13:05:31 +11:00
Yang Xizhi 0fffc829ab Fix invalid pattern outputs throwing NPE in crafting grid (#393) 2024-02-01 19:14:33 +11:00
NotMyWing 88635d9a8d Do not check white-/blacklist on extract
Slightly rollbacks #384, since extractables are filtered in getAvailableItems
Allows extracting inaccessible items from cells and overriding SB behavior via reporting non-extractables
2024-02-01 18:33:13 +11:00
Neeve 0fd0ed1b1c Fix Fluid Cells having no upgrades (#392) 2024-01-31 19:37:05 +11:00
Neeve 87f884228e Fix ME Storage Buses reporting contents regardless of settings (#384) 2024-01-30 16:10:52 +11:00
Serenibyss 3495d3dfd4 Use LoadingCache instead of HashMap for CableBusBakedModel (#385) 2024-01-30 14:19:50 +11:00
ZHAY10086 0acb03b83d Add zh_cn.lang entries for Sticky Card (#381) 2024-01-21 13:55:57 +11:00
Serenibyss 9adb0359dd Fix player UUID lookup server issue (#380) 2024-01-20 23:44:34 +11:00
Serenibyss ac259dce6a Fix Network Tool not working (#377) 2024-01-16 15:56:12 +11:00
Neeve 7a6d49412e Fix minor slot merge/update regressions (#376) 2024-01-16 15:55:13 +11:00
Yang Xizhi 10f47a560a Fix transformers causing NCDF on specific servers (#374) 2024-01-16 12:36:22 +11:00
Serenibyss a8f0bbe06b Add Sticky Card (#371)
Co-authored-by: NotMyWing <winwyv@gmail.com>
2024-01-16 12:27:13 +11:00
Serenibyss dd3cdfcec5 Fix landing/running particles for cable bus (#372)
Co-authored-by: NotMyWing <winwyv@gmail.com>
2024-01-15 13:40:01 -06:00
Neeve 503f14f0a6 Fix minor slot stack size regression (#375) 2024-01-15 13:39:04 -06:00
Neeve 30af345ceb Update mod base name (#373) 2024-01-16 01:13:04 +11:00
Serenibyss e8af0f228b Update ME IO Port tasks on grid changes (#370) 2024-01-15 18:01:53 +11:00
Serenibyss 0291ceff30 Fix Toast server crash (#367) 2024-01-14 13:15:45 +11:00
NotMyWing d0614ba7d8 Clear modVersion 2024-01-13 17:18:41 +11:00
Neeve 54366e2b35 Initialize GHA workflows for pushing & caching (#359) 2024-01-13 16:58:14 +11:00
Serenibyss d128b0c228 Fix ME Interface Terminal input search not checking beyond first input (#364) 2024-01-13 16:57:54 +11:00
Neeve f7aa4c92bc Fix CellInventory stack size data losses (#363)
Migrates the total item count and serialized stack sizes to `long`
2024-01-13 16:56:26 +11:00
Serenibyss 0709d2dfc4 Color applicator improvements (#360)
* Now properly updates the Applicator's set color when a dye runs out, instead of staying stuck on a color which has no dye left
* Holding Applicator in offhand will now paint cables on placement
* Middle-clicking a colored tile while holding an Applicator in main or off hand will now set the Applicator's color to that color, if the dye is available in the Applicator
2024-01-12 18:21:24 +11:00
mczph 2ea08a3fc9 zh_cn translation fix and additions (#361) 2024-01-09 21:02:40 -06:00
Serenibyss 8c7185f8ff Update buildscripts (#354) 2024-01-09 17:47:53 +11:00
Serenibyss f7651fff29 Add part placement preview, render all part boxes on hover (#349) 2024-01-09 15:53:52 +11:00
Serenibyss 51f2a42367 Tweak transparent Smart Cable texture (#356) 2024-01-09 15:43:36 +11:00
Serenibyss 4829ec8286 Remove part layer api in favor of capabilities (#355) 2024-01-08 09:52:05 -06:00
Serenibyss 0b7341e4a8 Allow for math expressions in GuiCraftAmount textbox (#353) 2024-01-07 13:55:22 +11:00
tier940 b252d1c891 Update ja_jp.lang (#351) 2024-01-02 09:35:24 -06:00
Stone a31de25257 Fix 2 cable rendering bugs (#350) 2024-01-02 09:35:00 -06:00
Serenibyss 01f56ae633 Fix Wireless Access Point displaying energy incorrectly (#346) 2023-12-30 14:41:16 +11:00
Serenibyss 669aa3188e Fix P2P Tunnels dropping ME Tunnels regardless of type (#347) 2023-12-30 14:39:21 +11:00
Neeve 219de337be Update mod metadata (#344) 2023-12-27 23:46:53 -06:00
Stone 7747899e90 Fix ME Level Emitter buttons config and ME IO Port not respecting its redstone mode (#345) 2023-12-28 14:53:46 +11:00
Neeve 82751e761e Add crafting job toasts (#342) 2023-12-25 20:53:51 -06:00
Neeve c4c0585fd3 Allow shift-clicking Patterns into Interface Terminals (#343) 2023-12-25 20:39:35 -06:00
Serenibyss 496e159010 Fix missed ME Interface retextures (#341) 2023-12-25 14:35:02 +11:00
Serenibyss 754ee1ba83 Retexture AE2 machines (#338) 2023-12-25 14:08:19 +11:00
Serenibyss ffe1a52456 Retexture AE2 multiparts (#336) 2023-12-25 13:49:01 +11:00
Serenibyss 28696bd531 Fix and improve cable models (#335) 2023-12-25 13:23:01 +11:00
Serenibyss 29098372af Add blue light for fully empty Cells (#334) 2023-12-25 12:46:13 +11:00
mczph 9dbcf21fa9 Add missing entries and color codes for zh_cn.lang (#339) 2023-12-25 12:36:32 +11:00
Serenibyss a5a1f79102 Change meteor compass to target chest (#332) 2023-12-20 20:01:21 -06:00
Neeve 8fb12119ef Fix oversized slot weirdness (#331) 2023-12-20 13:52:07 +11:00
PrototypeTrousers 7f83c73a28 fix interface dropping stacks over the stack limit. fix potential dupes
fixes #328
2023-12-16 16:30:17 -03:00
Neeve 80a473a93b Fix data loss in BasicCellInventory (#327) 2023-12-15 13:26:43 -03:00
Li adac94555b Remove redundant (#324)
https://github.com/PrototypeTrousers/Applied-Energistics-2/issues/323
2023-11-08 10:37:11 -03:00
PrototypeTrousers 2f11054132 bump version 2023-11-07 18:26:13 -03:00
PrototypeTrousers 1314ee4588 fix wireless pattern terminal not toggling substitution 2023-11-07 18:25:52 -03:00
zeng-git 4484863452 Update mappings to stable_39-1.12 (#322) 2023-11-07 18:21:59 -03:00
PrototypeTrousers ba9b790a02 attempt fix FE p2p when 2023-10-22 23:34:54 -03:00
PrototypeTrousers e4d862dbfd bump version 2023-10-13 03:53:29 -03:00
PrototypeTrousers 812e8c5990 fix #315 2023-10-13 03:50:47 -03:00
PrototypeTrousers e3eeee7784 forgot about fluid configuring terminal 2023-10-13 02:35:14 -03:00
PrototypeTrousers 467bb91628 switch MouseTweaks disabling method 2023-10-12 17:40:56 -03:00
PrototypeTrousers 10a12a9b97 small tweak to pattern terminal search 2023-10-12 16:59:57 -03:00
PrototypeTrousers e5f345d49c remove player inventory from oredict storage bus container 2023-10-12 16:49:59 -03:00
PrototypeTrousers 95ce9694aa slabs -> slab 2023-10-12 02:51:44 -03:00
PrototypeTrousers d1ec1a88ee fix magnet not working before turning it off and on again 2023-10-11 17:20:53 -03:00
PrototypeTrousers bfe82cdc0a fix CT recipe actions not running on crafting terminal crafts 2023-10-11 17:08:23 -03:00
PrototypeTrousers 4fe0d5e767 remove itemstages blocking item crafting 2023-10-11 16:28:06 -03:00
PrototypeTrousers b38148e095 attempt to fix something with terminals again 2023-10-11 14:29:34 -03:00
Neeve d528d9f205 Fix Matter Condenser's math & remove Player's maven (#316)
* Remove Player's maven

* Fix Matter Condenser's math

Fixes outputs getting geometrically compounded
2023-10-11 14:27:35 -03:00
PrototypeTrousers 60211cccdd bump version 2023-09-28 16:44:11 -03:00
Pansmith c3a331c13f Texture Replacements (#312) 2023-09-27 20:46:16 -03:00
tier940 add866443d Update ja_jp.lang (#309)
* Follow the latest

* fix
2023-09-27 20:46:07 -03:00
James Chung bf83de08b2 Add fix for leaking client TEs (#298)
* Add fix for leaking client TEs

* Remove client-side markDirty() call
2023-09-27 20:45:55 -03:00
PrototypeTrousers 6f822af262 bump version 2023-08-27 08:36:13 -03:00
435 changed files with 4519 additions and 3870 deletions
-25
View File
@@ -1,25 +0,0 @@
name: Build mod
on: [ push, pull_request, workflow_dispatch ]
jobs:
build:
name: Build mod
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '8'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew -Pnet.minecraftforge.gradle.disableUpdateChecker=true build
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: appliedenergistics2
path: build/libs
+68
View File
@@ -0,0 +1,68 @@
# Publishes built jars to distribution platforms
name: Publish
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+' # any semver tag, e.g. 1.2.3
env:
# type of release
RELEASE_TYPE: "release"
jobs:
Publish:
runs-on: ubuntu-latest
permissions:
contents: write # needed to create GitHub releases
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Check for Duplicate Tags
run: |
if git rev-parse -q --verify "refs/tags/${{ github.ref }}" >/dev/null; then
echo "Tag already exists. A version bump is required."
exit 1
fi
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Build Project
uses: gradle/gradle-build-action@v2
with:
arguments: 'build --build-cache --daemon' # use the daemon here so the rest of the process is faster
generate-job-summary: false
gradle-home-cache-includes: |
caches
jdks
notifications
wrapper
- name: Publish to GitHub
uses: softprops/action-gh-release@v1
with:
files: "build/libs/*.jar"
generate_release_notes: true
fail_on_unmatched_files: true
- name: Publish to Curseforge
uses: gradle/gradle-build-action@v2
env:
CURSEFORGE_API_KEY: "${{secrets.CURSEFORGE_API_KEY}}"
CURSEFORGE_PROJECT_ID: "${{secrets.CURSEFORGE_PROJECT_ID}}"
RELEASE_TYPE: "${{env.RELEASE_TYPE}}"
with:
arguments: 'curseforge --daemon'
generate-job-summary: false
gradle-home-cache-includes: |
caches
jdks
notifications
wrapper
+39
View File
@@ -0,0 +1,39 @@
# Updates the Gradle Cache when relevant files change
name: Update Gradle Cache
on:
workflow_dispatch:
push:
branches:
- master
paths:
- "gradle**" # covers gradle folder, gradle.properties, gradlew
- "build.gradle*"
- "settings.gradle*"
- "src/main/resources/*_at.cfg" # access transformers
jobs:
Update_Cache:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Update Cache
uses: gradle/gradle-build-action@v2
with:
arguments: 'test --build-cache --no-daemon' # disable daemon since only one gradle operation will happen
generate-job-summary: false
gradle-home-cache-includes: |
caches
jdks
notifications
wrapper
cache-write-only: true
+76 -25
View File
@@ -1,32 +1,83 @@
# exclude all .nopublish
/*
# include important folders ### Windows ###
# need gradle
!gradle/
!gradlew
!gradlew.bat
!build.gradle
!gradle.properties
!settings.gradle
!.travis.yml
# include markdowns thumbs.db
!README.md *.db
!LICENSE
# include sourcecode ### Java ###
!src/
# include git important files *.class
!.gitmodules
!.gitignore
# code format to reduce noise in git commits # Mobile Tools for Java (J2ME)
!codeformat/ .mtj.tmp/
# Github specific files and directories # Package Files #
!.github/ *.war
*.ear
*.txt
# Explicit ignores # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
Thumbs.db hs_err_pid*
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
/eclipse
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### Intellij IDEA ###
*.iml
*.ipr
*.iws
.idea/
.idea_modules/
/classes/
/out/
/build/
# Linux
*~
run/
logs/
-33
View File
@@ -1,33 +0,0 @@
sudo: required
dist: trusty
language: java
jdk:
- oraclejdk8
- openjdk8
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
- rm -f $HOME/.gradle/caches/minecraft/ForgeVersion.json
- rm -f $HOME/.gradle/caches/minecraft/ForgeVersion.json.etag
- rm -fr $HOME/.gradle/caches/minecraft/deobfedDeps
- rm -f $HOME/.gradle/caches/*/fileHashes/fileHashes.bin
- rm -f $HOME/.gradle/caches/*/fileHashes/fileHashes.lock
cache:
directories:
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'
- '$HOME/.gradle/wrapper'
- '$HOME/.gradle/caches'
addons:
sonarcloud:
organization: "appliedenergistics"
install: "./gradlew setupCIWorkspace"
script:
- "./gradlew build"
- "./gradlew test"
- "./gradlew sonarqube"
+14 -6
View File
@@ -1,19 +1,25 @@
This is a fork of AE2 i made for trying to solve issues for the [Omnifactory](https://www.curseforge.com/minecraft/modpacks/omnifactory) modpack. # Applied Energistics 2 Unofficial Extended Life
See [AE2-Omnifactory](https://github.com/PrototypeTrousers/Applied-Energistics-2/tree/AE2-Omnifactory) branch for commits and [Releases](https://github.com/PrototypeTrousers/Applied-Energistics-2/releases) for the compiled jars. [![Downloads](http://cf.way2muchnoise.eu/570458.svg)](https://www.curseforge.com/minecraft/mc-mods/ae2-extended-life) [![MCVersion](http://cf.way2muchnoise.eu/versions/570458.svg)](https://www.curseforge.com/minecraft/mc-mods/ae2-extended-life) [![GitHub issues](https://img.shields.io/github/issues/AE2-UEL/Applied-Energistics-2.svg)](https://github.com/AE2-UEL/Applied-Energistics-2/issues) [![GitHub pull requests](https://img.shields.io/github/issues-pr/AE2-UEL/Applied-Energistics-2.svg)](https://github.com/AE2-UEL/Applied-Energistics-2/pulls)
# Applied Energistics 2 (PrototypeTrousers fork for Omnifactory) ---
## About ## About
A Mod about Matter, Energy and using them to conquer the world.
A maintained fork of a Mod about Matter, Energy and using them to conquer the world.
This project started as a fork of [Applied Energistics 2](https://github.com/AppliedEnergistics/Applied-Energistics-2) by [PrototypeTrousers](https://github.com/PrototypeTrousers), initially addressing issues related to the [Nomifactory](https://www.curseforge.com/minecraft/modpacks/nomifactory) modpack. It is now being maintained by the [AE2 Unofficial Extended Life Team](https://github.com/AE2-UEL).
See [Releases](https://github.com/PrototypeTrousers/Applied-Energistics-2/releases) for the compiled jars.
## RecipeStages ## RecipeStages
You need to add the following into a CraftTweaker script: You need to add the following into a CraftTweaker script:
``` ```
mods.recipestages.Recipes.setPackageStage("appeng", allStages); mods.recipestages.Recipes.setPackageStage("appeng", allStages);
``` ```
The second argument allows you to customize which stages exactly you want to be craftable with AE2. Idk why would you like to restrict any, but you can. The second argument allows you to customize which stages exactly you want to be craftable with AE2. Not sure why you would do that, but we support that nonetheless!
## License ## License
* Applied Energistics 2 API * Applied Energistics 2 API
@@ -29,8 +35,10 @@ The second argument allows you to customize which stages exactly you want to be
- [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/) - [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/)
## Credits ## Credits
Thanks to
Special thanks to:
* PrototypeTrousers for the initial fork
* Notch et al for Minecraft * Notch et al for Minecraft
* Lex et al for MinecraftForge * Lex et al for MinecraftForge
* AlgorithmX2 for AppliedEnergistics2 * AlgorithmX2 for AppliedEnergistics2
+295 -95
View File
@@ -1,3 +1,4 @@
//version: 1704659416
/* /*
* DO NOT CHANGE THIS FILE! * DO NOT CHANGE THIS FILE!
* Also, you may replace this file at any time if there is an update available. * Also, you may replace this file at any time if there is an update available.
@@ -19,23 +20,24 @@ import static org.gradle.internal.logging.text.StyledTextOutput.Style
plugins { plugins {
id 'java' id 'java'
id 'java-library' id 'java-library'
id 'base'
id 'eclipse' id 'eclipse'
id 'maven-publish' id 'maven-publish'
id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7' id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7'
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.19' id 'com.gtnewhorizons.retrofuturagradle' version '1.3.25'
id 'net.darkhax.curseforgegradle' version '1.0.14' apply false id 'net.darkhax.curseforgegradle' version '1.1.17' apply false
id 'com.modrinth.minotaur' version '2.8.0' apply false id 'com.modrinth.minotaur' version '2.8.6' apply false
id 'com.diffplug.spotless' version '6.13.0' apply false id 'com.diffplug.spotless' version '6.13.0' apply false
id 'com.palantir.git-version' version '3.0.0' apply false id 'com.palantir.git-version' version '3.0.0' apply false
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
} id 'org.jetbrains.kotlin.jvm' version '1.8.0' apply false
id 'org.jetbrains.kotlin.kapt' version '1.8.0' apply false
if (verifySettingsGradle()) { id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false
throw new GradleException("Settings has been updated, please re-run task.")
} }
def out = services.get(StyledTextOutputFactory).create('an-output') def out = services.get(StyledTextOutputFactory).create('an-output')
// Project properties // Project properties
// Required properties: we don't know how to handle these being missing gracefully // Required properties: we don't know how to handle these being missing gracefully
@@ -50,31 +52,72 @@ checkPropertyExists("mixinsPackage")
checkPropertyExists("coreModClass") checkPropertyExists("coreModClass")
checkPropertyExists("containsMixinsAndOrCoreModOnly") checkPropertyExists("containsMixinsAndOrCoreModOnly")
// Optional properties: we can assume some default behavior if these are missing
propertyDefaultIfUnset("modVersion", "")
propertyDefaultIfUnset("includeMCVersionJar", false)
propertyDefaultIfUnset("autoUpdateBuildScript", false)
propertyDefaultIfUnset("modArchivesBaseName", project.modId)
propertyDefaultIfUnsetWithEnvVar("developmentEnvironmentUserName", "Developer", "DEV_USERNAME")
propertyDefaultIfUnset("generateGradleTokenClass", "")
propertyDefaultIfUnset("gradleTokenModId", "")
propertyDefaultIfUnset("gradleTokenModName", "")
propertyDefaultIfUnset("gradleTokenVersion", "")
propertyDefaultIfUnset("useSrcApiPath", false)
propertyDefaultIfUnset("includeWellKnownRepositories", true)
propertyDefaultIfUnset("includeCommonDevEnvMods", true)
propertyDefaultIfUnset("noPublishedSources", false)
propertyDefaultIfUnset("forceEnableMixins", false)
propertyDefaultIfUnsetWithEnvVar("enableCoreModDebug", false, "CORE_MOD_DEBUG")
propertyDefaultIfUnset("generateMixinConfig", true)
propertyDefaultIfUnset("usesShadowedDependencies", false)
propertyDefaultIfUnset("minimizeShadowedDependencies", true)
propertyDefaultIfUnset("relocateShadowedDependencies", true)
propertyDefaultIfUnset("separateRunDirectories", false)
propertyDefaultIfUnset("versionDisplayFormat", '$MOD_NAME \u2212 $VERSION')
propertyDefaultIfUnsetWithEnvVar("modrinthProjectId", "", "MODRINTH_PROJECT_ID")
propertyDefaultIfUnset("modrinthRelations", "")
propertyDefaultIfUnsetWithEnvVar("curseForgeProjectId", "", "CURSEFORGE_PROJECT_ID")
propertyDefaultIfUnset("curseForgeRelations", "")
propertyDefaultIfUnsetWithEnvVar("releaseType", "release", "RELEASE_TYPE")
propertyDefaultIfUnset("generateDefaultChangelog", false)
propertyDefaultIfUnset("customMavenPublishUrl", "") propertyDefaultIfUnset("customMavenPublishUrl", "")
propertyDefaultIfUnset("mavenArtifactGroup", getDefaultArtifactGroup())
propertyDefaultIfUnset("enableModernJavaSyntax", false)
propertyDefaultIfUnset("enableSpotless", false)
propertyDefaultIfUnset("enableJUnit", false)
propertyDefaultIfUnsetWithEnvVar("deploymentDebug", false, "DEPLOYMENT_DEBUG")
// Project property assertions // Project property assertions
final String javaSourceDir = 'src/main/java/' final String javaSourceDir = 'src/main/java/'
final String scalaSourceDir = 'src/main/scala/' final String scalaSourceDir = 'src/main/scala/'
// If Kotlin is supported, add the path here final String kotlinSourceDir = 'src/main/kotlin/'
final String modGroupPath = modGroup.toString().replace('.' as char, '/' as char) final String modGroupPath = modGroup.toString().replace('.' as char, '/' as char)
final String apiPackagePath = apiPackage.toString().replace('.' as char, '/' as char) final String apiPackagePath = apiPackage.toString().replace('.' as char, '/' as char)
String targetPackageJava = javaSourceDir + modGroupPath String targetPackageJava = javaSourceDir + modGroupPath
String targetPackageScala = scalaSourceDir + modGroupPath String targetPackageScala = scalaSourceDir + modGroupPath
String targetPackageKotlin = kotlinSourceDir + modGroupPath
// If Kotlin is supported, add the path here if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists() && !getFile(targetPackageKotlin).exists()) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find ${targetPackageJava} or ${targetPackageScala} or ${targetPackageKotlin}")
if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists()) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find ${targetPackageJava} or ${targetPackageScala}")
} }
if (apiPackage) { if (apiPackage) {
targetPackageJava = 'src/api/java/' + modGroupPath + '/api' final String endApiPath = modGroupPath + '/' + apiPackagePath
targetPackageScala = 'src/api/java/' + modGroupPath + '/api' if (useSrcApiPath) {
if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists()) { targetPackageJava = 'src/api/java/' + endApiPath
throw new GradleException("Could not resolve \"apiPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala}") targetPackageScala = 'src/api/scala/' + endApiPath
targetPackageKotlin = 'src/api/kotlin/' + endApiPath
} else {
targetPackageJava = javaSourceDir + endApiPath
targetPackageScala = scalaSourceDir + endApiPath
targetPackageKotlin = kotlinSourceDir + endApiPath
}
if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists() && !getFile(targetPackageKotlin).exists()) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala} or ${targetPackageKotlin}")
} }
} }
@@ -96,8 +139,9 @@ if (usesMixins.toBoolean()) {
final String mixinPackagePath = mixinsPackage.toString().replaceAll('\\.', '/') final String mixinPackagePath = mixinsPackage.toString().replaceAll('\\.', '/')
targetPackageJava = javaSourceDir + modGroupPath + '/' + mixinPackagePath targetPackageJava = javaSourceDir + modGroupPath + '/' + mixinPackagePath
targetPackageScala = scalaSourceDir + modGroupPath + '/' + mixinPackagePath targetPackageScala = scalaSourceDir + modGroupPath + '/' + mixinPackagePath
if (!getFile(targetPackageJava).exists()) { targetPackageKotlin = kotlinSourceDir + modGroupPath + '/' + mixinPackagePath
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala}") if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists() && !getFile(targetPackageKotlin).exists()) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala} or ${targetPackageKotlin}")
} }
} }
@@ -106,13 +150,105 @@ if (coreModClass) {
String targetFileJava = javaSourceDir + modGroupPath + '/' + coreModPath + '.java' String targetFileJava = javaSourceDir + modGroupPath + '/' + coreModPath + '.java'
String targetFileScala = scalaSourceDir + modGroupPath + '/' + coreModPath + '.scala' String targetFileScala = scalaSourceDir + modGroupPath + '/' + coreModPath + '.scala'
String targetFileScalaJava = scalaSourceDir + modGroupPath + '/' + coreModPath + '.java' String targetFileScalaJava = scalaSourceDir + modGroupPath + '/' + coreModPath + '.java'
if (!getFile(targetFileJava).exists() && !getFile(targetFileScala).exists() && !getFile(targetFileScalaJava).exists()) { String targetFileKotlin = kotlinSourceDir + modGroupPath + '/' + coreModPath + '.kt'
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava) if (!getFile(targetFileJava).exists() && !getFile(targetFileScala).exists() && !getFile(targetFileScalaJava).exists() && !getFile(targetFileKotlin).exists()) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find ${targetFileJava} or ${targetFileScala} or ${targetFileScalaJava} or ${targetFileKotlin}")
} }
} }
// Plugin application // Plugin application
// Scala
if (getFile('src/main/scala').exists()) {
apply plugin: 'scala'
}
if (getFile('src/main/kotlin').exists()) {
apply plugin: 'org.jetbrains.kotlin.jvm'
}
// Kotlin
pluginManager.withPlugin('org.jetbrains.kotlin.jvm') {
kotlin {
jvmToolchain(8)
}
def disabledKotlinTaskList = [
"kaptGenerateStubsMcLauncherKotlin",
"kaptGenerateStubsPatchedMcKotlin",
"kaptGenerateStubsInjectedTagsKotlin",
"compileMcLauncherKotlin",
"compilePatchedMcKotlin",
"compileInjectedTagsKotlin",
"kaptMcLauncherKotlin",
"kaptPatchedMcKotlin",
"kaptInjectedTagsKotlin",
"kspMcLauncherKotlin",
"kspPatchedMcKotlin",
"kspInjectedTagsKotlin",
]
tasks.configureEach { task ->
if (task.name in disabledKotlinTaskList) {
task.enabled = false
}
}
}
// Spotless
//noinspection GroovyAssignabilityCheck
project.extensions.add(com.diffplug.blowdryer.Blowdryer, 'Blowdryer', com.diffplug.blowdryer.Blowdryer) // make Blowdryer available in plugin application
if (enableSpotless.toBoolean()) {
apply plugin: 'com.diffplug.spotless'
// Spotless auto-formatter
// See https://github.com/diffplug/spotless/tree/main/plugin-gradle
// Can be locally toggled via spotless:off/spotless:on comments
spotless {
encoding 'UTF-8'
format 'misc', {
target '.gitignore'
trimTrailingWhitespace()
indentWithSpaces(4)
endWithNewline()
}
java {
target 'src/main/java/**/*.java', 'src/test/java/**/*.java' // exclude api as they are not our files
def orderFile = project.file('spotless.importorder')
if (!orderFile.exists()) {
orderFile = Blowdryer.file('spotless.importorder')
}
def formatFile = project.file('spotless.eclipseformat.xml')
if (!formatFile.exists()) {
formatFile = Blowdryer.file('spotless.eclipseformat.xml')
}
toggleOffOn()
importOrderFile(orderFile)
removeUnusedImports()
endWithNewline()
//noinspection GroovyAssignabilityCheck
eclipse('4.19.0').configFile(formatFile)
}
kotlin {
target 'src/*/kotlin/**/*.kt'
toggleOffOn()
ktfmt('0.39')
trimTrailingWhitespace()
indentWithSpaces(4)
endWithNewline()
}
scala {
target 'src/*/scala/**/*.scala'
scalafmt('3.7.1')
}
}
}
// Git version checking, also checking for if this is a submodule // Git version checking, also checking for if this is a submodule
if (project.file('.git/HEAD').isFile() || project.file('.git').isFile()) { if (project.file('.git/HEAD').isFile() || project.file('.git').isFile()) {
apply plugin: 'com.palantir.git-version' apply plugin: 'com.palantir.git-version'
@@ -123,6 +259,9 @@ if (usesShadowedDependencies.toBoolean()) {
apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'com.github.johnrengelman.shadow'
} }
// Configure Java
java { java {
toolchain { toolchain {
if (enableModernJavaSyntax.toBoolean()) { if (enableModernJavaSyntax.toBoolean()) {
@@ -164,8 +303,11 @@ tasks.withType(ScalaCompile).configureEach {
// Allow others using this buildscript to have custom gradle code run // Allow others using this buildscript to have custom gradle code run
if (getFile('addon.gradle').exists()) { if (getFile('addon.gradle').exists()) {
apply from: 'addon.gradle' apply from: 'addon.gradle'
} else if (getFile('addon.gradle.kts').exists()) {
apply from: 'addon.gradle.kts'
} }
// Configure Minecraft // Configure Minecraft
// Try to gather mod version from git tags if version is not manually specified // Try to gather mod version from git tags if version is not manually specified
@@ -183,21 +325,22 @@ if (!modVersion) {
if (includeMCVersionJar.toBoolean()){ if (includeMCVersionJar.toBoolean()){
version = "${minecraftVersion}-${modVersion}" version = "${minecraftVersion}-${modVersion}"
} else { }
else {
version = modVersion version = modVersion
} }
group = modGroup group = modGroup
archivesBaseName = modArchivesBaseName
base {
archivesName = modArchivesBaseName
}
minecraft { minecraft {
mcVersion = minecraftVersion mcVersion = minecraftVersion
username = developmentEnvironmentUserName.toString() username = developmentEnvironmentUserName.toString()
useDependencyAccessTransformers = true useDependencyAccessTransformers = true
setMcpMappingChannel("snapshot")
setMcpMappingVersion("20171003")
// Automatic token injection with RetroFuturaGradle // Automatic token injection with RetroFuturaGradle
if (gradleTokenModId) { if (gradleTokenModId) {
injectedTags.put gradleTokenModId, modId injectedTags.put gradleTokenModId, modId
@@ -209,11 +352,6 @@ minecraft {
injectedTags.put gradleTokenVersion, modVersion injectedTags.put gradleTokenVersion, modVersion
} }
injectedTags.put("VERSION", project.version)
injectedTags.put("AEVERSION", aeversion)
injectedTags.put("AECHANNEL", aechannel)
injectedTags.put("AEBUILD", aebuild)
// JVM arguments // JVM arguments
extraRunJvmArguments.add("-ea:${modGroup}") extraRunJvmArguments.add("-ea:${modGroup}")
if (usesMixins.toBoolean()) { if (usesMixins.toBoolean()) {
@@ -223,8 +361,21 @@ minecraft {
'-Dmixin.debug.export=true' '-Dmixin.debug.export=true'
]) ])
} }
if (enableCoreModDebug.toBoolean()) {
extraRunJvmArguments.addAll([
'-Dlegacy.debugClassLoading=true',
'-Dlegacy.debugClassLoadingFiner=true',
'-Dlegacy.debugClassLoadingSave=true'
])
}
}
if (coreModClass) { if (coreModClass) {
extraRunJvmArguments.add("-Dfml.coreMods.load=${modGroup}.${coreModClass}") for (runTask in ['runClient', 'runServer']) {
tasks.named(runTask).configure {
extraJvmArgs.add("-Dfml.coreMods.load=${modGroup}.${coreModClass}")
}
} }
} }
@@ -236,17 +387,6 @@ tasks.named('processIdeaSettings').configure {
dependsOn('injectTags') dependsOn('injectTags')
} }
tasks.register("generateMcModInfo") {
}
tasks.register("generatePackMcMeta") {
}
tasks.named('processIdeaSettings').configure {
dependsOn('injectTags')
}
// Repositories // Repositories
@@ -263,15 +403,19 @@ repositories.configureEach { repo ->
// Allow adding custom repositories to the buildscript // Allow adding custom repositories to the buildscript
if (getFile('repositories.gradle').exists()) { if (getFile('repositories.gradle').exists()) {
apply from: 'repositories.gradle' apply from: 'repositories.gradle'
} else if (getFile('repositories.gradle.kts').exists()) {
apply from: 'repositories.gradle.kts'
} }
repositories { repositories {
if (includeWellKnownRepositories.toBoolean() || includeCommonDevEnvMods.toBoolean()) {
exclusiveContent { exclusiveContent {
forRepository { forRepository {
//noinspection ForeignDelegate //noinspection ForeignDelegate
maven { maven {
name = 'Curse Maven' name = 'Curse Maven'
url = 'https://www.cursemaven.com' url = 'https://www.cursemaven.com'
// url = 'https://beta.cursemaven.com'
} }
} }
filter { filter {
@@ -298,10 +442,23 @@ repositories {
name 'BlameJared Maven' name 'BlameJared Maven'
url 'https://maven.blamejared.com' url 'https://maven.blamejared.com'
} }
gradlePluginPortal() maven {
mavenCentral() name 'GTNH Maven'
mavenLocal() url 'https://nexus.gtnewhorizons.com/repository/public/'
} }
}
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
// need to add this here even if we did not above
if (!includeWellKnownRepositories.toBoolean()) {
maven {
name 'Cleanroom Maven'
url 'https://maven.cleanroommc.com'
}
}
}
mavenLocal() // Must be last for caching to work
}
// Dependencies // Dependencies
@@ -318,32 +475,31 @@ configurations {
} }
} }
String mixinProviderSpec = 'zone.rong:mixinbooter:8.9'
dependencies { dependencies {
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
implementation 'zone.rong:mixinbooter:7.0'
String mixin = 'org.spongepowered:mixin:0.8.3'
if (usesMixins.toBoolean()) { if (usesMixins.toBoolean()) {
mixin = modUtils.enableMixins(mixin, "mixins.${modId}.refmap.json")
}
api(mixin) {
transitive = false
}
annotationProcessor(mixin) {
transitive = false
}
annotationProcessor 'org.ow2.asm:asm-debug-all:5.2' annotationProcessor 'org.ow2.asm:asm-debug-all:5.2'
// should use 24.1.1 but 30.0+ has a vulnerability fix // should use 24.1.1 but 30.0+ has a vulnerability fix
annotationProcessor 'com.google.guava:guava:30.0-jre' annotationProcessor 'com.google.guava:guava:30.0-jre'
// should use 2.8.6 but 2.8.9+ has a vulnerability fix // should use 2.8.6 but 2.8.9+ has a vulnerability fix
annotationProcessor 'com.google.code.gson:gson:2.8.9' annotationProcessor 'com.google.code.gson:gson:2.8.9'
mixinProviderSpec = modUtils.enableMixins(mixinProviderSpec, "mixins.${modId}.refmap.json")
api (mixinProviderSpec) {
transitive = false
}
annotationProcessor(mixinProviderSpec) {
transitive = false
}
} else if (forceEnableMixins.toBoolean()) {
runtimeOnly(mixinProviderSpec)
} }
if (enableJUnit.toBoolean()) { if (enableJUnit.toBoolean()) {
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
testImplementation 'org.hamcrest:hamcrest:2.2' testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
} }
if (enableModernJavaSyntax.toBoolean()) { if (enableModernJavaSyntax.toBoolean()) {
@@ -364,8 +520,11 @@ dependencies {
testCompileOnly "me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0" testCompileOnly "me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0"
} }
compileOnlyApi 'org.jetbrains:annotations:23.0.0' compileOnlyApi 'org.jetbrains:annotations:24.1.0'
annotationProcessor 'org.jetbrains:annotations:23.0.0' annotationProcessor 'org.jetbrains:annotations:24.1.0'
patchedMinecraft('net.minecraft:launchwrapper:1.17.2') {
transitive = false
}
if (includeCommonDevEnvMods.toBoolean()) { if (includeCommonDevEnvMods.toBoolean()) {
implementation 'mezz.jei:jei_1.12.2:4.16.1.302' implementation 'mezz.jei:jei_1.12.2:4.16.1.302'
@@ -374,11 +533,20 @@ dependencies {
} }
} }
if (getFile('gradle/scripts/dependencies.gradle').exists()) { pluginManager.withPlugin('org.jetbrains.kotlin.kapt') {
apply from: 'gradle/scripts/dependencies.gradle' if (usesMixins.toBoolean()) {
dependencies {
kapt(mixinProviderSpec)
}
}
}
if (getFile('dependencies.gradle').exists()) {
apply from: 'dependencies.gradle'
} else if (getFile('dependencies.gradle.kts').exists()) {
apply from: 'dependencies.gradle.kts'
} }
apply from: 'gradle/scripts/optional.gradle'
// Test configuration // Test configuration
@@ -412,6 +580,7 @@ test {
} }
} }
// Resource processing and jar building // Resource processing and jar building
processResources { processResources {
@@ -464,20 +633,20 @@ tasks.register('generateAssets') {
mcmodInfoFile.text = """[{ mcmodInfoFile.text = """[{
"modid": "\${modid}", "modid": "\${modid}",
"name": "\${modname}", "name": "\${modname}",
"description": "A Mod about Matter, Energy and using them to conquer the world..", "description": "An example mod for Minecraft 1.12.2 with Forge",
"version": "\${version}", "version": "\${version}",
"mcversion": "\${mcversion}", "mcversion": "\${mcversion}",
"logoFile": "assets/appliedenergistics2/meta/logo.png", "logoFile": "",
"url": "https://github.com/PrototypeTrousers/Applied-Energistics-2", "url": "",
"authorList": ["AlgorithmX2"], "authorList": [],
"credits": "AlgorithmX2", "credits": "",
"dependencies": [] "dependencies": []
}] }]
""" """
} }
// mixins.{modid}.json // mixins.{modid}.json
if (usesMixins.toBoolean()) { if (usesMixins.toBoolean() && generateMixinConfig.toBoolean()) {
def mixinConfigFile = getFile("src/main/resources/mixins.${modId}.json") def mixinConfigFile = getFile("src/main/resources/mixins.${modId}.json")
if (!mixinConfigFile.exists()) { if (!mixinConfigFile.exists()) {
def mixinConfigRefmap = "mixins.${modId}.refmap.json" def mixinConfigRefmap = "mixins.${modId}.refmap.json"
@@ -514,27 +683,50 @@ jar {
} }
} }
if (useSrcApiPath && apiPackage) {
from sourceSets.api.output from sourceSets.api.output
dependsOn apiClasses dependsOn apiClasses
// specify which files are really included, can control which APIs should be in include "${modGroupPath}/**"
include "appeng/**"
include "assets/**" include "assets/**"
include "mcmod.info" include "mcmod.info"
include "pack.mcmeta" include "pack.mcmeta"
include "META-INF/appliedenergistics2_at.cfg" if (accessTransformersFile) {
include "META-INF/${accessTransformersFile}"
}
}
}
// Configure default run tasks
if (separateRunDirectories.toBoolean()) {
runClient {
workingDir = file('run/client')
}
runServer {
workingDir = file('run/server')
}
} }
// Create API library jar // Create API library jar
tasks.register('apiJar', Jar) { tasks.register('apiJar', Jar) {
archiveClassifier.set 'api' archiveClassifier.set 'api'
if (useSrcApiPath) {
from(sourceSets.api.java) { from(sourceSets.api.java) {
include "${modGroupPath}/${apiPackagePath}/**" include "${modGroupPath}/${apiPackagePath}/**"
} }
from(sourceSets.api.output) { from(sourceSets.api.output) {
include "${modGroupPath}/${apiPackagePath}/**" include "${modGroupPath}/${apiPackagePath}/**"
} }
} else {
from(sourceSets.main.java) {
include "${modGroupPath}/${apiPackagePath}/**"
}
from(sourceSets.main.output) {
include "${modGroupPath}/${apiPackagePath}/**"
}
}
} }
// Configure shadow jar task // Configure shadow jar task
@@ -727,7 +919,7 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
def changelogFile = getChangelog() def changelogFile = getChangelog()
def changelogRaw = changelogFile.exists() ? changelogFile.getText('UTF-8') : "" def changelogRaw = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
mainFile.displayName = "${modName}: ${modVersion}" mainFile.displayName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion)
mainFile.releaseType = getReleaseType() mainFile.releaseType = getReleaseType()
mainFile.changelog = changelogRaw mainFile.changelog = changelogRaw
mainFile.changelogType = 'markdown' mainFile.changelogType = 'markdown'
@@ -743,6 +935,12 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
} }
String[] parts = dep.split(':') String[] parts = dep.split(':')
String type = parts[0], slug = parts[1] String type = parts[0], slug = parts[1]
def types = [
'req' : 'requiredDependency', 'required': 'requiredDependency',
'opt' : 'optionalDependency', 'optional': 'optionalDependency',
'embed' : 'embeddedLibrary', 'embedded': 'embeddedLibrary',
'incomp': 'incompatible', 'fail' : 'incompatible']
if (types.containsKey(type)) type = types[type]
if (!(type in ['requiredDependency', 'embeddedLibrary', 'optionalDependency', 'tool', 'incompatible'])) { if (!(type in ['requiredDependency', 'embeddedLibrary', 'optionalDependency', 'tool', 'incompatible'])) {
throw new Exception('Invalid Curseforge dependency type: ' + type) throw new Exception('Invalid Curseforge dependency type: ' + type)
} }
@@ -767,6 +965,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
modrinth { modrinth {
token = modrinthApiKey.getOrElse('debug_token') token = modrinthApiKey.getOrElse('debug_token')
projectId = modrinthProjectId projectId = modrinthProjectId
versionName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion)
changelog = changelogFile.exists() ? changelogFile.getText('UTF-8') : "" changelog = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
versionType = getReleaseType() versionType = getReleaseType()
versionNumber = modVersion versionNumber = modVersion
@@ -784,7 +983,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
} }
String[] parts = dep.split(':') String[] parts = dep.split(':')
String[] qual = parts[0].split('-') String[] qual = parts[0].split('-')
addModrinthDep(qual[0], qual[1], parts[1]) addModrinthDep(qual[0], qual.length > 1 ? qual[1] : 'project', parts[1])
} }
} }
tasks.modrinth.dependsOn(build) tasks.modrinth.dependsOn(build)
@@ -793,9 +992,17 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
def addModrinthDep(String scope, String type, String name) { def addModrinthDep(String scope, String type, String name) {
com.modrinth.minotaur.dependencies.Dependency dep com.modrinth.minotaur.dependencies.Dependency dep
def types = [
'req' : 'required',
'opt' : 'optional',
'embed' : 'embedded',
'incomp': 'incompatible', 'fail': 'incompatible']
if (types.containsKey(scope)) scope = types[scope]
if (!(scope in ['required', 'optional', 'incompatible', 'embedded'])) { if (!(scope in ['required', 'optional', 'incompatible', 'embedded'])) {
throw new Exception('Invalid modrinth dependency scope: ' + scope) throw new Exception('Invalid modrinth dependency scope: ' + scope)
} }
types = ['proj': 'project', '': 'project', 'p': 'project', 'ver': 'version', 'v': 'version']
if (types.containsKey(type)) type = types[type]
switch (type) { switch (type) {
case 'project': case 'project':
dep = new ModDependency(name, scope) dep = new ModDependency(name, scope)
@@ -823,8 +1030,8 @@ if (customMavenPublishUrl) {
} }
// providers is not available here, use System for getting env vars // providers is not available here, use System for getting env vars
groupId = System.getenv('ARTIFACT_GROUP_ID') ?: project.group groupId = System.getenv('ARTIFACT_GROUP_ID') ?: project.mavenArtifactGroup
artifactId = System.getenv('ARTIFACT_ID') ?: project.name artifactId = System.getenv('ARTIFACT_ID') ?: project.modArchivesBaseName
version = System.getenv('RELEASE_VERSION') ?: publishedVersion version = System.getenv('RELEASE_VERSION') ?: publishedVersion
} }
} }
@@ -862,7 +1069,6 @@ def getReleaseType() {
* Next, if 'generateDefaultChangelog' option is enabled, use that. * Next, if 'generateDefaultChangelog' option is enabled, use that.
* Otherwise, try to use a CHANGELOG.md file at root directory. * Otherwise, try to use a CHANGELOG.md file at root directory.
*/ */
def getChangelog() { def getChangelog() {
def final changelogEnv = providers.environmentVariable('CHANGELOG_LOCATION') def final changelogEnv = providers.environmentVariable('CHANGELOG_LOCATION')
if (changelogEnv.isPresent()) { if (changelogEnv.isPresent()) {
@@ -877,7 +1083,7 @@ def getChangelog() {
// Buildscript updating // Buildscript updating
def buildscriptGradleVersion = '8.1.1' def buildscriptGradleVersion = '8.5'
tasks.named('wrapper', Wrapper).configure { tasks.named('wrapper', Wrapper).configure {
gradleVersion = buildscriptGradleVersion gradleVersion = buildscriptGradleVersion
@@ -912,29 +1118,18 @@ static URL availableBuildScriptUrl() {
new URL("https://raw.githubusercontent.com/GregTechCEu/Buildscripts/master/build.gradle") new URL("https://raw.githubusercontent.com/GregTechCEu/Buildscripts/master/build.gradle")
} }
static URL exampleSettingsGradleUrl() { static URL availableSettingsGradleUrl() {
new URL("https://raw.githubusercontent.com/GregTechCEu/Buildscripts/master/settings.gradle") new URL("https://raw.githubusercontent.com/GregTechCEu/Buildscripts/master/settings.gradle")
} }
boolean verifySettingsGradle() {
def settingsFile = getFile("settings.gradle")
if (!settingsFile.exists()) {
println("Downloading default settings.gradle")
exampleSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } }
return true
}
return false
}
boolean performBuildScriptUpdate() { boolean performBuildScriptUpdate() {
if (isNewBuildScriptVersionAvailable()) { if (isNewBuildScriptVersionAvailable()) {
def buildscriptFile = getFile("build.gradle") def buildscriptFile = getFile("build.gradle")
def settingsFile = getFile("settings.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } } availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
availableSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } }
def out = services.get(StyledTextOutputFactory).create('buildscript-update-output') def out = services.get(StyledTextOutputFactory).create('buildscript-update-output')
out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!") out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
if (verifySettingsGradle()) {
throw new GradleException("Settings has been updated, please re-run task.")
}
return true return true
} }
return false return false
@@ -981,6 +1176,11 @@ tasks.register('faq') {
// Helpers // Helpers
def getDefaultArtifactGroup() {
def lastIndex = project.modGroup.lastIndexOf('.')
return lastIndex < 0 ? project.modGroup : project.modGroup.substring(0, lastIndex)
}
def getFile(String relativePath) { def getFile(String relativePath) {
return new File(projectDir, relativePath) return new File(projectDir, relativePath)
} }
+52
View File
@@ -0,0 +1,52 @@
//file:noinspection DependencyNotationArgument
// TODO remove when fixed in RFG ^
/*
* Add your dependencies here. Common configurations:
* - implementation("group:name:version:classifier"): if you need this for internal implementation details of the mod.
* Available at compiletime and runtime for your environment.
*
* - compileOnlyApi("g:n:v:c"): if you need this for internal implementation details of the mod.
* Available at compiletime but not runtime for your environment.
*
* - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry
*
* - testCONFIG("g:n:v:c"): replace CONFIG by one of the above, same as above but for the test sources instead of main
*
* You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed.
*
* To add a mod with CurseMaven, replace '("g:n:v:c")' in the above with 'rfg.deobf("curse.maven:project_slug-project_id:file_id")'
* Example: implementation rfg.deobf("curse.maven:gregtech-ce-unofficial-557242:4527757")
*
* To shadow a dependency, use 'shadowImplementation'. For more info, see https://github.com/GregTechCEu/Buildscripts/blob/master/docs/shadow.md
*
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
*/
dependencies {
// Mods always in-game
implementation rfg.deobf("curse.maven:gregtechceu-557242:4429261") // GTCEu
implementation rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848") // CCL 3.2.3.358
implementation rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles
implementation rfg.deobf("curse.maven:industrial-craft-242638:2547175") // IC2
implementation rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry
// Mods only in code by default
compileOnly "curse.maven:chisel-235279:2915375"
compileOnly "curse.maven:hwyla-253449:2568751"
compileOnly "curse.maven:recipe-stages-280554:3405072"
compileOnly "curse.maven:item-stages-280316:2696769"
compileOnly "curse.maven:game-stages-268655:2951844"
compileOnly "net.darkhax.tesla:Tesla-1.12.2:1.0.63"
compileOnly "curse.maven:CoFHCore-69162:2920433"
compileOnly "CraftTweaker2:CraftTweaker2-API:4.1.20.684"
compileOnly "curse.maven:inventory-tweaks-223094:2482482"
compileOnly "curse.maven:inventory-bogo-sorter-632327:4399738"
compileOnly rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31
compileOnly rfg.deobf("curse.maven:actually-additions-228404:3117927") // ActuallyAdditions r152
}
minecraft {
injectedTags.put('AEVERSION', aeversion)
injectedTags.put('AECHANNEL', aechannel)
injectedTags.put('AEBUILD', aebuild)
}
+79 -43
View File
@@ -1,93 +1,91 @@
modName = AE2 Unofficial Extended Life
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
modId = appliedenergistics2
modGroup = appeng
# Version of your mod.
# This field can be left empty if you want your mod's version to be determined by the latest git tag instead.
modVersion =
# AE2 Specific Version Settings
aeversion=rv6 aeversion=rv6
aechannel=stable aechannel=stable
aebuild=7 aebuild=7
aegroup=appeng
aebasename=appliedenergistics2
#########################################################
# Versions #
#########################################################
minecraft_version=1.12.2
mcp_mappings=snapshot_20171003
forge_version=14.23.5.2847
#########################################################
# Installable #
#########################################################
hwyla_version=1.8.26-B41_1.12.2
#########################################################
# Provided APIs #
#########################################################
jei_version=4.16.1.302
tesla_version=1.0.63
ic2_version=2.8.73-ex112
top_version=1.12-1.4.23-16
crafttweaker_version=4.1.20.684
ctm_version=MC1.12.2-0.3.1.16
forestry_version=5.8.2.387
#########################################################
# Deployment #
#########################################################
website_version=1.12.2
curse_versions=1.12.2
mapping_channel=snapshot
mapping_version=20171003
# Run Configurations
minecraft_username=Developer
extra_jvm_args=
modName=Applied Energistics 2
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
modId=appliedenergistics2
modGroup=appeng
# Version of your mod.
# This field can be left empty if you want your mod's version to be determined by the latest git tag instead.
modVersion=rv6-stable-7-extended_life-v0.55.21
# Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version)
includeMCVersionJar = false includeMCVersionJar = false
# The name of your jar when you produce builds, not including any versioning info # The name of your jar when you produce builds, not including any versioning info
modArchivesBaseName=appliedenergistics2 modArchivesBaseName = ae2-uel
# Will update your build.gradle automatically whenever an update is available # Will update your build.gradle automatically whenever an update is available
autoUpdateBuildScript = false autoUpdateBuildScript = false
minecraftVersion = 1.12.2 minecraftVersion = 1.12.2
# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you # Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you
# restart Minecraft in development. Choose this dependent on your mod: # restart Minecraft in development. Choose this dependent on your mod:
# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name # Do you need consistent player progressing (for example Thaumcraft)? -> Select a name
# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty # Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
# Alternatively this can be set with the 'DEV_USERNAME' environment variable. # Alternatively this can be set with the 'DEV_USERNAME' environment variable.
developmentEnvironmentUserName = Developer developmentEnvironmentUserName = Developer
# Enables using modern java syntax (up to version 17) via Jabel, while still targeting JVM 8. # Enables using modern java syntax (up to version 17) via Jabel, while still targeting JVM 8.
# See https://github.com/bsideup/jabel for details on how this works. # See https://github.com/bsideup/jabel for details on how this works.
# Using this requires that you use a Java 17 JDK for development. # Using this requires that you use a Java 17 JDK for development.
enableModernJavaSyntax = true enableModernJavaSyntax = true
# Generate a class with String fields for the mod id, name and version named with the fields below # Generate a class with String fields for the mod id, name and version named with the fields below
generateGradleTokenClass = appeng.Tags generateGradleTokenClass = appeng.Tags
gradleTokenModId= gradleTokenModId = MODID
gradleTokenModName= gradleTokenModName = MODNAME
gradleTokenVersion = VERSION gradleTokenVersion = VERSION
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can # In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty. # leave this property empty.
# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api # Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
apiPackage = api apiPackage = api
# If you want to keep your API code in src/api instead of src/main
useSrcApiPath = true
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/ # Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/
# There can be multiple files in a comma-separated list. # There can be multiple files in a comma-separated list.
# Example value: mymodid_at.cfg,jei_at.cfg # Example value: mymodid_at.cfg,jei_at.cfg
accessTransformersFile = appliedenergistics2_at.cfg accessTransformersFile = appliedenergistics2_at.cfg
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled! # Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = false usesMixins = false
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail! # Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
mixinsPackage = mixinsPackage =
# Automatically generates a mixin config json if enabled, with the name mixins.modid.json
generateMixinConfig = false
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! # Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin # Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
coreModClass = core.AE2ELCore coreModClass = core.AE2ELCore
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod (meaning that # If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod (meaning that
# there is no class annotated with @Mod) you want this to be true. When in doubt: leave it on false! # there is no class annotated with @Mod) you want this to be true. When in doubt: leave it on false!
containsMixinsAndOrCoreModOnly = false containsMixinsAndOrCoreModOnly = false
# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins. # Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins.
forceEnableMixins = false forceEnableMixins = false
# Outputs pre-transformed and post-transformed loaded classes to run/CLASSLOADER_TEMP. Can be used in combination with
# diff to see exactly what your ASM or Mixins are changing in the target file.
# Optionally can be specified with the 'CORE_MOD_DEBUG' env var. Will output a lot of files!
enableCoreModDebug = false
# Adds CurseMaven, Modrinth Maven, BlameJared maven, and some more well-known 1.12.2 repositories # Adds CurseMaven, Modrinth Maven, BlameJared maven, and some more well-known 1.12.2 repositories
includeWellKnownRepositories = true includeWellKnownRepositories = true
# Adds JEI and TheOneProbe to your development environment. Adds them as 'implementation', meaning they will # Adds JEI and TheOneProbe to your development environment. Adds them as 'implementation', meaning they will
# be available at compiletime and runtime for your mod (in-game and in-code). # be available at compiletime and runtime for your mod (in-game and in-code).
# Overrides the above setting to be always true, as these repositories are needed to fetch the mods # Overrides the above setting to be always true, as these repositories are needed to fetch the mods
includeCommonDevEnvMods = true includeCommonDevEnvMods = true
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your # If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your
# responsibility check the licence and request permission for distribution, if required. # responsibility check the licence and request permission for distribution, if required.
usesShadowedDependencies = false usesShadowedDependencies = false
@@ -96,11 +94,22 @@ usesShadowedDependencies=false
minimizeShadowedDependencies = true minimizeShadowedDependencies = true
# If disabled, won't rename the shadowed classes. # If disabled, won't rename the shadowed classes.
relocateShadowedDependencies = true relocateShadowedDependencies = true
# Separate run directories into "run/client" for runClient task, and "run/server" for runServer task.
# Useful for debugging a server and client simultaneously. If not enabled, it will be in the standard location "run/"
separateRunDirectories = false
# The display name format of versions published to Curse and Modrinth. $MOD_NAME and $VERSION are available variables.
# Default: $MOD_NAME \u2212 $VERSION. \u2212 is the minus character which looks much better than the hyphen minus on Curse.
versionDisplayFormat = $MOD_NAME \u2212 $VERSION
# Publishing to modrinth requires you to set the MODRINTH_API_KEY environment variable to your current modrinth API token. # Publishing to modrinth requires you to set the MODRINTH_API_KEY environment variable to your current modrinth API token.
# The project's ID on Modrinth. Can be either the slug or the ID. # The project's ID on Modrinth. Can be either the slug or the ID.
# Leave this empty if you don't want to publish on Modrinth. # Leave this empty if you don't want to publish on Modrinth.
# Alternatively this can be set with the 'MODRINTH_PROJECT_ID' environment variable. # Alternatively this can be set with the 'MODRINTH_PROJECT_ID' environment variable.
modrinthProjectId = modrinthProjectId =
# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth. # The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;... # Syntax: scope1-type1:name1;scope2-type2:name2;...
# Where scope can be one of [required, optional, incompatible, embedded], # Where scope can be one of [required, optional, incompatible, embedded],
@@ -108,38 +117,65 @@ modrinthProjectId=
# and the name is the Modrinth project or version slug/id of the other mod. # and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:jei;optional-project:top;incompatible-project:gregtech # Example: required-project:jei;optional-project:top;incompatible-project:gregtech
modrinthRelations = modrinthRelations =
# Publishing to CurseForge requires you to set the CURSEFORGE_API_KEY environment variable to one of your CurseForge API tokens. # Publishing to CurseForge requires you to set the CURSEFORGE_API_KEY environment variable to one of your CurseForge API tokens.
# The project's numeric ID on CurseForge. You can find this in the About Project box. # The project's numeric ID on CurseForge. You can find this in the About Project box.
# Leave this empty if you don't want to publish on CurseForge. # Leave this empty if you don't want to publish on CurseForge.
# Alternatively this can be set with the 'CURSEFORGE_PROJECT_ID' environment variable. # Alternatively this can be set with the 'CURSEFORGE_PROJECT_ID' environment variable.
curseForgeProjectId = curseForgeProjectId =
# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge. # The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
# Syntax: type1:name1;type2:name2;... # Syntax: type1:name1;type2:name2;...
# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible], # Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
# and the name is the CurseForge project slug of the other mod. # and the name is the CurseForge project slug of the other mod.
# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft # Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
curseForgeRelations = curseForgeRelations =
# This project's release type on CurseForge and/or Modrinth # This project's release type on CurseForge and/or Modrinth
# Alternatively this can be set with the 'RELEASE_TYPE' environment variable.
# Allowed types: release, beta, alpha # Allowed types: release, beta, alpha
releaseType=beta releaseType = release
# Generate a default changelog for releases. Requires git to be installed, as it uses it to generate a changelog of # Generate a default changelog for releases. Requires git to be installed, as it uses it to generate a changelog of
# commits since the last tagged release. # commits since the last tagged release.
generateDefaultChangelog = false generateDefaultChangelog = false
# Prevent the source code from being published # Prevent the source code from being published
noPublishedSources = false noPublishedSources = false
# Publish to a custom maven location. Follows a few rules:
# Group ID can be set with the 'ARTIFACT_GROUP_ID' environment variable, default to 'project.group'
# Artifact ID can be set with the 'ARTIFACT_ID' environment variable, default to 'project.name'
# Version can be set with the 'RELEASE_VERSION' environment variable, default to 'modVersion'
# For maven credentials:
# Username is set with the 'MAVEN_USER' environment variable, default to "NONE"
# Password is set with the 'MAVEN_PASSWORD' environment variable, default to "NONE"
customMavenPublishUrl =
# The group for maven artifacts. Defaults to the 'project.modGroup' until the last '.' (if any).
# So 'mymod' becomes 'mymod' and 'com.myname.mymodid' 'becomes com.myname'
mavenArtifactGroup =
# Enable spotless checks # Enable spotless checks
# Enforces code formatting on your source code # Enforces code formatting on your source code
# By default this will use the files found here: https://github.com/GregTechCEu/Buildscripts/tree/master/spotless # By default this will use the files found here: https://github.com/GregTechCEu/Buildscripts/tree/master/spotless
# to format your code. However, you can create your own version of these files and place them in your project's # to format your code. However, you can create your own version of these files and place them in your project's
# root directory to apply your own formatting options instead. # root directory to apply your own formatting options instead.
enableSpotless = false enableSpotless = false
# Enable JUnit testing platform used for testing your code. # Enable JUnit testing platform used for testing your code.
# Uses JUnit 5. See guide and documentation here: https://junit.org/junit5/docs/current/user-guide/ # Uses JUnit 5. See guide and documentation here: https://junit.org/junit5/docs/current/user-guide/
enableJUnit = true enableJUnit = true
# Deployment debug setting # Deployment debug setting
# Uncomment this to test deployments to CurseForge and Modrinth # Uncomment this to test deployments to CurseForge and Modrinth
# Alternatively, you can set the 'DEPLOYMENT_DEBUG' environment variable. # Alternatively, you can set the 'DEPLOYMENT_DEBUG' environment variable.
deploymentDebug = false deploymentDebug = false
# Gradle Settings # Gradle Settings
# Effectively applies the '--stacktrace' flag by default # Effectively applies the '--stacktrace' flag by default
org.gradle.logging.stacktrace = all org.gradle.logging.stacktrace = all
-120
View File
@@ -1,120 +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>.
*/
repositories {
mavenLocal()
maven {
url "https://cursemaven.com"
}
maven {
name = "CurseForge"
url = "https://minecraft.curseforge.com/api/maven/"
}
maven {
name "Mobius"
url "http://mobiusstrip.eu/maven"
}
maven {
name = "JEI repo"
url "http://dvs1.progwml6.com/files/maven"
}
maven {
name "Ellpeck"
url "https://maven.ellpeck.de"
}
maven {
name = "IC2 repo"
url = "http://maven.ic2.player.to"
}
maven {
name = "CoFH Maven"
url = "http://maven.covers1624.net"
}
maven { // TheOneProbe
name 'tterrag maven'
url "http://maven.tterrag.com/"
}
maven { // McJtyLib
name 'mcjty'
url "http://maven.k-4u.nl/"
}
maven { // CraftTweaker
name 'jared maven'
url "http://maven.blamejared.com/"
}
//maven { // modmaven, maven proxy
// name 'modmaven'
// url "https://modmaven.k-4u.nl/"
//}
}
configurations {
mods
}
dependencies {
// deobfCompile "gregtechce:gregtech:1.12.2:1.15.1.735"
// installable runtime dependencies
implementation rfg.deobf("curse.maven:gregtechceu-557242:4429261")
compileOnly "curse.maven:chisel-235279:2915375"
implementation rfg.deobf("curse.maven:baubles-227083:2518667")
//mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
mods "curse.maven:hwyla-253449:2568751"
mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev"
mods "mcjty.theoneprobe:TheOneProbe-${minecraft_version}:${top_version}"
// compile against provided APIs
compileOnly "mezz.jei:jei_${minecraft_version}:${jei_version}:api"
//compileOnly "mcp.mobius.waila:Hwyla:${hwyla_version}"
compileOnly "curse.maven:hwyla-253449:2568751"
//Code chicken lib, GTCE dependency
implementation rfg.deobf("curse.maven:CCL-242818:2779848")
compileOnly "curse.maven:recipe-stages-280554:3405072"
compileOnly "curse.maven:item-stages-280316:2696769"
compileOnly "curse.maven:game-stages-268655:2951844"
compileOnly "net.darkhax.tesla:Tesla-1.12.2:${tesla_version}"
compileOnly "net.industrial-craft:industrialcraft-2:${ic2_version}:api"
compileOnly "mcjty.theoneprobe:TheOneProbe-1.12:${top_version}:api"
compileOnly "curse.maven:CoFHCore-69162:2920433"
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
compileOnly "curse.maven:inventory-tweaks-223094:2482482"
compileOnly "curse.maven:inventory-bogo-sorter-632327:4399738"
compileOnly "team.chisel.ctm:CTM:${ctm_version}"
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
implementation rfg.deobf("net.sengir.forestry:forestry_${minecraft_version}:$forestry_version")
// at runtime, use the full JEI jar
runtimeOnly "mezz.jei:jei_${minecraft_version}:${jei_version}"
// unit test dependencies
testImplementation "junit:junit:4.12"
}
-54
View File
@@ -1,54 +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>.
*/
// HWYLA
tasks.register('installHwyla', Copy) {
dependsOn "deinstallHwyla"
from { configurations.mods }
include "**/*Hwyla*.jar"
into file("/run/mods")
}
tasks.register('deinstallHwyla', Delete) {
delete fileTree(dir: "/run/mods", include: "*Hwyla*.jar")
}
// IC2
tasks.register('installIC2', Copy) {
dependsOn "deinstallIC2"
from { configurations.mods }
include "**/*industrialcraft-2*.jar"
into file("/run/mods")
}
tasks.register('deinstallIC2', Delete) {
delete fileTree(dir: "/run/mods", include: "*industrialcraft-2*.jar")
}
// TOP
tasks.register('installTop', Copy) {
dependsOn["deinstallTop"]
from { configurations.mods }
include "**/*TheOneProbe*.jar"
into file("/run/mods")
}
tasks.register('deinstallTop', Delete) {
delete fileTree(dir: "/run/mods", include: "*TheOneProbe*.jar")
}
+2 -1
View File
@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
Vendored
+8 -4
View File
@@ -85,9 +85,6 @@ done
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@@ -133,11 +130,14 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
@@ -197,6 +197,10 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in # shell script including quotes and variable substitutions, so put them in
Vendored
+30 -22
View File
@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@@ -10,18 +26,22 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS= set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if %ERRORLEVEL% equ 0 goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +55,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,38 +65,26 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal
+8 -4
View File
@@ -3,9 +3,7 @@ pluginManagement {
maven { maven {
// RetroFuturaGradle // RetroFuturaGradle
name 'GTNH Maven' name 'GTNH Maven'
//noinspection HttpUrlsUsage url 'https://nexus.gtnewhorizons.com/repository/public/'
url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/'
allowInsecureProtocol = true
//noinspection GroovyAssignabilityCheck //noinspection GroovyAssignabilityCheck
mavenContent { mavenContent {
includeGroup 'com.gtnewhorizons' includeGroup 'com.gtnewhorizons'
@@ -19,8 +17,14 @@ pluginManagement {
} }
plugins { plugins {
id 'com.diffplug.blowdryerSetup' version '1.7.0'
// Automatic toolchain provisioning // Automatic toolchain provisioning
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0' id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}
blowdryerSetup {
repoSubfolder 'spotless'
github 'GregTechCEu/Buildscripts', 'tag', 'v1.0.7'
} }
rootProject.name = rootProject.projectDir.getName() rootProject.name = rootProject.projectDir.getName()
+5 -1
View File
@@ -81,7 +81,11 @@ public enum Settings
PLACE_BLOCK( EnumSet.of( YesNo.YES, YesNo.NO ) ), PLACE_BLOCK( EnumSet.of( YesNo.YES, YesNo.NO ) ),
SCHEDULING_MODE( EnumSet.allOf( SchedulingMode.class ) ); SCHEDULING_MODE( EnumSet.allOf( SchedulingMode.class ) ),
STICKY_MODE( EnumSet.of( YesNo.YES, YesNo.NO ) ),
;
private final EnumSet<? extends Enum<?>> values; private final EnumSet<? extends Enum<?>> values;
@@ -40,6 +40,7 @@ public enum Upgrades {
REDSTONE(0), REDSTONE(0),
CRAFTING(0), CRAFTING(0),
MAGNET(0), MAGNET(0),
STICKY(0),
/** /**
* Diamond Tier Upgrades. * Diamond Tier Upgrades.
@@ -100,6 +100,8 @@ public interface IMaterials {
IItemDefinition cardCrafting(); IItemDefinition cardCrafting();
IItemDefinition cardSticky();
IItemDefinition enderDust(); IItemDefinition enderDust();
IItemDefinition flour(); IItemDefinition flour();
@@ -40,11 +40,13 @@ public interface IChestOrDrive extends ICellContainer, IGridHost, IOrientable
/** /**
* 0 - cell is missing. * 0 - cell is missing.
* *
* 1 - green, * 1 - green, the cell is present and partially empty
* *
* 2 - orange, * 2 - orange, the cell is present and full on types
* *
* 3 - red * 3 - red, the cell is present and full on bytes
*
* 4 - blue, the cell is present but totally empty
* *
* @param slot slot index * @param slot slot index
* *
@@ -41,6 +41,13 @@ import appeng.api.util.AEPartLocation;
public interface IFacadeContainer public interface IFacadeContainer
{ {
/**
* Checks if the {@link IFacadePart} can be added to the given side.
*
* @return true if the facade can be successfully added
*/
boolean canAddFacade( IFacadePart a );
/** /**
* Attempts to add the {@link IFacadePart} to the given side. * Attempts to add the {@link IFacadePart} to the given side.
* *
+50 -26
View File
@@ -24,6 +24,7 @@
package appeng.api.parts; package appeng.api.parts;
import appeng.api.util.AEPartLocation;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumActionResult;
@@ -32,35 +33,11 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nullable;
public interface IPartHelper public interface IPartHelper
{ {
/**
* Register a new layer with the part layer system, this allows you to write an in between between tile entities and
* parts.
*
* AE By Default includes,
*
* 1. ISidedInventory ( and by extension IInventory. )
*
* 2. IFluidHandler Forge Fluids
*
* 3. IPowerEmitter BC Power output.
*
* 4. IPowerReceptor BC Power input.
*
* 5. IEnergySink IC2 Power input.
*
* 6. IEnergySource IC2 Power output.
*
* 7. IPipeConnection BC Pipe Connections
*
* As long as a valid layer is registered for a interface you can simply implement that interface on a part get
* implement it.
*
* @return true on success, false on failure, usually a error will be logged as well.
*/
boolean registerNewLayer( String string, String layerInterface );
/** /**
* use in use item, to try and place a IBusItem * use in use item, to try and place a IBusItem
@@ -79,4 +56,51 @@ public interface IPartHelper
* @return the render mode * @return the render mode
*/ */
CableRenderMode getCableRenderMode(); CableRenderMode getCableRenderMode();
/**
* Try to get a part at a specific place in the world.
*
* @param w world the part is in
* @param pos pos of the part host
* @param side side to test for a part on.
*
* @return the part if it exists, null otherwise
*/
@Nullable
IPart getPart( World w, BlockPos pos, AEPartLocation side );
/**
* Try to get a part host at a specific place in the world.
*
* @param w world the part host is in
* @param pos pos of the part host
*
* @return the part host if it exists, null otherwise
*/
@Nullable
IPartHost getPartHost( World w, BlockPos pos );
/**
* Get a part host if it exists, or place one if it doesn't.
*
* @param w world the part host is in
* @param pos pos to get or place the part host
* @param force whether to skip permission and existing block checks and forcibly place the part host here.
* @param p the placing player, or null if none
*
* @return the existing or created part host, or null if it didn't already exist and part host is unable to be placed.
*/
@Nullable
IPartHost getOrPlacePartHost( World w, BlockPos pos, boolean force, @Nullable EntityPlayer p );
/**
* Test if a part host can be successfully placed at a given position by the provided player.
*
* @param w world the part host is in
* @param pos pos to test for part host placement
* @param p the placing player, or null if none
*
* @return if the part can be placed at the provided world and position
*/
boolean canPlacePartHost( World w, BlockPos pos, @Nullable EntityPlayer p );
} }
+12 -6
View File
@@ -145,13 +145,24 @@ public interface IPartHost extends ICustomCableConnection
*/ */
SelectedPart selectPart( Vec3d pos ); SelectedPart selectPart( Vec3d pos );
/**
* Same as {@link #selectPart(Vec3d)}, but with global instead of local coordinates.
*/
default SelectedPart selectPartGlobal( Vec3d pos ) {
DimensionalCoord globalPos = getLocation();
return selectPart(pos.subtract(
globalPos.getPos().getX(),
globalPos.getPos().getY(),
globalPos.getPos().getZ()));
}
/** /**
* can be used by parts to trigger the tile or part to save. * can be used by parts to trigger the tile or part to save.
*/ */
void markForSave(); void markForSave();
/** /**
* part of the {@link LayerBase} * called when parts are added or removed
*/ */
void partChanged(); void partChanged();
@@ -169,11 +180,6 @@ public interface IPartHost extends ICustomCableConnection
*/ */
boolean isEmpty(); boolean isEmpty();
/**
* @return a mutable list of flags you can adjust to track state.
*/
Set<LayerFlags> getLayerFlags();
/** /**
* remove host from world... * remove host from world...
*/ */
@@ -1,98 +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.parts;
import java.util.Set;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import appeng.api.util.AEPartLocation;
/**
* All Layers must extends this, this get part implementation is provided to interface with the parts, however a real
* implementation will be used at runtime.
*
* TODO: Consider removing and replacing with capabilities.
*/
public abstract class LayerBase extends TileEntity // implements IPartHost
{
/**
* Grants access for the layer to the parts of the host.
*
* This Method looks silly, that is because its not used at runtime, a real implementation will be used instead.
*
* @param side side of part
*
* @return the part for the requested side.
*/
public IPart getPart( final AEPartLocation side )
{
return null; // place holder.
}
/**
* Grants access for the layer to the parts of the host.
*
* This Method looks silly, that is because its not used at runtime, a real implementation will be used instead.
*
* @param side side of part
*
* @return the part for the requested side.
*/
public IPart getPart( final EnumFacing side )
{
return null; // place holder.
}
/**
* called when the parts change in the container, YOU MUST CALL super.PartChanged();
*/
public void notifyNeighbors()
{
}
/**
* called when the parts change in the container, YOU MUST CALL super.PartChanged();
*/
public void partChanged()
{
}
/**
* @return a mutable list of flags you can adjust to track state.
*/
public Set<LayerFlags> getLayerFlags()
{
return null; // place holder.
}
public void markForSave()
{
// something!
}
}
@@ -1,35 +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.parts;
/**
* TODO: Consider removing and replacing with capabilities.
*/
public enum LayerFlags
{
IC2_ENET
}
@@ -123,6 +123,8 @@ public interface ICellInventory<T extends IAEStack<T>> extends IMEInventory<T>
* *
* 3 - red, ( usually means the cell is 100% full ) * 3 - red, ( usually means the cell is 100% full )
* *
* 4 - blue, ( usually means the cell is available and completely empty. )
*
* @return get the status of the cell based on its contents. * @return get the status of the cell based on its contents.
*/ */
int getStatusForCell(); int getStatusForCell();
@@ -89,4 +89,12 @@ public interface IMEInventoryHandler<T extends IAEStack<T>> extends IMEInventory
* @return true, if this inventory is valid for this pass. * @return true, if this inventory is valid for this pass.
*/ */
boolean validForPass( int i ); boolean validForPass( int i );
/**
* Gets whether an inventory is "Sticky" i.e. only it and other sticky storages that have partitions with certain
* items are allowed to be put into sticky storages.
*/
default boolean isSticky() {
return false;
}
} }
@@ -1,87 +0,0 @@
package yalter.mousetweaks.api;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
/**
* This is the interface you want to implement in your GuiScreen to make it compatible with Mouse Tweaks.
* If this interface is not enough (for example, you need a custom slot click function, or if you use a custom Container
* which happens to be incompatible), check IMTModGuiContainer2Ex instead.
* If you just need to disable Mouse Tweaks or the wheel tweak, see the MouseTweaksIgnore
* or the MouseTweaksDisableWheelTweak annotations.
*/
public interface IMTModGuiContainer2 {
/**
* If you want to disable Mouse Tweaks in your GuiScreen, return true from this method.
*
* @return True if Mouse Tweaks should be disabled, false otherwise.
*/
boolean MT_isMouseTweaksDisabled();
/**
* If you want to disable the Wheel Tweak in your GuiScreen, return true from this method.
*
* @return True if the Wheel Tweak should be disabled, false otherwise.
*/
boolean MT_isWheelTweakDisabled();
/**
* Returns the Container.
*
* @return Container that is currently in use.
*/
Container MT_getContainer();
/**
* Returns the Slot that is currently selected by the player, or null if no Slot is selected.
*
* @return Slot that is located under the mouse, or null if no Slot it currently under the mouse.
*/
Slot MT_getSlotUnderMouse();
/**
* Return true if the given Slot behaves like the vanilla crafting output slots (inside the crafting table,
* or the furnace output slot, or the anvil output slot, etc.). These slots are handled differently by Mouse Tweaks.
*
* @param slot the slot to check
* @return True if slot is a crafting output slot.
*/
boolean MT_isCraftingOutput(Slot slot);
/**
* Return true if the given Slot should be ignored by Mouse Tweaks. Examples of ignored slots are the item select
* slots and the Destroy Item slot in the vanilla creative inventory.
*
* @param slot the slot to check
* @return Tru if slot should be ignored by Mouse Tweaks.
*/
boolean MT_isIgnored(Slot slot);
/**
* If your container has an RMB dragging functionality (like vanilla containers), disable it inside this method.
* This method is called every frame (render tick), which is after all mouseClicked / mouseClickMove / mouseReleased
* events are handled (although note these events are handled every game tick, which is far less frequent than every
* render tick).<br><br>
*
* If true is returned from this method, Mouse Tweaks (after checking other conditions like isIgnored) will click
* the slot on which the right mouse button was initially pressed (in most cases this is the slot currently under
* mouse). This is needed because the vanilla RMB dragging functionality prevents the initial slot click.<br><br>
*
* For vanilla containers this method looks like this:
* <pre>
* this.ignoreMouseUp = true;
*
* if (this.dragSplitting) {
* if (this.dragSplittingButton == 1) {
* this.dragSplitting = false;
* return true;
* }
* }
*
* return false;
* </pre>
*
* @return True if Mouse Tweaks should click the slot on which the RMB was pressed.
*/
boolean MT_disableRMBDraggingFunctionality();
}
@@ -0,0 +1,14 @@
package yalter.mousetweaks.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Put this on your GuiScreen to disable Mouse Tweaks.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MouseTweaksIgnore {
}
+7 -7
View File
@@ -307,13 +307,13 @@ public abstract class AEBaseBlock extends Block {
return dir; return dir;
} }
final int west_x = forward.getFrontOffsetY() * up.getFrontOffsetZ() - forward.getFrontOffsetZ() * up.getFrontOffsetY(); final int west_x = forward.getYOffset() * up.getZOffset() - forward.getZOffset() * up.getYOffset();
final int west_y = forward.getFrontOffsetZ() * up.getFrontOffsetX() - forward.getFrontOffsetX() * up.getFrontOffsetZ(); final int west_y = forward.getZOffset() * up.getYOffset() - forward.getXOffset() * up.getZOffset();
final int west_z = forward.getFrontOffsetX() * up.getFrontOffsetY() - forward.getFrontOffsetY() * up.getFrontOffsetX(); final int west_z = forward.getXOffset() * up.getYOffset() - forward.getYOffset() * up.getXOffset();
EnumFacing west = null; EnumFacing west = null;
for (final EnumFacing dx : EnumFacing.VALUES) { for (final EnumFacing dx : EnumFacing.VALUES) {
if (dx.getFrontOffsetX() == west_x && dx.getFrontOffsetY() == west_y && dx.getFrontOffsetZ() == west_z) { if (dx.getXOffset() == west_x && dx.getYOffset() == west_y && dx.getZOffset() == west_z) {
west = dx; west = dx;
} }
} }
@@ -348,12 +348,12 @@ public abstract class AEBaseBlock extends Block {
@Override @Override
public String toString() { public String toString() {
String regName = this.getRegistryName() != null ? this.getRegistryName().getResourcePath() : "unregistered"; String regName = this.getRegistryName() != null ? this.getRegistryName().getPath() : "unregistered";
return this.getClass().getSimpleName() + "[" + regName + "]"; return this.getClass().getSimpleName() + "[" + regName + "]";
} }
protected String getUnlocalizedName(final ItemStack is) { protected String getTranslationKey(final ItemStack is) {
return this.getUnlocalizedName(); return this.getTranslationKey();
} }
protected boolean hasCustomRotation() { protected boolean hasCustomRotation() {
@@ -38,6 +38,7 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
@@ -77,8 +78,9 @@ public class AEBaseItemBlock extends ItemBlock {
} }
@Override @Override
public String getUnlocalizedName(final ItemStack is) { @NotNull
return this.blockType.getUnlocalizedName(is); public String getTranslationKey(final ItemStack is) {
return this.blockType.getTranslationKey(is);
} }
@Override @Override
@@ -137,7 +139,7 @@ public class AEBaseItemBlock extends ItemBlock {
ori = ((IOrientableBlock) this.blockType).getOrientable(w, pos); ori = ((IOrientableBlock) this.blockType).getOrientable(w, pos);
up = side; up = side;
forward = EnumFacing.SOUTH; forward = EnumFacing.SOUTH;
if (up.getFrontOffsetY() == 0) { if (up.getYOffset() == 0) {
forward = EnumFacing.UP; forward = EnumFacing.UP;
} }
} }
@@ -36,16 +36,16 @@ public abstract class AEBaseStairBlock extends BlockStairs {
super(block.getDefaultState()); super(block.getDefaultState());
Preconditions.checkNotNull(block); Preconditions.checkNotNull(block);
Preconditions.checkNotNull(block.getUnlocalizedName()); Preconditions.checkNotNull(block.getTranslationKey());
Preconditions.checkArgument(block.getUnlocalizedName().length() > 0); Preconditions.checkArgument(block.getTranslationKey().length() > 0);
this.setUnlocalizedName("stair." + type); this.setTranslationKey("stair." + type);
this.setLightOpacity(0); this.setLightOpacity(0);
} }
@Override @Override
public String toString() { public String toString() {
String regName = this.getRegistryName() != null ? this.getRegistryName().getResourcePath() : "unregistered"; String regName = this.getRegistryName() != null ? this.getRegistryName().getPath() : "unregistered";
return this.getClass().getSimpleName() + "[" + regName + "]"; return this.getClass().getSimpleName() + "[" + regName + "]";
} }
@@ -288,7 +288,7 @@ public abstract class AEBaseTileBlock extends AEBaseBlock implements ITileEntity
return false; return false;
} }
final String name = this.getUnlocalizedName(); final String name = this.getTranslationKey();
if (player.isSneaking()) { if (player.isSneaking()) {
final NBTTagCompound data = tileEntity.downloadSettings(SettingsFrom.MEMORY_CARD); final NBTTagCompound data = tileEntity.downloadSettings(SettingsFrom.MEMORY_CARD);
@@ -300,7 +300,7 @@ public abstract class AEBaseTileBlock extends AEBaseBlock implements ITileEntity
final String savedName = memoryCard.getSettingsName(heldItem); final String savedName = memoryCard.getSettingsName(heldItem);
final NBTTagCompound data = memoryCard.getData(heldItem); final NBTTagCompound data = memoryCard.getData(heldItem);
if (this.getUnlocalizedName().equals(savedName)) { if (this.getTranslationKey().equals(savedName)) {
tileEntity.uploadSettings(SettingsFrom.MEMORY_CARD, data, player); tileEntity.uploadSettings(SettingsFrom.MEMORY_CARD, data, player);
memoryCard.notifyUser(player, MemoryCardMessages.SETTINGS_LOADED); memoryCard.notifyUser(player, MemoryCardMessages.SETTINGS_LOADED);
} else { } else {
@@ -43,6 +43,7 @@ import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.common.property.IUnlistedProperty;
import javax.annotation.Nonnull;
import java.util.EnumSet; import java.util.EnumSet;
@@ -111,7 +112,7 @@ public class BlockCraftingUnit extends AEBaseTileBlock {
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -38,6 +38,8 @@ import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
public class BlockMolecularAssembler extends AEBaseTileBlock { public class BlockMolecularAssembler extends AEBaseTileBlock {
@@ -72,7 +74,7 @@ public class BlockMolecularAssembler extends AEBaseTileBlock {
*/ */
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -121,15 +121,15 @@ public class BlockCharger extends AEBaseTileBlock implements ICustomCollision {
final EnumFacing forward = tile.getForward(); final EnumFacing forward = tile.getForward();
final AEAxisAlignedBB bb = new AEAxisAlignedBB(twoPixels, twoPixels, twoPixels, 1.0 - twoPixels, 1.0 - twoPixels, 1.0 - twoPixels); final AEAxisAlignedBB bb = new AEAxisAlignedBB(twoPixels, twoPixels, twoPixels, 1.0 - twoPixels, 1.0 - twoPixels, 1.0 - twoPixels);
if (up.getFrontOffsetX() != 0) { if (up.getXOffset() != 0) {
bb.minX = 0; bb.minX = 0;
bb.maxX = 1; bb.maxX = 1;
} }
if (up.getFrontOffsetY() != 0) { if (up.getYOffset() != 0) {
bb.minY = 0; bb.minY = 0;
bb.maxY = 1; bb.maxY = 1;
} }
if (up.getFrontOffsetZ() != 0) { if (up.getZOffset() != 0) {
bb.minZ = 0; bb.minZ = 0;
bb.maxZ = 1; bb.maxZ = 1;
} }
@@ -68,7 +68,7 @@ public class BlockInscriber extends AEBaseTileBlock {
} }
@Override @Override
public String getUnlocalizedName(final ItemStack is) { public String getTranslationKey(final ItemStack is) {
return super.getUnlocalizedName(is); return super.getTranslationKey(is);
} }
} }
@@ -41,6 +41,7 @@ import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@@ -115,9 +116,9 @@ public class BlockLightDetector extends AEBaseTileBlock implements IOrientableBl
@Override @Override
public Iterable<AxisAlignedBB> getSelectedBoundingBoxesFromPool(final World w, final BlockPos pos, final Entity thePlayer, final boolean b) { public Iterable<AxisAlignedBB> getSelectedBoundingBoxesFromPool(final World w, final BlockPos pos, final Entity thePlayer, final boolean b) {
final EnumFacing up = this.getOrientable(w, pos).getUp(); final EnumFacing up = this.getOrientable(w, pos).getUp();
final double xOff = -0.3 * up.getFrontOffsetX(); final double xOff = -0.3 * up.getXOffset();
final double yOff = -0.3 * up.getFrontOffsetY(); final double yOff = -0.3 * up.getYOffset();
final double zOff = -0.3 * up.getFrontOffsetZ(); final double zOff = -0.3 * up.getZOffset();
return Collections.singletonList(new AxisAlignedBB(xOff + 0.3, yOff + 0.3, zOff + 0.3, xOff + 0.7, yOff + 0.7, zOff + 0.7)); return Collections.singletonList(new AxisAlignedBB(xOff + 0.3, yOff + 0.3, zOff + 0.3, xOff + 0.7, yOff + 0.7, zOff + 0.7));
} }
@@ -167,7 +168,7 @@ public class BlockLightDetector extends AEBaseTileBlock implements IOrientableBl
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -44,6 +44,7 @@ import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@@ -107,9 +108,9 @@ public class BlockQuartzFixture extends AEBaseBlock implements IOrientableBlock,
@Override @Override
public Iterable<AxisAlignedBB> getSelectedBoundingBoxesFromPool(final World w, final BlockPos pos, final Entity e, final boolean isVisual) { public Iterable<AxisAlignedBB> getSelectedBoundingBoxesFromPool(final World w, final BlockPos pos, final Entity e, final boolean isVisual) {
final EnumFacing up = this.getOrientable(w, pos).getUp(); final EnumFacing up = this.getOrientable(w, pos).getUp();
final double xOff = -0.3 * up.getFrontOffsetX(); final double xOff = -0.3 * up.getXOffset();
final double yOff = -0.3 * up.getFrontOffsetY(); final double yOff = -0.3 * up.getYOffset();
final double zOff = -0.3 * up.getFrontOffsetZ(); final double zOff = -0.3 * up.getZOffset();
return Collections.singletonList(new AxisAlignedBB(xOff + 0.3, yOff + 0.3, zOff + 0.3, xOff + 0.7, yOff + 0.7, zOff + 0.7)); return Collections.singletonList(new AxisAlignedBB(xOff + 0.3, yOff + 0.3, zOff + 0.3, xOff + 0.7, yOff + 0.7, zOff + 0.7));
} }
@@ -134,9 +135,9 @@ public class BlockQuartzFixture extends AEBaseBlock implements IOrientableBlock,
} }
final EnumFacing up = this.getOrientable(w, pos).getUp(); final EnumFacing up = this.getOrientable(w, pos).getUp();
final double xOff = -0.3 * up.getFrontOffsetX(); final double xOff = -0.3 * up.getXOffset();
final double yOff = -0.3 * up.getFrontOffsetY(); final double yOff = -0.3 * up.getYOffset();
final double zOff = -0.3 * up.getFrontOffsetZ(); final double zOff = -0.3 * up.getZOffset();
for (int bolts = 0; bolts < 3; bolts++) { for (int bolts = 0; bolts < 3; bolts++) {
if (AppEng.proxy.shouldAddParticles(r)) { if (AppEng.proxy.shouldAddParticles(r)) {
final LightningFX fx = new LightningFX(w, xOff + 0.5 + pos.getX(), yOff + 0.5 + pos.getY(), zOff + 0.5 + pos.getZ(), 0.0D, 0.0D, 0.0D); final LightningFX fx = new LightningFX(w, xOff + 0.5 + pos.getX(), yOff + 0.5 + pos.getY(), zOff + 0.5 + pos.getZ(), 0.0D, 0.0D, 0.0D);
@@ -192,7 +193,7 @@ public class BlockQuartzFixture extends AEBaseBlock implements IOrientableBlock,
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -87,9 +87,9 @@ public class BlockQuartzGrowthAccelerator extends AEBaseTileBlock implements IOr
double ry = 0.5 + pos.getY(); double ry = 0.5 + pos.getY();
double rz = 0.5 + pos.getZ(); double rz = 0.5 + pos.getZ();
rx += up.getFrontOffsetX() * d0; rx += up.getXOffset() * d0;
ry += up.getFrontOffsetY() * d0; ry += up.getYOffset() * d0;
rz += up.getFrontOffsetZ() * d0; rz += up.getZOffset() * d0;
final int x = pos.getX(); final int x = pos.getX();
final int y = pos.getY(); final int y = pos.getY();
@@ -103,25 +103,25 @@ public class BlockQuartzGrowthAccelerator extends AEBaseTileBlock implements IOr
case 0: case 0:
dx = 0.6; dx = 0.6;
dz = d1; dz = d1;
pt = new BlockPos(x + west.getFrontOffsetX(), y + west.getFrontOffsetY(), z + west.getFrontOffsetZ()); pt = new BlockPos(x + west.getXOffset(), y + west.getYOffset(), z + west.getZOffset());
break; break;
case 1: case 1:
dx = d1; dx = d1;
dz += 0.6; dz += 0.6;
pt = new BlockPos(x + forward.getFrontOffsetX(), y + forward.getFrontOffsetY(), z + forward.getFrontOffsetZ()); pt = new BlockPos(x + forward.getXOffset(), y + forward.getYOffset(), z + forward.getZOffset());
break; break;
case 2: case 2:
dx = d1; dx = d1;
dz = -0.6; dz = -0.6;
pt = new BlockPos(x - forward.getFrontOffsetX(), y - forward.getFrontOffsetY(), z - forward.getFrontOffsetZ()); pt = new BlockPos(x - forward.getXOffset(), y - forward.getYOffset(), z - forward.getZOffset());
break; break;
case 3: case 3:
dx = -0.6; dx = -0.6;
dz = d1; dz = d1;
pt = new BlockPos(x - west.getFrontOffsetX(), y - west.getFrontOffsetY(), z - west.getFrontOffsetZ()); pt = new BlockPos(x - west.getXOffset(), y - west.getYOffset(), z - west.getZOffset());
break; break;
} }
@@ -130,13 +130,13 @@ public class BlockQuartzGrowthAccelerator extends AEBaseTileBlock implements IOr
return; return;
} }
rx += dx * west.getFrontOffsetX(); rx += dx * west.getXOffset();
ry += dx * west.getFrontOffsetY(); ry += dx * west.getYOffset();
rz += dx * west.getFrontOffsetZ(); rz += dx * west.getZOffset();
rx += dz * forward.getFrontOffsetX(); rx += dz * forward.getXOffset();
ry += dz * forward.getFrontOffsetY(); ry += dz * forward.getYOffset();
rz += dz * forward.getFrontOffsetZ(); rz += dz * forward.getZOffset();
final LightningFX fx = new LightningFX(w, rx, ry, rz, 0.0D, 0.0D, 0.0D); final LightningFX fx = new LightningFX(w, rx, ry, rz, 0.0D, 0.0D, 0.0D);
Minecraft.getMinecraft().effectRenderer.addEffect(fx); Minecraft.getMinecraft().effectRenderer.addEffect(fx);
@@ -37,6 +37,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -56,7 +57,7 @@ public class BlockSecurityStation extends AEBaseTileBlock {
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -89,7 +89,7 @@ public class BlockTinyTNT extends AEBaseBlock implements ICustomCollision {
@Override @Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) { public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) {
if (world.isBlockIndirectlyGettingPowered(pos) > 0) { if (world.getRedstonePowerFromNeighbors(pos) > 0) {
this.startFuse(world, pos, null); this.startFuse(world, pos, null);
world.setBlockToAir(pos); world.setBlockToAir(pos);
} }
@@ -99,7 +99,7 @@ public class BlockTinyTNT extends AEBaseBlock implements ICustomCollision {
public void onBlockAdded(final World w, final BlockPos pos, final IBlockState state) { public void onBlockAdded(final World w, final BlockPos pos, final IBlockState state) {
super.onBlockAdded(w, pos, state); super.onBlockAdded(w, pos, state);
if (w.isBlockIndirectlyGettingPowered(pos) > 0) { if (w.getRedstonePowerFromNeighbors(pos) > 0) {
this.startFuse(w, pos, null); this.startFuse(w, pos, null);
w.setBlockToAir(pos); w.setBlockToAir(pos);
} }
@@ -102,20 +102,20 @@ public final class BlockVibrationChamber extends AEBaseTileBlock {
final EnumFacing forward = tc.getForward(); final EnumFacing forward = tc.getForward();
final EnumFacing up = tc.getUp(); final EnumFacing up = tc.getUp();
final int west_x = forward.getFrontOffsetY() * up.getFrontOffsetZ() - forward.getFrontOffsetZ() * up.getFrontOffsetY(); final int west_x = forward.getYOffset() * up.getZOffset() - forward.getZOffset() * up.getYOffset();
final int west_y = forward.getFrontOffsetZ() * up.getFrontOffsetX() - forward.getFrontOffsetX() * up.getFrontOffsetZ(); final int west_y = forward.getZOffset() * up.getXOffset() - forward.getXOffset() * up.getZOffset();
final int west_z = forward.getFrontOffsetX() * up.getFrontOffsetY() - forward.getFrontOffsetY() * up.getFrontOffsetX(); final int west_z = forward.getXOffset() * up.getYOffset() - forward.getYOffset() * up.getXOffset();
f1 += forward.getFrontOffsetX() * 0.6; f1 += forward.getXOffset() * 0.6;
f2 += forward.getFrontOffsetY() * 0.6; f2 += forward.getYOffset() * 0.6;
f3 += forward.getFrontOffsetZ() * 0.6; f3 += forward.getZOffset() * 0.6;
final float ox = r.nextFloat(); final float ox = r.nextFloat();
final float oy = r.nextFloat() * 0.2f; final float oy = r.nextFloat() * 0.2f;
f1 += up.getFrontOffsetX() * (-0.3 + oy); f1 += up.getXOffset() * (-0.3 + oy);
f2 += up.getFrontOffsetY() * (-0.3 + oy); f2 += up.getYOffset() * (-0.3 + oy);
f3 += up.getFrontOffsetZ() * (-0.3 + oy); f3 += up.getZOffset() * (-0.3 + oy);
f1 += west_x * (0.3 * ox - 0.15); f1 += west_x * (0.3 * ox - 0.15);
f2 += west_y * (0.3 * ox - 0.15); f2 += west_y * (0.3 * ox - 0.15);
@@ -29,9 +29,10 @@ import appeng.block.AEBaseTileBlock;
import appeng.client.UnlistedProperty; import appeng.client.UnlistedProperty;
import appeng.client.render.cablebus.CableBusBakedModel; import appeng.client.render.cablebus.CableBusBakedModel;
import appeng.client.render.cablebus.CableBusRenderState; import appeng.client.render.cablebus.CableBusRenderState;
import appeng.core.Api; import appeng.client.render.cablebus.FacadeRenderState;
import appeng.core.AppEng; import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketCableBusLandingParticle;
import appeng.core.sync.packets.PacketClick; import appeng.core.sync.packets.PacketClick;
import appeng.helpers.AEGlassMaterial; import appeng.helpers.AEGlassMaterial;
import appeng.integration.abstraction.IAEFacade; import appeng.integration.abstraction.IAEFacade;
@@ -71,10 +72,12 @@ import net.minecraft.util.math.RayTraceResult.Type;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
@@ -91,10 +94,6 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer(); private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
private static Class<? extends AEBaseTile> noTesrTile;
private static Class<? extends AEBaseTile> tesrTile;
public BlockCableBus() { public BlockCableBus() {
super(AEGlassMaterial.INSTANCE); super(AEGlassMaterial.INSTANCE);
this.setLightOpacity(0); this.setLightOpacity(0);
@@ -152,7 +151,7 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
} }
@Override @Override
public void onEntityCollidedWithBlock(final World w, final BlockPos pos, final IBlockState state, final Entity entityIn) { public void onEntityCollision(final World w, final BlockPos pos, final IBlockState state, final Entity entityIn) {
this.cb(w, pos).onEntityCollision(entityIn); this.cb(w, pos).onEntityCollision(entityIn);
} }
@@ -303,6 +302,90 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
return true; return true;
} }
@Override
public boolean addRunningEffects(IBlockState state, World world, BlockPos pos, Entity entity) {
if (world.isRemote) {
addRunningParticle(world, pos, entity);
}
return true;
}
@SideOnly(Side.CLIENT)
private void addRunningParticle(World world, BlockPos pos, Entity entity) {
final ICableBusContainer cb = this.cb(world, pos);
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(this.getDefaultState());
if (!(model instanceof CableBusBakedModel cableBusModel)) {
return;
}
final CableBusRenderState renderState = cb.getRenderState();
final TextureAtlasSprite texture = getSpriteForParticle(renderState, cableBusModel);
if (texture != null) {
final double d0 = entity.posX + (world.rand.nextFloat() - 0.5f) * entity.width;
final double d1 = entity.getEntityBoundingBox().minY + 0.1f;
final double d2 = entity.posZ + (world.rand.nextFloat() - 0.5f) * entity.width;
final ParticleDigging particle = new DestroyFX(world, d0, d1, d2, -entity.motionX * 4.0f, 1.5f, -entity.motionZ * 4.0f, this.getDefaultState()).setBlockPos(pos);
particle.setParticleTexture(texture);
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
}
}
@Override
public boolean addLandingEffects(IBlockState state, WorldServer world, BlockPos pos, IBlockState iblockstate, EntityLivingBase entity, int numberOfParticles) {
// for reasons only notch can explain, this method is only called on the server, so we have to sync
// a packet to all tracking players for landing particle effects
if (!world.isRemote) {
final PacketCableBusLandingParticle packet = new PacketCableBusLandingParticle(pos, entity, numberOfParticles);
final NetworkRegistry.TargetPoint point = new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 32);
NetworkHandler.instance().sendToAllTracking(packet, point);
}
return true;
}
@SideOnly(Side.CLIENT)
public void addLandingParticle(BlockPos pos, double entityX, double entityY, double entityZ, int numberOfParticles) {
final World world = Minecraft.getMinecraft().world;
final ICableBusContainer cb = this.cb(world, pos);
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(this.getDefaultState());
if (!(model instanceof CableBusBakedModel cableBusModel)) {
return;
}
final TextureAtlasSprite texture = getSpriteForParticle(cb.getRenderState(), cableBusModel);
if (texture != null) {
final Vec3d startVec = new Vec3d(entityX, entityY, entityZ);
final Vec3d endVec = startVec.add(0.0f, -4.0f, 0.0f);
RayTraceResult result = world.rayTraceBlocks(startVec, endVec, true, false, true);
final double speed = 0.15f;
if (result != null && result.typeOfHit == Type.BLOCK && numberOfParticles != 0) {
for (int i = 0; i < numberOfParticles; i++) {
final double d0 = world.rand.nextGaussian() * speed;
final double d1 = world.rand.nextGaussian() * speed;
final double d2 = world.rand.nextGaussian() * speed;
final ParticleDigging particle = new DestroyFX(world, entityX, entityY, entityZ, d0, d1, d2, this.getDefaultState()).setBlockPos(pos);
particle.setParticleTexture(texture);
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
}
}
}
}
@SideOnly(Side.CLIENT)
private TextureAtlasSprite getSpriteForParticle(CableBusRenderState renderState, CableBusBakedModel cableBusModel) {
final FacadeRenderState frs = renderState.getFacades().get(EnumFacing.UP);
if (frs != null) {
final IBlockState state = frs.getSourceBlock();
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state);
return model.getParticleTexture();
}
return Platform.pickRandom(cableBusModel.getParticleTextures(renderState));
}
@Override @Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) { public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) {
if (Platform.isServer()) { if (Platform.isServer()) {
@@ -378,10 +461,9 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
} }
public void setupTile() { public void setupTile() {
noTesrTile = Api.INSTANCE.partHelper().getCombinedInstance(TileCableBus.class); this.setTileEntity(TileCableBus.class);
this.setTileEntity(noTesrTile);
GameRegistry.registerTileEntity(noTesrTile, AppEng.MOD_ID.toLowerCase() + ":" + "BlockCableBus"); GameRegistry.registerTileEntity(TileCableBus.class, AppEng.MOD_ID.toLowerCase() + ":" + "BlockCableBus");
if (Platform.isClient()) { if (Platform.isClient()) {
setupTesr(); setupTesr();
@@ -390,9 +472,8 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
private static void setupTesr() { private static void setupTesr() {
tesrTile = Api.INSTANCE.partHelper().getCombinedInstance(TileCableBusTESR.class); GameRegistry.registerTileEntity(TileCableBusTESR.class, AppEng.MOD_ID.toLowerCase() + ":" + "ClientOnly_TESR_CableBus");
GameRegistry.registerTileEntity(tesrTile, AppEng.MOD_ID.toLowerCase() + ":" + "ClientOnly_TESR_CableBus"); ClientRegistry.bindTileEntitySpecialRenderer(TileCableBusTESR.class, new CableBusTESR());
ClientRegistry.bindTileEntitySpecialRenderer(BlockCableBus.getTesrTile(), new CableBusTESR());
} }
@Override @Override
@@ -438,14 +519,6 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
super.onEntityWalk(world, pos, entityIn); super.onEntityWalk(world, pos, entityIn);
} }
public static Class<? extends AEBaseTile> getNoTesrTile() {
return noTesrTile;
}
public static Class<? extends AEBaseTile> getTesrTile() {
return tesrTile;
}
// Helper to get access to the protected constructor // Helper to get access to the protected constructor
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
private static class DestroyFX extends ParticleDigging { private static class DestroyFX extends ParticleDigging {
@@ -33,6 +33,8 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class BlockController extends AEBaseTileBlock { public class BlockController extends AEBaseTileBlock {
@@ -144,7 +146,7 @@ public class BlockController extends AEBaseTileBlock {
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -40,6 +40,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -68,7 +69,7 @@ public class BlockWireless extends AEBaseTileBlock implements ICustomCollision {
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -44,6 +44,7 @@ import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Random; import java.util.Random;
@@ -81,7 +82,7 @@ public class BlockPaint extends AEBaseTileBlock {
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -37,6 +37,8 @@ import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.common.property.IUnlistedProperty;
import javax.annotation.Nonnull;
public abstract class BlockQuantumBase extends AEBaseTileBlock implements ICustomCollision { public abstract class BlockQuantumBase extends AEBaseTileBlock implements ICustomCollision {
@@ -86,7 +88,7 @@ public abstract class BlockQuantumBase extends AEBaseTileBlock implements ICusto
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -105,9 +105,9 @@ class QnbFormedBakedModel implements IBakedModel {
for (EnumFacing facing : EnumFacing.values()) { for (EnumFacing facing : EnumFacing.values()) {
// Offset the face by a slight amount so that it is drawn over the already drawn ring texture // Offset the face by a slight amount so that it is drawn over the already drawn ring texture
// (avoids z-fighting) // (avoids z-fighting)
float xOffset = Math.abs(facing.getFrontOffsetX() * 0.01f); float xOffset = Math.abs(facing.getXOffset() * 0.01f);
float yOffset = Math.abs(facing.getFrontOffsetY() * 0.01f); float yOffset = Math.abs(facing.getYOffset() * 0.01f);
float zOffset = Math.abs(facing.getFrontOffsetZ() * 0.01f); float zOffset = Math.abs(facing.getZOffset() * 0.01f);
builder.setDrawFaces(EnumSet.of(facing)); builder.setDrawFaces(EnumSet.of(facing));
builder.addCube( builder.addCube(
@@ -130,9 +130,9 @@ class QnbFormedBakedModel implements IBakedModel {
for (EnumFacing facing : EnumFacing.values()) { for (EnumFacing facing : EnumFacing.values()) {
// Offset the face by a slight amount so that it is drawn over the already drawn ring texture // Offset the face by a slight amount so that it is drawn over the already drawn ring texture
// (avoids z-fighting) // (avoids z-fighting)
float xOffset = Math.abs(facing.getFrontOffsetX() * 0.01f); float xOffset = Math.abs(facing.getXOffset() * 0.01f);
float yOffset = Math.abs(facing.getFrontOffsetY() * 0.01f); float yOffset = Math.abs(facing.getYOffset() * 0.01f);
float zOffset = Math.abs(facing.getFrontOffsetZ() * 0.01f); float zOffset = Math.abs(facing.getZOffset() * 0.01f);
builder.setDrawFaces(EnumSet.of(facing)); builder.setDrawFaces(EnumSet.of(facing));
builder.addCube( builder.addCube(
@@ -26,12 +26,15 @@ import appeng.tile.spatial.TileSpatialIOPort;
import appeng.util.Platform; import appeng.util.Platform;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -39,8 +42,11 @@ import javax.annotation.Nullable;
public class BlockSpatialIOPort extends AEBaseTileBlock { public class BlockSpatialIOPort extends AEBaseTileBlock {
public static final PropertyBool POWERED = PropertyBool.create("powered");
public BlockSpatialIOPort() { public BlockSpatialIOPort() {
super(Material.IRON); super(Material.IRON);
setDefaultState(getDefaultState().withProperty(POWERED, false));
} }
@Override @Override
@@ -51,6 +57,19 @@ public class BlockSpatialIOPort extends AEBaseTileBlock {
} }
} }
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
TileSpatialIOPort te = this.getTileEntity(worldIn, pos);
boolean powered = te != null && te.isActive();
return super.getActualState(state, worldIn, pos)
.withProperty(POWERED, powered);
}
@Override
protected IProperty[] getAEStates() {
return new IProperty[]{POWERED};
}
@Override @Override
public boolean onActivated(final World w, final BlockPos pos, final EntityPlayer p, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ) { public boolean onActivated(final World w, final BlockPos pos, final EntityPlayer p, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ) {
if (p.isSneaking()) { if (p.isSneaking()) {
@@ -34,6 +34,8 @@ import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.common.property.IUnlistedProperty;
import javax.annotation.Nonnull;
public class BlockSpatialPylon extends AEBaseTileBlock { public class BlockSpatialPylon extends AEBaseTileBlock {
@@ -83,7 +85,7 @@ public class BlockSpatialPylon extends AEBaseTileBlock {
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -38,6 +38,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -56,7 +57,7 @@ public class BlockChest extends AEBaseTileBlock {
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -40,6 +40,7 @@ import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.common.property.IUnlistedProperty;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -52,7 +53,7 @@ public class BlockDrive extends AEBaseTileBlock {
} }
@Override @Override
public BlockRenderLayer getBlockLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@@ -19,6 +19,7 @@
package appeng.block.storage; package appeng.block.storage;
import appeng.api.config.Upgrades;
import appeng.api.util.AEPartLocation; import appeng.api.util.AEPartLocation;
import appeng.block.AEBaseTileBlock; import appeng.block.AEBaseTileBlock;
import appeng.core.sync.GuiBridge; import appeng.core.sync.GuiBridge;
@@ -26,12 +27,15 @@ import appeng.tile.storage.TileIOPort;
import appeng.util.Platform; import appeng.util.Platform;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -39,17 +43,36 @@ import javax.annotation.Nullable;
public class BlockIOPort extends AEBaseTileBlock { public class BlockIOPort extends AEBaseTileBlock {
public static final PropertyBool POWERED = PropertyBool.create("powered");
public BlockIOPort() { public BlockIOPort() {
super(Material.IRON); super(Material.IRON);
setDefaultState(getDefaultState().withProperty(POWERED, false));
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
TileIOPort te = this.getTileEntity(worldIn, pos);
boolean powred = te != null && te.isActive();
return super.getActualState(state, worldIn, pos)
.withProperty(POWERED, powred);
}
@Override
protected IProperty[] getAEStates() {
return new IProperty[]{POWERED};
} }
@Override @Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) { public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) {
final TileIOPort te = this.getTileEntity(world, pos); final TileIOPort te = this.getTileEntity(world, pos);
if (te != null) { if (te != null) {
if (te.getInstalledUpgrades(Upgrades.REDSTONE) != 0) {
te.updateRedstoneState(); te.updateRedstoneState();
} }
} }
}
@Override @Override
public boolean onActivated(final World w, final BlockPos pos, final EntityPlayer p, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ) { public boolean onActivated(final World w, final BlockPos pos, final EntityPlayer p, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ) {
@@ -26,6 +26,8 @@ import appeng.helpers.ICustomCollision;
import appeng.tile.storage.TileSkyChest; import appeng.tile.storage.TileSkyChest;
import appeng.util.Platform; import appeng.util.Platform;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -48,6 +50,8 @@ public class BlockSkyChest extends AEBaseTileBlock implements ICustomCollision {
private static final double AABB_OFFSET_SIDES = 0.06; private static final double AABB_OFFSET_SIDES = 0.06;
private static final double AABB_OFFSET_TOP = 0.125; private static final double AABB_OFFSET_TOP = 0.125;
public static final PropertyBool NATURAL = PropertyBool.create("natural");
public enum SkyChestType { public enum SkyChestType {
STONE, BLOCK STONE, BLOCK
} }
@@ -61,6 +65,22 @@ public class BlockSkyChest extends AEBaseTileBlock implements ICustomCollision {
this.setHardness(50); this.setHardness(50);
this.blockResistance = 150.0f; this.blockResistance = 150.0f;
this.type = type; this.type = type;
setDefaultState(getDefaultState().withProperty(NATURAL, true));
}
@Override
protected IProperty[] getAEStates() {
return new IProperty[]{NATURAL};
}
@Override
public int getMetaFromState(IBlockState state) {
return state.getValue(NATURAL) ? 1 : 0;
}
@Override
public IBlockState getStateFromMeta(int meta) {
return getDefaultState().withProperty(NATURAL, meta == 1);
} }
@Override @Override
@@ -99,18 +119,18 @@ public class BlockSkyChest extends AEBaseTileBlock implements ICustomCollision {
o = sk.getUp(); o = sk.getUp();
} }
final double offsetX = o.getFrontOffsetX() == 0 ? AABB_OFFSET_SIDES : 0.0; final double offsetX = o.getXOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetY = o.getFrontOffsetY() == 0 ? AABB_OFFSET_SIDES : 0.0; final double offsetY = o.getYOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetZ = o.getFrontOffsetZ() == 0 ? AABB_OFFSET_SIDES : 0.0; final double offsetZ = o.getZOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
// for x/z top and bottom is swapped // for x/z top and bottom is swapped
final double minX = Math.max(0.0, offsetX + (o.getFrontOffsetX() < 0 ? AABB_OFFSET_BOTTOM : (o.getFrontOffsetX() * AABB_OFFSET_TOP))); final double minX = Math.max(0.0, offsetX + (o.getXOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getXOffset() * AABB_OFFSET_TOP)));
final double minY = Math.max(0.0, offsetY + (o.getFrontOffsetY() < 0 ? AABB_OFFSET_TOP : (o.getFrontOffsetY() * AABB_OFFSET_BOTTOM))); final double minY = Math.max(0.0, offsetY + (o.getYOffset() < 0 ? AABB_OFFSET_TOP : (o.getYOffset() * AABB_OFFSET_BOTTOM)));
final double minZ = Math.max(0.0, offsetZ + (o.getFrontOffsetZ() < 0 ? AABB_OFFSET_BOTTOM : (o.getFrontOffsetZ() * AABB_OFFSET_TOP))); final double minZ = Math.max(0.0, offsetZ + (o.getZOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getZOffset() * AABB_OFFSET_TOP)));
final double maxX = Math.min(1.0, 1.0 - offsetX - (o.getFrontOffsetX() < 0 ? AABB_OFFSET_TOP : (o.getFrontOffsetX() * AABB_OFFSET_BOTTOM))); final double maxX = Math.min(1.0, 1.0 - offsetX - (o.getXOffset() < 0 ? AABB_OFFSET_TOP : (o.getXOffset() * AABB_OFFSET_BOTTOM)));
final double maxY = Math.min(1.0, 1.0 - offsetY - (o.getFrontOffsetY() < 0 ? AABB_OFFSET_BOTTOM : (o.getFrontOffsetY() * AABB_OFFSET_TOP))); final double maxY = Math.min(1.0, 1.0 - offsetY - (o.getYOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getYOffset() * AABB_OFFSET_TOP)));
final double maxZ = Math.min(1.0, 1.0 - offsetZ - (o.getFrontOffsetZ() < 0 ? AABB_OFFSET_TOP : (o.getFrontOffsetZ() * AABB_OFFSET_BOTTOM))); final double maxZ = Math.min(1.0, 1.0 - offsetZ - (o.getZOffset() < 0 ? AABB_OFFSET_TOP : (o.getZOffset() * AABB_OFFSET_BOTTOM)));
return new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ); return new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
} }
@@ -40,7 +40,10 @@ public enum DriveSlotState implements IStringSerializable {
TYPES_FULL("types_full"), TYPES_FULL("types_full"),
// Completely full // Completely full
FULL("full"); FULL("full"),
// Online and completely empty
NO_CONTENTS("no_contents");
private final String name; private final String name;
@@ -64,6 +67,8 @@ public enum DriveSlotState implements IStringSerializable {
return DriveSlotState.TYPES_FULL; return DriveSlotState.TYPES_FULL;
case 3: case 3:
return DriveSlotState.FULL; return DriveSlotState.FULL;
case 4:
return DriveSlotState.NO_CONTENTS;
} }
} }
@@ -164,7 +164,7 @@ class BlockDefinitionBuilder implements IBlockBuilder {
// Create block and matching item, and set factory name of both // Create block and matching item, and set factory name of both
Block block = this.blockSupplier.get(); Block block = this.blockSupplier.get();
block.setRegistryName(AppEng.MOD_ID, this.registryName); block.setRegistryName(AppEng.MOD_ID, this.registryName);
block.setUnlocalizedName("appliedenergistics2." + this.registryName); block.setTranslationKey("appliedenergistics2." + this.registryName);
ItemBlock item = this.constructItemFromBlock(block); ItemBlock item = this.constructItemFromBlock(block);
if (item != null) { if (item != null) {
@@ -116,11 +116,11 @@ class BlockRendering implements IBlockRendering, ISelectiveResourceReloadListene
} }
if (this.modelCustomizer != null) { if (this.modelCustomizer != null) {
factory.addModelOverride(block.getRegistryName().getResourcePath(), this.modelCustomizer); factory.addModelOverride(block.getRegistryName().getPath(), this.modelCustomizer);
} else if (block instanceof AEBaseTileBlock) { } else if (block instanceof AEBaseTileBlock) {
// This is a default rotating model if the base-block uses an AE tile entity which exposes UP/FRONT as // This is a default rotating model if the base-block uses an AE tile entity which exposes UP/FRONT as
// extended props // extended props
factory.addModelOverride(block.getRegistryName().getResourcePath(), (l, m) -> { factory.addModelOverride(block.getRegistryName().getPath(), (l, m) -> {
AutoRotatingModel model = new AutoRotatingModel(m); AutoRotatingModel model = new AutoRotatingModel(m);
BlockRendering.this.reloads.add(model); BlockRendering.this.reloads.add(model);
return model; return model;
@@ -126,7 +126,7 @@ class ItemDefinitionBuilder implements IItemBuilder {
ItemDefinition definition = new ItemDefinition(this.registryName, item); ItemDefinition definition = new ItemDefinition(this.registryName, item);
item.setUnlocalizedName("appliedenergistics2." + this.registryName); item.setTranslationKey("appliedenergistics2." + this.registryName);
item.setCreativeTab(this.creativeTab); item.setCreativeTab(this.creativeTab);
// Register all extra handlers // Register all extra handlers
@@ -61,7 +61,7 @@ public class ModelOverrideComponent implements IPreInitComponent {
IModel missingModel = ModelLoaderRegistry.getMissingModel(); IModel missingModel = ModelLoaderRegistry.getMissingModel();
for (ModelResourceLocation location : keys) { for (ModelResourceLocation location : keys) {
if (!location.getResourceDomain().equals(AppEng.MOD_ID)) { if (!location.getNamespace().equals(AppEng.MOD_ID)) {
continue; continue;
} }
@@ -72,7 +72,7 @@ public class ModelOverrideComponent implements IPreInitComponent {
continue; continue;
} }
BiFunction<ModelResourceLocation, IBakedModel, IBakedModel> customizer = this.customizer.get(location.getResourcePath()); BiFunction<ModelResourceLocation, IBakedModel, IBakedModel> customizer = this.customizer.get(location.getPath());
if (customizer != null) { if (customizer != null) {
IBakedModel newModel = customizer.apply(location, orgModel); IBakedModel newModel = customizer.apply(location, orgModel);
@@ -54,6 +54,7 @@ import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
@@ -82,6 +83,7 @@ import java.util.ArrayList;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.UUID;
import static appeng.client.KeyBindings.WCT; import static appeng.client.KeyBindings.WCT;
import static appeng.client.KeyBindings.WFT; import static appeng.client.KeyBindings.WFT;
@@ -372,4 +374,16 @@ public class ClientHelper extends ServerHelper {
public boolean isActionKey(ActionKey key, int pressedKeyCode) { public boolean isActionKey(ActionKey key, int pressedKeyCode) {
return this.bindings.get(key).isActiveAndMatches(pressedKeyCode); return this.bindings.get(key).isActiveAndMatches(pressedKeyCode);
} }
@Override
public EntityPlayer getPlayerByUUID(UUID uuid) {
if (Platform.isClient()) {
if (Minecraft.getMinecraft().player.getUniqueID().equals(uuid)) {
return Minecraft.getMinecraft().player;
}
return null;
} else {
return super.getPlayerByUUID(uuid);
}
}
} }
+7 -48
View File
@@ -69,13 +69,11 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.items.SlotItemHandler;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import yalter.mousetweaks.api.IMTModGuiContainer2; import yalter.mousetweaks.api.MouseTweaksIgnore;
import javax.annotation.Nonnull;
import java.awt.*; import java.awt.*;
import java.io.IOException; import java.io.IOException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
@@ -88,8 +86,8 @@ import static appeng.integration.modules.jei.JEIPlugin.aeGuiHandler;
import static appeng.integration.modules.jei.JEIPlugin.runtime; import static appeng.integration.modules.jei.JEIPlugin.runtime;
@Optional.Interface(iface = "yalter.mousetweaks.api.IMTModGuiContainer2", modid = "mousetweaks") @MouseTweaksIgnore
public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContainer2 { public abstract class AEBaseGui extends GuiContainer {
private final List<InternalSlotME> meSlots = new ArrayList<>(); private final List<InternalSlotME> meSlots = new ArrayList<>();
// drag y // drag y
private final Set<Slot> drag_click = new HashSet<>(); private final Set<Slot> drag_click = new HashSet<>();
@@ -935,6 +933,10 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
} }
} else if (s instanceof AppEngSlot) { } else if (s instanceof AppEngSlot) {
AppEngSlot appEngSlot = ((AppEngSlot) s); AppEngSlot appEngSlot = ((AppEngSlot) s);
if (s.getStack().isEmpty()) {
super.drawSlot(s);
return;
}
appEngSlot.setDisplay(true); appEngSlot.setDisplay(true);
appEngSlot.setReturnAsSingleStack(true); appEngSlot.setReturnAsSingleStack(true);
@@ -986,47 +988,4 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
protected List<InternalSlotME> getMeSlots() { protected List<InternalSlotME> getMeSlots() {
return this.meSlots; return this.meSlots;
} }
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isMouseTweaksDisabled() {
return false;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isWheelTweakDisabled() {
return true;
}
@Override
@Optional.Method(modid = "mousetweaks")
public Container MT_getContainer() {
return this.inventorySlots;
}
@Override
@Optional.Method(modid = "mousetweaks")
public Slot MT_getSlotUnderMouse() {
return getSlotUnderMouse();
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isCraftingOutput(Slot slot) {
return slot instanceof SlotOutput || slot instanceof AppEngCraftingSlot;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isIgnored(Slot slot) {
return false;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_disableRMBDraggingFunctionality() {
return false;
}
} }
@@ -1,10 +1,14 @@
package appeng.client.gui; package appeng.client.gui;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.implementations.*; import appeng.client.gui.implementations.GuiCraftAmount;
import appeng.client.gui.implementations.GuiCraftConfirm;
import appeng.client.gui.implementations.GuiCraftingCPU;
import appeng.client.gui.implementations.GuiExpandedProcessingPatternTerm;
import appeng.client.gui.implementations.GuiPatternTerm;
import appeng.client.gui.implementations.GuiUpgradeable;
import appeng.container.interfaces.IJEIGhostIngredients; import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.SlotFake; import appeng.container.slot.IJEITargetSlot;
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
import mezz.jei.api.gui.IAdvancedGuiHandler; import mezz.jei.api.gui.IAdvancedGuiHandler;
import mezz.jei.api.gui.IGhostIngredientHandler; import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
@@ -78,12 +82,12 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
return (guiSloty * 3) + guiSlotx + (currentScroll * 3); return (guiSloty * 3) + guiSlotx + (currentScroll * 3);
} }
@SuppressWarnings("unchecked")
@Override @Override
@Nonnull @Nonnull
public <I> List<Target<I>> getTargets(@Nonnull AEBaseGui gui, @Nonnull I ingredient, boolean doStart) { public <I> List<Target<I>> getTargets(@Nonnull AEBaseGui gui, @Nonnull I ingredient, boolean doStart) {
ArrayList<Target<I>> targets = new ArrayList<>(); ArrayList<Target<I>> targets = new ArrayList<>();
if (gui instanceof IJEIGhostIngredients) { if (gui instanceof IJEIGhostIngredients g) {
IJEIGhostIngredients g = (IJEIGhostIngredients) gui;
List<Target<?>> phantomTargets = g.getPhantomTargets(ingredient); List<Target<?>> phantomTargets = g.getPhantomTargets(ingredient);
targets.addAll((List<Target<I>>) (Object) phantomTargets); targets.addAll((List<Target<I>>) (Object) phantomTargets);
} }
@@ -91,13 +95,8 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
if (gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm || gui instanceof GuiExpandedProcessingPatternTerm) { if (gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm || gui instanceof GuiExpandedProcessingPatternTerm) {
IJEIGhostIngredients ghostGui = ((IJEIGhostIngredients) gui); IJEIGhostIngredients ghostGui = ((IJEIGhostIngredients) gui);
for (Target<I> target : targets) { for (Target<I> target : targets) {
if (ghostGui.getFakeSlotTargetMap().get(target) instanceof SlotFake) { if (ghostGui.getFakeSlotTargetMap().get(target) instanceof IJEITargetSlot jeiSlot) {
if (((SlotFake) ghostGui.getFakeSlotTargetMap().get(target)).getStack().isEmpty()) { if (jeiSlot.needAccept()) {
target.accept(ingredient);
break;
}
} else if (ghostGui.getFakeSlotTargetMap().get(target) instanceof GuiFluidSlot) {
if (((GuiFluidSlot) ghostGui.getFakeSlotTargetMap().get(target)).getFluidStack() == null) {
target.accept(ingredient); target.accept(ingredient);
break; break;
} }
@@ -0,0 +1,208 @@
package appeng.client.gui;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.Stack;
public class MathExpressionParser {
private final Stack<String> postfixStack = new Stack<>();
private final Stack<Character> opStack = new Stack<>();
private static final int[] OPERATOR_PRIORITY = new int[] { 0, 3, 2, 1, -1, 1, 0, 2 };
public static double parse(String expression) {
double result;
if (expression == null) return Double.NaN;
expression = expression.replace(" ", "");
if (expression.length() == 1 && Character.isDigit(expression.charAt(0))) {
return expression.charAt(0) - '0';
}
try {
expression = transform(expression);
result = new MathExpressionParser().calculate(expression);
} catch (Exception e) {
return Double.NaN;
}
return result;
}
/**
* replace '-' with '~'
* e.g.-2+-1*(-3E-2)-(-1) -> ~2+~1*(~3E~2)-(~1)
*/
private static String transform(String expression) {
char[] arr = expression.toCharArray();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '-') {
if (i == 0) {
arr[i] = '~';
} else {
char c = arr[i - 1];
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == 'E' || c == 'e') {
arr[i] = '~';
}
}
}
}
if (arr[0] == '~' || arr[1] == '(') {
arr[0] = '-';
return "0" + new String(arr);
} else {
return new String(arr);
}
}
public double calculate(String expression) {
Stack<String> resultStack = new Stack<>();
prepare(expression);
Collections.reverse(postfixStack);
String firstValue, secondValue, currentValue;
while (!postfixStack.isEmpty()) {
currentValue = postfixStack.pop();
if (!isOperator(currentValue.charAt(0))) {
currentValue = currentValue.replace("~", "-");
resultStack.push(currentValue);
} else {
secondValue = resultStack.pop();
firstValue = resultStack.pop();
firstValue = firstValue.replace("~", "-");
secondValue = secondValue.replace("~", "-");
String tempResult = calculate(firstValue, secondValue, currentValue.charAt(0));
resultStack.push(String.valueOf(tempResult));
}
}
return Double.parseDouble(resultStack.pop());
}
private void prepare(String expression) {
opStack.push(',');
char[] arr = expression.toCharArray();
int currentIndex = 0;
int count = 0;
char currentOp, peekOp;
for (int i = 0; i < arr.length; i++) {
currentOp = arr[i];
if (isOperator(currentOp)) {
if (count > 0) {
postfixStack.push(new String(arr, currentIndex, count));
}
peekOp = opStack.peek();
if (currentOp == ')') {
while (opStack.peek() != '(') {
postfixStack.push(String.valueOf(opStack.pop()));
}
opStack.pop();
} else {
while (currentOp != '(' && peekOp != ',' && compare(currentOp, peekOp)) {
postfixStack.push(String.valueOf(opStack.pop()));
peekOp = opStack.peek();
}
opStack.push(currentOp);
}
count = 0;
currentIndex = i + 1;
} else {
count++;
}
}
if (count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {
postfixStack.push(new String(arr, currentIndex, count));
}
while (opStack.peek() != ',') {
postfixStack.push(String.valueOf(opStack.pop()));
}
}
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
}
private static boolean compare(char cur, char peek) {
return OPERATOR_PRIORITY[(peek) - 40] >= OPERATOR_PRIORITY[(cur) - 40];
}
private String calculate(String firstValue, String secondValue, char currentOp) {
return switch (currentOp) {
case '+' -> add(firstValue, secondValue);
case '-' -> sub(firstValue, secondValue);
case '*' -> mul(firstValue, secondValue);
case '/' -> div(firstValue, secondValue);
default -> "";
};
}
public static String add(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.add(b2));
}
/**
* subtraction
*
* @param v1 p1
* @param v2 p2
* @return sub
*/
public static String sub(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.subtract(b2));
}
/**
* multiplication
*
* @param v1 p1
* @param v2 p2
* @return mul
*/
public static String mul(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.multiply(b2));
}
/**
* division. e = 10^-10
*
* @param v1 p1
* @param v2 p2
* @return div
*/
public static String div(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.divide(b2, 16, RoundingMode.HALF_UP));
}
/**
* rounding
*
* @param v p
* @param scale scale
* @return result
*/
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
return b.divide(BigDecimal.ONE, scale, RoundingMode.HALF_UP).doubleValue();
}
public static String round(String v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(v);
return String.valueOf(b.divide(BigDecimal.ONE, scale, RoundingMode.HALF_UP));
}
}
@@ -22,10 +22,9 @@ package appeng.client.gui.implementations;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions; import appeng.api.definitions.IDefinitions;
import appeng.api.definitions.IParts; import appeng.api.definitions.IParts;
import appeng.api.features.IWirelessTermHandler;
import appeng.api.storage.ITerminalHost; import appeng.api.storage.ITerminalHost;
import appeng.client.gui.AEBaseGui; import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiNumberBox; import appeng.client.gui.MathExpressionParser;
import appeng.client.gui.widgets.GuiTabButton; import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.implementations.ContainerCraftAmount; import appeng.container.implementations.ContainerCraftAmount;
@@ -42,6 +41,7 @@ import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import appeng.parts.reporting.PartPatternTerminal; import appeng.parts.reporting.PartPatternTerminal;
import appeng.parts.reporting.PartTerminal; import appeng.parts.reporting.PartTerminal;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
@@ -50,7 +50,7 @@ import java.io.IOException;
public class GuiCraftAmount extends AEBaseGui { public class GuiCraftAmount extends AEBaseGui {
private GuiNumberBox amountToCraft; private GuiTextField amountToCraft;
private GuiTabButton originalGuiBtn; private GuiTabButton originalGuiBtn;
private GuiButton next; private GuiButton next;
@@ -126,7 +126,7 @@ public class GuiCraftAmount extends AEBaseGui {
this.buttonList.add(this.originalGuiBtn = new GuiTabButton(this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender)); this.buttonList.add(this.originalGuiBtn = new GuiTabButton(this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender));
} }
this.amountToCraft = new GuiNumberBox(this.fontRenderer, this.guiLeft + 62, this.guiTop + 57, 59, this.fontRenderer.FONT_HEIGHT, Integer.class); this.amountToCraft = new GuiTextField(0, this.fontRenderer, this.guiLeft + 62, this.guiTop + 57, 59, this.fontRenderer.FONT_HEIGHT);
this.amountToCraft.setEnableBackgroundDrawing(false); this.amountToCraft.setEnableBackgroundDrawing(false);
this.amountToCraft.setMaxStringLength(16); this.amountToCraft.setMaxStringLength(16);
this.amountToCraft.setTextColor(0xFFFFFF); this.amountToCraft.setTextColor(0xFFFFFF);
@@ -149,8 +149,17 @@ public class GuiCraftAmount extends AEBaseGui {
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize); this.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize);
try { try {
long amt = Long.parseLong(this.amountToCraft.getText()); String out = this.amountToCraft.getText();
this.next.enabled = (!this.amountToCraft.getText().isEmpty() && amt > 0); double resultD = MathExpressionParser.parse(out);
long amt;
if (resultD <= 0 || Double.isNaN(resultD)) {
amt = 0;
} else {
amt = (long) MathExpressionParser.round(resultD, 0);
}
this.next.enabled = amt > 0;
} catch (final NumberFormatException e) { } catch (final NumberFormatException e) {
this.next.enabled = false; this.next.enabled = false;
} }
@@ -164,33 +173,7 @@ public class GuiCraftAmount extends AEBaseGui {
if (key == Keyboard.KEY_RETURN || key == Keyboard.KEY_NUMPADENTER) { if (key == Keyboard.KEY_RETURN || key == Keyboard.KEY_NUMPADENTER) {
this.actionPerformed(this.next); this.actionPerformed(this.next);
} }
if ((key == 211 || key == 205 || key == 203 || key == 14 || character == '-' || Character.isDigit(character)) && this.amountToCraft if (!this.amountToCraft.textboxKeyTyped(character, key)) {
.textboxKeyTyped(character, key)) {
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
}
} else {
super.keyTyped(character, key); super.keyTyped(character, key);
} }
} }
@@ -207,7 +190,15 @@ public class GuiCraftAmount extends AEBaseGui {
} }
if (btn == this.next) { if (btn == this.next) {
NetworkHandler.instance().sendToServer(new PacketCraftRequest(Integer.parseInt(this.amountToCraft.getText()), isShiftKeyDown())); double resultD = MathExpressionParser.parse(this.amountToCraft.getText());
int result;
if (resultD <= 0 || Double.isNaN(resultD)) {
result = 1;
} else {
result = (int) MathExpressionParser.round(resultD, 0);
}
NetworkHandler.instance().sendToServer(new PacketCraftRequest(result, isShiftKeyDown()));
} }
} catch (final NumberFormatException e) { } catch (final NumberFormatException e) {
// nope.. // nope..
@@ -226,22 +217,15 @@ public class GuiCraftAmount extends AEBaseGui {
try { try {
String out = this.amountToCraft.getText(); String out = this.amountToCraft.getText();
boolean fixed = false; double resultD = MathExpressionParser.parse(out);
while (out.startsWith("0") && out.length() > 1) { int result;
out = out.substring(1);
fixed = true;
}
if (fixed) { if (resultD <= 0 || Double.isNaN(resultD)) {
this.amountToCraft.setText(out); result = 0;
} else {
result = (int) MathExpressionParser.round(resultD, 0);
} }
if (out.isEmpty()) {
out = "0";
}
long result = Integer.parseInt(out);
if (result == 1 && i > 1) { if (result == 1 && i > 1) {
result = 0; result = 0;
} }
@@ -251,8 +235,7 @@ public class GuiCraftAmount extends AEBaseGui {
result = 1; result = 1;
} }
out = Long.toString(result); out = Integer.toString(result);
Integer.parseInt(out);
this.amountToCraft.setText(out); this.amountToCraft.setText(out);
} catch (final NumberFormatException e) { } catch (final NumberFormatException e) {
// :P // :P
@@ -394,7 +394,7 @@ public class GuiFluidInterfaceConfigurationTerminal extends AEBaseGui implements
return false; return false;
} }
boolean foundMatchingItemStack = false; boolean foundMatchingFluidStack = false;
final String displayName = Platform.getFluidDisplayName(iaeFluidStack).toLowerCase(); final String displayName = Platform.getFluidDisplayName(iaeFluidStack).toLowerCase();
@@ -405,10 +405,12 @@ public class GuiFluidInterfaceConfigurationTerminal extends AEBaseGui implements
return false; return false;
} }
} else if (displayName.contains(term)) { } else if (displayName.contains(term)) {
foundMatchingItemStack = true; foundMatchingFluidStack = true;
} else {
return false;
} }
} }
return foundMatchingItemStack; return foundMatchingFluidStack;
} }
/** /**
@@ -409,6 +409,8 @@ public class GuiInterfaceConfigurationTerminal extends AEBaseGui implements IJEI
} }
} else if (displayName.contains(term)) { } else if (displayName.contains(term)) {
foundMatchingItemStack = true; foundMatchingItemStack = true;
} else {
return false;
} }
} }
return foundMatchingItemStack; return foundMatchingItemStack;
@@ -50,6 +50,7 @@ import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Loader;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
@@ -567,15 +568,15 @@ public class GuiInterfaceTerminal extends AEBaseGui {
return searchTerm.matches(GuiText.InvalidPattern.getLocal()); return searchTerm.matches(GuiText.InvalidPattern.getLocal());
} }
NBTTagList tag = new NBTTagList(); final NBTTagList tag;
if (pass == 0) { if (pass == 0) {
tag = encodedValue.getTagList("in", 10); tag = encodedValue.getTagList("in", Constants.NBT.TAG_COMPOUND);
} else { } else {
tag = encodedValue.getTagList("out", 10); tag = encodedValue.getTagList("out", Constants.NBT.TAG_COMPOUND);
} }
boolean foundMatchingItemStack = false; boolean foundMatchingItemStack = false;
final String[] splitTerm = searchTerm.split(" ");
for (int i = 0; i < tag.tagCount(); i++) { for (int i = 0; i < tag.tagCount(); i++) {
final ItemStack parsedItemStack = new ItemStack(tag.getCompoundTagAt(i)); final ItemStack parsedItemStack = new ItemStack(tag.getCompoundTagAt(i));
@@ -584,7 +585,7 @@ public class GuiInterfaceTerminal extends AEBaseGui {
.getItemDisplayName(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(parsedItemStack)) .getItemDisplayName(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(parsedItemStack))
.toLowerCase(); .toLowerCase();
for (String term : searchTerm.split(" ")) { for (String term : splitTerm) {
if (term.length() > 1 && (term.startsWith("-") || term.startsWith("!"))) { if (term.length() > 1 && (term.startsWith("-") || term.startsWith("!"))) {
term = term.substring(1); term = term.substring(1);
if (displayName.contains(term)) { if (displayName.contains(term)) {
@@ -47,6 +47,7 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.FluidUtil;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import javax.annotation.Nonnull;
import java.awt.*; import java.awt.*;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@@ -54,7 +55,7 @@ import java.util.*;
public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients { public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
private final Map<Target<?>, Object> mapTargetSlot = new HashMap<>(); protected final Map<Target<?>, Object> mapTargetSlot = new HashMap<>();
protected final ContainerUpgradeable cvb; protected final ContainerUpgradeable cvb;
protected final IUpgradeableHost bc; protected final IUpgradeableHost bc;
@@ -218,24 +219,25 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
List<Target<?>> targets = new ArrayList<>(); List<Target<?>> targets = new ArrayList<>();
List<IJEITargetSlot> slots = new ArrayList<>(); List<IJEITargetSlot> slots = new ArrayList<>();
if (this.inventorySlots.inventorySlots.size() > 0) { if (!this.inventorySlots.inventorySlots.isEmpty()) {
for (Slot slot : this.inventorySlots.inventorySlots) { for (Slot slot : this.inventorySlots.inventorySlots) {
if (slot instanceof SlotFake && (!itemStack.isEmpty() || this instanceof GuiCellWorkbench && fluidStack != null)) { if (slot instanceof SlotFake && (!itemStack.isEmpty() || this instanceof GuiCellWorkbench && fluidStack != null)) {
slots.add((IJEITargetSlot) slot); slots.add((IJEITargetSlot) slot);
} }
} }
} }
if (this.getGuiSlots().size() > 0) { if (!this.getGuiSlots().isEmpty()) {
for (GuiCustomSlot slot : this.getGuiSlots()) { for (GuiCustomSlot slot : this.getGuiSlots()) {
if (slot instanceof GuiFluidSlot && fluidStack != null) { if (slot instanceof GuiFluidSlot && fluidStack != null) {
slots.add((IJEITargetSlot) slot); slots.add((IJEITargetSlot) slot);
} }
} }
} }
for (Object slot : slots) { for (IJEITargetSlot slot : slots) {
ItemStack finalItemStack = itemStack; ItemStack finalItemStack = itemStack;
FluidStack finalFluidStack = fluidStack; FluidStack finalFluidStack = fluidStack;
Target<Object> targetItem = new Target<Object>() { Target<Object> targetItem = new Target<>() {
@Nonnull
@Override @Override
public Rectangle getArea() { public Rectangle getArea() {
if (slot instanceof SlotFake && ((SlotFake) slot).isSlotEnabled()) { if (slot instanceof SlotFake && ((SlotFake) slot).isSlotEnabled()) {
@@ -247,20 +249,20 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
} }
@Override @Override
public void accept(Object ingredient) { public void accept(@Nonnull Object ingredient) {
PacketInventoryAction p = null; PacketInventoryAction p = null;
try { try {
if (slot instanceof SlotFake && ((SlotFake) slot).isSlotEnabled()) { if (slot instanceof SlotFake && ((SlotFake) slot).isSlotEnabled()) {
if (finalItemStack.isEmpty() && finalFluidStack != null) { if (finalItemStack.isEmpty() && finalFluidStack != null) {
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(FluidUtil.getFilledBucket(finalFluidStack))); p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(FluidUtil.getFilledBucket(finalFluidStack)));
} else if (!finalItemStack.isEmpty()) { } else if (!finalItemStack.isEmpty()) {
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(finalItemStack)); p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(finalItemStack));
} }
} else { } else {
if (finalFluidStack == null) { if (finalFluidStack == null) {
return; return;
} }
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(AEFluidStack.fromFluidStack(finalFluidStack).asItemStackRepresentation())); p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(AEFluidStack.fromFluidStack(finalFluidStack).asItemStackRepresentation()));
} }
NetworkHandler.instance().sendToServer(p); NetworkHandler.instance().sendToServer(p);
@@ -0,0 +1,52 @@
package appeng.client.gui.toasts;
import appeng.core.localization.GuiText;
import net.minecraft.client.gui.toasts.GuiToast;
import net.minecraft.client.gui.toasts.IToast;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.jetbrains.annotations.NotNull;
@SideOnly(Side.CLIENT)
public class CraftingStatusToast implements IToast {
private final ItemStack itemStack;
private final boolean cancelled;
private long firstDrawTime;
private boolean newDisplay;
public CraftingStatusToast(@NotNull ItemStack itemStack, boolean cancelled) {
this.itemStack = itemStack;
this.cancelled = cancelled;
}
@NotNull
public Visibility draw(@NotNull GuiToast toastGui, long delta)
{
if (this.newDisplay)
{
this.firstDrawTime = delta;
this.newDisplay = false;
}
var minecraft = toastGui.getMinecraft();
var fontRenderer = minecraft.fontRenderer;
// Texture
minecraft.getTextureManager().bindTexture(TEXTURE_TOASTS);
GlStateManager.color(1.0F, 1.0F, 1.0F);
toastGui.drawTexturedModalRect(0, 0, 0, 32, 160, 32);
// Text
var statusText = cancelled ? GuiText.CraftingToastCancelled : GuiText.CraftingToastDone;
fontRenderer.drawString(statusText.getLocal(), 30, 7, -11534256);
fontRenderer.drawString(itemStack.getDisplayName(), 30, 18, -16777216);
// Item
RenderHelper.enableGUIStandardItemLighting();
minecraft.getRenderItem().renderItemAndEffectIntoGUI(null, itemStack, 8, 8);
return delta - this.firstDrawTime < 5000L ? Visibility.SHOW : Visibility.HIDE;
}
}
@@ -47,7 +47,7 @@ public class TesrRenderHelper {
* at the center of a block. * at the center of a block.
*/ */
public static void moveToFace(EnumFacing face) { public static void moveToFace(EnumFacing face) {
GlStateManager.translate(face.getFrontOffsetX() * 0.50, face.getFrontOffsetY() * 0.50, face.getFrontOffsetZ() * 0.50); GlStateManager.translate(face.getXOffset() * 0.50, face.getYOffset() * 0.50, face.getZOffset() * 0.50);
} }
/** /**
@@ -331,6 +331,10 @@ class CableBuilder {
TextureAtlasSprite oddChannel = this.smartCableTextures.getOddTextureForChannels((int) (channels / (AEConfig.instance().getNormalChannelCapacity() / 8))); TextureAtlasSprite oddChannel = this.smartCableTextures.getOddTextureForChannels((int) (channels / (AEConfig.instance().getNormalChannelCapacity() / 8)));
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels((int) (channels / (AEConfig.instance().getNormalChannelCapacity() / 8))); TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels((int) (channels / (AEConfig.instance().getNormalChannelCapacity() / 8)));
// Thin part of connector, here to prevent the color of the channels
// from leaking into it
addCoveredCableSizedCube(facing, cubeBuilder);
// For to-machine connections, use a thicker end-cap for the connection // For to-machine connections, use a thicker end-cap for the connection
if (connectionType != AECableType.GLASS && !cableBusAdjacent) { if (connectionType != AECableType.GLASS && !cableBusAdjacent) {
this.addBigCoveredCableSizedCube(facing, cubeBuilder); this.addBigCoveredCableSizedCube(facing, cubeBuilder);
@@ -351,7 +355,6 @@ class CableBuilder {
cubeBuilder.setTexture(texture); cubeBuilder.setTexture(texture);
} }
addCoveredCableSizedCube(facing, cubeBuilder);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setRenderFullBright(true);
@@ -467,8 +470,8 @@ class CableBuilder {
// Dense cables show used channels in groups of 4, rounded up // Dense cables show used channels in groups of 4, rounded up
channels = (int) ((channels + 3) / 4) / (AEConfig.instance().getDenseChannelCapacity() / 32); channels = (int) ((channels + 3) / 4) / (AEConfig.instance().getDenseChannelCapacity() / 32);
TextureAtlasSprite oddChannel = this.smartCableTextures.getOddTextureForChannels(channels); TextureAtlasSprite oddChannel = this.smartCableTextures.getOddTextureForDenseChannels(channels);
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels); TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForDenseChannels(channels);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setRenderFullBright(true);
@@ -493,7 +496,7 @@ class CableBuilder {
TextureAtlasSprite texture = this.connectionTextures.get(AECableType.DENSE_COVERED).get(cableColor); TextureAtlasSprite texture = this.connectionTextures.get(AECableType.DENSE_COVERED).get(cableColor);
cubeBuilder.setTexture(texture); cubeBuilder.setTexture(texture);
setStraightCableUVs(cubeBuilder, facing, 5, 11); setStraightCableUVs(cubeBuilder, facing, 3, 13);
addStraightDenseCableSizedCube(facing, cubeBuilder); addStraightDenseCableSizedCube(facing, cubeBuilder);
} }
@@ -504,15 +507,15 @@ class CableBuilder {
TextureAtlasSprite texture = this.connectionTextures.get(AECableType.DENSE_SMART).get(cableColor); TextureAtlasSprite texture = this.connectionTextures.get(AECableType.DENSE_SMART).get(cableColor);
cubeBuilder.setTexture(texture); cubeBuilder.setTexture(texture);
setStraightCableUVs(cubeBuilder, facing, 5, 11); setStraightCableUVs(cubeBuilder, facing, 3, 13);
addStraightDenseCableSizedCube(facing, cubeBuilder); addStraightDenseCableSizedCube(facing, cubeBuilder);
// Dense cables show used channels in groups of 4, rounded up // Dense cables show used channels in groups of 4, rounded up
channels = (int) ((channels + 3) / 4) / (AEConfig.instance().getDenseChannelCapacity() / 32); channels = (int) ((channels + 3) / 4) / (AEConfig.instance().getDenseChannelCapacity() / 32);
TextureAtlasSprite oddChannel = this.smartCableTextures.getOddTextureForChannels(channels); TextureAtlasSprite oddChannel = this.smartCableTextures.getOddTextureForDenseChannels(channels);
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels); TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForDenseChannels(channels);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setRenderFullBright(true);
@@ -556,14 +559,14 @@ class CableBuilder {
case DOWN: case DOWN:
case UP: case UP:
cubeBuilder.setUvRotation(EnumFacing.EAST, 3); cubeBuilder.setUvRotation(EnumFacing.EAST, 3);
cubeBuilder.addCube(3, 0, 3, 13, 16, 13); cubeBuilder.addCube(3, -0.01f, 3, 13, 16.01f, 13);
cubeBuilder.setUvRotation(EnumFacing.EAST, 0); cubeBuilder.setUvRotation(EnumFacing.EAST, 0);
break; break;
case EAST: case EAST:
case WEST: case WEST:
cubeBuilder.setUvRotation(EnumFacing.SOUTH, 3); cubeBuilder.setUvRotation(EnumFacing.SOUTH, 3);
cubeBuilder.setUvRotation(EnumFacing.NORTH, 3); cubeBuilder.setUvRotation(EnumFacing.NORTH, 3);
cubeBuilder.addCube(0, 3, 3, 16, 13, 13); cubeBuilder.addCube(-0.01f, 3, 3, 16.01f, 13, 13);
cubeBuilder.setUvRotation(EnumFacing.SOUTH, 0); cubeBuilder.setUvRotation(EnumFacing.SOUTH, 0);
cubeBuilder.setUvRotation(EnumFacing.NORTH, 0); cubeBuilder.setUvRotation(EnumFacing.NORTH, 0);
break; break;
@@ -571,7 +574,7 @@ class CableBuilder {
case SOUTH: case SOUTH:
cubeBuilder.setUvRotation(EnumFacing.EAST, 3); cubeBuilder.setUvRotation(EnumFacing.EAST, 3);
cubeBuilder.setUvRotation(EnumFacing.WEST, 3); cubeBuilder.setUvRotation(EnumFacing.WEST, 3);
cubeBuilder.addCube(3, 3, 0, 13, 13, 16); cubeBuilder.addCube(3, 3, -0.01f, 13, 13, 16.01f);
cubeBuilder.setUvRotation(EnumFacing.EAST, 0); cubeBuilder.setUvRotation(EnumFacing.EAST, 0);
cubeBuilder.setUvRotation(EnumFacing.WEST, 0); cubeBuilder.setUvRotation(EnumFacing.WEST, 0);
break; break;
@@ -611,14 +614,14 @@ class CableBuilder {
case DOWN: case DOWN:
case UP: case UP:
cubeBuilder.setUvRotation(EnumFacing.EAST, 3); cubeBuilder.setUvRotation(EnumFacing.EAST, 3);
cubeBuilder.addCube(5, 0, 5, 11, 16, 11); cubeBuilder.addCube(5, -0.01f, 5, 11, 16.01f, 11);
cubeBuilder.setUvRotation(EnumFacing.EAST, 0); cubeBuilder.setUvRotation(EnumFacing.EAST, 0);
break; break;
case EAST: case EAST:
case WEST: case WEST:
cubeBuilder.setUvRotation(EnumFacing.SOUTH, 3); cubeBuilder.setUvRotation(EnumFacing.SOUTH, 3);
cubeBuilder.setUvRotation(EnumFacing.NORTH, 3); cubeBuilder.setUvRotation(EnumFacing.NORTH, 3);
cubeBuilder.addCube(0, 5, 5, 16, 11, 11); cubeBuilder.addCube(-0.01f, 5, 5, 16.01f, 11, 11);
cubeBuilder.setUvRotation(EnumFacing.SOUTH, 0); cubeBuilder.setUvRotation(EnumFacing.SOUTH, 0);
cubeBuilder.setUvRotation(EnumFacing.NORTH, 0); cubeBuilder.setUvRotation(EnumFacing.NORTH, 0);
break; break;
@@ -626,7 +629,7 @@ class CableBuilder {
case SOUTH: case SOUTH:
cubeBuilder.setUvRotation(EnumFacing.EAST, 3); cubeBuilder.setUvRotation(EnumFacing.EAST, 3);
cubeBuilder.setUvRotation(EnumFacing.WEST, 3); cubeBuilder.setUvRotation(EnumFacing.WEST, 3);
cubeBuilder.addCube(5, 5, 0, 11, 11, 16); cubeBuilder.addCube(5, 5, -0.01f, 11, 11, 16.01f);
cubeBuilder.setUvRotation(EnumFacing.EAST, 0); cubeBuilder.setUvRotation(EnumFacing.EAST, 0);
cubeBuilder.setUvRotation(EnumFacing.WEST, 0); cubeBuilder.setUvRotation(EnumFacing.WEST, 0);
break; break;
@@ -702,6 +705,7 @@ class CableBuilder {
} }
Collections.addAll(locations, SmartCableTextures.SMART_CHANNELS_TEXTURES); Collections.addAll(locations, SmartCableTextures.SMART_CHANNELS_TEXTURES);
Collections.addAll(locations, SmartCableTextures.DENSE_SMART_CHANNELS_TEXTURES);
return locations; return locations;
} }
@@ -24,6 +24,10 @@ import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType; import appeng.api.util.AECableType;
import appeng.api.util.AEColor; import appeng.api.util.AEColor;
import appeng.block.networking.BlockCableBus; import appeng.block.networking.BlockCableBus;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BakedQuad;
@@ -38,6 +42,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient; import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -45,8 +50,6 @@ import java.util.Map.Entry;
public class CableBusBakedModel implements IBakedModel { public class CableBusBakedModel implements IBakedModel {
static final Map<CableBusRenderState, List<BakedQuad>> CABLE_MODEL_CACHE = new HashMap<>();
private final CableBuilder cableBuilder; private final CableBuilder cableBuilder;
private final FacadeBuilder facadeBuilder; private final FacadeBuilder facadeBuilder;
@@ -57,11 +60,24 @@ public class CableBusBakedModel implements IBakedModel {
private final TextureMap textureMap = Minecraft.getMinecraft().getTextureMapBlocks(); private final TextureMap textureMap = Minecraft.getMinecraft().getTextureMapBlocks();
private final LoadingCache<CableBusRenderState, List<BakedQuad>> cableModelCache;
CableBusBakedModel(CableBuilder cableBuilder, FacadeBuilder facadeBuilder, Map<ResourceLocation, IBakedModel> partModels, TextureAtlasSprite particleTexture) { CableBusBakedModel(CableBuilder cableBuilder, FacadeBuilder facadeBuilder, Map<ResourceLocation, IBakedModel> partModels, TextureAtlasSprite particleTexture) {
this.cableBuilder = cableBuilder; this.cableBuilder = cableBuilder;
this.facadeBuilder = facadeBuilder; this.facadeBuilder = facadeBuilder;
this.partModels = partModels; this.partModels = partModels;
this.particleTexture = particleTexture; this.particleTexture = particleTexture;
this.cableModelCache = CacheBuilder.newBuilder()
.maximumWeight(5000)
.weigher((Weigher<CableBusRenderState, List<BakedQuad>>) (k, v) -> v.size())
.build(new CacheLoader<>() {
@Override
public List<BakedQuad> load(@Nonnull CableBusRenderState rs) {
final List<BakedQuad> model = new ArrayList<>();
addCableQuads(rs, model);
return model;
}
});
} }
@Override @Override
@@ -82,12 +98,7 @@ public class CableBusBakedModel implements IBakedModel {
if (layer == BlockRenderLayer.CUTOUT) { if (layer == BlockRenderLayer.CUTOUT) {
// First, handle the cable at the center of the cable bus // First, handle the cable at the center of the cable bus
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent(renderState, k -> final List<BakedQuad> cableModel = cableModelCache.getUnchecked(renderState);
{
final List<BakedQuad> model = new ArrayList<>();
this.addCableQuads(renderState, model);
return model;
});
quads.addAll(cableModel); quads.addAll(cableModel);
// Then handle attachments // Then handle attachments
@@ -27,26 +27,21 @@ import com.google.common.collect.ImmutableMap;
import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.IModel; import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry; import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.resource.IResourceType;
import net.minecraftforge.client.resource.ISelectiveResourceReloadListener;
import net.minecraftforge.client.resource.VanillaResourceType;
import net.minecraftforge.common.model.IModelState; import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation; import net.minecraftforge.common.model.TRSRTransformation;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate;
/** /**
* The built-in model for the cable bus block. * The built-in model for the cable bus block.
*/ */
public class CableBusModel implements IModel, ISelectiveResourceReloadListener { public class CableBusModel implements IModel {
private final PartModels partModels; private final PartModels partModels;
@@ -106,12 +101,4 @@ public class CableBusModel implements IModel, ISelectiveResourceReloadListener {
public IModelState getDefaultState() { public IModelState getDefaultState() {
return TRSRTransformation.identity(); return TRSRTransformation.identity();
} }
@Override
public void onResourceManagerReload(IResourceManager resourceManager, Predicate<IResourceType> resourcePredicate) {
if (resourcePredicate.test(VanillaResourceType.MODELS)) {
CableBusBakedModel.CABLE_MODEL_CACHE.clear();
}
}
} }
@@ -398,7 +398,7 @@ public class CubeBuilder {
builder.put(i, x, y, z); builder.put(i, x, y, z);
break; break;
case NORMAL: case NORMAL:
builder.put(i, face.getFrontOffsetX(), face.getFrontOffsetY(), face.getFrontOffsetZ()); builder.put(i, face.getXOffset(), face.getYOffset(), face.getZOffset());
break; break;
case COLOR: case COLOR:
// Color format is RGBA // Color format is RGBA
@@ -72,7 +72,7 @@ public class QuadRotator {
// Figure out where the position is in the array // Figure out where the position is in the array
VertexFormat format = quad.getFormat(); VertexFormat format = quad.getFormat();
int posIdx = this.findPositionOffset(format) / 4; int posIdx = this.findPositionOffset(format) / 4;
int stride = format.getNextOffset() / 4; int stride = format.getSize() / 4;
int normalIdx = format.getNormalOffset(); int normalIdx = format.getNormalOffset();
VertexFormatElement.EnumType normalType = null; VertexFormatElement.EnumType normalType = null;
// Figure out the type of the normals // Figure out the type of the normals
@@ -32,20 +32,43 @@ import java.util.function.Function;
*/ */
public class SmartCableTextures { public class SmartCableTextures {
public static final ResourceLocation[] SMART_CHANNELS_TEXTURES = {new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_00"), public static final ResourceLocation[] SMART_CHANNELS_TEXTURES = {
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_00"),
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_01"),
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_02"),
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_03"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_14") 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"),
}; };
// Textures used to display channels on smart cables. There's two sets of 5 textures each, and // Textures used to display channels on smart cables. There's two sets of 5 textures each, and
// one of each set are composed together to get even/odd colored channels // one of each set are composed together to get even/odd colored channels
private final TextureAtlasSprite[] textures; private final TextureAtlasSprite[] textures;
public static final ResourceLocation[] DENSE_SMART_CHANNELS_TEXTURES = {
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_00"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_01"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_02"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_03"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_04"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_10"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_11"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_12"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_13"),
new ResourceLocation(AppEng.MOD_ID, "parts/cable/dense_smart/channels_14"),
};
// Textures used to display channels on dense smart cables. There's two sets of 5 textures each, and
// one of each set are composed together to get even/odd colored channels
private final TextureAtlasSprite[] denseTextures;
public SmartCableTextures(Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) { public SmartCableTextures(Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
this.textures = Arrays.stream(SMART_CHANNELS_TEXTURES).map(bakedTextureGetter::apply).toArray(TextureAtlasSprite[]::new); this.textures = Arrays.stream(SMART_CHANNELS_TEXTURES).map(bakedTextureGetter::apply).toArray(TextureAtlasSprite[]::new);
this.denseTextures = Arrays.stream(DENSE_SMART_CHANNELS_TEXTURES).map(bakedTextureGetter::apply).toArray(TextureAtlasSprite[]::new);
} }
/** /**
@@ -61,8 +84,18 @@ public class SmartCableTextures {
} }
} }
public TextureAtlasSprite getOddTextureForDenseChannels(int channels) {
if (channels < 0) {
return this.denseTextures[0];
} else if (channels <= 4) {
return this.denseTextures[channels];
} else {
return this.denseTextures[4];
}
}
/** /**
* The odd variant is used for displaying channels 5-8 as in use. * The even variant is used for displaying channels 5-8 as in use.
*/ */
public TextureAtlasSprite getEvenTextureForChannels(int channels) { public TextureAtlasSprite getEvenTextureForChannels(int channels) {
if (channels < 5) { if (channels < 5) {
@@ -73,4 +106,14 @@ public class SmartCableTextures {
return this.textures[9]; return this.textures[9];
} }
} }
public TextureAtlasSprite getEvenTextureForDenseChannels(int channels) {
if (channels < 5) {
return this.denseTextures[5];
} else if (channels <= 8) {
return this.denseTextures[1 + channels];
} else {
return this.denseTextures[9];
}
}
} }
@@ -21,6 +21,7 @@ package appeng.client.render.model;
import appeng.block.AEBaseTileBlock; import appeng.block.AEBaseTileBlock;
import appeng.client.render.FacingToRotation; import appeng.client.render.FacingToRotation;
import com.google.common.base.Objects;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
@@ -30,19 +31,22 @@ import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemOverrideList; import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import javax.vecmath.Matrix4f; import javax.vecmath.Vector3f;
import javax.vecmath.Tuple4f;
import javax.vecmath.Vector4f; import javax.vecmath.Vector4f;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.minecraft.util.EnumFacing.DOWN;
public class AutoRotatingModel implements IBakedModel, IResourceManagerReloadListener { public class AutoRotatingModel implements IBakedModel, IResourceManagerReloadListener {
@@ -64,171 +68,34 @@ public class AutoRotatingModel implements IBakedModel, IResourceManagerReloadLis
FacingToRotation f2r = FacingToRotation.get(forward, up); FacingToRotation f2r = FacingToRotation.get(forward, up);
List<BakedQuad> original = AutoRotatingModel.this.parent.getQuads(state, f2r.resultingRotate(side), 0); List<BakedQuad> original = AutoRotatingModel.this.parent.getQuads(state, f2r.resultingRotate(side), 0);
List<BakedQuad> rotated = new ArrayList<>(original.size()); List<BakedQuad> rotated = new ArrayList<>(original.size());
for (BakedQuad quad : original) {
VertexFormat format = quad.getFormat();
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
VertexRotator rot = new VertexRotator(f2r, quad.getFace());
rot.setParent(builder);
quad.pipe(rot);
if (quad.getFace() != null) {
builder.setQuadOrientation(f2r.rotate(quad.getFace()));
} else {
builder.setQuadOrientation(null);
final Matrix4f transformMatrix = new Matrix4f(); }
final Tuple4f vertexTransformingVec = new Vector4f(); BakedQuad unpackedQuad = builder.build();
// Transform the matrix so the top and front facings of the model matches the block in-world // Make a copy of it to resolve the vertex data and throw away the unpacked stuff
transformMatrixByFacings(transformMatrix, up, forward); // This also fixes a bug in Forge's UnpackedBakedQuad, which unpacks a byte-based normal like 0,0,-1
// to 0,0,-0.99607843. We replace these normals with the proper 0,0,-1 when rotation, which
for (BakedQuad b : original) { // causes a bug in the AO lighter, if an unpacked quad pipes this value back to it.
EnumFacing newFace = f2r.rotate(b.getFace()); // Packing it back to the vanilla vertex format will fix this inconsistency because it converts
rotated.add(rebakeQuad(b, newFace, transformMatrix, vertexTransformingVec)); // the normal back to a byte-based format, which then re-applies Forge's own bug when piping it
// to the AO lighter, thus fixing our problem.
BakedQuad packedQuad = new BakedQuad(unpackedQuad.getVertexData(), quad.getTintIndex(), unpackedQuad.getFace(), quad.getSprite(), quad
.shouldApplyDiffuseLighting(), quad.getFormat());
rotated.add(packedQuad);
} }
return rotated; return rotated;
} }
private void transformMatrixByFacings(Matrix4f transformMatrix, EnumFacing topFacing, EnumFacing frontFacing) {
Matrix4f intermediaryMatrix = new Matrix4f();
transformMatrix.setIdentity();
moveToPivot(transformMatrix, intermediaryMatrix, true);
if (topFacing.getAxis() == EnumFacing.Axis.Y) {
switch (frontFacing) {
case NORTH:
rotateY(transformMatrix, intermediaryMatrix, (float) (0));
break;
case SOUTH:
rotateY(transformMatrix, intermediaryMatrix, (float) (-Math.PI));
break;
case EAST:
rotateY(transformMatrix, intermediaryMatrix, (float) (-Math.PI / 2));
break;
case WEST:
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI / 2));
break;
}
if (topFacing == DOWN) {
rotateX(transformMatrix, intermediaryMatrix, (float) (Math.PI));
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI));
}
} else {
switch (topFacing) {
case WEST:
rotateZ(transformMatrix, intermediaryMatrix, (float) (Math.PI / 2));
switch (frontFacing) {
case DOWN:
rotateY(transformMatrix, intermediaryMatrix, (float) (-Math.PI / 2));
break;
case UP:
rotateY(transformMatrix, intermediaryMatrix, (float) (+Math.PI / 2));
break;
case SOUTH:
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI));
}
break;
case EAST:
rotateZ(transformMatrix, intermediaryMatrix, (float) (-Math.PI / 2));
switch (frontFacing) {
case DOWN:
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI / 2));
break;
case UP:
rotateY(transformMatrix, intermediaryMatrix, (float) (-Math.PI / 2));
break;
case SOUTH:
rotateY(transformMatrix, intermediaryMatrix, (float) (-Math.PI));
}
break;
case NORTH:
rotateX(transformMatrix, intermediaryMatrix, (float) (-Math.PI / 2));
switch (frontFacing) {
case DOWN:
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI));
break;
case EAST:
rotateY(transformMatrix, intermediaryMatrix, (float) (-Math.PI / 2));
break;
case WEST:
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI / 2));
}
break;
default:
rotateX(transformMatrix, intermediaryMatrix, (float) (Math.PI / 2));
switch (frontFacing) {
case UP:
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI));
break;
case EAST:
rotateY(transformMatrix, intermediaryMatrix, (float) (-Math.PI / 2));
break;
case SOUTH:
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI / 2));
break;
case WEST:
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI / 2));
break;
}
}
if (frontFacing.getAxis() == EnumFacing.Axis.Y) {
//rotateX(transformMatrix, intermediaryMatrix, (float) (Math.PI));
rotateY(transformMatrix, intermediaryMatrix, (float) (Math.PI));
}
}
moveToPivot(transformMatrix, intermediaryMatrix, false);
}
private void moveToPivot(Matrix4f matrix, Matrix4f intermediary, boolean positive) {
intermediary.setIdentity();
float pivot = positive ? .5F : -.5F;
intermediary.m03 = pivot;
intermediary.m13 = pivot;
intermediary.m23 = pivot;
matrix.mul(intermediary);
}
private void rotateX(Matrix4f matrix, Matrix4f intermediary, float angle) {
intermediary.setIdentity();
intermediary.rotX(angle);
matrix.mul(intermediary);
}
private void rotateY(Matrix4f matrix, Matrix4f intermediary, float angle) {
intermediary.setIdentity();
intermediary.rotY(angle);
matrix.mul(intermediary);
}
private void rotateZ(Matrix4f matrix, Matrix4f intermediary, float angle) {
intermediary.setIdentity();
intermediary.rotZ(angle);
matrix.mul(intermediary);
}
private BakedQuad rebakeQuad(BakedQuad b, EnumFacing newFacing, Matrix4f transformMatrix, Tuple4f vertexTransformingVec) {
int[] newQuad = new int[28];
int[] quadData = b.getVertexData();
for (int k = 0; k < 4; ++k) {
// Getting the offset for the current vertex.
int vertexIndex = k * 7;
vertexTransformingVec.x = Float.intBitsToFloat(quadData[vertexIndex]);
vertexTransformingVec.y = Float.intBitsToFloat(quadData[vertexIndex + 1]);
vertexTransformingVec.z = Float.intBitsToFloat(quadData[vertexIndex + 2]);
vertexTransformingVec.w = 1;
// Transforming it by the model matrix.
transformMatrix.transform(vertexTransformingVec);
// Converting the new data to ints.
int x = Float.floatToRawIntBits(vertexTransformingVec.x);
int y = Float.floatToRawIntBits(vertexTransformingVec.y);
int z = Float.floatToRawIntBits(vertexTransformingVec.z);
// Vertex position data
newQuad[vertexIndex] = x;
newQuad[vertexIndex + 1] = y;
newQuad[vertexIndex + 2] = z;
newQuad[vertexIndex + 3] = quadData[vertexIndex + 3];
newQuad[vertexIndex + 4] = quadData[vertexIndex + 4]; //texture
newQuad[vertexIndex + 5] = quadData[vertexIndex + 5];
// Vertex brightness
newQuad[vertexIndex + 6] = 0x81818181;
}
return new BakedQuad(newQuad, b.getTintIndex(), newFacing, b.getSprite(), b.shouldApplyDiffuseLighting(), b.getFormat());
}
@Override @Override
public boolean isAmbientOcclusion() { public boolean isAmbientOcclusion() {
return this.parent.isAmbientOcclusion(); return this.parent.isAmbientOcclusion();
@@ -292,4 +159,140 @@ public class AutoRotatingModel implements IBakedModel, IResourceManagerReloadLis
this.quadCache.invalidateAll(); this.quadCache.invalidateAll();
} }
public static class VertexRotator extends QuadGatheringTransformer {
private final FacingToRotation f2r;
private final EnumFacing face;
public VertexRotator(FacingToRotation f2r, EnumFacing face) {
this.f2r = f2r;
this.face = face;
}
@Override
public void setParent(IVertexConsumer parent) {
super.setParent(parent);
if (Objects.equal(this.getVertexFormat(), parent.getVertexFormat())) {
return;
}
this.setVertexFormat(parent.getVertexFormat());
}
@Override
protected void processQuad() {
VertexFormat format = this.parent.getVertexFormat();
int count = format.getElementCount();
for (int v = 0; v < 4; v++) {
for (int e = 0; e < count; e++) {
VertexFormatElement element = format.getElement(e);
if (element.getUsage() == VertexFormatElement.EnumUsage.POSITION) {
this.parent.put(e, this.transform(this.quadData[e][v]));
} else if (element.getUsage() == VertexFormatElement.EnumUsage.NORMAL) {
this.parent.put(e, this.transformNormal(this.quadData[e][v]));
} else {
this.parent.put(e, this.quadData[e][v]);
}
}
}
}
private float[] transform(float[] fs) {
switch (fs.length) {
case 3:
Vector3f vec = new Vector3f(fs[0], fs[1], fs[2]);
vec.x -= 0.5f;
vec.y -= 0.5f;
vec.z -= 0.5f;
this.f2r.getMat().transform(vec);
vec.x += 0.5f;
vec.y += 0.5f;
vec.z += 0.5f;
return new float[]{vec.x, vec.y, vec.z
};
case 4:
Vector4f vecc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
vecc.x -= 0.5f;
vecc.y -= 0.5f;
vecc.z -= 0.5f;
this.f2r.getMat().transform(vecc);
vecc.x += 0.5f;
vecc.y += 0.5f;
vecc.z += 0.5f;
return new float[]{vecc.x, vecc.y, vecc.z, vecc.w
};
default:
return fs;
}
}
private float[] transformNormal(float[] fs) {
if (this.face == null) {
switch (fs.length) {
case 3:
Vector3f vec = new Vector3f(fs);
this.f2r.getMat().transform(vec);
return new float[]{
vec.getX(),
vec.getY(),
vec.getZ()
};
case 4:
Vector4f vec4 = new Vector4f(fs);
this.f2r.getMat().transform(vec4);
return new float[]{
vec4.getX(),
vec4.getY(),
vec4.getZ(),
0
};
default:
return fs;
}
} else {
switch (fs.length) {
case 3:
Vec3i vec = this.f2r.rotate(this.face).getDirectionVec();
return new float[]{
vec.getX(),
vec.getY(),
vec.getZ()
};
case 4:
Vector4f veccc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
Vec3i vecc = this.f2r.rotate(this.face).getDirectionVec();
return new float[]{
vecc.getX(),
vecc.getY(),
vecc.getZ(),
veccc.w
};
default:
return fs;
}
}
}
@Override
public void setQuadTint(int tint) {
this.parent.setQuadTint(tint);
}
@Override
public void setQuadOrientation(EnumFacing orientation) {
this.parent.setQuadOrientation(orientation);
}
@Override
public void setApplyDiffuseLighting(boolean diffuse) {
this.parent.setApplyDiffuseLighting(diffuse);
}
@Override
public void setTexture(TextureAtlasSprite texture) {
this.parent.setTexture(texture);
}
}
} }
@@ -43,16 +43,16 @@ public class BuiltInModelLoader implements ICustomModelLoader {
@Override @Override
public boolean accepts(ResourceLocation modelLocation) { public boolean accepts(ResourceLocation modelLocation) {
if (!modelLocation.getResourceDomain().equals(AppEng.MOD_ID)) { if (!modelLocation.getNamespace().equals(AppEng.MOD_ID)) {
return false; return false;
} }
return this.builtInModels.containsKey(modelLocation.getResourcePath()); return this.builtInModels.containsKey(modelLocation.getPath());
} }
@Override @Override
public IModel loadModel(ResourceLocation modelLocation) throws Exception { public IModel loadModel(ResourceLocation modelLocation) throws Exception {
return this.builtInModels.get(modelLocation.getResourcePath()); return this.builtInModels.get(modelLocation.getPath());
} }
@Override @Override
@@ -21,33 +21,26 @@ package appeng.client.render.model;
import appeng.block.storage.BlockDrive; import appeng.block.storage.BlockDrive;
import appeng.block.storage.DriveSlotState; import appeng.block.storage.DriveSlotState;
import appeng.block.storage.DriveSlotsState; import appeng.block.storage.DriveSlotsState;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemOverrideList; import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.vecmath.Matrix4f; import javax.vecmath.Matrix4f;
import javax.vecmath.Tuple4f;
import javax.vecmath.Vector3f; import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class DriveBakedModel implements IBakedModel, IResourceManagerReloadListener { public class DriveBakedModel implements IBakedModel {
private final IBakedModel bakedBase; private final IBakedModel bakedBase;
private final Map<DriveSlotState, IBakedModel> bakedCells; private final Map<DriveSlotState, IBakedModel> bakedCells;
private final Int2ObjectMap<Map<DriveSlotState, List<BakedQuad>>> slot2DSMap = new Int2ObjectOpenHashMap<>();
public DriveBakedModel(IBakedModel bakedBase, Map<DriveSlotState, IBakedModel> bakedCells) { public DriveBakedModel(IBakedModel bakedBase, Map<DriveSlotState, IBakedModel> bakedCells) {
this.bakedBase = bakedBase; this.bakedBase = bakedBase;
@@ -59,7 +52,8 @@ public class DriveBakedModel implements IBakedModel, IResourceManagerReloadListe
List<BakedQuad> result = new ArrayList<>(this.bakedBase.getQuads(state, side, rand)); List<BakedQuad> result = new ArrayList<>(this.bakedBase.getQuads(state, side, rand));
if (side == null && state instanceof IExtendedBlockState extState) { if (side == null && state instanceof IExtendedBlockState) {
IExtendedBlockState extState = (IExtendedBlockState) state;
if (!extState.getUnlistedNames().contains(BlockDrive.SLOTS_STATE)) { if (!extState.getUnlistedNames().contains(BlockDrive.SLOTS_STATE)) {
return result; return result;
@@ -67,38 +61,31 @@ public class DriveBakedModel implements IBakedModel, IResourceManagerReloadListe
DriveSlotsState slotsState = extState.getValue(BlockDrive.SLOTS_STATE); DriveSlotsState slotsState = extState.getValue(BlockDrive.SLOTS_STATE);
for (int row = 0; row < 5; row++) { for (int row = 0; row < 5; row++) {
for (int col = 0; col < 2; col++) { for (int col = 0; col < 2; col++) {
int slot = row * 2 + col; DriveSlotState slotState = slotsState.getState(row * 2 + col);
DriveSlotState slotState = slotsState.getState(slot);
slot2DSMap.putIfAbsent(slot, new Object2ObjectOpenHashMap<>());
int finalCol = col;
int finalRow = row;
List<BakedQuad> lbq = slot2DSMap.get(slot).computeIfAbsent(slotState, q -> {
List<BakedQuad> res = new ArrayList<>();
IBakedModel bakedCell = this.bakedCells.get(slotState); IBakedModel bakedCell = this.bakedCells.get(slotState);
final Matrix4f transformMatrix = new Matrix4f(); Matrix4f transform = new Matrix4f();
transformMatrix.setIdentity(); transform.setIdentity();
final Tuple4f transform = new Vector4f();
// Position this drive model copy at the correct slot. The transform is based on // Position this drive model copy at the correct slot. The transform is based on
// the // the
// cell-model being in slot 0,0 at the top left of the drive. // cell-model being in slot 0,0 at the top left of the drive.
float xOffset = -finalCol * 8 / 16.0f; float xOffset = -col * 8 / 16.0f;
float yOffset = -finalRow * 3 / 16.0f; float yOffset = -row * 3 / 16.0f;
transformMatrix.setTranslation(new Vector3f(xOffset, yOffset, 0)); transform.setTranslation(new Vector3f(xOffset, yOffset, 0));
MatrixVertexTransformer transformer = new MatrixVertexTransformer(transform);
for (BakedQuad bakedQuad : bakedCell.getQuads(state, null, rand)) { for (BakedQuad bakedQuad : bakedCell.getQuads(state, null, rand)) {
res.add(rebakeQuad(bakedQuad, transformMatrix, transform)); UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(bakedQuad.getFormat());
transformer.setParent(builder);
transformer.setVertexFormat(builder.getVertexFormat());
bakedQuad.pipe(transformer);
result.add(builder.build());
} }
return res;
});
result.addAll(lbq);
} }
} }
} }
@@ -106,41 +93,6 @@ public class DriveBakedModel implements IBakedModel, IResourceManagerReloadListe
return result; return result;
} }
private BakedQuad rebakeQuad(BakedQuad b, Matrix4f transformMatrix, Tuple4f vertexTransformingVec) {
int[] newQuad = new int[28];
int[] quadData = b.getVertexData();
for (int k = 0; k < 4; ++k) {
// Getting the offset for the current vertex.
int vertexIndex = k * 7;
vertexTransformingVec.x = Float.intBitsToFloat(quadData[vertexIndex]);
vertexTransformingVec.y = Float.intBitsToFloat(quadData[vertexIndex + 1]);
vertexTransformingVec.z = Float.intBitsToFloat(quadData[vertexIndex + 2]);
vertexTransformingVec.w = 1;
// Transforming it by the model matrix.
transformMatrix.transform(vertexTransformingVec);
// Converting the new data to ints.
int x = Float.floatToRawIntBits(vertexTransformingVec.x);
int y = Float.floatToRawIntBits(vertexTransformingVec.y);
int z = Float.floatToRawIntBits(vertexTransformingVec.z);
// Vertex position data
newQuad[vertexIndex] = x;
newQuad[vertexIndex + 1] = y;
newQuad[vertexIndex + 2] = z;
newQuad[vertexIndex + 3] = quadData[vertexIndex + 3];
newQuad[vertexIndex + 4] = quadData[vertexIndex + 4]; //texture
newQuad[vertexIndex + 5] = quadData[vertexIndex + 5];
// Vertex brightness
newQuad[vertexIndex + 6] = 0x81818181;
}
return new BakedQuad(newQuad, b.getTintIndex(), b.getFace(), b.getSprite(), b.shouldApplyDiffuseLighting(), b.getFormat());
}
@Override @Override
public boolean isAmbientOcclusion() { public boolean isAmbientOcclusion() {
return this.bakedBase.isAmbientOcclusion(); return this.bakedBase.isAmbientOcclusion();
@@ -170,9 +122,4 @@ public class DriveBakedModel implements IBakedModel, IResourceManagerReloadListe
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return this.bakedBase.getOverrides(); return this.bakedBase.getOverrides();
} }
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
slot2DSMap.clear();
}
} }
@@ -42,12 +42,14 @@ public class DriveModel implements IModel {
private static final ResourceLocation MODEL_BASE = new ResourceLocation("appliedenergistics2:block/drive_base"); private static final ResourceLocation MODEL_BASE = new ResourceLocation("appliedenergistics2:block/drive_base");
private static final Map<DriveSlotState, ResourceLocation> MODELS_CELLS = ImmutableMap.of( private static final Map<DriveSlotState, ResourceLocation> MODELS_CELLS = ImmutableMap.<DriveSlotState, ResourceLocation>builder()
DriveSlotState.EMPTY, new ResourceLocation("appliedenergistics2:block/drive_cell_empty"), .put(DriveSlotState.EMPTY, new ResourceLocation("appliedenergistics2:block/drive_cell_empty"))
DriveSlotState.OFFLINE, new ResourceLocation("appliedenergistics2:block/drive_cell_off"), .put(DriveSlotState.OFFLINE, new ResourceLocation("appliedenergistics2:block/drive_cell_off"))
DriveSlotState.ONLINE, new ResourceLocation("appliedenergistics2:block/drive_cell_on"), .put(DriveSlotState.ONLINE, new ResourceLocation("appliedenergistics2:block/drive_cell_on"))
DriveSlotState.TYPES_FULL, new ResourceLocation("appliedenergistics2:block/drive_cell_types_full"), .put(DriveSlotState.TYPES_FULL, new ResourceLocation("appliedenergistics2:block/drive_cell_types_full"))
DriveSlotState.FULL, new ResourceLocation("appliedenergistics2:block/drive_cell_full")); .put(DriveSlotState.FULL, new ResourceLocation("appliedenergistics2:block/drive_cell_full"))
.put(DriveSlotState.NO_CONTENTS, new ResourceLocation("appliedenergistics2:block/drive_cell_no_contents"))
.build();
@Override @Override
public Collection<ResourceLocation> getDependencies() { public Collection<ResourceLocation> getDependencies() {
@@ -137,14 +137,14 @@ public enum UVLModelLoader implements ICustomModelLoader {
@Override @Override
public boolean accepts(ResourceLocation modelLocation) { public boolean accepts(ResourceLocation modelLocation) {
String modelPath = modelLocation.getResourcePath(); String modelPath = modelLocation.getPath();
if (modelLocation.getResourcePath().startsWith("models/")) { if (modelLocation.getPath().startsWith("models/")) {
modelPath = modelPath.substring("models/".length()); modelPath = modelPath.substring("models/".length());
} }
try (InputStreamReader io = new InputStreamReader(Minecraft.getMinecraft() try (InputStreamReader io = new InputStreamReader(Minecraft.getMinecraft()
.getResourceManager() .getResourceManager()
.getResource(new ResourceLocation(modelLocation.getResourceDomain(), "models/" + modelPath + ".json")) .getResource(new ResourceLocation(modelLocation.getNamespace(), "models/" + modelPath + ".json"))
.getInputStream())) { .getInputStream())) {
return gson.fromJson(io, UVLMarker.class).ae2_uvl_marker; return gson.fromJson(io, UVLMarker.class).ae2_uvl_marker;
} catch (Exception e) { } catch (Exception e) {
@@ -174,11 +174,11 @@ public enum UVLModelLoader implements ICustomModelLoader {
private final IModel parent; private final IModel parent;
public UVLModelWrapper(ResourceLocation modelLocation) { public UVLModelWrapper(ResourceLocation modelLocation) {
String modelPath = modelLocation.getResourcePath(); String modelPath = modelLocation.getPath();
if (modelLocation.getResourcePath().startsWith("models/")) { if (modelLocation.getPath().startsWith("models/")) {
modelPath = modelPath.substring("models/".length()); modelPath = modelPath.substring("models/".length());
} }
ResourceLocation armatureLocation = new ResourceLocation(modelLocation.getResourceDomain(), "armatures/" + modelPath + ".json"); ResourceLocation armatureLocation = new ResourceLocation(modelLocation.getNamespace(), "armatures/" + modelPath + ".json");
ModelBlockAnimation animation = ModelBlockAnimation.loadVanillaAnimation(UVLModelLoader.this.resourceManager, armatureLocation); ModelBlockAnimation animation = ModelBlockAnimation.loadVanillaAnimation(UVLModelLoader.this.resourceManager, armatureLocation);
ModelBlock model; ModelBlock model;
{ {
@@ -187,12 +187,12 @@ public enum UVLModelLoader implements ICustomModelLoader {
ModelBlock lvt_5_1_ = null; ModelBlock lvt_5_1_ = null;
try { try {
String s = modelLocation.getResourcePath(); String s = modelLocation.getPath();
iresource = Minecraft.getMinecraft() iresource = Minecraft.getMinecraft()
.getResourceManager() .getResourceManager()
.getResource( .getResource(
new ResourceLocation(modelLocation.getResourceDomain(), "models/" + modelPath + ".json")); new ResourceLocation(modelLocation.getNamespace(), "models/" + modelPath + ".json"));
reader = new InputStreamReader(iresource.getInputStream(), Charsets.UTF_8); reader = new InputStreamReader(iresource.getInputStream(), Charsets.UTF_8);
lvt_5_1_ = JsonUtils.gsonDeserialize(this.UVLSERIALIZER, reader, ModelBlock.class, false); lvt_5_1_ = JsonUtils.gsonDeserialize(this.UVLSERIALIZER, reader, ModelBlock.class, false);
@@ -41,7 +41,7 @@ public class SpatialPylonRendering extends BlockRenderingCustomizer {
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) { public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.builtInModel(MODEL_ID.getResourcePath(), new SpatialPylonModel()); rendering.builtInModel(MODEL_ID.getPath(), new SpatialPylonModel());
rendering.stateMapper(this::mapState); rendering.stateMapper(this::mapState);
} }
@@ -39,15 +39,7 @@ import appeng.client.me.SlotME;
import appeng.container.guisync.GuiSync; import appeng.container.guisync.GuiSync;
import appeng.container.guisync.SyncData; import appeng.container.guisync.SyncData;
import appeng.container.implementations.ContainerInterface; import appeng.container.implementations.ContainerInterface;
import appeng.container.slot.AppEngSlot; import appeng.container.slot.*;
import appeng.container.slot.SlotCraftingMatrix;
import appeng.container.slot.SlotCraftingTerm;
import appeng.container.slot.SlotDisabled;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotInaccessible;
import appeng.container.slot.SlotPlayerHotBar;
import appeng.container.slot.SlotPlayerInv;
import appeng.container.slot.SlotRestrictedInput;
import appeng.container.slot.SlotRestrictedInput.PlacableItemType; import appeng.container.slot.SlotRestrictedInput.PlacableItemType;
import appeng.core.AELog; import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
@@ -65,14 +57,12 @@ import appeng.util.item.AEItemStack;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container; import net.minecraft.inventory.*;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.PlayerInvWrapper; import net.minecraftforge.items.wrapper.PlayerInvWrapper;
import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -409,10 +399,7 @@ public abstract class AEBaseContainer extends Container {
return ItemStack.EMPTY; // don't insert duplicate encoded patterns to interfaces return ItemStack.EMPTY; // don't insert duplicate encoded patterns to interfaces
} }
int maxSize = t.getMaxStackSize(); int maxSize = Math.min(tis.getMaxStackSize(), d.getSlotStackLimit());
if (maxSize > d.getSlotStackLimit()) {
maxSize = d.getSlotStackLimit();
}
int placeAble = maxSize - t.getCount(); int placeAble = maxSize - t.getCount();
@@ -448,10 +435,7 @@ public abstract class AEBaseContainer extends Container {
if (d.isItemValid(tis)) { if (d.isItemValid(tis)) {
if (!d.getHasStack()) { if (!d.getHasStack()) {
int maxSize = tis.getMaxStackSize(); int maxSize = Math.min(tis.getMaxStackSize(), d.getSlotStackLimit());
if (maxSize > d.getSlotStackLimit()) {
maxSize = d.getSlotStackLimit();
}
final ItemStack tmp = tis.copy(); final ItemStack tmp = tis.copy();
if (tmp.getCount() > maxSize) { if (tmp.getCount() > maxSize) {
@@ -967,6 +951,55 @@ public abstract class AEBaseContainer extends Container {
b.putStack(testB); b.putStack(testB);
} }
@Override
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, @NotNull EntityPlayer player) {
if (slotId >= 0 && clickTypeIn == ClickType.PICKUP) {
final var slot = this.getSlot(slotId);
if (slot instanceof AppEngSlot appEngSlot) {
var slotStack = slot.getStack();
var draggedStack = this.invPlayer.getItemStack();
// The default vanilla behavior assumes that slots can't hold more items than the default stack size.
// Thus, it's possible to underflow the vanilla code when clicking non-empty slots with an item stack.
if (!draggedStack.isEmpty()) {
if (appEngSlot.isItemValid(draggedStack)) {
if (slotStack.getItem() == draggedStack.getItem() && slotStack.getMetadata() == draggedStack.getMetadata() && ItemStack.areItemStackTagsEqual(slotStack, draggedStack)) {
// Slot size or stack size, whichever is smaller.
var maxSize = Math.min(appEngSlot.getSlotStackLimit(), draggedStack.getMaxStackSize());
// The maximum number of items that can be inserted into the slot, non-negative.
var maxInsertable = Math.min(draggedStack.getCount(),
Math.max(0, maxSize - appEngSlot.getStack().getCount()));
if (maxInsertable != 0) {
var toInsert = Math.min(maxInsertable, dragType == 0 ? maxInsertable : 1);
draggedStack.shrink(toInsert);
slotStack.grow(toInsert);
slot.putStack(slot.getStack());
return ItemStack.EMPTY;
}
}
}
}
// Fixes taking and halving issues from oversized slots.
else if (dragType == 0 || dragType == 1) {
if (slot.canTakeStack(player) && !slotStack.isEmpty()) {
var result = slotStack.copy();
var toTake = Math.min(slotStack.getCount(), slotStack.getMaxStackSize());
this.invPlayer.setItemStack(slot.decrStackSize(dragType == 0 ? toTake : (toTake + 1) / 2));
slot.putStack(slot.getStack());
return result;
}
}
}
}
return super.slotClick(slotId, dragType, clickTypeIn, player);
}
public void onUpdate(final String field, final Object oldValue, final Object newValue) { public void onUpdate(final String field, final Object oldValue, final Object newValue) {
} }
@@ -163,7 +163,7 @@ public final class ContainerFluidInterfaceConfigurationTerminal extends AEBaseCo
} }
} }
if (!this.data.hasNoTags()) { if (!this.data.isEmpty()) {
try { try {
NetworkHandler.instance().sendTo(new PacketCompressedNBT(this.data), (EntityPlayerMP) this.getPlayerInv().player); NetworkHandler.instance().sendTo(new PacketCompressedNBT(this.data), (EntityPlayerMP) this.getPlayerInv().player);
} catch (final IOException e) { } catch (final IOException e) {
@@ -251,7 +251,7 @@ public final class ContainerFluidInterfaceConfigurationTerminal extends AEBaseCo
final String name = '=' + Long.toString(inv.which, Character.MAX_RADIX); final String name = '=' + Long.toString(inv.which, Character.MAX_RADIX);
final NBTTagCompound tag = data.getCompoundTag(name); final NBTTagCompound tag = data.getCompoundTag(name);
if (tag.hasNoTags()) { if (tag.isEmpty()) {
tag.setLong("sortBy", inv.sortBy); tag.setLong("sortBy", inv.sortBy);
tag.setString("un", inv.unlocalizedName); tag.setString("un", inv.unlocalizedName);
tag.setTag("pos", NBTUtil.createPosTag(inv.pos)); tag.setTag("pos", NBTUtil.createPosTag(inv.pos));
@@ -28,13 +28,8 @@ import appeng.container.guisync.GuiSync;
import appeng.container.slot.*; import appeng.container.slot.*;
import appeng.helpers.DualityInterface; import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost; import appeng.helpers.IInterfaceHost;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.AppEngInternalOversizedInventory;
import appeng.util.Platform; import appeng.util.Platform;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.item.ItemStack;
public class ContainerInterface extends ContainerUpgradeable implements IOptionalSlotHost { public class ContainerInterface extends ContainerUpgradeable implements IOptionalSlotHost {
@@ -71,19 +66,6 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
} }
} }
@Override
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayer player) {
if (slotId >= 0 && slotId < this.inventorySlots.size()) {
if (this.inventorySlots.get(slotId) instanceof SlotOversized) {
((AppEngInternalOversizedInventory) ((SlotOversized) this.inventorySlots.get(slotId)).getItemHandler()).limitExtraction(true);
ItemStack ret = super.slotClick(slotId, dragType, clickTypeIn, player);
((AppEngInternalOversizedInventory) ((SlotOversized) this.inventorySlots.get(slotId)).getItemHandler()).limitExtraction(false);
return ret;
}
}
return super.slotClick(slotId, dragType, clickTypeIn, player);
}
@Override @Override
protected int getHeight() { protected int getHeight() {
return 256; return 256;
@@ -153,7 +153,7 @@ public final class ContainerInterfaceConfigurationTerminal extends AEBaseContain
} }
} }
if (!this.data.hasNoTags()) { if (!this.data.isEmpty()) {
try { try {
NetworkHandler.instance().sendTo(new PacketCompressedNBT(this.data), (EntityPlayerMP) this.getPlayerInv().player); NetworkHandler.instance().sendTo(new PacketCompressedNBT(this.data), (EntityPlayerMP) this.getPlayerInv().player);
} catch (final IOException e) { } catch (final IOException e) {
@@ -296,7 +296,7 @@ public final class ContainerInterfaceConfigurationTerminal extends AEBaseContain
final String name = '=' + Long.toString(inv.which, Character.MAX_RADIX); final String name = '=' + Long.toString(inv.which, Character.MAX_RADIX);
final NBTTagCompound tag = data.getCompoundTag(name); final NBTTagCompound tag = data.getCompoundTag(name);
if (tag.hasNoTags()) { if (tag.isEmpty()) {
tag.setLong("sortBy", inv.sortBy); tag.setLong("sortBy", inv.sortBy);
tag.setString("un", inv.unlocalizedName); tag.setString("un", inv.unlocalizedName);
tag.setTag("pos", NBTUtil.createPosTag(inv.pos)); tag.setTag("pos", NBTUtil.createPosTag(inv.pos));
@@ -25,9 +25,12 @@ import appeng.api.config.YesNo;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionHost;
import appeng.client.me.SlotDisconnected;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.slot.AppEngSlot;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketCompressedNBT; import appeng.core.sync.packets.PacketCompressedNBT;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.helpers.DualityInterface; import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost; import appeng.helpers.IInterfaceHost;
import appeng.helpers.InventoryAction; import appeng.helpers.InventoryAction;
@@ -44,6 +47,7 @@ import appeng.util.inv.WrapperCursorItemHandler;
import appeng.util.inv.WrapperFilteredItemHandler; import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.WrapperRangeItemHandler; import appeng.util.inv.WrapperRangeItemHandler;
import appeng.util.inv.filter.IAEItemFilter; import appeng.util.inv.filter.IAEItemFilter;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -51,6 +55,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@@ -160,7 +165,7 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer {
} }
} }
if (!this.data.hasNoTags()) { if (!this.data.isEmpty()) {
try { try {
NetworkHandler.instance().sendTo(new PacketCompressedNBT(this.data), (EntityPlayerMP) this.getPlayerInv().player); NetworkHandler.instance().sendTo(new PacketCompressedNBT(this.data), (EntityPlayerMP) this.getPlayerInv().player);
} catch (final IOException e) { } catch (final IOException e) {
@@ -175,6 +180,26 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer {
public void doAction(final EntityPlayerMP player, final InventoryAction action, final int slot, final long id) { public void doAction(final EntityPlayerMP player, final InventoryAction action, final int slot, final long id) {
final InvTracker inv = this.byId.get(id); final InvTracker inv = this.byId.get(id);
if (inv != null) { if (inv != null) {
// The code below this block assumes "slot" is an interface slot id. Not in this case.
if (action == InventoryAction.PLACE_SINGLE) {
final AppEngSlot playerSlot;
try {
playerSlot = (AppEngSlot) this.inventorySlots.get(slot);
} catch (IndexOutOfBoundsException ignored) { return; }
if (!playerSlot.isPlayerSide() || !playerSlot.getHasStack()) return;
var itemStack = playerSlot.getStack();
if (!itemStack.isEmpty()) {
var handler = new WrapperFilteredItemHandler(
new WrapperRangeItemHandler(inv.server, 0, 9 * (inv.numUpgrades + 1)), new PatternSlotFilter());
playerSlot.putStack(ItemHandlerHelper.insertItem(handler, itemStack, false));
detectAndSendChanges();
}
return;
}
final ItemStack is = inv.server.getStackInSlot(slot); final ItemStack is = inv.server.getStackInSlot(slot);
final boolean hasItemInHand = !player.inventory.getItemStack().isEmpty(); final boolean hasItemInHand = !player.inventory.getItemStack().isEmpty();
@@ -271,8 +296,6 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer {
} }
break; break;
default:
return;
} }
this.updateHeld(player); this.updateHeld(player);
@@ -330,7 +353,7 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer {
final String name = '=' + Long.toString(inv.which, Character.MAX_RADIX); final String name = '=' + Long.toString(inv.which, Character.MAX_RADIX);
final NBTTagCompound tag = data.getCompoundTag(name); final NBTTagCompound tag = data.getCompoundTag(name);
if (tag.hasNoTags()) { if (tag.isEmpty()) {
tag.setLong("sortBy", inv.sortBy); tag.setLong("sortBy", inv.sortBy);
tag.setString("un", inv.unlocalizedName); tag.setString("un", inv.unlocalizedName);
tag.setTag("pos", NBTUtil.createPosTag(inv.pos)); tag.setTag("pos", NBTUtil.createPosTag(inv.pos));
@@ -356,6 +379,27 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer {
data.setTag(name, tag); data.setTag(name, tag);
} }
@Override
public ItemStack transferStackInSlot(EntityPlayer p, int idx) {
if (Platform.isClient()) {
var playerSlot = this.inventorySlots.get(idx);
if (playerSlot instanceof AppEngSlot playerAppEngSlot && playerAppEngSlot.isPlayerSide()) {
for (var slot : this.inventorySlots) {
if (slot instanceof SlotDisconnected slotDisconnected && !slot.getHasStack()) {
// Signal the server to move the pattern.
var packet = new PacketInventoryAction(InventoryAction.PLACE_SINGLE,
playerAppEngSlot.slotNumber, slotDisconnected.getSlot().getId());
NetworkHandler.instance().sendToServer(packet);
return ItemStack.EMPTY;
}
}
}
}
return super.transferStackInSlot(p, idx);
}
private static class InvTracker { private static class InvTracker {
private final long sortBy; private final long sortBy;
@@ -38,8 +38,6 @@ public class ContainerOreDictStorageBus extends AEBaseContainer {
public ContainerOreDictStorageBus(final InventoryPlayer ip, final PartOreDicStorageBus anchor) { public ContainerOreDictStorageBus(final InventoryPlayer ip, final PartOreDicStorageBus anchor) {
super(ip, anchor); super(ip, anchor);
this.part = anchor; this.part = anchor;
this.bindPlayerInventory(ip, 14, 256 - /* height of player inventory */82);
} }
@Override @Override
@@ -50,6 +50,9 @@ public class ContainerStorageBus extends ContainerUpgradeable {
@GuiSync(4) @GuiSync(4)
public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY; public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY;
@GuiSync(7)
public YesNo stickyMode = YesNo.NO;
public ContainerStorageBus(final InventoryPlayer ip, final PartStorageBus te) { public ContainerStorageBus(final InventoryPlayer ip, final PartStorageBus te) {
super(ip, te); super(ip, te);
this.storageBus = te; this.storageBus = te;
@@ -111,6 +114,7 @@ public class ContainerStorageBus extends ContainerUpgradeable {
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE)); this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
this.setReadWriteMode((AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS)); this.setReadWriteMode((AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
this.setStorageFilter((StorageFilter) this.getUpgradeable().getConfigManager().getSetting(Settings.STORAGE_FILTER)); this.setStorageFilter((StorageFilter) this.getUpgradeable().getConfigManager().getSetting(Settings.STORAGE_FILTER));
this.setStickyMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.STICKY_MODE));
} }
this.standardDetectAndSendChanges(); this.standardDetectAndSendChanges();
@@ -168,4 +172,12 @@ public class ContainerStorageBus extends ContainerUpgradeable {
private void setStorageFilter(final StorageFilter storageFilter) { private void setStorageFilter(final StorageFilter storageFilter) {
this.storageFilter = storageFilter; this.storageFilter = storageFilter;
} }
public YesNo getStickyMode() {
return this.stickyMode;
}
private void setStickyMode(final YesNo stickyMode) {
this.stickyMode = stickyMode;
}
} }
@@ -19,6 +19,7 @@
package appeng.container.implementations; package appeng.container.implementations;
import appeng.api.config.PowerMultiplier;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.guisync.GuiSync; import appeng.container.guisync.GuiSync;
import appeng.container.slot.SlotRestrictedInput; import appeng.container.slot.SlotRestrictedInput;
@@ -51,7 +52,7 @@ public class ContainerWireless extends AEBaseContainer {
final int boosters = this.boosterSlot.getStack().isEmpty() ? 0 : this.boosterSlot.getStack().getCount(); final int boosters = this.boosterSlot.getStack().isEmpty() ? 0 : this.boosterSlot.getStack().getCount();
this.setRange((long) (10 * AEConfig.instance().wireless_getMaxRange(boosters))); this.setRange((long) (10 * AEConfig.instance().wireless_getMaxRange(boosters)));
this.setDrain((long) (100 * AEConfig.instance().wireless_getPowerDrain(boosters))); this.setDrain((long) (100 * PowerMultiplier.CONFIG.multiply(AEConfig.instance().wireless_getPowerDrain(boosters))));
super.detectAndSendChanges(); super.detectAndSendChanges();
} }
@@ -63,8 +63,6 @@ public class ContainerWirelessCraftingTerminal extends ContainerMEPortableTermin
this.addSlotToContainer(this.outputSlot = new SlotCraftingTerm(this.getPlayerInv().player, this.getActionSource(), this this.addSlotToContainer(this.outputSlot = new SlotCraftingTerm(this.getPlayerInv().player, this.getActionSource(), this
.getPowerSource(), this.wirelessTerminalGUIObject, crafting, crafting, this.output, 131, -72 + 18, this)); .getPowerSource(), this.wirelessTerminalGUIObject, crafting, crafting, this.output, 131, -72 + 18, this));
this.bindPlayerInventory(ip, 0, 0);
this.onCraftMatrixChanged(new WrapperInvItemHandler(crafting)); this.onCraftMatrixChanged(new WrapperInvItemHandler(crafting));
} }
@@ -133,15 +133,18 @@ public class AppEngCraftingSlot extends AppEngSlot {
@Override @Override
public ItemStack onTake(final EntityPlayer playerIn, final ItemStack stack) { public ItemStack onTake(final EntityPlayer playerIn, final ItemStack stack) {
net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerCraftingEvent(playerIn, stack, new WrapperInvItemHandler(this.craftMatrix));
this.onCrafting(stack); this.onCrafting(stack);
net.minecraftforge.common.ForgeHooks.setCraftingPlayer(playerIn); stack.getItem().onCreated(stack, playerIn.world, playerIn);
final InventoryCrafting ic = new InventoryCrafting(this.getContainer(), 3, 3); final InventoryCrafting ic = new InventoryCrafting(this.getContainer(), 3, 3);
for (int x = 0; x < this.craftMatrix.getSlots(); x++) { for (int x = 0; x < this.craftMatrix.getSlots(); x++) {
ic.setInventorySlotContents(x, this.craftMatrix.getStackInSlot(x)); ic.setInventorySlotContents(x, this.craftMatrix.getStackInSlot(x));
} }
net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerCraftingEvent(playerIn, stack, ic);
net.minecraftforge.common.ForgeHooks.setCraftingPlayer(playerIn);
final NonNullList<ItemStack> aitemstack = this.getRemainingItems(ic, playerIn.world); final NonNullList<ItemStack> aitemstack = this.getRemainingItems(ic, playerIn.world);
ItemHandlerUtil.copy(ic, this.craftMatrix, false); ItemHandlerUtil.copy(ic, this.craftMatrix, false);
@@ -158,6 +158,24 @@ public class AppEngSlot extends Slot {
@Override @Override
public boolean canTakeStack(final EntityPlayer par1EntityPlayer) { public boolean canTakeStack(final EntityPlayer par1EntityPlayer) {
if (this.isSlotEnabled()) {
var draggedStack = par1EntityPlayer.inventory.getItemStack();
ItemStack slotStack = this.getStack();
if (!draggedStack.isEmpty()) {
if (draggedStack.isItemEqual(slotStack)) {
if (draggedStack.getCount() >= draggedStack.getMaxStackSize()) {
// Prevent over-pulling.
return false;
}
} else if (slotStack.getCount() > slotStack.getMaxStackSize()) {
// Prevent swapping when clicking slots that hold more items than the max stack size.
return false;
}
}
}
if (this.isSlotEnabled()) { if (this.isSlotEnabled()) {
return !this.itemHandler.extractItem(this.index, Integer.MAX_VALUE, true).isEmpty(); return !this.itemHandler.extractItem(this.index, Integer.MAX_VALUE, true).isEmpty();
} }
@@ -1,4 +1,9 @@
package appeng.container.slot; package appeng.container.slot;
public interface IJEITargetSlot { public interface IJEITargetSlot {
default boolean needAccept() {
return false;
}
} }
@@ -97,26 +97,9 @@ public class SlotCraftingTerm extends AppEngCraftingSlot {
return is; return is;
} }
// Don't render the item client-side if the item stage for it is not unlocked yet
@Override @Override
public ItemStack getStack() { public boolean shouldDisplay() {
if (Platform.isClient() && Loader.isModLoaded("itemstages")) { return !getStack().isEmpty();
return itemstageStack();
}
return super.getStack();
}
@SideOnly(Side.CLIENT)
ItemStack itemstageStack() {
final ItemStack item = super.getStack();
final String itemsStage = ItemStages.getStage(item);
final String enchantStage = ItemStages.getEnchantStage(item);
final EntityPlayer player = Minecraft.getMinecraft().player;
if ((itemsStage != null && !GameStageHelper.hasStage(player, itemsStage))
|| (enchantStage != null && !GameStageHelper.hasStage(player, enchantStage)))
return ItemStack.EMPTY;
return super.getStack();
} }
public void doClick(final InventoryAction action, final EntityPlayer who) { public void doClick(final InventoryAction action, final EntityPlayer who) {
@@ -196,15 +179,6 @@ public class SlotCraftingTerm extends AppEngCraftingSlot {
} }
} }
if (Loader.isModLoaded("itemstages")) {
final String itemsStage = ItemStages.getStage(recipe.getRecipeOutput());
final String enchantStage = ItemStages.getEnchantStage(recipe.getRecipeOutput());
if ((itemsStage != null && !GameStageHelper.hasStage(player, itemsStage))
|| (enchantStage != null && !GameStageHelper.hasStage(player, enchantStage)))
return null;
}
return recipe; return recipe;
} }
@@ -50,7 +50,6 @@ public class SlotFake extends AppEngSlot implements IJEITargetSlot {
if (!is.isEmpty()) { if (!is.isEmpty()) {
is = is.copy(); is = is.copy();
} }
super.putStack(is); super.putStack(is);
} }
@@ -58,4 +57,10 @@ public class SlotFake extends AppEngSlot implements IJEITargetSlot {
public boolean canTakeStack(final EntityPlayer par1EntityPlayer) { public boolean canTakeStack(final EntityPlayer par1EntityPlayer) {
return false; return false;
} }
@Override
public boolean needAccept() {
return this.getStack().isEmpty();
}
} }
+7 -1
View File
@@ -83,6 +83,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
private int craftingCalculationTimePerTick = 5; private int craftingCalculationTimePerTick = 5;
private PowerUnits selectedPowerUnit = PowerUnits.AE; private PowerUnits selectedPowerUnit = PowerUnits.AE;
private boolean showCraftableTooltip = true; private boolean showCraftableTooltip = true;
private boolean showPlacementPreview = true;
// Spatial IO/Dimension // Spatial IO/Dimension
private int storageProviderID = -1; private int storageProviderID = -1;
@@ -257,6 +258,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
this.useLargeFonts = this.get("Client", "useTerminalUseLargeFont", false).getBoolean(false); this.useLargeFonts = this.get("Client", "useTerminalUseLargeFont", false).getBoolean(false);
this.useColoredCraftingStatus = this.get("Client", "useColoredCraftingStatus", true).getBoolean(true); this.useColoredCraftingStatus = this.get("Client", "useColoredCraftingStatus", true).getBoolean(true);
this.showCraftableTooltip = this.get("Client", "showCraftableTooltip", true, "Whether to add \"Craftable\" to item tooltips when they can be crafted automatically.").getBoolean(true); this.showCraftableTooltip = this.get("Client", "showCraftableTooltip", true, "Whether to add \"Craftable\" to item tooltips when they can be crafted automatically.").getBoolean(true);
this.showPlacementPreview = this.get("Client", "showPlacementPreview", true, "Whether to show a preview of part and facade placement.").getBoolean(true);
// load buttons.. // load buttons..
for (int btnNum = 0; btnNum < 4; btnNum++) { for (int btnNum = 0; btnNum < 4; btnNum++) {
@@ -268,7 +270,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
this.craftByStacks[btnNum] = Math.abs(cmb.getInt(this.craftByStacks[btnNum])); this.craftByStacks[btnNum] = Math.abs(cmb.getInt(this.craftByStacks[btnNum]));
this.priorityByStacks[btnNum] = Math.abs(pmb.getInt(this.priorityByStacks[btnNum])); this.priorityByStacks[btnNum] = Math.abs(pmb.getInt(this.priorityByStacks[btnNum]));
this.levelByStacks[btnNum] = Math.abs(pmb.getInt(this.levelByStacks[btnNum])); this.levelByStacks[btnNum] = Math.abs(lmb.getInt(this.levelByStacks[btnNum]));
cmb.setComment("Controls buttons on Crafting Screen : Capped at " + buttonCap); cmb.setComment("Controls buttons on Crafting Screen : Capped at " + buttonCap);
pmb.setComment("Controls buttons on Priority Screen : Capped at " + buttonCap); pmb.setComment("Controls buttons on Priority Screen : Capped at " + buttonCap);
@@ -514,6 +516,10 @@ public final class AEConfig extends Configuration implements IConfigurableObject
return this.showCraftableTooltip; return this.showCraftableTooltip;
} }
public boolean showPlacementPreview() {
return this.showPlacementPreview;
}
public boolean isDisableColoredCableRecipesInJEI() { public boolean isDisableColoredCableRecipesInJEI() {
return this.disableColoredCableRecipesInJEI; return this.disableColoredCableRecipesInJEI;
} }
@@ -25,6 +25,7 @@ import appeng.client.ActionKey;
import appeng.client.EffectType; import appeng.client.EffectType;
import appeng.core.sync.AppEngPacket; import appeng.core.sync.AppEngPacket;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World; import net.minecraft.world.World;
@@ -32,6 +33,7 @@ import net.minecraft.world.World;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.UUID;
public abstract class CommonHelper { public abstract class CommonHelper {
@@ -66,4 +68,5 @@ public abstract class CommonHelper {
public abstract boolean isActionKey(@Nonnull final ActionKey key, int pressedKeyCode); public abstract boolean isActionKey(@Nonnull final ActionKey key, int pressedKeyCode);
public abstract EntityPlayer getPlayerByUUID(UUID uuid);
} }
+3 -3
View File
@@ -40,12 +40,12 @@ public final class CreativeTab extends CreativeTabs {
} }
@Override @Override
public ItemStack getTabIconItem() { public ItemStack getIcon() {
return this.getIconItemStack(); return this.createIcon();
} }
@Override @Override
public ItemStack getIconItemStack() { public ItemStack createIcon() {
final IDefinitions definitions = AEApi.instance().definitions(); final IDefinitions definitions = AEApi.instance().definitions();
final IBlocks blocks = definitions.blocks(); final IBlocks blocks = definitions.blocks();
final IItems items = definitions.items(); final IItems items = definitions.items();
@@ -42,12 +42,12 @@ public final class CreativeTabFacade extends CreativeTabs {
} }
@Override @Override
public ItemStack getTabIconItem() { public ItemStack getIcon() {
return this.getIconItemStack(); return this.createIcon();
} }
@Override @Override
public ItemStack getIconItemStack() { public ItemStack createIcon() {
final Optional<Item> maybeFacade = AEApi.instance().definitions().items().facade().maybeItem(); final Optional<Item> maybeFacade = AEApi.instance().definitions().items().facade().maybeItem();
if (maybeFacade.isPresent()) { if (maybeFacade.isPresent()) {
return ((ItemFacade) maybeFacade.get()).getCreativeTabIcon(); return ((ItemFacade) maybeFacade.get()).getCreativeTabIcon();

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