├── .editorconfig ├── .git-blame-ignore-revs ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── 000-report-bug.yml │ └── 001-request-feature.yml ├── scripts │ └── test_no_error_reports └── workflows │ ├── build-and-test.yml │ └── release-tags.yml ├── .gitignore ├── CODEOWNERS ├── LICENSE.txt ├── addon.gradle ├── build.gradle ├── dependencies.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── repositories.gradle ├── settings.gradle └── src └── main ├── java └── codechicken │ ├── core │ ├── CCUpdateChecker.java │ ├── ClassDiscoverer.java │ ├── ClientUtils.java │ ├── CommonUtils.java │ ├── GuiModListScroll.java │ ├── IGuiPacketSender.java │ ├── IStringMatcher.java │ ├── ProfileTimer.java │ ├── ReflectionManager.java │ ├── ServerUtils.java │ ├── TaskProfiler.java │ ├── asm │ │ ├── CodeChickenAccessTransformer.java │ │ ├── CodeChickenCoreModContainer.java │ │ ├── DefaultImplementationTransformer.java │ │ ├── DelegatedTransformer.java │ │ ├── DependancyLister.java │ │ ├── InterfaceDependancies.java │ │ ├── MCPDeobfuscationTransformer.java │ │ ├── MethodASMifier.java │ │ └── TweakTransformer.java │ ├── commands │ │ ├── CoreCommand.java │ │ ├── PlayerCommand.java │ │ └── ServerCommand.java │ ├── featurehack │ │ ├── EntityRenderHook.java │ │ ├── EntityUpdateHook.java │ │ ├── FeatureHack.java │ │ ├── GameDataManipulator.java │ │ ├── LiquidTextures.java │ │ ├── RenderEntityRenderHook.java │ │ ├── RenderNull.java │ │ ├── TweakTransformerHelper.java │ │ └── mc │ │ │ ├── TextureLavaFX.java │ │ │ ├── TextureLavaFlowFX.java │ │ │ ├── TextureWaterFX.java │ │ │ └── TextureWaterFlowFX.java │ ├── fluid │ │ ├── ExtendedFluidTank.java │ │ ├── FluidUtils.java │ │ └── TankAccess.java │ ├── gui │ │ ├── ClickCounter.java │ │ ├── GuiCCButton.java │ │ ├── GuiCCTextField.java │ │ ├── GuiScreenWidget.java │ │ ├── GuiScrollPane.java │ │ ├── GuiScrollSlot.java │ │ ├── GuiWidget.java │ │ └── IGuiActionListener.java │ ├── internal │ │ └── CCCEventHandler.java │ ├── inventory │ │ └── GuiContainerWidget.java │ └── launch │ │ ├── CodeChickenCorePlugin.java │ │ └── DepLoader.java │ ├── lib │ ├── asm │ │ ├── ASMBlock.java │ │ ├── ASMHelper.java │ │ ├── ASMInit.java │ │ ├── ASMReader.java │ │ ├── CC_ClassWriter.java │ │ ├── ClassConstantPoolParser.java │ │ ├── ClassHeirachyManager.java │ │ ├── ImportantInsnVisitor.java │ │ ├── InsnComparator.java │ │ ├── InsnListSection.java │ │ ├── LocalVariablesSorterVisitor.java │ │ ├── ModularASMTransformer.java │ │ ├── ObfMapping.java │ │ └── RedirectorTransformer.java │ ├── colour │ │ ├── Colour.java │ │ ├── ColourARGB.java │ │ ├── ColourRGBA.java │ │ └── CustomGradient.java │ ├── config │ │ ├── ConfigFile.java │ │ ├── ConfigTag.java │ │ ├── ConfigTagParent.java │ │ ├── DefaultingConfigFile.java │ │ └── SimpleProperties.java │ ├── data │ │ ├── MCDataInput.java │ │ ├── MCDataInputStream.java │ │ ├── MCDataOutput.java │ │ ├── MCDataOutputStream.java │ │ └── MCDataOutputWrapper.java │ ├── gui │ │ ├── Canvas9Seg.java │ │ └── GuiDraw.java │ ├── inventory │ │ ├── ContainerExtended.java │ │ ├── ContainerSynchronised.java │ │ ├── IContainerSyncVar.java │ │ ├── IntegerSync.java │ │ ├── InventoryCopy.java │ │ ├── InventoryNBT.java │ │ ├── InventoryRange.java │ │ ├── InventorySimple.java │ │ ├── InventoryUtils.java │ │ ├── ItemKey.java │ │ ├── SlotDummy.java │ │ ├── SlotDummyOutput.java │ │ └── SlotHandleClicks.java │ ├── lighting │ │ ├── LC.java │ │ ├── LightMatrix.java │ │ ├── LightModel.java │ │ ├── PlanarLightMatrix.java │ │ ├── PlanarLightModel.java │ │ └── SimpleBrightnessModel.java │ ├── math │ │ └── MathHelper.java │ ├── packet │ │ ├── ICustomPacketTile.java │ │ └── PacketCustom.java │ ├── raytracer │ │ ├── ExtendedMOP.java │ │ ├── IndexedCuboid6.java │ │ └── RayTracer.java │ ├── render │ │ ├── BlockRenderer.java │ │ ├── CCModel.java │ │ ├── CCModelLibrary.java │ │ ├── CCRenderPipeline.java │ │ ├── CCRenderState.java │ │ ├── ColourMultiplier.java │ │ ├── EntityDigIconFX.java │ │ ├── FontUtils.java │ │ ├── IFaceRenderer.java │ │ ├── ManagedTextureFX.java │ │ ├── PlaceholderTexture.java │ │ ├── QBImporter.java │ │ ├── RenderUtils.java │ │ ├── ShaderProgram.java │ │ ├── SpriteSheetManager.java │ │ ├── TextureDataHolder.java │ │ ├── TextureFX.java │ │ ├── TextureSpecial.java │ │ ├── TextureUtils.java │ │ ├── Vertex5.java │ │ └── uv │ │ │ ├── IconTransformation.java │ │ │ ├── MultiIconTransformation.java │ │ │ ├── UV.java │ │ │ ├── UVRotation.java │ │ │ ├── UVScale.java │ │ │ ├── UVTransformation.java │ │ │ ├── UVTransformationList.java │ │ │ └── UVTranslation.java │ ├── tool │ │ ├── LibDownloader.java │ │ ├── MCStripTransformer.java │ │ ├── Main.java │ │ ├── StripClassLoader.java │ │ ├── ToolMain.java │ │ └── module │ │ │ ├── JOptModule.java │ │ │ └── ModuleQBConverter.java │ ├── util │ │ ├── Copyable.java │ │ └── LangProxy.java │ ├── vec │ │ ├── AxisCycle.java │ │ ├── BlockCoord.java │ │ ├── Cuboid6.java │ │ ├── CuboidCoord.java │ │ ├── ITransformation.java │ │ ├── IrreversibleTransformationException.java │ │ ├── Line3.java │ │ ├── Matrix4.java │ │ ├── Quat.java │ │ ├── Rectangle4i.java │ │ ├── RedundantTransformation.java │ │ ├── Rotation.java │ │ ├── Scale.java │ │ ├── SwapYZ.java │ │ ├── Transformation.java │ │ ├── TransformationList.java │ │ ├── Translation.java │ │ ├── VariableTransformation.java │ │ └── Vector3.java │ └── world │ │ ├── ChunkExtension.java │ │ ├── IChunkLoadTile.java │ │ ├── TileChunkLoadHook.java │ │ ├── WorldExtension.java │ │ ├── WorldExtensionInstantiator.java │ │ └── WorldExtensionManager.java │ └── obfuscator │ ├── ConstantObfuscator.java │ ├── DummyOutputStream.java │ ├── IHeirachyEvaluator.java │ ├── ILogStreams.java │ ├── ObfDirection.java │ ├── ObfRemapper.java │ ├── ObfuscationMap.java │ ├── ObfuscationRun.java │ └── SystemLogStreams.java └── resources ├── assets └── codechickencore │ ├── asm │ └── tweaks.asm │ └── lang │ ├── de_DE.lang │ ├── en_US.lang │ ├── it_IT.lang │ └── ru_RU.lang └── mcmod.info /.editorconfig: -------------------------------------------------------------------------------- 1 | # This is the universal Text Editor Configuration 2 | # for all GTNewHorizons projects 3 | # See: https://editorconfig.org/ 4 | 5 | root = true 6 | 7 | [*] 8 | charset = utf-8 9 | end_of_line = lf 10 | indent_size = 4 11 | indent_style = space 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | 15 | [*.{bat,ini}] 16 | end_of_line = crlf 17 | 18 | [*.{dtd,json,info,mcmeta,md,sh,svg,xml,xsd,xsl,yaml,yml}] 19 | indent_size = 2 20 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Ignore spotlessApply reformat 2 | 955a875d42bd8f725d389ef8c4f571824f2ae0c8 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | *.[jJ][aA][rR] binary 4 | 5 | *.[pP][nN][gG] binary 6 | *.[jJ][pP][gG] binary 7 | *.[jJ][pP][eE][gG] binary 8 | *.[gG][iI][fF] binary 9 | *.[tT][iI][fF] binary 10 | *.[tT][iI][fF][fF] binary 11 | *.[iI][cC][oO] binary 12 | *.[sS][vV][gG] text 13 | *.[eE][pP][sS] binary 14 | *.[xX][cC][fF] binary 15 | 16 | *.[kK][aA][rR] binary 17 | *.[mM]4[aA] binary 18 | *.[mM][iI][dD] binary 19 | *.[mM][iI][dD][iI] binary 20 | *.[mM][pP]3 binary 21 | *.[oO][gG][gG] binary 22 | *.[rR][aA] binary 23 | 24 | *.7[zZ] binary 25 | *.[gG][zZ] binary 26 | *.[tT][aA][rR] binary 27 | *.[tT][gG][zZ] binary 28 | *.[zZ][iI][pP] binary 29 | 30 | *.[tT][cC][nN] binary 31 | *.[sS][oO] binary 32 | *.[dD][lL][lL] binary 33 | *.[dD][yY][lL][iI][bB] binary 34 | *.[pP][sS][dD] binary 35 | *.[tT][tT][fF] binary 36 | *.[oO][tT][fF] binary 37 | 38 | *.[pP][aA][tT][cC][hH] -text 39 | 40 | *.[bB][aA][tT] text eol=crlf 41 | *.[cC][mM][dD] text eol=crlf 42 | *.[pP][sS]1 text eol=crlf 43 | 44 | *[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary 45 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/000-report-bug.yml: -------------------------------------------------------------------------------- 1 | name: Report Bug 2 | description: "Report a bug." 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: "A bug/crash report with sufficient information and logs to reproduce and track down." 7 | - type: input 8 | id: discord 9 | attributes: 10 | label: Your GTNH Discord Username 11 | description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info. 12 | placeholder: "Example: Fake#1234" 13 | - type: input 14 | id: version 15 | attributes: 16 | label: Mod Version 17 | description: "What version of the Mod are you using?" 18 | placeholder: "Example: 1.0.0" 19 | validations: 20 | required: true 21 | - type: textarea 22 | id: report 23 | attributes: 24 | label: Bug Report 25 | description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log." 26 | placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox." 27 | validations: 28 | required: true 29 | - type: dropdown 30 | id: java 31 | attributes: 32 | label: Java Version 33 | description: What Java version are you using? It's worth mentioning that if you play on Java9+ you should try update to latest minor release (e.g. prefer Java 17.0.6 over 17.0.2) of that version. 34 | options: 35 | - Java 8 36 | - Java 9 37 | - Java 11 38 | - Java 17 39 | - Java 19 40 | - Java 20 41 | - Java 21 42 | - Other (Please Specify) 43 | validations: 44 | required: true 45 | - type: textarea 46 | id: modlist 47 | attributes: 48 | label: Mod List or GTNH Pack Version 49 | description: "List of mods, ideally a minimal reproducible set (can be retrieved from latest.log). If using GTNH please indicate pack version and any changed mods, not the entire modlist." 50 | placeholder: "List of mods or GTNH Pack version goes here" 51 | validations: 52 | required: true 53 | - type: checkboxes 54 | id: final 55 | attributes: 56 | label: Final Checklist 57 | description: Certify that you read things 58 | options: 59 | - label: "I have searched the issues and haven't found a similar issue." 60 | required: true 61 | 62 | 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/001-request-feature.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: "Request a feature." 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: "Please use this form to request features. We ask you check if it was already requested though" 7 | - type: input 8 | id: discord 9 | attributes: 10 | label: Your GTNH Discord Username 11 | description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info. 12 | placeholder: "Example: Wumpus#1234" 13 | - type: textarea 14 | id: request 15 | attributes: 16 | label: Feature Request 17 | description: "Relevant information, as well as relevant images" 18 | placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox." 19 | validations: 20 | required: true 21 | - type: checkboxes 22 | id: final 23 | attributes: 24 | label: Final Checklist 25 | description: Certify that you read things 26 | options: 27 | - label: "I have searched the issues and haven't found a similar issue." 28 | required: true 29 | -------------------------------------------------------------------------------- /.github/scripts/test_no_error_reports: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # bashsupport disable=BP5006 # Global environment variables 4 | RUNDIR="run" \ 5 | CRASH="crash-reports" \ 6 | SERVERLOG="server.log" 7 | 8 | # enable nullglob to get 0 results when no match rather than the pattern 9 | shopt -s nullglob 10 | 11 | # store matches in array 12 | crash_reports=("$RUNDIR/$CRASH/crash"*.txt) 13 | 14 | # if array not empty there are crash_reports 15 | if [ "${#crash_reports[@]}" -gt 0 ]; then 16 | # get the latest crash_report from array 17 | latest_crash_report="${crash_reports[-1]}" 18 | { 19 | printf 'Latest crash report detected %s:\n' "${latest_crash_report##*/}" 20 | cat "$latest_crash_report" 21 | } >&2 22 | exit 1 23 | fi 24 | 25 | if grep --quiet --fixed-strings 'Fatal errors were detected' "$SERVERLOG"; then 26 | { 27 | printf 'Fatal errors detected:\n' 28 | cat server.log 29 | } >&2 30 | exit 1 31 | fi 32 | 33 | if grep --quiet --fixed-strings 'The state engine was in incorrect state ERRORED and forced into state SERVER_STOPPED' \ 34 | "$SERVERLOG"; then 35 | { 36 | printf 'Server force stopped:' 37 | cat server.log 38 | } >&2 39 | exit 1 40 | fi 41 | 42 | if ! grep --quiet --perl-regexp --only-matching '.+Done \(.+\)\! For help, type "help" or "\?"' "$SERVERLOG"; then 43 | { 44 | printf 'Server did not finish startup:' 45 | cat server.log 46 | } >&2 47 | exit 1 48 | fi 49 | 50 | printf 'No crash reports detected' 51 | exit 0 52 | -------------------------------------------------------------------------------- /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Build and test 3 | 4 | on: 5 | pull_request: 6 | branches: [ master, main ] 7 | push: 8 | branches: [ master, main ] 9 | 10 | jobs: 11 | build-and-test: 12 | uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/build-and-test.yml@master 13 | secrets: inherit 14 | -------------------------------------------------------------------------------- /.github/workflows/release-tags.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Release tagged build 3 | 4 | on: 5 | push: 6 | tags: [ '*' ] 7 | 8 | permissions: 9 | contents: write 10 | 11 | jobs: 12 | release-tags: 13 | uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/release-tags.yml@master 14 | secrets: inherit 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .settings 3 | /.idea/ 4 | /run/ 5 | /build/ 6 | /eclipse/ 7 | .classpath 8 | .project 9 | /bin/ 10 | /config/ 11 | /crash-reports/ 12 | /logs/ 13 | options.txt 14 | /saves/ 15 | usernamecache.json 16 | banned-ips.json 17 | banned-players.json 18 | eula.txt 19 | ops.json 20 | server.properties 21 | servers.dat 22 | usercache.json 23 | whitelist.json 24 | /out/ 25 | *.iml 26 | *.ipr 27 | *.iws 28 | src/main/resources/mixins.*.json 29 | *.bat 30 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Any Github changes require admin approval 2 | /.github/** @GTNewHorizons/admin 3 | 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 ChickenBones 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /addon.gradle: -------------------------------------------------------------------------------- 1 | minecraft { 2 | if (replaceGradleTokenInFile) { 3 | tagReplacementFiles.add "CodeChickenCorePlugin.java" 4 | if(gradleTokenVersion) { 5 | injectedTags.put gradleTokenVersion, versionDetails().lastTag 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | //version: 1707058017 2 | 3 | plugins { 4 | id 'com.gtnewhorizons.gtnhconvention' 5 | } 6 | -------------------------------------------------------------------------------- /dependencies.gradle: -------------------------------------------------------------------------------- 1 | // Add your dependencies here 2 | 3 | dependencies { 4 | } 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTNewHorizons/CodeChickenCore/850e2b9368bfd792137c0b1102a79be18c0c1745/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - ./gradlew setupCIWorkspace -------------------------------------------------------------------------------- /repositories.gradle: -------------------------------------------------------------------------------- 1 | // Add any additional repositiroes for your dependencies here 2 | 3 | repositories { 4 | mavenLocal() 5 | } 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | 2 | pluginManagement { 3 | repositories { 4 | maven { 5 | // RetroFuturaGradle 6 | name "GTNH Maven" 7 | url "https://nexus.gtnewhorizons.com/repository/public/" 8 | mavenContent { 9 | includeGroup("com.gtnewhorizons") 10 | includeGroupByRegex("com\\.gtnewhorizons\\..+") 11 | } 12 | } 13 | gradlePluginPortal() 14 | mavenCentral() 15 | mavenLocal() 16 | } 17 | } 18 | 19 | plugins { 20 | id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.38' 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/CCUpdateChecker.java: -------------------------------------------------------------------------------- 1 | package codechicken.core; 2 | 3 | import com.google.common.base.Function; 4 | 5 | import cpw.mods.fml.relauncher.FMLInjectionData; 6 | 7 | public class CCUpdateChecker { 8 | 9 | public static void tick() {} 10 | 11 | public static void addUpdateMessage(String s) {} 12 | 13 | public static String mcVersion() { 14 | return (String) FMLInjectionData.data()[4]; 15 | } 16 | 17 | public static void updateCheck(final String mod, final String version) {} 18 | 19 | public static void updateCheck(String mod) {} 20 | 21 | public static void updateCheck(String url, Function handler) {} 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/ClientUtils.java: -------------------------------------------------------------------------------- 1 | package codechicken.core; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.GuiScreen; 5 | import net.minecraft.network.NetworkManager; 6 | import net.minecraft.server.MinecraftServer; 7 | import net.minecraft.util.EnumChatFormatting; 8 | import net.minecraft.world.World; 9 | 10 | import codechicken.core.internal.CCCEventHandler; 11 | import cpw.mods.fml.common.FMLCommonHandler; 12 | import cpw.mods.fml.common.ModContainer; 13 | import cpw.mods.fml.relauncher.Side; 14 | import cpw.mods.fml.relauncher.SideOnly; 15 | 16 | public class ClientUtils extends CommonUtils { 17 | 18 | private static Minecraft mc() { 19 | return Minecraft.getMinecraft(); 20 | } 21 | 22 | public static World getWorld() { 23 | return mc().theWorld; 24 | } 25 | 26 | public static boolean inWorld() // TODO unused 27 | { 28 | return mc().getNetHandler() != null; 29 | } 30 | 31 | public static void openSMPGui(int windowId, GuiScreen gui) { 32 | mc().displayGuiScreen(gui); 33 | if (windowId != 0) mc().thePlayer.openContainer.windowId = windowId; 34 | } 35 | 36 | public static float getRenderFrame() { 37 | return CCCEventHandler.renderFrame; 38 | } 39 | 40 | public static double getRenderTime() { 41 | return CCCEventHandler.renderTime + getRenderFrame(); 42 | } 43 | 44 | public static String getServerIP() { 45 | try { 46 | NetworkManager networkManager = mc().getNetHandler().getNetworkManager(); 47 | String s = networkManager.getSocketAddress().toString(); 48 | s = s.substring(s.indexOf("/") + 1); 49 | return s; 50 | } catch (RuntimeException e) { 51 | throw e; 52 | } catch (Exception e) { 53 | throw new RuntimeException(e); 54 | } 55 | } 56 | 57 | @SideOnly(Side.CLIENT) 58 | public static String getWorldSaveName() { 59 | return mc().isSingleplayer() ? MinecraftServer.getServer().getFolderName() : null; 60 | } 61 | 62 | public static void enhanceSupportersList(Object mod) { 63 | ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod); 64 | mc.getMetadata().description = mc.getMetadata().description 65 | .replace("Supporters:", EnumChatFormatting.AQUA + "Supporters:"); 66 | GuiModListScroll.register(mod); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/CommonUtils.java: -------------------------------------------------------------------------------- 1 | package codechicken.core; 2 | 3 | import java.io.File; 4 | 5 | import net.minecraft.entity.Entity; 6 | import net.minecraft.entity.EntityList; 7 | import net.minecraft.world.World; 8 | import net.minecraftforge.common.DimensionManager; 9 | 10 | import cpw.mods.fml.common.FMLCommonHandler; 11 | import cpw.mods.fml.relauncher.FMLInjectionData; 12 | 13 | public class CommonUtils { 14 | 15 | public static boolean isClient() { 16 | return FMLCommonHandler.instance().getSide().isClient(); 17 | } 18 | 19 | public static File getSaveLocation(World world) { 20 | File base = DimensionManager.getCurrentSaveRootDirectory(); 21 | return world.provider.dimensionId == 0 ? base : new File(base, world.provider.getSaveFolder()); 22 | } 23 | 24 | public static File getSaveLocation(int dim) { 25 | return getSaveLocation(DimensionManager.getWorld(dim)); 26 | } 27 | 28 | public static String getWorldName(World world) { 29 | return world.getWorldInfo().getWorldName(); 30 | } 31 | 32 | public static int getDimension(World world) { 33 | return world.provider.dimensionId; 34 | } 35 | 36 | public static File getMinecraftDir() { 37 | return (File) FMLInjectionData.data()[6]; 38 | } 39 | 40 | public static String getRelativePath(File parent, File child) { 41 | if (parent.isFile() || !child.getPath().startsWith(parent.getPath())) return null; 42 | 43 | return child.getPath().substring(parent.getPath().length() + 1); 44 | } 45 | 46 | public static void registerHandledEntity(Class entityClass, String identifier) { 47 | EntityList.classToStringMapping.put(entityClass, identifier); 48 | EntityList.stringToClassMapping.put(identifier, entityClass); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/IGuiPacketSender.java: -------------------------------------------------------------------------------- 1 | package codechicken.core; 2 | 3 | import net.minecraft.entity.player.EntityPlayerMP; 4 | 5 | public interface IGuiPacketSender { 6 | 7 | void sendPacket(EntityPlayerMP player, int windowId); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/IStringMatcher.java: -------------------------------------------------------------------------------- 1 | package codechicken.core; 2 | 3 | public interface IStringMatcher { 4 | 5 | public boolean matches(String test); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/ProfileTimer.java: -------------------------------------------------------------------------------- 1 | package codechicken.core; 2 | 3 | import codechicken.core.launch.CodeChickenCorePlugin; 4 | 5 | public class ProfileTimer { 6 | 7 | public double decay; 8 | public long startTime; 9 | public long nanoTime; 10 | public int scanCount; 11 | public int logScans; 12 | public String logName; 13 | 14 | public ProfileTimer() { 15 | this(0.98); 16 | } 17 | 18 | public ProfileTimer(double decay) { 19 | this.decay = decay; 20 | } 21 | 22 | public ProfileTimer log(String logName, int scans) { 23 | this.logScans = scans; 24 | this.logName = logName; 25 | return this; 26 | } 27 | 28 | public void start() { 29 | startTime = System.nanoTime(); 30 | } 31 | 32 | public void end() { 33 | long t = System.nanoTime() - startTime; 34 | nanoTime = (long) (nanoTime * decay + t * (1 - decay)); 35 | 36 | scanCount++; 37 | if (logScans > 0 && scanCount % logScans == 0) 38 | CodeChickenCorePlugin.logger.info("Profiled " + logName + " " + nanoTime + "ns"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/ServerUtils.java: -------------------------------------------------------------------------------- 1 | package codechicken.core; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Locale; 8 | import java.util.Map; 9 | 10 | import net.minecraft.entity.player.EntityPlayer; 11 | import net.minecraft.entity.player.EntityPlayerMP; 12 | import net.minecraft.inventory.Container; 13 | import net.minecraft.server.MinecraftServer; 14 | import net.minecraft.util.IChatComponent; 15 | 16 | import com.mojang.authlib.GameProfile; 17 | 18 | import codechicken.lib.asm.ObfMapping; 19 | 20 | public class ServerUtils extends CommonUtils { 21 | 22 | public static MinecraftServer mc() { 23 | return MinecraftServer.getServer(); 24 | } 25 | 26 | public static EntityPlayerMP getPlayer(String playername) { 27 | return mc().getConfigurationManager().func_152612_a(playername); 28 | } 29 | 30 | public static List getPlayers() { 31 | return mc().getConfigurationManager().playerEntityList; 32 | } 33 | 34 | public static ArrayList getPlayersInDimension(int dimension) { 35 | ArrayList players = new ArrayList(); 36 | for (EntityPlayer p : getPlayers()) if (p.dimension == dimension) players.add(p); 37 | 38 | return players; 39 | } 40 | 41 | public static void openSMPContainer(EntityPlayerMP player, Container container, IGuiPacketSender packetSender) { 42 | player.getNextWindowId(); 43 | player.closeContainer(); 44 | packetSender.sendPacket(player, player.currentWindowId); 45 | player.openContainer = container; 46 | player.openContainer.windowId = player.currentWindowId; 47 | player.openContainer.addCraftingToCrafters(player); 48 | } 49 | 50 | private static Field field_152661_c; 51 | private static Class c_ProfileEntry; 52 | private static Method func_152668_a; 53 | 54 | static { 55 | try { 56 | field_152661_c = ReflectionManager.getField( 57 | new ObfMapping( 58 | "net/minecraft/server/management/PlayerProfileCache", 59 | "field_152661_c", 60 | "[Ljava/util/Map;")); 61 | c_ProfileEntry = ServerUtils.class.getClassLoader() 62 | .loadClass("net.minecraft.server.management.PlayerProfileCache$ProfileEntry"); 63 | func_152668_a = c_ProfileEntry.getDeclaredMethod( 64 | new ObfMapping( 65 | "net/minecraft/server/management/PlayerProfileCache$ProfileEntry", 66 | "func_152668_a", 67 | "()Lcom/mojang/authlib/GameProfile;").toRuntime().s_name); 68 | func_152668_a.setAccessible(true); 69 | 70 | } catch (Exception e) { 71 | throw new RuntimeException(e); 72 | } 73 | } 74 | 75 | public static GameProfile getGameProfile(String username) { 76 | EntityPlayer player = getPlayer(username); 77 | if (player != null) return player.getGameProfile(); 78 | 79 | username = username.toLowerCase(Locale.ROOT); 80 | try { // use reflection to bypass saving the game profiles every time we ask the cache for one 81 | Object cacheEntry = ((Map) field_152661_c.get(mc().func_152358_ax())).get(username); 82 | if (cacheEntry != null) return (GameProfile) func_152668_a.invoke(cacheEntry); 83 | } catch (Exception e) { 84 | throw new RuntimeException(e); 85 | } 86 | return mc().func_152358_ax().func_152655_a(username); 87 | } 88 | 89 | public static boolean isPlayerOP(String username) { 90 | GameProfile prof = getGameProfile(username); 91 | return prof != null && mc().getConfigurationManager().func_152596_g(prof); 92 | } 93 | 94 | public static boolean isPlayerOwner(String username) { 95 | return mc().isSinglePlayer() && mc().getServerOwner().equalsIgnoreCase(username); 96 | } 97 | 98 | public static void sendChatToAll(IChatComponent msg) { 99 | for (EntityPlayer p : getPlayers()) p.addChatComponentMessage(msg); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/TaskProfiler.java: -------------------------------------------------------------------------------- 1 | package codechicken.core; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map.Entry; 7 | 8 | public class TaskProfiler { 9 | 10 | public static class ProfilerResult { 11 | 12 | public final String name; 13 | public final long time; 14 | public final double fraction; 15 | 16 | public ProfilerResult(String name, long time, long totalTime) { 17 | this.name = name; 18 | this.time = time; 19 | fraction = time / (double) totalTime; 20 | } 21 | } 22 | 23 | public HashMap times = new HashMap(); 24 | 25 | public String currentSection; 26 | private long startTime; 27 | private long totalTime; 28 | 29 | public void start(String section) { 30 | if (currentSection != null) end(); 31 | 32 | currentSection = section; 33 | startTime = System.nanoTime(); 34 | } 35 | 36 | public void end() { 37 | long time = System.nanoTime() - startTime; 38 | totalTime += time; 39 | 40 | Long prev = times.get(currentSection); 41 | if (prev == null) prev = 0L; 42 | times.put(currentSection, prev + time); 43 | currentSection = null; 44 | } 45 | 46 | public List getResults() { 47 | ArrayList results = new ArrayList(times.size()); 48 | for (Entry e : times.entrySet()) 49 | results.add(new ProfilerResult(e.getKey(), e.getValue(), totalTime)); 50 | return results; 51 | } 52 | 53 | public void clear() { 54 | if (currentSection != null) end(); 55 | times.clear(); 56 | totalTime = 0; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/asm/CodeChickenAccessTransformer.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.asm; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.Field; 5 | 6 | import com.google.common.collect.ImmutableBiMap; 7 | 8 | import codechicken.lib.asm.ObfMapping; 9 | import cpw.mods.fml.common.asm.transformers.AccessTransformer; 10 | import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; 11 | 12 | public class CodeChickenAccessTransformer extends AccessTransformer { 13 | 14 | private static boolean makeAllPublic; 15 | private static Field f_classNameBiMap; 16 | private static Object emptyMap = ImmutableBiMap.of(); 17 | 18 | public CodeChickenAccessTransformer() throws IOException { 19 | super(); 20 | loadPublicConfig(); 21 | } 22 | 23 | private void loadPublicConfig() { 24 | if (ObfMapping.obfuscated) return; 25 | 26 | makeAllPublic = CodeChickenCoreModContainer.config.getTag("dev.runtimePublic").setComment( 27 | "Enabling this setting will make all minecraft classes public at runtime in MCP just as they are in modloader." 28 | + "\nYou should ONLY use this when you are testing with a mod that relies on runtime publicity and doesn't include access transformers." 29 | + "\nSuch mods are doing the wrong thing and should be fixed.") 30 | .getBooleanValue(false); 31 | 32 | if (!makeAllPublic) return; 33 | 34 | try { 35 | f_classNameBiMap = FMLDeobfuscatingRemapper.class.getDeclaredField("classNameBiMap"); 36 | f_classNameBiMap.setAccessible(true); 37 | } catch (Exception e) { 38 | throw new RuntimeException(e); 39 | } 40 | } 41 | 42 | @Override 43 | public byte[] transform(String name, String transformedName, byte[] bytes) { 44 | boolean setPublic = makeAllPublic && name.startsWith("net.minecraft."); 45 | if (setPublic) setClassMap(name); 46 | bytes = super.transform(name, transformedName, bytes); 47 | if (setPublic) restoreClassMap(); 48 | return bytes; 49 | } 50 | 51 | private void restoreClassMap() { 52 | try { 53 | f_classNameBiMap.set(FMLDeobfuscatingRemapper.INSTANCE, emptyMap); 54 | } catch (Exception e) { 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | 59 | private void setClassMap(String name) { 60 | try { 61 | f_classNameBiMap.set(FMLDeobfuscatingRemapper.INSTANCE, ImmutableBiMap.of(name.replace('.', '/'), "")); 62 | } catch (Exception e) { 63 | throw new RuntimeException(e); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/asm/CodeChickenCoreModContainer.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.asm; 2 | 3 | import java.io.File; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | import net.minecraftforge.common.MinecraftForge; 8 | 9 | import com.google.common.eventbus.EventBus; 10 | import com.google.common.eventbus.Subscribe; 11 | 12 | import codechicken.core.ClientUtils; 13 | import codechicken.core.featurehack.LiquidTextures; 14 | import codechicken.core.internal.CCCEventHandler; 15 | import codechicken.core.launch.CodeChickenCorePlugin; 16 | import codechicken.lib.config.ConfigFile; 17 | import cpw.mods.fml.common.DummyModContainer; 18 | import cpw.mods.fml.common.FMLCommonHandler; 19 | import cpw.mods.fml.common.LoadController; 20 | import cpw.mods.fml.common.ModMetadata; 21 | import cpw.mods.fml.common.event.FMLInitializationEvent; 22 | import cpw.mods.fml.common.event.FMLPreInitializationEvent; 23 | import cpw.mods.fml.common.versioning.ArtifactVersion; 24 | import cpw.mods.fml.common.versioning.VersionParser; 25 | import cpw.mods.fml.common.versioning.VersionRange; 26 | 27 | public class CodeChickenCoreModContainer extends DummyModContainer { 28 | 29 | public static ConfigFile config; 30 | 31 | public static void loadConfig() { 32 | if (config == null) 33 | config = new ConfigFile(new File(CodeChickenCorePlugin.minecraftDir, "config/CodeChickenCore.cfg")) 34 | .setComment("CodeChickenCore configuration file."); 35 | } 36 | 37 | public CodeChickenCoreModContainer() { 38 | super(getModMetadata()); 39 | } 40 | 41 | private static ModMetadata getModMetadata() { 42 | final ModMetadata modMetadata = new ModMetadata(); 43 | modMetadata.name = "CodeChicken Core"; 44 | modMetadata.modId = "CodeChickenCore"; 45 | modMetadata.version = Tags.VERSION; 46 | return modMetadata; 47 | } 48 | 49 | @Override 50 | public List getDependants() { 51 | LinkedList deps = new LinkedList(); 52 | if (!getVersion().contains("$")) { 53 | deps.add(VersionParser.parseVersionReference("Forge@[10.13.3,)")); 54 | deps.add(VersionParser.parseVersionReference("NotEnoughItems@[1.0.5,)")); 55 | deps.add(VersionParser.parseVersionReference("EnderStorage@[1.4.7,)")); 56 | deps.add(VersionParser.parseVersionReference("ChickenChunks@[1.3.4,)")); 57 | deps.add(VersionParser.parseVersionReference("Translocator@[1.1.2,)")); 58 | deps.add(VersionParser.parseVersionReference("WR-CBE|Core@[1.4.1,)")); 59 | } 60 | return deps; 61 | } 62 | 63 | @Override 64 | public boolean registerBus(EventBus bus, LoadController controller) { 65 | bus.register(this); 66 | return true; 67 | } 68 | 69 | @Subscribe 70 | public void preInit(FMLPreInitializationEvent event) { 71 | if (event.getSide().isClient()) LiquidTextures.init(); 72 | } 73 | 74 | @Subscribe 75 | public void init(FMLInitializationEvent event) { 76 | if (event.getSide().isClient()) { 77 | ClientUtils.enhanceSupportersList("CodeChickenCore"); 78 | 79 | FMLCommonHandler.instance().bus().register(new CCCEventHandler()); 80 | MinecraftForge.EVENT_BUS.register(new CCCEventHandler()); 81 | } 82 | } 83 | 84 | @Override 85 | public VersionRange acceptableMinecraftVersionRange() { 86 | return VersionParser.parseRange(CodeChickenCorePlugin.mcVersion); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/asm/DefaultImplementationTransformer.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.asm; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.HashSet; 7 | import java.util.LinkedList; 8 | 9 | import net.minecraft.launchwrapper.IClassTransformer; 10 | import net.minecraft.launchwrapper.LaunchClassLoader; 11 | 12 | import org.objectweb.asm.tree.ClassNode; 13 | import org.objectweb.asm.tree.MethodNode; 14 | 15 | import codechicken.lib.asm.ASMHelper; 16 | import codechicken.lib.asm.ClassHeirachyManager; 17 | import codechicken.lib.asm.ObfMapping; 18 | 19 | public class DefaultImplementationTransformer implements IClassTransformer { 20 | 21 | private static LaunchClassLoader cl = (LaunchClassLoader) ClassHeirachyManager.class.getClassLoader(); 22 | 23 | private static ClassNode getClassNode(String name) { 24 | try { 25 | return ASMHelper.createClassNode(cl.getClassBytes(name.replace('/', '.'))); 26 | } catch (IOException e) { 27 | throw new RuntimeException(e); 28 | } 29 | } 30 | 31 | static class InterfaceImpl { 32 | 33 | public final String iname; 34 | public ArrayList impls = new ArrayList(); 35 | 36 | public InterfaceImpl(String iname, String cname) { 37 | this.iname = iname; 38 | HashSet names = new HashSet(); 39 | ClassNode inode = getClassNode(iname); 40 | for (MethodNode method : inode.methods) names.add(method.name + method.desc); 41 | 42 | ClassNode cnode = getClassNode(cname); 43 | for (MethodNode method : cnode.methods) if (names.contains(method.name + method.desc)) { 44 | impls.add(method); 45 | method.desc = new ObfMapping(cnode.name, method.name, method.desc).toRuntime().s_desc; 46 | } 47 | } 48 | 49 | public boolean patch(ClassNode cnode) { 50 | LinkedList names = new LinkedList(); 51 | for (MethodNode method : cnode.methods) { 52 | ObfMapping m = new ObfMapping(cnode.name, method.name, method.desc).toRuntime(); 53 | names.add(m.s_name + m.s_desc); 54 | } 55 | 56 | boolean changed = false; 57 | for (MethodNode impl : impls) { 58 | if (names.contains(impl.name + impl.desc)) continue; 59 | 60 | MethodNode copy = new MethodNode( 61 | impl.access, 62 | impl.name, 63 | impl.desc, 64 | impl.signature, 65 | impl.exceptions == null ? null : impl.exceptions.toArray(new String[0])); 66 | ASMHelper.copy(impl, copy); 67 | cnode.methods.add(impl); 68 | changed = true; 69 | } 70 | return changed; 71 | } 72 | } 73 | 74 | private static HashMap impls = new HashMap(); 75 | 76 | public static void registerDefaultImpl(String iname, String cname) { 77 | impls.put(iname.replace('.', '/'), new InterfaceImpl(iname, cname)); 78 | } 79 | 80 | @Override 81 | public byte[] transform(String name, String transformedName, byte[] bytes) { 82 | if (transformedName.startsWith("net.minecraft") || impls.isEmpty()) return bytes; 83 | 84 | ClassNode cnode = ASMHelper.createClassNode(bytes); 85 | boolean changed = false; 86 | for (String iname : cnode.interfaces) { 87 | InterfaceImpl impl = impls.get(iname); 88 | if (impl != null) changed |= impl.patch(cnode); 89 | } 90 | 91 | return changed ? ASMHelper.createBytes(cnode, 0) : bytes; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/asm/DependancyLister.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.asm; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | import org.objectweb.asm.ClassVisitor; 10 | import org.objectweb.asm.FieldVisitor; 11 | import org.objectweb.asm.Label; 12 | import org.objectweb.asm.MethodVisitor; 13 | import org.objectweb.asm.Opcodes; 14 | 15 | public class DependancyLister extends ClassVisitor { 16 | 17 | private static Pattern classdesc = Pattern.compile("L(.+?);"); 18 | 19 | private class DependancyMethodLister extends MethodVisitor { 20 | 21 | public DependancyMethodLister(int api) { 22 | super(api); 23 | } 24 | 25 | @Override 26 | public void visitFieldInsn(int opcode, String owner, String name, String desc) { 27 | dependDesc(desc); 28 | } 29 | 30 | @Override 31 | public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { 32 | dependDesc(desc); 33 | } 34 | 35 | @Override 36 | public void visitMethodInsn(int opcode, String owner, String name, String desc) { 37 | depend(owner); 38 | dependDesc(desc); 39 | } 40 | } 41 | 42 | private HashSet dependancies = new HashSet(); 43 | 44 | public DependancyLister(int api) { 45 | super(api); 46 | } 47 | 48 | @Override 49 | public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { 50 | dependDesc(desc); 51 | return null; 52 | } 53 | 54 | private void dependDesc(String desc) { 55 | Matcher match = classdesc.matcher(desc); 56 | while (match.find()) { 57 | String s = match.group(); 58 | depend(s.substring(1, s.length() - 1)); 59 | } 60 | } 61 | 62 | private void depend(String classname) { 63 | dependancies.add(classname); 64 | } 65 | 66 | @Override 67 | public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { 68 | dependDesc(desc); 69 | return new DependancyMethodLister(Opcodes.ASM4); 70 | } 71 | 72 | @Override 73 | public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { 74 | depend(superName); 75 | if (interfaces != null) for (String interfacename : interfaces) depend(interfacename); 76 | } 77 | 78 | public List getDependancies() { 79 | return new ArrayList(dependancies); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/asm/InterfaceDependancies.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.asm; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target({ ElementType.TYPE }) 10 | public @interface InterfaceDependancies {} 11 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/asm/MethodASMifier.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.asm; 2 | 3 | import static org.objectweb.asm.Opcodes.ASM4; 4 | 5 | import java.io.File; 6 | import java.io.PrintWriter; 7 | 8 | import net.minecraft.launchwrapper.Launch; 9 | 10 | import org.objectweb.asm.ClassReader; 11 | import org.objectweb.asm.ClassVisitor; 12 | import org.objectweb.asm.MethodVisitor; 13 | import org.objectweb.asm.util.Printer; 14 | import org.objectweb.asm.util.TraceMethodVisitor; 15 | 16 | import codechicken.lib.asm.ObfMapping; 17 | 18 | public class MethodASMifier extends ClassVisitor { 19 | 20 | PrintWriter printWriter; 21 | ObfMapping method; 22 | Printer asmifier; 23 | 24 | public MethodASMifier(ObfMapping method, Printer printer, PrintWriter printWriter) { 25 | super(ASM4); 26 | this.method = method; 27 | this.printWriter = printWriter; 28 | asmifier = printer; 29 | } 30 | 31 | @Override 32 | public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { 33 | if (method.matches(name, desc)) { 34 | Printer localPrinter = asmifier.visitMethod(access, name, desc, signature, exceptions); 35 | return new TraceMethodVisitor(null, localPrinter); 36 | } 37 | 38 | return null; 39 | } 40 | 41 | @Override 42 | public void visitEnd() { 43 | asmifier.visitClassEnd(); 44 | asmifier.print(printWriter); 45 | super.visitEnd(); 46 | } 47 | 48 | public static void printMethod(ObfMapping method, Printer printer, File toFile) { 49 | try { 50 | printMethod(method, Launch.classLoader.getClassBytes(method.javaClass()), printer, toFile); 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | 56 | public static void printMethod(ObfMapping method, byte[] bytes, Printer printer, File toFile) { 57 | try { 58 | if (!toFile.getParentFile().exists()) toFile.getParentFile().mkdirs(); 59 | if (!toFile.exists()) toFile.createNewFile(); 60 | 61 | PrintWriter printWriter = new PrintWriter(toFile); 62 | 63 | ClassVisitor cv = new MethodASMifier(method, printer, printWriter); 64 | ClassReader cr = new ClassReader(bytes); 65 | cr.accept(cv, 0); 66 | 67 | printWriter.close(); 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/commands/PlayerCommand.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.commands; 2 | 3 | import net.minecraft.command.ICommandSender; 4 | import net.minecraft.entity.Entity; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.entity.player.EntityPlayerMP; 7 | import net.minecraft.util.MovingObjectPosition; 8 | import net.minecraft.util.MovingObjectPosition.MovingObjectType; 9 | import net.minecraft.util.Vec3; 10 | import net.minecraft.world.ChunkPosition; 11 | import net.minecraft.world.WorldServer; 12 | 13 | public abstract class PlayerCommand extends CoreCommand { 14 | 15 | @Override 16 | public boolean canCommandSenderUseCommand(ICommandSender var1) { 17 | if (!super.canCommandSenderUseCommand(var1)) return false; 18 | return var1 instanceof EntityPlayer; 19 | } 20 | 21 | @Override 22 | public void handleCommand(String command, String playername, String[] args, WCommandSender listener) { 23 | EntityPlayerMP player = (EntityPlayerMP) listener.wrapped; 24 | handleCommand(getWorld(player), player, args); 25 | } 26 | 27 | public abstract void handleCommand(WorldServer world, EntityPlayerMP player, String[] args); 28 | 29 | public ChunkPosition getPlayerLookingAtBlock(EntityPlayerMP player, float reach) { 30 | Vec3 vec3d = Vec3 31 | .createVectorHelper(player.posX, (player.posY + 1.6200000000000001D) - player.yOffset, player.posZ); 32 | Vec3 vec3d1 = player.getLook(1.0F); 33 | Vec3 vec3d2 = vec3d.addVector(vec3d1.xCoord * reach, vec3d1.yCoord * reach, vec3d1.zCoord * reach); 34 | MovingObjectPosition hit = player.worldObj.rayTraceBlocks(vec3d, vec3d2); 35 | if (hit == null || hit.typeOfHit != MovingObjectType.BLOCK) { 36 | return null; 37 | } 38 | 39 | return new ChunkPosition(hit.blockX, hit.blockY, hit.blockZ); 40 | } 41 | 42 | public Entity getPlayerLookingAtEntity(EntityPlayerMP player, float reach) { 43 | Vec3 vec3d = Vec3 44 | .createVectorHelper(player.posX, (player.posY + 1.6200000000000001D) - player.yOffset, player.posZ); 45 | Vec3 vec3d1 = player.getLook(1.0F); 46 | Vec3 vec3d2 = vec3d.addVector(vec3d1.xCoord * reach, vec3d1.yCoord * reach, vec3d1.zCoord * reach); 47 | MovingObjectPosition hit = player.worldObj.rayTraceBlocks(vec3d, vec3d2); 48 | if (hit == null || hit.typeOfHit != MovingObjectType.ENTITY) { 49 | return null; 50 | } 51 | 52 | return hit.entityHit; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/commands/ServerCommand.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.commands; 2 | 3 | import net.minecraft.command.ICommandSender; 4 | import net.minecraft.server.MinecraftServer; 5 | 6 | public abstract class ServerCommand extends CoreCommand { 7 | 8 | @Override 9 | public void processCommand(ICommandSender var1, String[] var2) { 10 | handleCommand(var2, (MinecraftServer) var1); 11 | } 12 | 13 | @Override 14 | public boolean canCommandSenderUseCommand(ICommandSender var1) { 15 | if (!super.canCommandSenderUseCommand(var1)) return false; 16 | return var1 instanceof MinecraftServer; 17 | } 18 | 19 | public abstract void handleCommand(String[] args, MinecraftServer listener); 20 | 21 | public final boolean OPOnly() { 22 | return false; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/EntityRenderHook.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | import net.minecraft.world.World; 6 | 7 | public class EntityRenderHook extends Entity { 8 | 9 | public static interface IRenderCallback { 10 | 11 | public void render(float frame, int pass); 12 | 13 | public boolean shouldRenderInPass(int pass); 14 | 15 | public boolean isValid(); 16 | } 17 | 18 | public final IRenderCallback callback; 19 | 20 | public EntityRenderHook(World world, double x, double y, double z, IRenderCallback callback) { 21 | super(world); 22 | setPosition(x, y, z); 23 | ignoreFrustumCheck = true; 24 | this.callback = callback; 25 | } 26 | 27 | @Override 28 | public void onUpdate() { 29 | if (!callback.isValid()) setDead(); 30 | } 31 | 32 | @Override 33 | protected void entityInit() {} 34 | 35 | @Override 36 | protected void readEntityFromNBT(NBTTagCompound var1) {} 37 | 38 | @Override 39 | protected void writeEntityToNBT(NBTTagCompound var1) {} 40 | 41 | @Override 42 | public boolean shouldRenderInPass(int pass) { 43 | return callback.shouldRenderInPass(pass); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/EntityUpdateHook.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | import net.minecraft.world.World; 6 | 7 | public class EntityUpdateHook extends Entity { 8 | 9 | public static interface IUpdateCallback { 10 | 11 | public void onUpdate(); 12 | 13 | public boolean isValid(); 14 | } 15 | 16 | public final IUpdateCallback callback; 17 | 18 | public EntityUpdateHook(World world, int x, int y, int z, IUpdateCallback callback) { 19 | super(world); 20 | setPosition(x, y, z); 21 | this.callback = callback; 22 | } 23 | 24 | @Override 25 | public void onUpdate() { 26 | if (!callback.isValid()) setDead(); 27 | else callback.onUpdate(); 28 | } 29 | 30 | @Override 31 | protected void entityInit() {} 32 | 33 | @Override 34 | protected void readEntityFromNBT(NBTTagCompound var1) {} 35 | 36 | @Override 37 | protected void writeEntityToNBT(NBTTagCompound var1) {} 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/FeatureHack.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack; 2 | 3 | import cpw.mods.fml.client.registry.RenderingRegistry; 4 | import cpw.mods.fml.common.FMLCommonHandler; 5 | import cpw.mods.fml.relauncher.Side; 6 | import cpw.mods.fml.relauncher.SideOnly; 7 | 8 | public class FeatureHack { 9 | 10 | private static boolean updateHookEnabled = false; 11 | private static boolean renderHookEnabled = false; 12 | 13 | public static void enableUpdateHook() { 14 | if (updateHookEnabled) return; 15 | 16 | updateHookEnabled = true; 17 | if (FMLCommonHandler.instance().getSide().isClient()) enableClientUpdateHook(); 18 | } 19 | 20 | @SideOnly(Side.CLIENT) 21 | public static void enableRenderHook() { 22 | if (renderHookEnabled) return; 23 | 24 | renderHookEnabled = true; 25 | RenderingRegistry.registerEntityRenderingHandler(EntityUpdateHook.class, new RenderNull()); 26 | } 27 | 28 | @SideOnly(Side.CLIENT) 29 | private static void enableClientUpdateHook() { 30 | RenderingRegistry.registerEntityRenderingHandler(EntityRenderHook.class, new RenderEntityRenderHook()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/GameDataManipulator.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack; 2 | 3 | import java.lang.reflect.Field; 4 | import java.util.Map; 5 | 6 | import net.minecraft.item.Item; 7 | import net.minecraft.util.ObjectIntIdentityMap; 8 | import net.minecraft.util.RegistryNamespaced; 9 | import net.minecraft.util.RegistrySimple; 10 | 11 | import codechicken.lib.asm.ObfMapping; 12 | 13 | public class GameDataManipulator { 14 | 15 | public static Field f_registryObjects; 16 | public static Field f_underlyingIntegerMap; 17 | 18 | static { 19 | try { 20 | f_registryObjects = RegistrySimple.class.getDeclaredField( 21 | new ObfMapping("net/minecraft/util/RegistrySimple", "field_82596_a", "Ljava/util/Map;") 22 | .toRuntime().s_name); 23 | f_registryObjects.setAccessible(true); 24 | f_underlyingIntegerMap = RegistryNamespaced.class.getDeclaredField( 25 | new ObfMapping( 26 | "net/minecraft/util/RegistryNamespaced", 27 | "field_148759_a", 28 | "Lnet/minecraft/util/ObjectIntIdentityMap;").toRuntime().s_name); 29 | f_underlyingIntegerMap.setAccessible(true); 30 | } catch (Exception e) { 31 | throw new RuntimeException(e); 32 | } 33 | } 34 | 35 | public static void replaceItem(int id, Item item) { 36 | try { 37 | String name = Item.itemRegistry.getNameForObject(Item.getItemById(id)); 38 | ((Map) f_registryObjects.get(Item.itemRegistry)).put(name, item); 39 | ((ObjectIntIdentityMap) f_underlyingIntegerMap.get(Item.itemRegistry)).func_148746_a(item, id); 40 | } catch (Exception e) { 41 | throw new RuntimeException(e); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/LiquidTextures.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import net.minecraft.init.Blocks; 6 | import net.minecraft.util.IIcon; 7 | import net.minecraftforge.client.event.TextureStitchEvent; 8 | import net.minecraftforge.common.MinecraftForge; 9 | 10 | import codechicken.core.ReflectionManager; 11 | import codechicken.core.asm.TweakTransformer; 12 | import codechicken.core.featurehack.mc.TextureLavaFX; 13 | import codechicken.core.featurehack.mc.TextureLavaFlowFX; 14 | import codechicken.core.featurehack.mc.TextureWaterFX; 15 | import codechicken.core.featurehack.mc.TextureWaterFlowFX; 16 | import codechicken.lib.asm.ObfMapping; 17 | import cpw.mods.fml.common.eventhandler.SubscribeEvent; 18 | 19 | public class LiquidTextures { 20 | 21 | public static IIcon[] newTextures = new IIcon[4]; 22 | 23 | public static boolean replaceLava; 24 | public static boolean replaceWater; 25 | 26 | private static Field field_tex; 27 | 28 | public static void init() { 29 | replaceWater = TweakTransformer.tweaks.getTag("replaceWaterFX") 30 | .setComment("Set this to true to use the pre1.5 water textures").getBooleanValue(false); 31 | replaceLava = TweakTransformer.tweaks.getTag("replaceLavaFX") 32 | .setComment("Set this to true to use the pre1.5 lava textures").getBooleanValue(false); 33 | if (replaceWater) { 34 | newTextures[0] = new TextureWaterFX().texture; 35 | newTextures[1] = new TextureWaterFlowFX().texture; 36 | } 37 | if (replaceLava) { 38 | newTextures[2] = new TextureLavaFX().texture; 39 | newTextures[3] = new TextureLavaFlowFX().texture; 40 | } 41 | 42 | if (replaceWater || replaceLava) { 43 | MinecraftForge.EVENT_BUS.register(new LiquidTextures()); 44 | field_tex = ReflectionManager.getField( 45 | new ObfMapping("net/minecraft/block/BlockLiquid", "field_149806_a", "[Lnet/minecraft/util/IIcon;")); 46 | } 47 | } 48 | 49 | @SubscribeEvent 50 | public void postStitch(TextureStitchEvent.Post event) { 51 | IIcon[] icons; 52 | if (replaceLava) { 53 | icons = ReflectionManager.get(field_tex, IIcon[].class, Blocks.flowing_lava); 54 | icons[0] = newTextures[2]; 55 | icons[1] = newTextures[3]; 56 | icons = ReflectionManager.get(field_tex, IIcon[].class, Blocks.lava); 57 | icons[0] = newTextures[2]; 58 | icons[1] = newTextures[3]; 59 | } 60 | if (replaceWater) { 61 | icons = ReflectionManager.get(field_tex, IIcon[].class, Blocks.flowing_water); 62 | icons[0] = newTextures[0]; 63 | icons[1] = newTextures[1]; 64 | icons = ReflectionManager.get(field_tex, IIcon[].class, Blocks.water); 65 | icons[0] = newTextures[0]; 66 | icons[1] = newTextures[1]; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/RenderEntityRenderHook.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack; 2 | 3 | import net.minecraft.client.renderer.entity.Render; 4 | import net.minecraft.entity.Entity; 5 | import net.minecraft.util.ResourceLocation; 6 | import net.minecraftforge.client.MinecraftForgeClient; 7 | 8 | import org.lwjgl.opengl.GL11; 9 | 10 | public class RenderEntityRenderHook extends Render { 11 | 12 | @Override 13 | public void doRender(Entity entity, double x, double y, double z, float f, float frame) { 14 | EntityRenderHook hook = (EntityRenderHook) entity; 15 | GL11.glTranslated(x - hook.posX, y - hook.posY, z - hook.posZ); 16 | ((EntityRenderHook) entity).callback.render(frame, MinecraftForgeClient.getRenderPass()); 17 | GL11.glTranslated(hook.posX - x, hook.posY - y, hook.posZ - z); 18 | } 19 | 20 | @Override 21 | protected ResourceLocation getEntityTexture(Entity entity) { 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/RenderNull.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack; 2 | 3 | import net.minecraft.client.renderer.entity.Render; 4 | import net.minecraft.entity.Entity; 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | public class RenderNull extends Render { 8 | 9 | @Override 10 | public void doRender(Entity var1, double var2, double var4, double var6, float var8, float var9) {} 11 | 12 | @Override 13 | protected ResourceLocation getEntityTexture(Entity entity) { 14 | return null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/TweakTransformerHelper.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack; 2 | 3 | import static net.minecraftforge.common.util.ForgeDirection.UP; 4 | 5 | import java.util.Random; 6 | 7 | import net.minecraft.block.Block; 8 | import net.minecraft.init.Blocks; 9 | import net.minecraft.world.World; 10 | 11 | public class TweakTransformerHelper { 12 | 13 | public static void quenchFireTick(World world, int x, int y, int z, Random rand) { 14 | Block base = world.getBlock(x, y - 1, z); 15 | boolean supported = (base != null && base.isFireSource(world, x, y - 1, z, UP)); 16 | 17 | if (!Blocks.fire.canPlaceBlockAt(world, x, y, z) || !supported && world.isRaining() 18 | && (world.canLightningStrikeAt(x, y, z) || world.canLightningStrikeAt(x - 1, y, z) 19 | || world.canLightningStrikeAt(x + 1, y, z) 20 | || world.canLightningStrikeAt(x, y, z - 1) 21 | || world.canLightningStrikeAt(x, y, z + 1))) 22 | world.setBlockToAir(x, y, z); 23 | else { 24 | int meta = world.getBlockMetadata(x, y, z); 25 | if (meta < 15) world.setBlockMetadataWithNotify(x, y, z, meta + rand.nextInt(3) / 2, 0); 26 | 27 | world.scheduleBlockUpdate(x, y, z, Blocks.fire, Blocks.fire.tickRate(world) + rand.nextInt(10)); 28 | 29 | if (!supported && !Blocks.fire.canCatchFire(world, x, y - 1, z, UP) && meta == 15 && rand.nextInt(4) == 0) 30 | world.setBlockToAir(x, y, z); 31 | } 32 | } 33 | 34 | public static boolean canPlaceBlockAt(World world, int x, int y, int z) { 35 | Block block = world.getBlock(x, y, z); 36 | return block.isAir(world, x, y, z) || block.isReplaceable(world, x, y, z); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/featurehack/mc/TextureWaterFX.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.featurehack.mc; 2 | 3 | import codechicken.lib.colour.ColourRGBA; 4 | import codechicken.lib.render.TextureFX; 5 | import cpw.mods.fml.relauncher.Side; 6 | import cpw.mods.fml.relauncher.SideOnly; 7 | 8 | @SideOnly(Side.CLIENT) 9 | public class TextureWaterFX extends TextureFX { 10 | 11 | /** red RGB value for water texture */ 12 | protected float[] red = new float[256]; 13 | 14 | /** green RGB value for water texture */ 15 | protected float[] green = new float[256]; 16 | 17 | /** blue RGB value for water texture */ 18 | protected float[] blue = new float[256]; 19 | 20 | /** alpha RGB value for water texture */ 21 | protected float[] alpha = new float[256]; 22 | 23 | public TextureWaterFX() { 24 | super(16, "water_still_fx"); 25 | setup(); 26 | } 27 | 28 | @Override 29 | public void setup() { 30 | super.setup(); 31 | red = new float[tileSizeSquare]; 32 | green = new float[tileSizeSquare]; 33 | blue = new float[tileSizeSquare]; 34 | alpha = new float[tileSizeSquare]; 35 | } 36 | 37 | public void onTick() { 38 | int var1; 39 | int var2; 40 | float var3; 41 | int var5; 42 | int var6; 43 | 44 | for (var1 = 0; var1 < tileSizeBase; ++var1) { 45 | for (var2 = 0; var2 < tileSizeBase; ++var2) { 46 | var3 = 0.0F; 47 | 48 | for (int var4 = var1 - 1; var4 <= var1 + 1; ++var4) { 49 | var5 = var4 & tileSizeMask; 50 | var6 = var2 & tileSizeMask; 51 | var3 += this.red[var5 + var6 * tileSizeBase]; 52 | } 53 | 54 | this.green[var1 + var2 * tileSizeBase] = var3 / 3.3F + this.blue[var1 + var2 * tileSizeBase] * 0.8F; 55 | } 56 | } 57 | 58 | for (var1 = 0; var1 < tileSizeBase; ++var1) { 59 | for (var2 = 0; var2 < tileSizeBase; ++var2) { 60 | this.blue[var1 + var2 * tileSizeBase] += this.alpha[var1 + var2 * tileSizeBase] * 0.05F; 61 | 62 | if (this.blue[var1 + var2 * tileSizeBase] < 0.0F) { 63 | this.blue[var1 + var2 * tileSizeBase] = 0.0F; 64 | } 65 | 66 | this.alpha[var1 + var2 * tileSizeBase] -= 0.1F; 67 | 68 | if (Math.random() < 0.05D) { 69 | this.alpha[var1 + var2 * tileSizeBase] = 0.5F; 70 | } 71 | } 72 | } 73 | 74 | float[] var12 = this.green; 75 | this.green = this.red; 76 | this.red = var12; 77 | 78 | for (var2 = 0; var2 < tileSizeSquare; ++var2) { 79 | var3 = this.red[var2]; 80 | 81 | if (var3 > 1.0F) { 82 | var3 = 1.0F; 83 | } 84 | 85 | if (var3 < 0.0F) { 86 | var3 = 0.0F; 87 | } 88 | 89 | float var13 = var3 * var3; 90 | var5 = (int) (32.0F + var13 * 32.0F); 91 | var6 = (int) (50.0F + var13 * 64.0F); 92 | int var7 = 255; 93 | int var8 = (int) (146.0F + var13 * 50.0F); 94 | 95 | if (this.anaglyphEnabled) { 96 | int var9 = (var5 * 30 + var6 * 59 + var7 * 11) / 100; 97 | int var10 = (var5 * 30 + var6 * 70) / 100; 98 | int var11 = (var5 * 30 + var7 * 70) / 100; 99 | var5 = var9; 100 | var6 = var10; 101 | var7 = var11; 102 | } 103 | 104 | imageData[var2] = new ColourRGBA(var5, var6, var7, var8).argb(); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/fluid/ExtendedFluidTank.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.fluid; 2 | 3 | import net.minecraft.nbt.NBTTagCompound; 4 | import net.minecraftforge.fluids.FluidStack; 5 | import net.minecraftforge.fluids.FluidTankInfo; 6 | import net.minecraftforge.fluids.IFluidTank; 7 | 8 | public class ExtendedFluidTank implements IFluidTank { 9 | 10 | private FluidStack fluid; 11 | private boolean changeType; 12 | private int capacity; 13 | 14 | public ExtendedFluidTank(FluidStack type, int capacity) { 15 | if (type == null) { 16 | type = FluidUtils.water; 17 | changeType = true; 18 | } 19 | 20 | fluid = FluidUtils.copy(type, 0); 21 | this.capacity = capacity; 22 | } 23 | 24 | public ExtendedFluidTank(int capacity) { 25 | this(null, capacity); 26 | } 27 | 28 | @Override 29 | public FluidStack getFluid() { 30 | return fluid.copy(); 31 | } 32 | 33 | @Override 34 | public int getCapacity() { 35 | return capacity; 36 | } 37 | 38 | public boolean canAccept(FluidStack type) { 39 | return type == null || (fluid.amount == 0 && changeType) || fluid.isFluidEqual(type); 40 | } 41 | 42 | @Override 43 | public int fill(FluidStack resource, boolean doFill) { 44 | if (resource == null) return 0; 45 | 46 | if (!canAccept(resource)) return 0; 47 | 48 | int tofill = Math.min(getCapacity() - fluid.amount, resource.amount); 49 | if (doFill && tofill > 0) { 50 | if (!fluid.isFluidEqual(resource)) fluid = FluidUtils.copy(resource, fluid.amount + tofill); 51 | else fluid.amount += tofill; 52 | onLiquidChanged(); 53 | } 54 | 55 | return tofill; 56 | } 57 | 58 | @Override 59 | public FluidStack drain(int maxDrain, boolean doDrain) { 60 | if (fluid.amount == 0 || maxDrain <= 0) return null; 61 | 62 | int todrain = Math.min(maxDrain, fluid.amount); 63 | if (doDrain && todrain > 0) { 64 | fluid.amount -= todrain; 65 | onLiquidChanged(); 66 | } 67 | return FluidUtils.copy(fluid, todrain); 68 | } 69 | 70 | public FluidStack drain(FluidStack resource, boolean doDrain) { 71 | if (resource == null || !resource.isFluidEqual(fluid)) return null; 72 | 73 | return drain(resource.amount, doDrain); 74 | } 75 | 76 | public void onLiquidChanged() {} 77 | 78 | public void fromTag(NBTTagCompound tag) { 79 | fluid = FluidUtils.read(tag); 80 | } 81 | 82 | public NBTTagCompound toTag() { 83 | return FluidUtils.write(fluid, new NBTTagCompound()); 84 | } 85 | 86 | @Override 87 | public int getFluidAmount() { 88 | return fluid.amount; 89 | } 90 | 91 | @Override 92 | public FluidTankInfo getInfo() { 93 | return new FluidTankInfo(this); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/fluid/FluidUtils.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.fluid; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.nbt.NBTTagCompound; 6 | import net.minecraftforge.common.util.ForgeDirection; 7 | import net.minecraftforge.fluids.Fluid; 8 | import net.minecraftforge.fluids.FluidContainerRegistry; 9 | import net.minecraftforge.fluids.FluidRegistry; 10 | import net.minecraftforge.fluids.FluidStack; 11 | import net.minecraftforge.fluids.IFluidHandler; 12 | 13 | import codechicken.lib.inventory.InventoryUtils; 14 | 15 | public class FluidUtils { 16 | 17 | public static int B = FluidContainerRegistry.BUCKET_VOLUME; 18 | public static FluidStack water = new FluidStack(FluidRegistry.WATER, 1000); 19 | public static FluidStack lava = new FluidStack(FluidRegistry.LAVA, 1000); 20 | 21 | public static boolean fillTankWithContainer(IFluidHandler tank, EntityPlayer player) { 22 | ItemStack stack = player.getCurrentEquippedItem(); 23 | FluidStack liquid = FluidContainerRegistry.getFluidForFilledItem(stack); 24 | 25 | if (liquid == null) return false; 26 | 27 | if (tank.fill(ForgeDirection.UNKNOWN, liquid, false) != liquid.amount && !player.capabilities.isCreativeMode) 28 | return false; 29 | 30 | tank.fill(ForgeDirection.UNKNOWN, liquid, true); 31 | 32 | if (!player.capabilities.isCreativeMode) 33 | InventoryUtils.consumeItem(player.inventory, player.inventory.currentItem); 34 | 35 | player.inventoryContainer.detectAndSendChanges(); 36 | return true; 37 | } 38 | 39 | public static boolean emptyTankIntoContainer(IFluidHandler tank, EntityPlayer player, FluidStack tankLiquid) { 40 | ItemStack stack = player.getCurrentEquippedItem(); 41 | 42 | if (!FluidContainerRegistry.isEmptyContainer(stack)) return false; 43 | 44 | ItemStack filled = FluidContainerRegistry.fillFluidContainer(tankLiquid, stack); 45 | FluidStack liquid = FluidContainerRegistry.getFluidForFilledItem(filled); 46 | 47 | if (liquid == null || filled == null) return false; 48 | 49 | tank.drain(ForgeDirection.UNKNOWN, liquid.amount, true); 50 | 51 | if (!player.capabilities.isCreativeMode) { 52 | if (stack.stackSize == 1) player.inventory.setInventorySlotContents(player.inventory.currentItem, filled); 53 | else if (player.inventory.addItemStackToInventory(filled)) stack.stackSize--; 54 | else return false; 55 | } 56 | 57 | player.inventoryContainer.detectAndSendChanges(); 58 | return true; 59 | } 60 | 61 | public static FluidStack copy(FluidStack liquid, int quantity) { 62 | liquid = liquid.copy(); 63 | liquid.amount = quantity; 64 | return liquid; 65 | } 66 | 67 | public static FluidStack read(NBTTagCompound tag) { 68 | FluidStack stack = FluidStack.loadFluidStackFromNBT(tag); 69 | return stack != null ? stack : FluidUtils.emptyFluid(); 70 | } 71 | 72 | public static NBTTagCompound write(FluidStack fluid, NBTTagCompound tag) { 73 | return fluid == null || fluid.getFluid() == null ? new NBTTagCompound() 74 | : fluid.writeToNBT(new NBTTagCompound()); 75 | } 76 | 77 | public static int getLuminosity(FluidStack stack, double density) { 78 | Fluid fluid = stack.getFluid(); 79 | if (fluid == null) return 0; 80 | int light = fluid.getLuminosity(stack); 81 | if (fluid.isGaseous()) light = (int) (light * density); 82 | return light; 83 | } 84 | 85 | public static FluidStack emptyFluid() { 86 | return new FluidStack(water, 0); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/fluid/TankAccess.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.fluid; 2 | 3 | import net.minecraftforge.common.util.ForgeDirection; 4 | import net.minecraftforge.fluids.FluidStack; 5 | import net.minecraftforge.fluids.IFluidHandler; 6 | 7 | public class TankAccess { 8 | 9 | public IFluidHandler tank; 10 | public ForgeDirection side; 11 | 12 | public TankAccess(IFluidHandler tank, ForgeDirection side) { 13 | this.tank = tank; 14 | this.side = side; 15 | } 16 | 17 | public TankAccess(IFluidHandler tank, int side) { 18 | this(tank, ForgeDirection.getOrientation(side)); 19 | } 20 | 21 | public int fill(FluidStack resource, boolean doFill) { 22 | return tank.fill(side, resource, doFill); 23 | } 24 | 25 | public FluidStack drain(int maxDrain, boolean doDrain) { 26 | return tank.drain(side, maxDrain, doDrain); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/gui/ClickCounter.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.gui; 2 | 3 | import java.util.Map; 4 | import java.util.TreeMap; 5 | 6 | import com.google.common.base.Objects; 7 | 8 | public class ClickCounter { 9 | 10 | public class ClickCount { 11 | 12 | public T clicked; 13 | public long time; 14 | public int count; 15 | 16 | public boolean update(T clicked) { 17 | if (!Objects.equal(this.clicked, clicked)) { 18 | this.clicked = clicked; 19 | count = 0; 20 | time = Long.MIN_VALUE; 21 | return false; 22 | } 23 | return true; 24 | } 25 | } 26 | 27 | public Map buttons = new TreeMap(); 28 | 29 | public ClickCount getCount(int button) { 30 | ClickCount c = buttons.get(button); 31 | if (c == null) buttons.put(button, c = new ClickCount()); 32 | return c; 33 | } 34 | 35 | public void mouseDown(T clicked, int button) { 36 | ClickCount c = getCount(button); 37 | c.update(clicked); 38 | } 39 | 40 | public int mouseUp(T clicked, int button) { 41 | ClickCount c = getCount(button); 42 | if (!c.update(clicked)) return 0; 43 | 44 | long time = System.currentTimeMillis(); 45 | if (time - c.time < 500) c.count++; 46 | else c.count = 1; 47 | c.time = time; 48 | return c.count; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/gui/GuiCCButton.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.gui; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.audio.PositionedSoundRecord; 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | import org.lwjgl.opengl.GL11; 8 | 9 | public class GuiCCButton extends GuiWidget { 10 | 11 | public String text; 12 | public String actionCommand; 13 | private boolean isEnabled = true; 14 | public boolean visible = true; 15 | 16 | public GuiCCButton(int x, int y, int width, int height, String text) { 17 | super(x, y, width, height); 18 | this.text = text; 19 | } 20 | 21 | public void setText(String s) { 22 | text = s; 23 | } 24 | 25 | public boolean isEnabled() { 26 | return isEnabled; 27 | } 28 | 29 | public void setEnabled(boolean b) { 30 | isEnabled = b; 31 | } 32 | 33 | @Override 34 | public void mouseClicked(int x, int y, int button) { 35 | if (isEnabled && pointInside(x, y) && actionCommand != null) { 36 | sendAction(actionCommand, button); 37 | Minecraft.getMinecraft().getSoundHandler() 38 | .playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F)); 39 | } 40 | } 41 | 42 | @Override 43 | public void draw(int mousex, int mousey, float frame) { 44 | if (!visible) return; 45 | 46 | drawButtonTex(mousex, mousey); 47 | if (text != null) drawText(mousex, mousey); 48 | } 49 | 50 | public void drawButtonTex(int mousex, int mousey) { 51 | GL11.glColor4f(1, 1, 1, 1); 52 | renderEngine.bindTexture(guiTex); 53 | int state = getButtonTex(mousex, mousey); 54 | drawTexturedModalRect(x, y, 0, 46 + state * 20, width / 2, height / 2); // top left 55 | drawTexturedModalRect(x + width / 2, y, 200 - width / 2, 46 + state * 20, width / 2, height / 2); // top right 56 | drawTexturedModalRect(x, y + height / 2, 0, 46 + state * 20 + 20 - height / 2, width / 2, height / 2); // bottom 57 | // left 58 | drawTexturedModalRect( 59 | x + width / 2, 60 | y + height / 2, 61 | 200 - width / 2, 62 | 46 + state * 20 + 20 - height / 2, 63 | width / 2, 64 | height / 2); // bottom right 65 | } 66 | 67 | public int getButtonTex(int mousex, int mousey) { 68 | return !isEnabled ? 0 : pointInside(mousex, mousey) ? 2 : 1; 69 | } 70 | 71 | public void drawText(int mousex, int mousey) { 72 | drawCenteredString(fontRenderer, text, x + width / 2, y + (height - 8) / 2, getTextColour(mousex, mousey)); 73 | } 74 | 75 | public int getTextColour(int mousex, int mousey) { 76 | return !isEnabled ? 0xFFA0A0A0 : pointInside(mousex, mousey) ? 0xFFFFFFA0 : 0xFFE0E0E0; 77 | } 78 | 79 | public GuiCCButton setActionCommand(String string) { 80 | actionCommand = string; 81 | return this; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/gui/GuiScreenWidget.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.gui; 2 | 3 | import java.awt.Point; 4 | import java.util.ArrayList; 5 | 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.GuiScreen; 8 | 9 | import org.lwjgl.input.Mouse; 10 | import org.lwjgl.opengl.GL11; 11 | 12 | import codechicken.lib.gui.GuiDraw; 13 | 14 | public class GuiScreenWidget extends GuiScreen implements IGuiActionListener { 15 | 16 | public ArrayList widgets = new ArrayList(); 17 | public int xSize, ySize, guiTop, guiLeft; 18 | 19 | public GuiScreenWidget() { 20 | this(176, 166); 21 | } 22 | 23 | public GuiScreenWidget(int xSize, int ySize) { 24 | super(); 25 | this.xSize = xSize; 26 | this.ySize = ySize; 27 | } 28 | 29 | @Override 30 | public void initGui() { 31 | guiTop = (height - ySize) / 2; 32 | guiLeft = (width - xSize) / 2; 33 | if (!widgets.isEmpty()) resize(); 34 | } 35 | 36 | public void reset() { 37 | widgets.clear(); 38 | initGui(); 39 | addWidgets(); 40 | resize(); 41 | } 42 | 43 | @Override 44 | public void setWorldAndResolution(Minecraft mc, int i, int j) { 45 | boolean init = this.mc == null; 46 | super.setWorldAndResolution(mc, i, j); 47 | if (init) { 48 | addWidgets(); 49 | resize(); 50 | } 51 | } 52 | 53 | public void add(GuiWidget widget) { 54 | widgets.add(widget); 55 | widget.onAdded(this); 56 | } 57 | 58 | @Override 59 | public void drawScreen(int mousex, int mousey, float f) { 60 | GL11.glTranslated(guiLeft, guiTop, 0); 61 | drawBackground(); 62 | for (GuiWidget widget : widgets) widget.draw(mousex - guiLeft, mousey - guiTop, f); 63 | drawForeground(); 64 | GL11.glTranslated(-guiLeft, -guiTop, 0); 65 | } 66 | 67 | public void drawBackground() {} 68 | 69 | public void drawForeground() {} 70 | 71 | @Override 72 | protected void mouseClicked(int x, int y, int button) { 73 | super.mouseClicked(x, y, button); 74 | for (GuiWidget widget : widgets) widget.mouseClicked(x - guiLeft, y - guiTop, button); 75 | } 76 | 77 | @Override 78 | protected void mouseMovedOrUp(int x, int y, int button) { 79 | super.mouseMovedOrUp(x, y, button); 80 | for (GuiWidget widget : widgets) widget.mouseMovedOrUp(x - guiLeft, y - guiTop, button); 81 | } 82 | 83 | @Override 84 | protected void mouseClickMove(int x, int y, int button, long time) { 85 | super.mouseClickMove(x, y, button, time); 86 | for (GuiWidget widget : widgets) widget.mouseDragged(x - guiLeft, y - guiTop, button, time); 87 | } 88 | 89 | @Override 90 | public void updateScreen() { 91 | super.updateScreen(); 92 | if (mc.currentScreen == this) for (GuiWidget widget : widgets) widget.update(); 93 | } 94 | 95 | @Override 96 | public void keyTyped(char c, int keycode) { 97 | super.keyTyped(c, keycode); 98 | for (GuiWidget widget : widgets) widget.keyTyped(c, keycode); 99 | } 100 | 101 | @Override 102 | public void handleMouseInput() { 103 | super.handleMouseInput(); 104 | int i = Mouse.getEventDWheel(); 105 | if (i != 0) { 106 | Point p = GuiDraw.getMousePosition(); 107 | int scroll = i > 0 ? 1 : -1; 108 | for (GuiWidget widget : widgets) widget.mouseScrolled(p.x, p.y, scroll); 109 | } 110 | } 111 | 112 | @Override 113 | public void actionPerformed(String ident, Object... params) {} 114 | 115 | public void resize() {} 116 | 117 | public void addWidgets() {} 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/gui/GuiWidget.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.gui; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.FontRenderer; 5 | import net.minecraft.client.gui.Gui; 6 | import net.minecraft.client.gui.GuiScreen; 7 | import net.minecraft.client.renderer.texture.TextureManager; 8 | import net.minecraft.util.ResourceLocation; 9 | 10 | public class GuiWidget extends Gui { 11 | 12 | protected static final ResourceLocation guiTex = new ResourceLocation("textures/gui/widgets.png"); 13 | 14 | public GuiScreen parentScreen; 15 | public TextureManager renderEngine; 16 | public FontRenderer fontRenderer; 17 | 18 | public int x; 19 | public int y; 20 | public int width; 21 | public int height; 22 | 23 | public GuiWidget(int x, int y, int width, int height) { 24 | setSize(x, y, width, height); 25 | } 26 | 27 | public void setSize(int x, int y, int width, int height) { 28 | this.x = x; 29 | this.y = y; 30 | this.width = width; 31 | this.height = height; 32 | } 33 | 34 | public boolean pointInside(int px, int py) { 35 | return px >= x && px < x + width && py >= y && py < y + height; 36 | } 37 | 38 | public void sendAction(String actionCommand, Object... params) { 39 | sendAction(parentScreen, actionCommand, params); 40 | } 41 | 42 | public static void sendAction(GuiScreen screen, String actionCommand, Object... params) { 43 | if (actionCommand != null && screen instanceof IGuiActionListener) 44 | ((IGuiActionListener) screen).actionPerformed(actionCommand, params); 45 | } 46 | 47 | public void mouseClicked(int x, int y, int button) {} 48 | 49 | public void mouseMovedOrUp(int x, int y, int button) {} 50 | 51 | public void mouseDragged(int x, int y, int button, long time) {} 52 | 53 | public void update() {} 54 | 55 | public void draw(int mousex, int mousey, float frame) {} 56 | 57 | public void keyTyped(char c, int keycode) {} 58 | 59 | public void mouseScrolled(int x, int y, int scroll) {} 60 | 61 | public void onAdded(GuiScreen s) { 62 | Minecraft mc = Minecraft.getMinecraft(); 63 | parentScreen = s; 64 | renderEngine = mc.renderEngine; 65 | fontRenderer = mc.fontRenderer; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/gui/IGuiActionListener.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.gui; 2 | 3 | public interface IGuiActionListener { 4 | 5 | public void actionPerformed(String actionCommand, Object... params); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/internal/CCCEventHandler.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.internal; 2 | 3 | import net.minecraftforge.client.event.GuiScreenEvent; 4 | 5 | import codechicken.core.GuiModListScroll; 6 | import cpw.mods.fml.client.GuiModList; 7 | import cpw.mods.fml.common.eventhandler.SubscribeEvent; 8 | import cpw.mods.fml.common.gameevent.TickEvent; 9 | import cpw.mods.fml.common.gameevent.TickEvent.Phase; 10 | import cpw.mods.fml.relauncher.Side; 11 | import cpw.mods.fml.relauncher.SideOnly; 12 | 13 | public class CCCEventHandler { 14 | 15 | public static int renderTime; 16 | public static float renderFrame; 17 | 18 | @SubscribeEvent 19 | public void clientTick(TickEvent.ClientTickEvent event) { 20 | if (event.phase == Phase.END) { 21 | renderTime++; 22 | } 23 | } 24 | 25 | @SubscribeEvent 26 | public void renderTick(TickEvent.RenderTickEvent event) { 27 | if (event.phase == Phase.START) renderFrame = event.renderTickTime; 28 | } 29 | 30 | @SubscribeEvent 31 | @SideOnly(Side.CLIENT) 32 | public void posGuiRender(GuiScreenEvent.DrawScreenEvent.Post event) { 33 | if (event.gui instanceof GuiModList) GuiModListScroll.draw((GuiModList) event.gui, event.mouseX, event.mouseY); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/codechicken/core/inventory/GuiContainerWidget.java: -------------------------------------------------------------------------------- 1 | package codechicken.core.inventory; 2 | 3 | import java.awt.Point; 4 | import java.util.ArrayList; 5 | 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.inventory.GuiContainer; 8 | import net.minecraft.inventory.Container; 9 | 10 | import org.lwjgl.input.Mouse; 11 | import org.lwjgl.opengl.GL11; 12 | 13 | import codechicken.core.gui.GuiWidget; 14 | import codechicken.core.gui.IGuiActionListener; 15 | import codechicken.lib.gui.GuiDraw; 16 | 17 | public class GuiContainerWidget extends GuiContainer implements IGuiActionListener { 18 | 19 | public ArrayList widgets = new ArrayList(); 20 | 21 | public GuiContainerWidget(Container inventorySlots) { 22 | this(inventorySlots, 176, 166); 23 | } 24 | 25 | public GuiContainerWidget(Container inventorySlots, int xSize, int ySize) { 26 | super(inventorySlots); 27 | this.xSize = xSize; 28 | this.ySize = ySize; 29 | } 30 | 31 | @Override 32 | public void setWorldAndResolution(Minecraft mc, int i, int j) { 33 | super.setWorldAndResolution(mc, i, j); 34 | if (widgets.isEmpty()) addWidgets(); 35 | } 36 | 37 | public void add(GuiWidget widget) { 38 | widgets.add(widget); 39 | widget.onAdded(this); 40 | } 41 | 42 | @Override 43 | protected void drawGuiContainerBackgroundLayer(float f, int mousex, int mousey) { 44 | GL11.glTranslated(guiLeft, guiTop, 0); 45 | drawBackground(); 46 | for (GuiWidget widget : widgets) widget.draw(mousex - guiLeft, mousey - guiTop, f); 47 | 48 | GL11.glTranslated(-guiLeft, -guiTop, 0); 49 | } 50 | 51 | public void drawBackground() {} 52 | 53 | @Override 54 | protected void mouseClicked(int x, int y, int button) { 55 | super.mouseClicked(x, y, button); 56 | for (GuiWidget widget : widgets) widget.mouseClicked(x - guiLeft, y - guiTop, button); 57 | } 58 | 59 | @Override 60 | protected void mouseMovedOrUp(int x, int y, int button) { 61 | super.mouseMovedOrUp(x, y, button); 62 | for (GuiWidget widget : widgets) widget.mouseMovedOrUp(x - guiLeft, y - guiTop, button); 63 | } 64 | 65 | @Override 66 | protected void mouseClickMove(int x, int y, int button, long time) { 67 | super.mouseClickMove(x, y, button, time); 68 | for (GuiWidget widget : widgets) widget.mouseDragged(x - guiLeft, y - guiTop, button, time); 69 | } 70 | 71 | @Override 72 | public void updateScreen() { 73 | super.updateScreen(); 74 | if (mc.currentScreen == this) for (GuiWidget widget : widgets) widget.update(); 75 | } 76 | 77 | @Override 78 | public void keyTyped(char c, int keycode) { 79 | super.keyTyped(c, keycode); 80 | for (GuiWidget widget : widgets) widget.keyTyped(c, keycode); 81 | } 82 | 83 | @Override 84 | public void handleMouseInput() { 85 | super.handleMouseInput(); 86 | int i = Mouse.getEventDWheel(); 87 | if (i != 0) { 88 | Point p = GuiDraw.getMousePosition(); 89 | int scroll = i > 0 ? 1 : -1; 90 | for (GuiWidget widget : widgets) widget.mouseScrolled(p.x, p.y, scroll); 91 | } 92 | } 93 | 94 | @Override 95 | public void actionPerformed(String ident, Object... params) {} 96 | 97 | public void addWidgets() {} 98 | 99 | @Override 100 | public void onGuiClosed() { 101 | super.onGuiClosed(); 102 | widgets.clear(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/asm/ASMInit.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.asm; 2 | 3 | import net.minecraft.launchwrapper.Launch; 4 | 5 | /** 6 | * Initialisation class for using this package. Call this on coremod load 7 | */ 8 | public class ASMInit { 9 | 10 | private static boolean initialised = false; 11 | 12 | public static void init() { 13 | if (!initialised) { 14 | Launch.classLoader.addTransformerExclusion("codechicken.lib.asm"); 15 | Launch.classLoader.addTransformerExclusion("codechicken.lib.config"); 16 | initialised = true; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/asm/CC_ClassWriter.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.asm; 2 | 3 | import org.objectweb.asm.ClassWriter; 4 | 5 | public class CC_ClassWriter extends ClassWriter { 6 | 7 | private final boolean runtime; 8 | 9 | public CC_ClassWriter(int flags) { 10 | this(flags, false); 11 | } 12 | 13 | public CC_ClassWriter(int flags, boolean runtime) { 14 | super(flags); 15 | this.runtime = runtime; 16 | } 17 | 18 | @Override 19 | protected String getCommonSuperClass(String type1, String type2) { 20 | String c = type1.replace('/', '.'); 21 | String d = type2.replace('/', '.'); 22 | if (ClassHeirachyManager.classExtends(d, c)) return type1; 23 | if (ClassHeirachyManager.classExtends(c, d)) return type2; 24 | do { 25 | c = ClassHeirachyManager.getSuperClass(c, runtime); 26 | } while (!ClassHeirachyManager.classExtends(d, c)); 27 | return c.replace('.', '/'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/asm/ImportantInsnVisitor.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.asm; 2 | 3 | import org.objectweb.asm.ClassVisitor; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | import org.objectweb.asm.tree.MethodNode; 7 | 8 | public class ImportantInsnVisitor extends ClassVisitor { 9 | 10 | public class ImportantInsnMethodVisitor extends MethodVisitor { 11 | 12 | MethodVisitor delegate; 13 | 14 | public ImportantInsnMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) { 15 | super(Opcodes.ASM4, new MethodNode(access, name, desc, signature, exceptions)); 16 | delegate = cv.visitMethod(access, name, desc, signature, exceptions); 17 | } 18 | 19 | @Override 20 | public void visitEnd() { 21 | super.visitEnd(); 22 | MethodNode mnode = (MethodNode) mv; 23 | mnode.instructions = InsnComparator.getImportantList(mnode.instructions); 24 | mnode.accept(delegate); 25 | } 26 | } 27 | 28 | public ImportantInsnVisitor(ClassVisitor cv) { 29 | super(Opcodes.ASM4, cv); 30 | } 31 | 32 | @Override 33 | public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { 34 | return new ImportantInsnMethodVisitor(access, name, desc, signature, exceptions); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/asm/LocalVariablesSorterVisitor.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.asm; 2 | 3 | import java.util.Set; 4 | 5 | import org.objectweb.asm.ClassVisitor; 6 | import org.objectweb.asm.MethodVisitor; 7 | import org.objectweb.asm.Opcodes; 8 | import org.objectweb.asm.commons.LocalVariablesSorter; 9 | 10 | public class LocalVariablesSorterVisitor extends ClassVisitor { 11 | 12 | public Set methods; 13 | public String owner; 14 | 15 | public LocalVariablesSorterVisitor(Set methods, ClassVisitor cv) { 16 | super(Opcodes.ASM4, cv); 17 | this.methods = methods; 18 | } 19 | 20 | public LocalVariablesSorterVisitor(ClassVisitor cv) { 21 | this(null, cv); 22 | } 23 | 24 | @Override 25 | public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { 26 | super.visit(version, access, name, signature, superName, interfaces); 27 | owner = name; 28 | } 29 | 30 | @Override 31 | public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { 32 | MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); 33 | return methods == null || methods.contains(new ObfMapping(owner, name, desc)) 34 | ? new LocalVariablesSorter(access, desc, mv) 35 | : mv; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/colour/ColourARGB.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.colour; 2 | 3 | public class ColourARGB extends Colour { 4 | 5 | public ColourARGB(int colour) { 6 | super((colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF, (colour >> 24) & 0xFF); 7 | } 8 | 9 | public ColourARGB(int a, int r, int g, int b) { 10 | super(r, g, b, a); 11 | } 12 | 13 | public ColourARGB(ColourARGB colour) { 14 | super(colour); 15 | } 16 | 17 | public ColourARGB copy() { 18 | return new ColourARGB(this); 19 | } 20 | 21 | public int pack() { 22 | return pack(this); 23 | } 24 | 25 | public static int pack(Colour colour) { 26 | return (colour.a & 0xFF) << 24 | (colour.r & 0xFF) << 16 | (colour.g & 0xFF) << 8 | (colour.b & 0xFF); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/colour/ColourRGBA.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.colour; 2 | 3 | public class ColourRGBA extends Colour { 4 | 5 | public ColourRGBA(int colour) { 6 | super((colour >> 24) & 0xFF, (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF); 7 | } 8 | 9 | public ColourRGBA(double r, double g, double b, double a) { 10 | super((int) (255 * r), (int) (255 * g), (int) (255 * b), (int) (255 * a)); 11 | } 12 | 13 | public ColourRGBA(int r, int g, int b, int a) { 14 | super(r, g, b, a); 15 | } 16 | 17 | public ColourRGBA(ColourRGBA colour) { 18 | super(colour); 19 | } 20 | 21 | public int pack() { 22 | return pack(this); 23 | } 24 | 25 | @Override 26 | public Colour copy() { 27 | return new ColourRGBA(this); 28 | } 29 | 30 | public static int pack(Colour colour) { 31 | return (colour.r & 0xFF) << 24 | (colour.g & 0xFF) << 16 | (colour.b & 0xFF) << 8 | (colour.a & 0xFF); 32 | } 33 | 34 | public static int multiply(int c1, int c2) { 35 | if (c1 == -1) return c2; 36 | if (c2 == -1) return c1; 37 | int r = (((c1 >>> 24) * (c2 >>> 24)) & 0xFF00) << 16; 38 | int g = (((c1 >> 16 & 0xFF) * (c2 >> 16 & 0xFF)) & 0xFF00) << 8; 39 | int b = ((c1 >> 8 & 0xFF) * (c2 >> 8 & 0xFF)) & 0xFF00; 40 | int a = ((c1 & 0xFF) * (c2 & 0xFF)) >> 8; 41 | return r | g | b | a; 42 | } 43 | 44 | public static int multiplyC(int c, float f) { 45 | int r = (int) ((c >>> 24) * f); 46 | int g = (int) ((c >> 16 & 0xFF) * f); 47 | int b = (int) ((c >> 8 & 0xFF) * f); 48 | return r << 24 | g << 16 | b << 8 | c & 0xFF; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/colour/CustomGradient.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.colour; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | import codechicken.lib.math.MathHelper; 8 | import codechicken.lib.render.TextureUtils; 9 | 10 | public class CustomGradient { 11 | 12 | public int[] gradient; 13 | 14 | public CustomGradient(ResourceLocation textureFile) { 15 | BufferedImage img = TextureUtils.loadBufferedImage(textureFile); 16 | if (img == null) throw new RuntimeException("File not found: " + textureFile.toString()); 17 | 18 | int[] data = new int[img.getWidth()]; 19 | img.getRGB(0, 0, img.getWidth(), 1, data, 0, img.getWidth()); 20 | gradient = new int[img.getWidth()]; 21 | for (int i = 0; i < data.length; i++) gradient[i] = (data[i] << 8) | (((data[i]) >> 24) & 0xFF); 22 | } 23 | 24 | public ColourRGBA getColour(double position) { 25 | return new ColourRGBA(getColourI(position)); 26 | } 27 | 28 | public int getColourI(double position) { 29 | int off = (int) MathHelper.clip(gradient.length * position, 0, gradient.length - 1); 30 | return gradient[off]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/config/ConfigFile.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.config; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileReader; 7 | import java.io.IOException; 8 | import java.io.PrintWriter; 9 | 10 | public class ConfigFile extends ConfigTagParent { 11 | 12 | public static final byte[] crlf = new byte[] { 0xD, 0xA }; 13 | 14 | public File file; 15 | private boolean loading; 16 | 17 | public ConfigFile(File file) { 18 | newlinemode = 2; 19 | load(file); 20 | } 21 | 22 | protected ConfigFile() {} 23 | 24 | protected void load(File file) { 25 | try { 26 | if (!file.getParentFile().exists()) file.getParentFile().mkdirs(); 27 | if (!file.exists()) file.createNewFile(); 28 | } catch (IOException e) { 29 | throw new RuntimeException(e); 30 | } 31 | this.file = file; 32 | loadConfig(); 33 | } 34 | 35 | protected void loadConfig() { 36 | loading = true; 37 | BufferedReader reader; 38 | try { 39 | reader = new BufferedReader(new FileReader(file)); 40 | 41 | while (true) { 42 | reader.mark(2000); 43 | String line = reader.readLine(); 44 | if (line != null && line.startsWith("#")) { 45 | if (comment == null || comment.equals("")) comment = line.substring(1); 46 | else comment = comment + "\n" + line.substring(1); 47 | } else { 48 | reader.reset(); 49 | break; 50 | } 51 | } 52 | loadChildren(reader); 53 | reader.close(); 54 | 55 | } catch (IOException e) { 56 | throw new RuntimeException(e); 57 | } 58 | 59 | loading = false; 60 | } 61 | 62 | @Override 63 | public ConfigFile setComment(String header) { 64 | super.setComment(header); 65 | return this; 66 | } 67 | 68 | @Override 69 | public ConfigFile setSortMode(int mode) { 70 | super.setSortMode(mode); 71 | return this; 72 | } 73 | 74 | @Override 75 | public String getNameQualifier() { 76 | return ""; 77 | } 78 | 79 | public static String readLine(BufferedReader reader) throws IOException { 80 | String line = reader.readLine(); 81 | return line == null ? null : line.replace("\t", ""); 82 | } 83 | 84 | public static void writeLine(PrintWriter writer, String line, int tabs) { 85 | for (int i = 0; i < tabs; i++) writer.print('\t'); 86 | 87 | writer.println(line); 88 | } 89 | 90 | public void saveConfig() { 91 | if (loading) return; 92 | 93 | PrintWriter writer; 94 | try { 95 | writer = new PrintWriter(file); 96 | } catch (FileNotFoundException e) { 97 | throw new RuntimeException(e); 98 | } 99 | 100 | writeComment(writer, 0); 101 | ConfigFile.writeLine(writer, "", 0); 102 | saveTagTree(writer, 0, ""); 103 | writer.flush(); 104 | writer.close(); 105 | } 106 | 107 | public boolean isLoading() { 108 | return loading; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/config/DefaultingConfigFile.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.config; 2 | 3 | import java.io.File; 4 | 5 | public class DefaultingConfigFile extends ConfigFile { 6 | 7 | public DefaultingConfigFile(File file) { 8 | super(); 9 | if (file.exists()) load(file); 10 | } 11 | 12 | @Override 13 | public void saveConfig() { 14 | if (file != null) super.saveConfig(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/config/SimpleProperties.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.config; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.InputStreamReader; 7 | import java.io.PrintStream; 8 | import java.nio.charset.Charset; 9 | import java.util.HashMap; 10 | import java.util.Map.Entry; 11 | 12 | public class SimpleProperties { 13 | 14 | public HashMap propertyMap = new HashMap(); 15 | public File propertyFile; 16 | public boolean saveOnChange = false; 17 | public String encoding; 18 | 19 | private boolean loading = false; 20 | 21 | public SimpleProperties(File file, boolean saveOnChange, String encoding) { 22 | propertyFile = file; 23 | this.saveOnChange = saveOnChange; 24 | this.encoding = encoding; 25 | } 26 | 27 | public SimpleProperties(File file, boolean saveOnChange) { 28 | this(file, saveOnChange, Charset.defaultCharset().name()); 29 | } 30 | 31 | public SimpleProperties(File file) { 32 | this(file, true); 33 | } 34 | 35 | public void load() { 36 | clear(); 37 | loading = true; 38 | 39 | try { 40 | BufferedReader reader = new BufferedReader( 41 | new InputStreamReader(new FileInputStream(propertyFile), encoding)); 42 | while (true) { 43 | String read = reader.readLine(); 44 | if (read == null) break; 45 | 46 | int equalIndex = read.indexOf('='); 47 | if (equalIndex == -1) continue; 48 | 49 | setProperty(read.substring(0, equalIndex), read.substring(equalIndex + 1)); 50 | } 51 | reader.close(); 52 | } catch (Exception e) { 53 | throw new RuntimeException(e); 54 | } 55 | loading = false; 56 | } 57 | 58 | public void save() { 59 | try { 60 | PrintStream writer = new PrintStream(propertyFile); 61 | 62 | for (Entry entry : propertyMap.entrySet()) { 63 | writer.println(entry.getKey() + "=" + entry.getValue()); 64 | } 65 | 66 | writer.close(); 67 | } catch (Exception e) { 68 | throw new RuntimeException(e); 69 | } 70 | } 71 | 72 | public void clear() { 73 | propertyMap.clear(); 74 | } 75 | 76 | public boolean hasProperty(String key) { 77 | return propertyMap.containsKey(key); 78 | } 79 | 80 | public void removeProperty(String key) { 81 | if (propertyMap.remove(key) != null && saveOnChange && !loading) save(); 82 | } 83 | 84 | public void setProperty(String key, int value) { 85 | setProperty(key, Integer.toString(value)); 86 | } 87 | 88 | public void setProperty(String key, boolean value) { 89 | setProperty(key, Boolean.toString(value)); 90 | } 91 | 92 | public void setProperty(String key, String value) { 93 | propertyMap.put(key, value); 94 | if (saveOnChange && !loading) save(); 95 | } 96 | 97 | public int getProperty(String property, int defaultvalue) { 98 | try { 99 | return Integer.parseInt(getProperty(property, Integer.toString(defaultvalue))); 100 | } catch (NumberFormatException nfe) { 101 | return defaultvalue; 102 | } 103 | } 104 | 105 | public boolean getProperty(String property, boolean defaultvalue) { 106 | try { 107 | return Boolean.parseBoolean(getProperty(property, Boolean.toString(defaultvalue))); 108 | } catch (NumberFormatException nfe) { 109 | return defaultvalue; 110 | } 111 | } 112 | 113 | public String getProperty(String property, String defaultvalue) { 114 | String value = propertyMap.get(property); 115 | if (value == null) { 116 | setProperty(property, defaultvalue); 117 | return defaultvalue; 118 | } 119 | return value; 120 | } 121 | 122 | public String getProperty(String property) { 123 | return propertyMap.get(property); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/data/MCDataInput.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.data; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | import net.minecraftforge.fluids.FluidStack; 6 | 7 | import codechicken.lib.vec.BlockCoord; 8 | 9 | public interface MCDataInput { 10 | 11 | public long readLong(); 12 | 13 | public int readInt(); 14 | 15 | public short readShort(); 16 | 17 | public int readUShort(); 18 | 19 | public byte readByte(); 20 | 21 | public short readUByte(); 22 | 23 | public double readDouble(); 24 | 25 | public float readFloat(); 26 | 27 | public boolean readBoolean(); 28 | 29 | public char readChar(); 30 | 31 | public int readVarShort(); 32 | 33 | public int readVarInt(); 34 | 35 | public byte[] readByteArray(int length); 36 | 37 | public String readString(); 38 | 39 | public BlockCoord readCoord(); 40 | 41 | public NBTTagCompound readNBTTagCompound(); 42 | 43 | public ItemStack readItemStack(); 44 | 45 | public FluidStack readFluidStack(); 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/data/MCDataInputStream.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.data; 2 | 3 | import java.io.InputStream; 4 | 5 | public class MCDataInputStream extends InputStream { 6 | 7 | private MCDataInput in; 8 | 9 | public MCDataInputStream(MCDataInput in) { 10 | this.in = in; 11 | } 12 | 13 | @Override 14 | public int read() { 15 | return in.readByte() & 0xFF; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/data/MCDataOutput.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.data; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | import net.minecraftforge.fluids.FluidStack; 6 | 7 | import codechicken.lib.vec.BlockCoord; 8 | 9 | public interface MCDataOutput { 10 | 11 | public MCDataOutput writeLong(long l); 12 | 13 | public MCDataOutput writeInt(int i); 14 | 15 | public MCDataOutput writeShort(int s); 16 | 17 | public MCDataOutput writeByte(int b); 18 | 19 | public MCDataOutput writeDouble(double d); 20 | 21 | public MCDataOutput writeFloat(float f); 22 | 23 | public MCDataOutput writeBoolean(boolean b); 24 | 25 | public MCDataOutput writeChar(char c); 26 | 27 | public MCDataOutput writeVarInt(int i); 28 | 29 | public MCDataOutput writeVarShort(int s); 30 | 31 | public MCDataOutput writeByteArray(byte[] array); 32 | 33 | public MCDataOutput writeString(String s); 34 | 35 | public MCDataOutput writeCoord(int x, int y, int z); 36 | 37 | public MCDataOutput writeCoord(BlockCoord coord); 38 | 39 | public MCDataOutput writeNBTTagCompound(NBTTagCompound tag); 40 | 41 | public MCDataOutput writeItemStack(ItemStack stack); 42 | 43 | public MCDataOutput writeFluidStack(FluidStack liquid); 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/data/MCDataOutputStream.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.data; 2 | 3 | import java.io.OutputStream; 4 | 5 | public class MCDataOutputStream extends OutputStream { 6 | 7 | private MCDataOutput out; 8 | 9 | public MCDataOutputStream(MCDataOutput out) { 10 | this.out = out; 11 | } 12 | 13 | @Override 14 | public void write(int b) { 15 | out.writeByte(b); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/gui/Canvas9Seg.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.gui; 2 | 3 | import net.minecraft.client.renderer.Tessellator; 4 | import net.minecraft.util.ResourceLocation; 5 | 6 | import codechicken.lib.render.CCRenderState; 7 | import codechicken.lib.render.TextureDataHolder; 8 | import codechicken.lib.render.TextureUtils; 9 | 10 | public class Canvas9Seg { 11 | 12 | public final ResourceLocation tex; 13 | public float[] seg_u = new float[4]; 14 | public float[] seg_v = new float[4]; 15 | public int[] seg_w = new int[3]; 16 | public int[] seg_h = new int[3]; 17 | 18 | public Canvas9Seg(ResourceLocation tex) { 19 | this.tex = tex; 20 | load(); 21 | } 22 | 23 | private int[] readMarkers(TextureDataHolder data, int stride, int size) { 24 | int[] markers = new int[4]; 25 | 26 | int marker = 1; 27 | int prev_col = data.data[0]; 28 | for (int i = 1; i < size; i++) { 29 | if (data.data[i * stride] != prev_col) { 30 | markers[marker] = i; 31 | prev_col = data.data[i * stride]; 32 | if (++marker == 4) break; 33 | } 34 | } 35 | 36 | markers[0] += 1; 37 | markers[3] -= 1; 38 | return markers; 39 | } 40 | 41 | private void parseMarkers(TextureDataHolder data, int stride, int size, int[] sizes, float[] texcoords) { 42 | int[] markers = readMarkers(data, stride, size); 43 | for (int i = 0; i < 4; i++) { 44 | texcoords[i] = markers[i] / (float) size; 45 | if (i > 0) sizes[i - 1] = markers[i] - markers[i - 1]; 46 | } 47 | } 48 | 49 | private void load() { 50 | TextureDataHolder data = TextureUtils.loadTexture(tex); 51 | parseMarkers(data, 1, data.width, seg_w, seg_u); 52 | parseMarkers(data, data.width, data.height, seg_h, seg_v); 53 | } 54 | 55 | private void drawSeg(int[] sw, int[] sh, int seg) { 56 | Tessellator t = Tessellator.instance; 57 | int u = seg % 3; 58 | int v = seg / 3; 59 | t.addVertexWithUV(sw[u], sh[v], 0, seg_u[u], seg_v[v]); 60 | t.addVertexWithUV(sw[u], sh[v + 1], 0, seg_u[u], seg_v[v + 1]); 61 | t.addVertexWithUV(sw[u + 1], sh[v + 1], 0, seg_u[u + 1], seg_v[v + 1]); 62 | t.addVertexWithUV(sw[u + 1], sh[v], 0, seg_u[u + 1], seg_v[v]); 63 | } 64 | 65 | public void draw(CCRenderState state, int x, int y, int w, int h) { 66 | CCRenderState.changeTexture(tex); 67 | state.resetInstance(); 68 | state.startDrawingInstance(); 69 | 70 | int[] sw = new int[] { x, x + seg_w[0], x + w - seg_w[2], x + w }; 71 | int[] sh = new int[] { y, y + seg_h[0], y + h - seg_h[2], y + h }; 72 | 73 | for (int seg = 0; seg < 9; seg++) drawSeg(sw, sh, seg); 74 | 75 | state.drawInstance(); 76 | } 77 | 78 | public void draw(int x, int y, int w, int h) { 79 | draw(CCRenderState.instance(), x, y, w, h); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/ContainerSynchronised.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import net.minecraft.entity.player.EntityPlayerMP; 8 | import net.minecraft.inventory.Container; 9 | import net.minecraft.item.ItemStack; 10 | 11 | import codechicken.lib.packet.PacketCustom; 12 | 13 | public abstract class ContainerSynchronised extends ContainerExtended { 14 | 15 | private ArrayList syncVars = new ArrayList(); 16 | 17 | /** 18 | * Create a packet to be used to send a synced variable update. Calls getPacket. Can be overriden to add extra 19 | * identifying data or change the type (default 2) 20 | */ 21 | public PacketCustom createSyncPacket() { 22 | return getPacket(2); 23 | } 24 | 25 | @Override 26 | public final void detectAndSendChanges() { 27 | super.detectAndSendChanges(); 28 | 29 | for (int i = 0; i < syncVars.size(); i++) { 30 | IContainerSyncVar var = syncVars.get(i); 31 | if (var.changed()) { 32 | PacketCustom packet = createSyncPacket(); 33 | packet.writeByte(i); 34 | var.writeChange(packet); 35 | sendContainerPacket(packet); 36 | var.reset(); 37 | } 38 | } 39 | } 40 | 41 | @Override 42 | public void sendContainerAndContentsToPlayer(Container container, List list, 43 | List playerCrafters) { 44 | super.sendContainerAndContentsToPlayer(container, list, playerCrafters); 45 | for (int i = 0; i < syncVars.size(); i++) { 46 | IContainerSyncVar var = syncVars.get(i); 47 | PacketCustom packet = createSyncPacket(); 48 | packet.writeByte(i); 49 | var.writeChange(packet); 50 | var.reset(); 51 | for (EntityPlayerMP player : playerCrafters) packet.sendToPlayer(player); 52 | } 53 | } 54 | 55 | public void addSyncVar(IContainerSyncVar var) { 56 | syncVars.add(var); 57 | } 58 | 59 | @Override 60 | public final void handleClientPacket(PacketCustom packet) { 61 | syncVars.get(packet.readUByte()).readChange(packet); 62 | } 63 | 64 | public List getSyncedVars() { 65 | return Collections.unmodifiableList(syncVars); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/IContainerSyncVar.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import codechicken.lib.packet.PacketCustom; 4 | 5 | public interface IContainerSyncVar { 6 | 7 | public boolean changed(); 8 | 9 | public void reset(); 10 | 11 | public void writeChange(PacketCustom packet); 12 | 13 | public void readChange(PacketCustom packet); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/IntegerSync.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import codechicken.lib.packet.PacketCustom; 4 | 5 | public abstract class IntegerSync implements IContainerSyncVar { 6 | 7 | public int c_value; 8 | 9 | @Override 10 | public boolean changed() { 11 | return getValue() != c_value; 12 | } 13 | 14 | @Override 15 | public void reset() { 16 | c_value = getValue(); 17 | } 18 | 19 | @Override 20 | public void writeChange(PacketCustom packet) { 21 | packet.writeInt(getValue()); 22 | } 23 | 24 | @Override 25 | public void readChange(PacketCustom packet) { 26 | c_value = packet.readInt(); 27 | } 28 | 29 | public abstract int getValue(); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/InventoryCopy.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.inventory.IInventory; 5 | import net.minecraft.item.ItemStack; 6 | 7 | /** 8 | * Creates a copy of an IInventory for extended simulation 9 | */ 10 | public class InventoryCopy implements IInventory { 11 | 12 | public boolean[] accessible; 13 | public ItemStack[] items; 14 | public IInventory inv; 15 | 16 | public InventoryCopy(IInventory inv) { 17 | items = new ItemStack[inv.getSizeInventory()]; 18 | accessible = new boolean[inv.getSizeInventory()]; 19 | this.inv = inv; 20 | update(); 21 | } 22 | 23 | public void update() { 24 | for (int i = 0; i < items.length; i++) { 25 | ItemStack stack = inv.getStackInSlot(i); 26 | if (stack != null) items[i] = stack.copy(); 27 | } 28 | } 29 | 30 | public InventoryCopy open(InventoryRange access) { 31 | int lslot = access.lastSlot(); 32 | if (lslot > accessible.length) { 33 | boolean[] l_accessible = new boolean[lslot]; 34 | ItemStack[] l_items = new ItemStack[lslot]; 35 | System.arraycopy(accessible, 0, l_accessible, 0, accessible.length); 36 | System.arraycopy(items, 0, l_items, 0, items.length); 37 | accessible = l_accessible; 38 | items = l_items; 39 | } 40 | 41 | for (int slot : access.slots) accessible[slot] = true; 42 | return this; 43 | } 44 | 45 | @Override 46 | public int getSizeInventory() { 47 | return items.length; 48 | } 49 | 50 | @Override 51 | public ItemStack getStackInSlot(int slot) { 52 | return items[slot]; 53 | } 54 | 55 | public ItemStack decrStackSize(int slot, int amount) { 56 | return InventoryUtils.decrStackSize(this, slot, amount); 57 | } 58 | 59 | @Override 60 | public ItemStack getStackInSlotOnClosing(int slot) { 61 | return InventoryUtils.getStackInSlotOnClosing(this, slot); 62 | } 63 | 64 | @Override 65 | public void setInventorySlotContents(int slot, ItemStack stack) { 66 | items[slot] = stack; 67 | markDirty(); 68 | } 69 | 70 | @Override 71 | public String getInventoryName() { 72 | return "copy"; 73 | } 74 | 75 | @Override 76 | public boolean isUseableByPlayer(EntityPlayer player) { 77 | return true; 78 | } 79 | 80 | @Override 81 | public void openInventory() {} 82 | 83 | @Override 84 | public void closeInventory() {} 85 | 86 | @Override 87 | public int getInventoryStackLimit() { 88 | return 64; 89 | } 90 | 91 | @Override 92 | public void markDirty() {} 93 | 94 | @Override 95 | public boolean isItemValidForSlot(int i, ItemStack itemstack) { 96 | return inv.isItemValidForSlot(i, itemstack); 97 | } 98 | 99 | @Override 100 | public boolean hasCustomInventoryName() { 101 | return true; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/InventoryNBT.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.inventory.IInventory; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.nbt.NBTTagCompound; 7 | 8 | /** 9 | * IInventory implementation which saves and loads from an NBT tag 10 | */ 11 | public class InventoryNBT implements IInventory { 12 | 13 | protected ItemStack[] items; 14 | protected NBTTagCompound tag; 15 | 16 | public InventoryNBT(int size, NBTTagCompound tag) { 17 | this.tag = tag; 18 | items = new ItemStack[size]; 19 | readNBT(); 20 | } 21 | 22 | private void writeNBT() { 23 | tag.setTag("items", InventoryUtils.writeItemStacksToTag(items, getInventoryStackLimit())); 24 | } 25 | 26 | private void readNBT() { 27 | if (tag.hasKey("items")) InventoryUtils.readItemStacksFromTag(items, tag.getTagList("items", 10)); 28 | } 29 | 30 | @Override 31 | public int getSizeInventory() { 32 | return items.length; 33 | } 34 | 35 | @Override 36 | public ItemStack getStackInSlot(int slot) { 37 | return items[slot]; 38 | } 39 | 40 | @Override 41 | public ItemStack decrStackSize(int slot, int amount) { 42 | return InventoryUtils.decrStackSize(this, slot, amount); 43 | } 44 | 45 | @Override 46 | public ItemStack getStackInSlotOnClosing(int slot) { 47 | return InventoryUtils.getStackInSlotOnClosing(this, slot); 48 | } 49 | 50 | @Override 51 | public void setInventorySlotContents(int slot, ItemStack stack) { 52 | items[slot] = stack; 53 | markDirty(); 54 | } 55 | 56 | @Override 57 | public String getInventoryName() { 58 | return "NBT"; 59 | } 60 | 61 | @Override 62 | public int getInventoryStackLimit() { 63 | return 64; 64 | } 65 | 66 | @Override 67 | public void markDirty() { 68 | writeNBT(); 69 | } 70 | 71 | @Override 72 | public boolean isUseableByPlayer(EntityPlayer var1) { 73 | return true; 74 | } 75 | 76 | @Override 77 | public void openInventory() {} 78 | 79 | @Override 80 | public void closeInventory() {} 81 | 82 | @Override 83 | public boolean isItemValidForSlot(int i, ItemStack itemstack) { 84 | return true; 85 | } 86 | 87 | @Override 88 | public boolean hasCustomInventoryName() { 89 | return true; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/InventoryRange.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import net.minecraft.inventory.IInventory; 4 | import net.minecraft.inventory.ISidedInventory; 5 | import net.minecraft.item.ItemStack; 6 | 7 | /** 8 | * Inventory wrapper for unified ISided/IInventory access 9 | */ 10 | public class InventoryRange { 11 | 12 | public IInventory inv; 13 | public int side; 14 | public ISidedInventory sidedInv; 15 | public int[] slots; 16 | 17 | public InventoryRange(IInventory inv, int side) { 18 | this.inv = inv; 19 | this.side = side; 20 | if (inv instanceof ISidedInventory) { 21 | sidedInv = (ISidedInventory) inv; 22 | slots = sidedInv.getAccessibleSlotsFromSide(side); 23 | } else { 24 | slots = new int[inv.getSizeInventory()]; 25 | for (int i = 0; i < slots.length; i++) slots[i] = i; 26 | } 27 | } 28 | 29 | public InventoryRange(IInventory inv) { 30 | this(inv, 0); 31 | } 32 | 33 | public InventoryRange(IInventory inv, int fslot, int size) { 34 | this.inv = inv; 35 | slots = new int[size]; 36 | for (int i = 0; i < slots.length; i++) slots[i] = fslot + i; 37 | } 38 | 39 | public InventoryRange(IInventory inv, InventoryRange access) { 40 | this.inv = inv; 41 | this.slots = access.slots; 42 | this.side = access.side; 43 | if (inv instanceof ISidedInventory) sidedInv = (ISidedInventory) inv; 44 | } 45 | 46 | public boolean canInsertItem(int slot, ItemStack item) { 47 | return sidedInv == null ? inv.isItemValidForSlot(slot, item) : sidedInv.canInsertItem(slot, item, side); 48 | } 49 | 50 | public boolean canExtractItem(int slot, ItemStack item) { 51 | return sidedInv == null ? inv.isItemValidForSlot(slot, item) : sidedInv.canExtractItem(slot, item, side); 52 | } 53 | 54 | public int lastSlot() { 55 | int last = 0; 56 | for (int slot : slots) if (slot > last) last = slot; 57 | return last; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/InventorySimple.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.inventory.IInventory; 5 | import net.minecraft.item.ItemStack; 6 | 7 | /** 8 | * Simple IInventory implementation with an array of items, name and maximum stack size 9 | */ 10 | public class InventorySimple implements IInventory { 11 | 12 | public ItemStack[] items; 13 | public int limit; 14 | public String name; 15 | 16 | public InventorySimple(ItemStack[] items, int limit, String name) { 17 | this.items = items; 18 | this.limit = limit; 19 | this.name = name; 20 | } 21 | 22 | public InventorySimple(ItemStack[] items, String name) { 23 | this(items, 64, name); 24 | } 25 | 26 | public InventorySimple(ItemStack[] items, int limit) { 27 | this(items, limit, "inv"); 28 | } 29 | 30 | public InventorySimple(ItemStack[] items) { 31 | this(items, 64, "inv"); 32 | } 33 | 34 | public InventorySimple(int size, int limit, String name) { 35 | this(new ItemStack[size], limit, name); 36 | } 37 | 38 | public InventorySimple(int size, int limit) { 39 | this(size, limit, "inv"); 40 | } 41 | 42 | public InventorySimple(int size, String name) { 43 | this(size, 64, name); 44 | } 45 | 46 | public InventorySimple(int size) { 47 | this(size, 64, "inv"); 48 | } 49 | 50 | @Override 51 | public int getSizeInventory() { 52 | return items.length; 53 | } 54 | 55 | @Override 56 | public ItemStack getStackInSlot(int slot) { 57 | return items[slot]; 58 | } 59 | 60 | @Override 61 | public ItemStack decrStackSize(int slot, int amount) { 62 | return InventoryUtils.decrStackSize(this, slot, amount); 63 | } 64 | 65 | @Override 66 | public ItemStack getStackInSlotOnClosing(int slot) { 67 | return InventoryUtils.getStackInSlotOnClosing(this, slot); 68 | } 69 | 70 | @Override 71 | public void setInventorySlotContents(int slot, ItemStack stack) { 72 | items[slot] = stack; 73 | markDirty(); 74 | } 75 | 76 | @Override 77 | public String getInventoryName() { 78 | return name; 79 | } 80 | 81 | @Override 82 | public int getInventoryStackLimit() { 83 | return limit; 84 | } 85 | 86 | @Override 87 | public boolean isUseableByPlayer(EntityPlayer var1) { 88 | return true; 89 | } 90 | 91 | @Override 92 | public void openInventory() {} 93 | 94 | @Override 95 | public void closeInventory() {} 96 | 97 | @Override 98 | public boolean isItemValidForSlot(int i, ItemStack itemstack) { 99 | return true; 100 | } 101 | 102 | @Override 103 | public boolean hasCustomInventoryName() { 104 | return true; 105 | } 106 | 107 | @Override 108 | public void markDirty() {} 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/ItemKey.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import static codechicken.lib.inventory.InventoryUtils.actualDamage; 4 | 5 | import net.minecraft.item.Item; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.nbt.NBTTagCompound; 8 | import net.minecraftforge.oredict.OreDictionary; 9 | 10 | import com.google.common.base.Objects; 11 | 12 | /** 13 | * Comparable ItemStack with a hashCode implementation. 14 | */ 15 | public class ItemKey implements Comparable { 16 | 17 | public ItemStack stack; 18 | private int hashcode = 0; 19 | 20 | public ItemKey(ItemStack k) { 21 | stack = k; 22 | } 23 | 24 | public ItemKey(Item item, int damage) { 25 | this(new ItemStack(item, 1, damage)); 26 | } 27 | 28 | public ItemKey(Item item, NBTTagCompound tag) { 29 | this(item, OreDictionary.WILDCARD_VALUE, tag); 30 | } 31 | 32 | public ItemKey(Item item, int damage, NBTTagCompound tag) { 33 | this(item, damage); 34 | stack.setTagCompound(tag); 35 | } 36 | 37 | @Override 38 | public boolean equals(Object obj) { 39 | if (!(obj instanceof ItemKey)) return false; 40 | 41 | ItemKey k = (ItemKey) obj; 42 | return stack.getItem() == k.stack.getItem() && actualDamage(stack) == actualDamage(k.stack) 43 | && Objects.equal(stack.stackTagCompound, k.stack.stackTagCompound); 44 | } 45 | 46 | @Override 47 | public int hashCode() { 48 | return hashcode != 0 ? hashcode 49 | : (hashcode = Objects.hashCode(stack.getItem(), actualDamage(stack), stack.stackTagCompound)); 50 | } 51 | 52 | public int compareInt(int a, int b) { 53 | return a == b ? 0 : a < b ? -1 : 1; 54 | } 55 | 56 | @Override 57 | public int compareTo(ItemKey o) { 58 | if (stack.getItem() != o.stack.getItem()) 59 | return compareInt(Item.getIdFromItem(stack.getItem()), Item.getIdFromItem(o.stack.getItem())); 60 | if (actualDamage(stack) != actualDamage(o.stack)) return compareInt(actualDamage(stack), actualDamage(o.stack)); 61 | return 0; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/SlotDummy.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.inventory.IInventory; 5 | import net.minecraft.item.ItemStack; 6 | 7 | public class SlotDummy extends SlotHandleClicks { 8 | 9 | public final int stackLimit; 10 | 11 | public SlotDummy(IInventory inv, int slot, int x, int y) { 12 | this(inv, slot, x, y, 64); 13 | } 14 | 15 | public SlotDummy(IInventory inv, int slot, int x, int y, int limit) { 16 | super(inv, slot, x, y); 17 | stackLimit = limit; 18 | } 19 | 20 | @Override 21 | public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier) { 22 | ItemStack held = player.inventory.getItemStack(); 23 | boolean shift = modifier == 1; 24 | slotClick(held, button, shift); 25 | return null; 26 | } 27 | 28 | public void slotClick(ItemStack held, int button, boolean shift) { 29 | ItemStack tstack = getStack(); 30 | if (held != null && (tstack == null || !InventoryUtils.canStack(held, tstack))) { 31 | int quantity = Math.min(held.stackSize, stackLimit); 32 | if (shift) quantity = Math.min(stackLimit, held.getMaxStackSize() * 16); 33 | if (button == 1) quantity = 1; 34 | putStack(InventoryUtils.copyStack(held, quantity)); 35 | } else if (tstack != null) { 36 | int inc; 37 | if (held != null) { 38 | inc = button == 1 ? -held.stackSize : held.stackSize; 39 | if (shift) inc *= 16; 40 | } else { 41 | inc = button == 1 ? -1 : 1; 42 | if (shift) inc *= 16; 43 | } 44 | int quantity = tstack.stackSize + inc; 45 | if (quantity <= 0) putStack(null); 46 | else putStack(InventoryUtils.copyStack(tstack, quantity)); 47 | } 48 | } 49 | 50 | @Override 51 | public void putStack(ItemStack stack) { 52 | if (stack != null && stack.stackSize > stackLimit) stack = InventoryUtils.copyStack(stack, stackLimit); 53 | super.putStack(stack); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/SlotDummyOutput.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.inventory.IInventory; 5 | import net.minecraft.item.ItemStack; 6 | 7 | public class SlotDummyOutput extends SlotHandleClicks { 8 | 9 | public SlotDummyOutput(IInventory inv, int slot, int x, int y) { 10 | super(inv, slot, x, y); 11 | } 12 | 13 | @Override 14 | public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier) { 15 | return null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/inventory/SlotHandleClicks.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.inventory; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.inventory.IInventory; 5 | import net.minecraft.inventory.Slot; 6 | import net.minecraft.item.ItemStack; 7 | 8 | public abstract class SlotHandleClicks extends Slot { 9 | 10 | public SlotHandleClicks(IInventory inv, int slot, int x, int y) { 11 | super(inv, slot, x, y); 12 | } 13 | 14 | public abstract ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/lighting/LC.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.lighting; 2 | 3 | import codechicken.lib.render.CCModel; 4 | import codechicken.lib.util.Copyable; 5 | import codechicken.lib.vec.Rotation; 6 | import codechicken.lib.vec.Vector3; 7 | 8 | public class LC implements Copyable { 9 | 10 | public int side; 11 | public float fa; 12 | public float fb; 13 | public float fc; 14 | public float fd; 15 | 16 | public LC() { 17 | this(0, 0, 0, 0, 0); 18 | } 19 | 20 | public LC(int s, float a, float b, float c, float d) { 21 | side = s; 22 | fa = a; 23 | fb = b; 24 | fc = c; 25 | fd = d; 26 | } 27 | 28 | public LC set(int s, float a, float b, float c, float d) { 29 | side = s; 30 | fa = a; 31 | fb = b; 32 | fc = c; 33 | fd = d; 34 | return this; 35 | } 36 | 37 | public LC set(LC lc) { 38 | return set(lc.side, lc.fa, lc.fb, lc.fc, lc.fd); 39 | } 40 | 41 | public LC compute(Vector3 vec, Vector3 normal) { 42 | int side = CCModel.findSide(normal); 43 | if (side < 0) return set(12, 1, 0, 0, 0); 44 | return compute(vec, side); 45 | } 46 | 47 | public LC compute(Vector3 vec, int side) { 48 | boolean offset = false; 49 | switch (side) { 50 | case 0: 51 | offset = vec.y <= 0; 52 | break; 53 | case 1: 54 | offset = vec.y >= 1; 55 | break; 56 | case 2: 57 | offset = vec.z <= 0; 58 | break; 59 | case 3: 60 | offset = vec.z >= 1; 61 | break; 62 | case 4: 63 | offset = vec.x <= 0; 64 | break; 65 | case 5: 66 | offset = vec.x >= 1; 67 | break; 68 | } 69 | if (!offset) side += 6; 70 | return computeO(vec, side); 71 | } 72 | 73 | public LC computeO(Vector3 vec, int side) { 74 | Vector3 v1 = Rotation.axes[((side & 0xE) + 3) % 6]; 75 | Vector3 v2 = Rotation.axes[((side & 0xE) + 5) % 6]; 76 | float d1 = (float) vec.scalarProject(v1); 77 | float d2 = 1 - d1; 78 | float d3 = (float) vec.scalarProject(v2); 79 | float d4 = 1 - d3; 80 | return set(side, d2 * d4, d2 * d3, d1 * d4, d1 * d3); 81 | } 82 | 83 | @Override 84 | public LC copy() { 85 | return new LC(side, fa, fb, fc, fd); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/lighting/LightModel.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.lighting; 2 | 3 | import codechicken.lib.render.CCRenderState; 4 | import codechicken.lib.vec.Rotation; 5 | import codechicken.lib.vec.Vector3; 6 | 7 | public class LightModel implements CCRenderState.IVertexOperation { 8 | 9 | public static final int operationIndex = CCRenderState.registerOperation(); 10 | 11 | public static class Light { 12 | 13 | public Vector3 ambient = new Vector3(); 14 | public Vector3 diffuse = new Vector3(); 15 | public Vector3 position; 16 | 17 | public Light(Vector3 pos) { 18 | position = pos.copy().normalize(); 19 | } 20 | 21 | public Light setDiffuse(Vector3 vec) { 22 | diffuse.set(vec); 23 | return this; 24 | } 25 | 26 | public Light setAmbient(Vector3 vec) { 27 | ambient.set(vec); 28 | return this; 29 | } 30 | } 31 | 32 | public static LightModel standardLightModel; 33 | 34 | static { 35 | standardLightModel = new LightModel().setAmbient(new Vector3(0.4, 0.4, 0.4)) 36 | .addLight(new Light(new Vector3(0.2, 1, -0.7)).setDiffuse(new Vector3(0.6, 0.6, 0.6))) 37 | .addLight(new Light(new Vector3(-0.2, 1, 0.7)).setDiffuse(new Vector3(0.6, 0.6, 0.6))); 38 | } 39 | 40 | private Vector3 ambient = new Vector3(); 41 | private Light[] lights = new Light[8]; 42 | private int lightCount; 43 | 44 | public LightModel addLight(Light light) { 45 | lights[lightCount++] = light; 46 | return this; 47 | } 48 | 49 | public LightModel setAmbient(Vector3 vec) { 50 | ambient.set(vec); 51 | return this; 52 | } 53 | 54 | /** 55 | * @param colour The pre-lighting vertex colour. RGBA format 56 | * @param normal The normal at the vertex 57 | * @return The lighting applied colour 58 | */ 59 | public int apply(int colour, Vector3 normal) { 60 | Vector3 n_colour = ambient.copy(); 61 | for (int l = 0; l < lightCount; l++) { 62 | Light light = lights[l]; 63 | double n_l = light.position.dotProduct(normal); 64 | double f = n_l > 0 ? 1 : 0; 65 | n_colour.x += light.ambient.x + f * light.diffuse.x * n_l; 66 | n_colour.y += light.ambient.y + f * light.diffuse.y * n_l; 67 | n_colour.z += light.ambient.z + f * light.diffuse.z * n_l; 68 | } 69 | 70 | if (n_colour.x > 1) n_colour.x = 1; 71 | if (n_colour.y > 1) n_colour.y = 1; 72 | if (n_colour.z > 1) n_colour.z = 1; 73 | 74 | n_colour.multiply((colour >>> 24) / 255D, (colour >> 16 & 0xFF) / 255D, (colour >> 8 & 0xFF) / 255D); 75 | return (int) (n_colour.x * 255) << 24 | (int) (n_colour.y * 255) << 16 76 | | (int) (n_colour.z * 255) << 8 77 | | colour & 0xFF; 78 | } 79 | 80 | @Override 81 | public boolean load(CCRenderState state) { 82 | if (!state.computeLighting) return false; 83 | 84 | state.pipeline.addDependency(CCRenderState.normalAttrib()); 85 | state.pipeline.addDependency(CCRenderState.colourAttrib()); 86 | return true; 87 | } 88 | 89 | @Override 90 | public void operate(CCRenderState state) { 91 | state.setColourInstance(apply(state.colour, state.normal)); 92 | } 93 | 94 | @Override 95 | public int operationID() { 96 | return operationIndex; 97 | } 98 | 99 | public PlanarLightModel reducePlanar() { 100 | int[] colours = new int[6]; 101 | for (int i = 0; i < 6; i++) colours[i] = apply(-1, Rotation.axes[i]); 102 | return new PlanarLightModel(colours); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/lighting/PlanarLightMatrix.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.lighting; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.world.IBlockAccess; 5 | 6 | import codechicken.lib.render.CCRenderState; 7 | import codechicken.lib.vec.BlockCoord; 8 | 9 | public class PlanarLightMatrix extends PlanarLightModel { 10 | 11 | public static final int operationIndex = CCRenderState.registerOperation(); 12 | public static PlanarLightMatrix instance = new PlanarLightMatrix(); 13 | 14 | public IBlockAccess access; 15 | public BlockCoord pos = new BlockCoord(); 16 | 17 | private int sampled = 0; 18 | public int[] brightness = new int[6]; 19 | 20 | public PlanarLightMatrix() { 21 | super(PlanarLightModel.standardLightModel.colours); 22 | } 23 | 24 | public PlanarLightMatrix locate(IBlockAccess a, int x, int y, int z) { 25 | access = a; 26 | pos.set(x, y, z); 27 | sampled = 0; 28 | return this; 29 | } 30 | 31 | public int brightness(int side) { 32 | if ((sampled & 1 << side) == 0) { 33 | Block b = access.getBlock(pos.x, pos.y, pos.z); 34 | brightness[side] = access 35 | .getLightBrightnessForSkyBlocks(pos.x, pos.y, pos.z, b.getLightValue(access, pos.x, pos.y, pos.z)); 36 | sampled |= 1 << side; 37 | } 38 | return brightness[side]; 39 | } 40 | 41 | @Override 42 | public boolean load(CCRenderState state) { 43 | state.pipeline.addDependency(CCRenderState.sideAttrib()); 44 | return true; 45 | } 46 | 47 | @Override 48 | public void operate(CCRenderState state) { 49 | super.operate(state); 50 | state.setBrightnessInstance(brightness(state.side)); 51 | } 52 | 53 | @Override 54 | public int operationID() { 55 | return operationIndex; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/lighting/PlanarLightModel.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.lighting; 2 | 3 | import codechicken.lib.colour.ColourRGBA; 4 | import codechicken.lib.render.CCRenderState; 5 | 6 | /** 7 | * Faster precomputed version of LightModel that only works for axis planar sides 8 | */ 9 | public class PlanarLightModel implements CCRenderState.IVertexOperation { 10 | 11 | public static PlanarLightModel standardLightModel = LightModel.standardLightModel.reducePlanar(); 12 | 13 | public int[] colours; 14 | 15 | public PlanarLightModel(int[] colours) { 16 | this.colours = colours; 17 | } 18 | 19 | @Override 20 | public boolean load(CCRenderState state) { 21 | if (!state.computeLighting) return false; 22 | 23 | state.pipeline.addDependency(CCRenderState.sideAttrib()); 24 | state.pipeline.addDependency(CCRenderState.colourAttrib()); 25 | return true; 26 | } 27 | 28 | @Override 29 | public void operate(CCRenderState state) { 30 | state.setColourInstance(ColourRGBA.multiply(state.colour, colours[state.side])); 31 | } 32 | 33 | @Override 34 | public int operationID() { 35 | return LightModel.operationIndex; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/lighting/SimpleBrightnessModel.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.lighting; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.world.IBlockAccess; 5 | 6 | import codechicken.lib.render.CCRenderState; 7 | import codechicken.lib.vec.BlockCoord; 8 | 9 | /** 10 | * Faster precomputed version of LightModel that only works for axis planar sides 11 | */ 12 | public class SimpleBrightnessModel implements CCRenderState.IVertexOperation { 13 | 14 | public static final int operationIndex = CCRenderState.registerOperation(); 15 | public static SimpleBrightnessModel instance = new SimpleBrightnessModel(); 16 | 17 | public IBlockAccess access; 18 | public BlockCoord pos = new BlockCoord(); 19 | 20 | private int sampled = 0; 21 | private final int[] samples = new int[6]; 22 | private final BlockCoord c = new BlockCoord(); 23 | 24 | public void locate(IBlockAccess a, int x, int y, int z) { 25 | access = a; 26 | pos.set(x, y, z); 27 | sampled = 0; 28 | } 29 | 30 | public int sample(int side) { 31 | if ((sampled & 1 << side) == 0) { 32 | c.set(pos).offset(side); 33 | Block block = access.getBlock(c.x, c.y, c.z); 34 | samples[side] = access 35 | .getLightBrightnessForSkyBlocks(c.x, c.y, c.z, block.getLightValue(access, c.x, c.y, c.z)); 36 | sampled |= 1 << side; 37 | } 38 | return samples[side]; 39 | } 40 | 41 | @Override 42 | public boolean load(CCRenderState state) { 43 | state.pipeline.addDependency(CCRenderState.sideAttrib()); 44 | return true; 45 | } 46 | 47 | @Override 48 | public void operate(CCRenderState state) { 49 | state.setBrightnessInstance(sample(state.side)); 50 | } 51 | 52 | @Override 53 | public int operationID() { 54 | return operationIndex; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/packet/ICustomPacketTile.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.packet; 2 | 3 | public interface ICustomPacketTile { 4 | 5 | public void handleDescriptionPacket(PacketCustom packet); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/raytracer/ExtendedMOP.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.raytracer; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.util.MovingObjectPosition; 5 | import net.minecraft.util.Vec3; 6 | 7 | public class ExtendedMOP extends MovingObjectPosition implements Comparable { 8 | 9 | public Object data; 10 | /** 11 | * The square distance from the start of the raytrace. 12 | */ 13 | public double dist; 14 | 15 | public ExtendedMOP(Entity entity, Object data) { 16 | super(entity); 17 | setData(data); 18 | } 19 | 20 | public ExtendedMOP(int x, int y, int z, int side, Vec3 hit, Object data) { 21 | super(x, y, z, side, hit); 22 | setData(data); 23 | } 24 | 25 | public ExtendedMOP(MovingObjectPosition mop, Object data, double dist) { 26 | super(0, 0, 0, 0, mop.hitVec); 27 | typeOfHit = mop.typeOfHit; 28 | blockX = mop.blockX; 29 | blockY = mop.blockY; 30 | blockZ = mop.blockZ; 31 | sideHit = mop.sideHit; 32 | subHit = mop.subHit; 33 | setData(data); 34 | this.dist = dist; 35 | } 36 | 37 | public void setData(Object data) { 38 | if (data instanceof Integer) subHit = ((Integer) data).intValue(); 39 | this.data = data; 40 | } 41 | 42 | @SuppressWarnings("unchecked") 43 | public static T getData(MovingObjectPosition mop) { 44 | if (mop instanceof ExtendedMOP) return (T) ((ExtendedMOP) mop).data; 45 | 46 | return (T) Integer.valueOf(mop.subHit); 47 | } 48 | 49 | @Override 50 | public int compareTo(ExtendedMOP o) { 51 | return dist == o.dist ? 0 : dist < o.dist ? -1 : 1; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/raytracer/IndexedCuboid6.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.raytracer; 2 | 3 | import codechicken.lib.vec.Cuboid6; 4 | 5 | public class IndexedCuboid6 extends Cuboid6 { 6 | 7 | public Object data; 8 | 9 | public IndexedCuboid6(Object data, Cuboid6 cuboid) { 10 | super(cuboid); 11 | this.data = data; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/ColourMultiplier.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render; 2 | 3 | import codechicken.lib.colour.ColourRGBA; 4 | 5 | public class ColourMultiplier implements CCRenderState.IVertexOperation { 6 | 7 | private static final ThreadLocal instances = ThreadLocal 8 | .withInitial(() -> new ColourMultiplier(-1)); 9 | 10 | public static ColourMultiplier instance(int colour) { 11 | ColourMultiplier instance = instances.get(); 12 | instance.colour = colour; 13 | return instance; 14 | } 15 | 16 | public static final int operationIndex = CCRenderState.registerOperation(); 17 | public int colour; 18 | 19 | public ColourMultiplier(int colour) { 20 | this.colour = colour; 21 | } 22 | 23 | @Override 24 | public boolean load(CCRenderState state) { 25 | if (colour == -1) { 26 | state.setColourInstance(-1); 27 | return false; 28 | } 29 | 30 | state.pipeline.addDependency(state.colourAttrib); 31 | return true; 32 | } 33 | 34 | @Override 35 | public void operate(CCRenderState state) { 36 | state.setColourInstance(ColourRGBA.multiply(state.colour, colour)); 37 | } 38 | 39 | @Override 40 | public int operationID() { 41 | return operationIndex; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/FontUtils.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.FontRenderer; 5 | import net.minecraft.item.ItemStack; 6 | 7 | import org.lwjgl.opengl.GL11; 8 | 9 | public class FontUtils { 10 | 11 | public static FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; 12 | 13 | public static void drawCenteredString(String s, int xCenter, int y, int colour) { 14 | fontRenderer.drawString(s, xCenter - fontRenderer.getStringWidth(s) / 2, y, colour); 15 | } 16 | 17 | public static void drawRightString(String s, int xRight, int y, int colour) { 18 | fontRenderer.drawString(s, xRight - fontRenderer.getStringWidth(s), y, colour); 19 | } 20 | 21 | public static final String[] prefixes = new String[] { "K", "M", "G" }; 22 | 23 | public static void drawItemQuantity(int x, int y, ItemStack item, String quantity, int mode) { 24 | if (item == null || (quantity == null && item.stackSize <= 1)) return; 25 | 26 | if (quantity == null) { 27 | switch (mode) { 28 | case 2: 29 | int q = item.stackSize; 30 | String postfix = ""; 31 | for (int p = 0; p < 3 && q > 1000; p++) { 32 | q /= 1000; 33 | postfix = prefixes[p]; 34 | } 35 | quantity = Integer.toString(q) + postfix; 36 | case 1: 37 | quantity = ""; 38 | if (item.stackSize / 64 > 0) quantity += item.stackSize / 64 + "s"; 39 | if (item.stackSize % 64 > 0) quantity += item.stackSize % 64; 40 | break; 41 | default: 42 | quantity = Integer.toString(item.stackSize); 43 | break; 44 | } 45 | } 46 | 47 | double scale = quantity.length() > 2 ? 0.5 : 1; 48 | double sheight = 8 * scale; 49 | double swidth = fontRenderer.getStringWidth(quantity) * scale; 50 | 51 | GL11.glDisable(GL11.GL_LIGHTING); 52 | GL11.glDisable(GL11.GL_DEPTH_TEST); 53 | GL11.glPushMatrix(); 54 | GL11.glTranslated(x + 16 - swidth, y + 16 - sheight, 0); 55 | GL11.glScaled(scale, scale, 1); 56 | fontRenderer.drawStringWithShadow(quantity, 0, 0, 0xFFFFFF); 57 | GL11.glPopMatrix(); 58 | GL11.glEnable(GL11.GL_LIGHTING); 59 | GL11.glEnable(GL11.GL_DEPTH_TEST); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/IFaceRenderer.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render; 2 | 3 | public interface IFaceRenderer { 4 | 5 | public void renderFace(Vertex5[] face, int side); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/ManagedTextureFX.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render; 2 | 3 | public class ManagedTextureFX extends TextureFX { 4 | 5 | public boolean changed; 6 | 7 | public ManagedTextureFX(int size, String name) { 8 | super(size, name); 9 | imageData = new int[size * size]; 10 | } 11 | 12 | @Override 13 | public void setup() {} 14 | 15 | public void setData(int[] data) { 16 | System.arraycopy(data, 0, imageData, 0, imageData.length); 17 | changed = true; 18 | } 19 | 20 | @Override 21 | public boolean changed() { 22 | boolean r = changed; 23 | changed = false; 24 | return r; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/PlaceholderTexture.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render; 2 | 3 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 4 | import net.minecraft.client.resources.IResourceManager; 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | public class PlaceholderTexture extends TextureAtlasSprite { 8 | 9 | protected PlaceholderTexture(String par1) { 10 | super(par1); 11 | } 12 | 13 | @Override 14 | public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) { 15 | return true; 16 | } 17 | 18 | @Override 19 | public boolean load(IResourceManager manager, ResourceLocation location) { 20 | return true; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/TextureDataHolder.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | public class TextureDataHolder { 6 | 7 | public int width; 8 | public int height; 9 | public int[] data; 10 | 11 | public TextureDataHolder(int width, int height) { 12 | this.width = width; 13 | this.height = height; 14 | data = new int[width * height]; 15 | } 16 | 17 | public TextureDataHolder(int[] data, int width) { 18 | this.data = data; 19 | this.width = width; 20 | height = data.length / width; 21 | } 22 | 23 | public TextureDataHolder(BufferedImage img) { 24 | this(img.getWidth(), img.getHeight()); 25 | img.getRGB(0, 0, width, height, data, 0, width); 26 | } 27 | 28 | public TextureDataHolder copyData() { 29 | int[] copy = new int[data.length]; 30 | System.arraycopy(data, 0, copy, 0, data.length); 31 | data = copy; 32 | return this; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/TextureFX.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render; 2 | 3 | import net.minecraft.client.Minecraft; 4 | 5 | import codechicken.lib.render.SpriteSheetManager.SpriteSheet; 6 | import cpw.mods.fml.relauncher.Side; 7 | import cpw.mods.fml.relauncher.SideOnly; 8 | 9 | @SideOnly(Side.CLIENT) 10 | public class TextureFX { 11 | 12 | public int[] imageData; 13 | public int tileSizeBase = 16; 14 | public int tileSizeSquare = 256; 15 | public int tileSizeMask = 15; 16 | public int tileSizeSquareMask = 255; 17 | 18 | public boolean anaglyphEnabled; 19 | public TextureSpecial texture; 20 | 21 | public TextureFX(int spriteIndex, SpriteSheet sheet) { 22 | texture = sheet.bindTextureFX(spriteIndex, this); 23 | } 24 | 25 | public TextureFX(int size, String name) { 26 | texture = new TextureSpecial(name).blank(size).selfRegister().addTextureFX(this); 27 | } 28 | 29 | public TextureFX setAtlas(int index) { 30 | texture.atlasIndex = index; 31 | return this; 32 | } 33 | 34 | public void setup() { 35 | imageData = new int[tileSizeSquare]; 36 | } 37 | 38 | public void onTextureDimensionsUpdate(int width, int height) { 39 | if (width != height) 40 | throw new IllegalArgumentException("Non-Square textureFX not supported (" + width + ":" + height + ")"); 41 | 42 | tileSizeBase = width; 43 | tileSizeSquare = tileSizeBase * tileSizeBase; 44 | tileSizeMask = tileSizeBase - 1; 45 | tileSizeSquareMask = tileSizeSquare - 1; 46 | setup(); 47 | } 48 | 49 | public void update() { 50 | anaglyphEnabled = Minecraft.getMinecraft().gameSettings.anaglyph; 51 | onTick(); 52 | } 53 | 54 | public void onTick() {} 55 | 56 | public boolean changed() { 57 | return true; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/Vertex5.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | import codechicken.lib.render.uv.UV; 8 | import codechicken.lib.render.uv.UVTransformation; 9 | import codechicken.lib.util.Copyable; 10 | import codechicken.lib.vec.Transformation; 11 | import codechicken.lib.vec.Vector3; 12 | 13 | public class Vertex5 implements Copyable { 14 | 15 | public Vector3 vec; 16 | public UV uv; 17 | 18 | public Vertex5() { 19 | this(new Vector3(), new UV()); 20 | } 21 | 22 | public Vertex5(Vector3 vert, UV uv) { 23 | this.vec = vert; 24 | this.uv = uv; 25 | } 26 | 27 | public Vertex5(Vector3 vert, double u, double v) { 28 | this(vert, new UV(u, v)); 29 | } 30 | 31 | public Vertex5(double x, double y, double z, double u, double v) { 32 | this(x, y, z, u, v, 0); 33 | } 34 | 35 | public Vertex5(double x, double y, double z, double u, double v, int tex) { 36 | this(new Vector3(x, y, z), new UV(u, v, tex)); 37 | } 38 | 39 | public Vertex5 set(double x, double y, double z, double u, double v) { 40 | vec.set(x, y, z); 41 | uv.set(u, v); 42 | return this; 43 | } 44 | 45 | public Vertex5 set(double x, double y, double z, double u, double v, int tex) { 46 | vec.set(x, y, z); 47 | uv.set(u, v, tex); 48 | return this; 49 | } 50 | 51 | public Vertex5 set(Vertex5 vert) { 52 | vec.set(vert.vec); 53 | uv.set(vert.uv); 54 | return this; 55 | } 56 | 57 | public Vertex5(Vertex5 vertex5) { 58 | this(vertex5.vec.copy(), vertex5.uv.copy()); 59 | } 60 | 61 | public Vertex5 copy() { 62 | return new Vertex5(this); 63 | } 64 | 65 | public String toString() { 66 | MathContext cont = new MathContext(4, RoundingMode.HALF_UP); 67 | return "Vertex: (" + new BigDecimal(vec.x, cont) 68 | + ", " 69 | + new BigDecimal(vec.y, cont) 70 | + ", " 71 | + new BigDecimal(vec.z, cont) 72 | + ") " 73 | + "(" 74 | + new BigDecimal(uv.u, cont) 75 | + ", " 76 | + new BigDecimal(uv.v, cont) 77 | + ") (" 78 | + uv.tex 79 | + ")"; 80 | } 81 | 82 | public Vertex5 apply(Transformation t) { 83 | vec.apply(t); 84 | return this; 85 | } 86 | 87 | public Vertex5 apply(UVTransformation t) { 88 | uv.apply(t); 89 | return this; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/uv/IconTransformation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render.uv; 2 | 3 | import net.minecraft.util.IIcon; 4 | 5 | import codechicken.lib.vec.IrreversibleTransformationException; 6 | 7 | public class IconTransformation extends UVTransformation { 8 | 9 | public IIcon icon; 10 | 11 | public IconTransformation(IIcon icon) { 12 | this.icon = icon; 13 | } 14 | 15 | @Override 16 | public void apply(UV uv) { 17 | uv.u = icon.getInterpolatedU(uv.u * 16); 18 | uv.v = icon.getInterpolatedV(uv.v * 16); 19 | } 20 | 21 | @Override 22 | public UVTransformation inverse() { 23 | throw new IrreversibleTransformationException(this); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/uv/MultiIconTransformation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render.uv; 2 | 3 | import net.minecraft.util.IIcon; 4 | 5 | import codechicken.lib.vec.IrreversibleTransformationException; 6 | 7 | public class MultiIconTransformation extends UVTransformation { 8 | 9 | public IIcon[] icons; 10 | 11 | public MultiIconTransformation(IIcon... icons) { 12 | this.icons = icons; 13 | } 14 | 15 | @Override 16 | public void apply(UV uv) { 17 | IIcon icon = icons[uv.tex % icons.length]; 18 | uv.u = icon.getInterpolatedU(uv.u * 16); 19 | uv.v = icon.getInterpolatedV(uv.v * 16); 20 | } 21 | 22 | @Override 23 | public UVTransformation inverse() { 24 | throw new IrreversibleTransformationException(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/uv/UV.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render.uv; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | import codechicken.lib.util.Copyable; 8 | 9 | public class UV implements Copyable { 10 | 11 | public double u; 12 | public double v; 13 | public int tex; 14 | 15 | public UV() {} 16 | 17 | public UV(double u, double v) { 18 | this(u, v, 0); 19 | } 20 | 21 | public UV(double u, double v, int tex) { 22 | this.u = u; 23 | this.v = v; 24 | this.tex = tex; 25 | } 26 | 27 | public UV(UV uv) { 28 | this(uv.u, uv.v, uv.tex); 29 | } 30 | 31 | public UV set(double u, double v, int tex) { 32 | this.u = u; 33 | this.v = v; 34 | this.tex = tex; 35 | return this; 36 | } 37 | 38 | public UV set(double u, double v) { 39 | return set(u, v, tex); 40 | } 41 | 42 | public UV set(UV uv) { 43 | return set(uv.u, uv.v, uv.tex); 44 | } 45 | 46 | public UV copy() { 47 | return new UV(this); 48 | } 49 | 50 | public UV add(UV uv) { 51 | u += uv.u; 52 | v += uv.v; 53 | return this; 54 | } 55 | 56 | public UV multiply(double d) { 57 | u *= d; 58 | v *= d; 59 | return this; 60 | } 61 | 62 | public String toString() { 63 | MathContext cont = new MathContext(4, RoundingMode.HALF_UP); 64 | return "UV(" + new BigDecimal(u, cont) + ", " + new BigDecimal(v, cont) + ")"; 65 | } 66 | 67 | public UV apply(UVTransformation t) { 68 | t.apply(this); 69 | return this; 70 | } 71 | 72 | @Override 73 | public boolean equals(Object o) { 74 | if (!(o instanceof UV)) return false; 75 | UV uv = (UV) o; 76 | return u == uv.u && v == uv.v; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/uv/UVRotation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render.uv; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | import codechicken.lib.math.MathHelper; 8 | 9 | public class UVRotation extends UVTransformation { 10 | 11 | public double angle; 12 | 13 | /** 14 | * @param angle The angle to rotate counterclockwise in radians 15 | */ 16 | public UVRotation(double angle) { 17 | this.angle = angle; 18 | } 19 | 20 | @Override 21 | public void apply(UV uv) { 22 | double c = MathHelper.cos(angle); 23 | double s = MathHelper.sin(angle); 24 | double u2 = c * uv.u + s * uv.v; 25 | uv.v = -s * uv.u + c * uv.v; 26 | uv.u = u2; 27 | } 28 | 29 | @Override 30 | public UVTransformation inverse() { 31 | return new UVRotation(-angle); 32 | } 33 | 34 | @Override 35 | public UVTransformation merge(UVTransformation next) { 36 | if (next instanceof UVRotation) return new UVRotation(angle + ((UVRotation) next).angle); 37 | 38 | return null; 39 | } 40 | 41 | @Override 42 | public boolean isRedundant() { 43 | return MathHelper.between(-1E-5, angle, 1E-5); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | MathContext cont = new MathContext(4, RoundingMode.HALF_UP); 49 | return "UVRotation(" + new BigDecimal(angle, cont) + ")"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/uv/UVScale.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render.uv; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | public class UVScale extends UVTransformation { 8 | 9 | double su; 10 | double sv; 11 | 12 | public UVScale(double scaleu, double scalev) { 13 | su = scaleu; 14 | sv = scalev; 15 | } 16 | 17 | public UVScale(double d) { 18 | this(d, d); 19 | } 20 | 21 | @Override 22 | public void apply(UV uv) { 23 | uv.u *= su; 24 | uv.v *= sv; 25 | } 26 | 27 | @Override 28 | public UVTransformation inverse() { 29 | return new UVScale(1 / su, 1 / sv); 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | MathContext cont = new MathContext(4, RoundingMode.HALF_UP); 35 | return "UVScale(" + new BigDecimal(su, cont) + ", " + new BigDecimal(sv, cont) + ")"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/uv/UVTransformation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render.uv; 2 | 3 | import codechicken.lib.render.CCRenderState; 4 | import codechicken.lib.vec.ITransformation; 5 | 6 | /** 7 | * Abstract supertype for any UV transformation 8 | */ 9 | public abstract class UVTransformation extends ITransformation 10 | implements CCRenderState.IVertexOperation { 11 | 12 | public static final int operationIndex = CCRenderState.registerOperation(); 13 | 14 | public UVTransformation at(UV point) { 15 | return new UVTransformationList( 16 | new UVTranslation(-point.u, -point.v), 17 | this, 18 | new UVTranslation(point.u, point.v)); 19 | } 20 | 21 | public UVTransformationList with(UVTransformation t) { 22 | return new UVTransformationList(this, t); 23 | } 24 | 25 | @Override 26 | public boolean load(CCRenderState state) { 27 | return !isRedundant(); 28 | } 29 | 30 | @Override 31 | public void operate(CCRenderState state) { 32 | apply(state.vert.uv); 33 | } 34 | 35 | @Override 36 | public int operationID() { 37 | return operationIndex; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/uv/UVTransformationList.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render.uv; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | 6 | public class UVTransformationList extends UVTransformation { 7 | 8 | private ArrayList transformations = new ArrayList(); 9 | 10 | public UVTransformationList(UVTransformation... transforms) { 11 | for (UVTransformation t : transforms) 12 | if (t instanceof UVTransformationList) transformations.addAll(((UVTransformationList) t).transformations); 13 | else transformations.add(t); 14 | 15 | compact(); 16 | } 17 | 18 | @Override 19 | public void apply(UV uv) { 20 | for (int i = 0; i < transformations.size(); i++) transformations.get(i).apply(uv); 21 | } 22 | 23 | @Override 24 | public UVTransformationList with(UVTransformation t) { 25 | if (t.isRedundant()) return this; 26 | 27 | if (t instanceof UVTransformationList) transformations.addAll(((UVTransformationList) t).transformations); 28 | else transformations.add(t); 29 | 30 | compact(); 31 | return this; 32 | } 33 | 34 | public UVTransformationList prepend(UVTransformation t) { 35 | if (t.isRedundant()) return this; 36 | 37 | if (t instanceof UVTransformationList) transformations.addAll(0, ((UVTransformationList) t).transformations); 38 | else transformations.add(0, t); 39 | 40 | compact(); 41 | return this; 42 | } 43 | 44 | private void compact() { 45 | ArrayList newList = new ArrayList(transformations.size()); 46 | Iterator iterator = transformations.iterator(); 47 | UVTransformation prev = null; 48 | while (iterator.hasNext()) { 49 | UVTransformation t = iterator.next(); 50 | if (t.isRedundant()) continue; 51 | 52 | if (prev != null) { 53 | UVTransformation m = prev.merge(t); 54 | if (m == null) newList.add(prev); 55 | else if (m.isRedundant()) t = null; 56 | else t = m; 57 | } 58 | prev = t; 59 | } 60 | if (prev != null) newList.add(prev); 61 | 62 | if (newList.size() < transformations.size()) transformations = newList; 63 | } 64 | 65 | @Override 66 | public boolean isRedundant() { 67 | return transformations.size() == 0; 68 | } 69 | 70 | @Override 71 | public UVTransformation inverse() { 72 | UVTransformationList rev = new UVTransformationList(); 73 | for (int i = transformations.size() - 1; i >= 0; i--) rev.with(transformations.get(i).inverse()); 74 | return rev; 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | String s = ""; 80 | for (UVTransformation t : transformations) s += "\n" + t.toString(); 81 | return s.trim(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/render/uv/UVTranslation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.render.uv; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | import codechicken.lib.math.MathHelper; 8 | 9 | public class UVTranslation extends UVTransformation { 10 | 11 | public double du; 12 | public double dv; 13 | 14 | public UVTranslation(double u, double v) { 15 | du = u; 16 | dv = v; 17 | } 18 | 19 | @Override 20 | public void apply(UV uv) { 21 | uv.u += du; 22 | uv.v += dv; 23 | } 24 | 25 | @Override 26 | public UVTransformation at(UV point) { 27 | return this; 28 | } 29 | 30 | @Override 31 | public UVTransformation inverse() { 32 | return new UVTranslation(-du, -dv); 33 | } 34 | 35 | @Override 36 | public UVTransformation merge(UVTransformation next) { 37 | if (next instanceof UVTranslation) { 38 | UVTranslation t = (UVTranslation) next; 39 | return new UVTranslation(du + t.du, dv + t.dv); 40 | } 41 | 42 | return null; 43 | } 44 | 45 | @Override 46 | public boolean isRedundant() { 47 | return MathHelper.between(-1E-5, du, 1E-5) && MathHelper.between(-1E-5, dv, 1E-5); 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | MathContext cont = new MathContext(4, RoundingMode.HALF_UP); 53 | return "UVTranslation(" + new BigDecimal(du, cont) + ", " + new BigDecimal(dv, cont) + ")"; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/tool/LibDownloader.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.tool; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.InputStream; 6 | import java.lang.reflect.Method; 7 | import java.net.URL; 8 | import java.net.URLClassLoader; 9 | import java.net.URLConnection; 10 | import java.nio.ByteBuffer; 11 | import java.util.LinkedList; 12 | import java.util.List; 13 | 14 | public class LibDownloader { 15 | 16 | private static String[] libs = new String[] { "org/ow2/asm/asm-debug-all/5.0.3/asm-debug-all-5.0.3.jar", 17 | "com/google/guava/guava/14.0/guava-14.0.jar", "net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar", 18 | "org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar", 19 | "org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar" }; 20 | private static File libDir = new File("lib"); 21 | 22 | private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23); 23 | 24 | public static void load() { 25 | if (!libDir.exists()) libDir.mkdir(); 26 | if (!libDir.isDirectory()) throw new RuntimeException("/lib is not a directory"); 27 | 28 | List missing = checkExists(); 29 | for (String lib : missing) download(lib); 30 | addPaths(libs); 31 | } 32 | 33 | private static void addPaths(String[] libs) { 34 | try { 35 | URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader(); 36 | Method m_addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class }); 37 | m_addURL.setAccessible(true); 38 | for (String lib : libs) m_addURL.invoke(cl, new File(libDir, fileName(lib)).toURI().toURL()); 39 | } catch (Exception e) { 40 | throw new RuntimeException("Failed to add libraries to classpath", e); 41 | } 42 | } 43 | 44 | private static void download(String lib) { 45 | File libFile = new File(libDir, fileName(lib)); 46 | try { 47 | URL libDownload = new URL("http://repo1.maven.org/maven2/" + lib); 48 | URLConnection connection = libDownload.openConnection(); 49 | connection.setConnectTimeout(5000); 50 | connection.setReadTimeout(5000); 51 | connection.setRequestProperty("User-Agent", "CodeChickenLib Downloader"); 52 | int sizeGuess = connection.getContentLength(); 53 | download(connection.getInputStream(), sizeGuess, libFile); 54 | } catch (Exception e) { 55 | libFile.delete(); 56 | throw new RuntimeException("A download error occured", e); 57 | } 58 | } 59 | 60 | private static void download(InputStream is, int sizeGuess, File target) throws Exception { 61 | String name = target.getName(); 62 | if (sizeGuess > downloadBuffer.capacity()) 63 | throw new Exception(String.format("The file %s is too large to be downloaded", name)); 64 | 65 | downloadBuffer.clear(); 66 | 67 | int bytesRead, fullLength = 0; 68 | 69 | System.out.format("Downloading lib %s", name); 70 | byte[] smallBuffer = new byte[1024]; 71 | while ((bytesRead = is.read(smallBuffer)) >= 0) { 72 | downloadBuffer.put(smallBuffer, 0, bytesRead); 73 | fullLength += bytesRead; 74 | System.out.format("\rDownloading lib %s %d%%", name, (int) (fullLength * 100 / sizeGuess)); 75 | } 76 | System.out.format("\rDownloaded lib %s \n", name); 77 | is.close(); 78 | downloadBuffer.limit(fullLength); 79 | 80 | if (!target.exists()) target.createNewFile(); 81 | 82 | downloadBuffer.position(0); 83 | FileOutputStream fos = new FileOutputStream(target); 84 | fos.getChannel().write(downloadBuffer); 85 | fos.close(); 86 | } 87 | 88 | private static String fileName(String lib) { 89 | return lib.replaceAll(".+/", ""); 90 | } 91 | 92 | private static List checkExists() { 93 | LinkedList list = new LinkedList(); 94 | for (String lib : libs) { 95 | File file = new File(libDir, fileName(lib)); 96 | if (!file.exists()) list.add(lib); 97 | } 98 | return list; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/tool/MCStripTransformer.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.tool; 2 | 3 | import java.util.Iterator; 4 | 5 | import org.objectweb.asm.ClassReader; 6 | import org.objectweb.asm.MethodVisitor; 7 | import org.objectweb.asm.Opcodes; 8 | import org.objectweb.asm.commons.Remapper; 9 | import org.objectweb.asm.commons.RemappingMethodAdapter; 10 | import org.objectweb.asm.tree.ClassNode; 11 | import org.objectweb.asm.tree.MethodNode; 12 | 13 | import codechicken.lib.asm.ASMHelper; 14 | 15 | public class MCStripTransformer { 16 | 17 | public static class ReferenceDetector extends Remapper { 18 | 19 | boolean found = false; 20 | 21 | @Override 22 | public String map(String typeName) { 23 | if (typeName.startsWith("net/minecraft") || !typeName.contains("/")) found = true; 24 | return typeName; 25 | } 26 | } 27 | 28 | public static byte[] transform(byte[] bytes) { 29 | ClassNode cnode = ASMHelper.createClassNode(bytes, ClassReader.EXPAND_FRAMES); 30 | 31 | boolean changed = false; 32 | Iterator it = cnode.methods.iterator(); 33 | while (it.hasNext()) { 34 | MethodNode mnode = it.next(); 35 | ReferenceDetector r = new ReferenceDetector(); 36 | mnode.accept(new RemappingMethodAdapter(mnode.access, mnode.desc, new MethodVisitor(Opcodes.ASM4) {}, r)); 37 | if (r.found) { 38 | it.remove(); 39 | changed = true; 40 | } 41 | } 42 | if (changed) bytes = ASMHelper.createBytes(cnode, 0); 43 | return bytes; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/tool/Main.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.tool; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | LibDownloader.load(); 7 | try { 8 | Class c_toolMain = new StripClassLoader().loadClass("codechicken.lib.tool.ToolMain"); 9 | c_toolMain.getDeclaredMethod("main", String[].class).invoke(null, new Object[] { args }); 10 | } catch (Exception e) { 11 | throw new RuntimeException(e); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/tool/StripClassLoader.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.tool; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.net.URL; 7 | import java.net.URLClassLoader; 8 | 9 | public class StripClassLoader extends URLClassLoader { 10 | 11 | public StripClassLoader() { 12 | super(new URL[0], StripClassLoader.class.getClassLoader()); 13 | } 14 | 15 | @Override 16 | public Class loadClass(String name) throws ClassNotFoundException { 17 | if (!name.startsWith("codechicken.lib")) return super.loadClass(name); 18 | 19 | try { 20 | String resName = name.replace('.', '/') + ".class"; 21 | InputStream res = getResourceAsStream(resName); 22 | if (res == null) throw new ClassNotFoundException("Could not find resource: " + resName); 23 | byte[] bytes = readFully(res); 24 | bytes = transform(bytes); 25 | return defineClass(name, bytes, 0, bytes.length); 26 | 27 | } catch (IOException e) { 28 | throw new ClassNotFoundException(name, e); 29 | } 30 | } 31 | 32 | public static byte[] readFully(InputStream is) throws IOException { 33 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 34 | 35 | int read; 36 | byte[] data = new byte[16384]; 37 | while ((read = is.read(data, 0, data.length)) > 0) buffer.write(data, 0, read); 38 | 39 | return buffer.toByteArray(); 40 | } 41 | 42 | private byte[] transform(byte[] bytes) { 43 | 44 | bytes = MCStripTransformer.transform(bytes); 45 | return bytes; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/tool/ToolMain.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.tool; 2 | 3 | import codechicken.lib.tool.module.ModuleQBConverter; 4 | 5 | public class ToolMain { 6 | 7 | public static interface Module { 8 | 9 | public void main(String[] args); 10 | 11 | public String name(); 12 | 13 | public void printHelp(); 14 | } 15 | 16 | public static Module[] modules = new Module[] { new ModuleQBConverter() }; 17 | 18 | private static void printHelp() { 19 | System.out.println("Usage: [module] [args]"); 20 | System.out.println(" Modules: "); 21 | for (Module m : modules) System.out.println(" - " + m.name()); 22 | System.out.println("-h [module] for module help"); 23 | } 24 | 25 | public static void main(String[] args) { 26 | if (args.length > 0) { 27 | for (Module m : modules) if (args[0].equals(m.name())) { 28 | String[] args2 = new String[args.length - 1]; 29 | System.arraycopy(args, 1, args2, 0, args2.length); 30 | m.main(args2); 31 | return; 32 | } 33 | if (args[0].equals("-h") && args.length >= 2) { 34 | for (Module m : modules) if (args[1].equals(m.name())) { 35 | m.printHelp(); 36 | return; 37 | } 38 | } 39 | } 40 | printHelp(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/tool/module/JOptModule.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.tool.module; 2 | 3 | import java.io.IOException; 4 | 5 | import codechicken.lib.tool.ToolMain; 6 | import joptsimple.OptionException; 7 | import joptsimple.OptionParser; 8 | import joptsimple.OptionSet; 9 | 10 | public abstract class JOptModule implements ToolMain.Module { 11 | 12 | OptionParser parser = new OptionParser(); 13 | 14 | @Override 15 | public void main(String[] args) { 16 | OptionSet options; 17 | try { 18 | options = parser.parse(args); 19 | } catch (OptionException ex) { 20 | System.err.println(ex.getLocalizedMessage()); 21 | System.exit(-1); 22 | return; 23 | } 24 | 25 | try { 26 | main(parser, options); 27 | } catch (Exception e) { 28 | throw new RuntimeException(e); 29 | } 30 | } 31 | 32 | protected abstract void main(OptionParser parser, OptionSet options); 33 | 34 | @Override 35 | public void printHelp() { 36 | try { 37 | parser.printHelpOn(System.out); 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/tool/module/ModuleQBConverter.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.tool.module; 2 | 3 | import static java.util.Arrays.asList; 4 | 5 | import java.io.File; 6 | 7 | import codechicken.lib.render.QBImporter; 8 | import joptsimple.OptionParser; 9 | import joptsimple.OptionSet; 10 | 11 | public class ModuleQBConverter extends JOptModule { 12 | 13 | public ModuleQBConverter() { 14 | parser.acceptsAll(asList("?", "h", "help"), "Show the help"); 15 | parser.acceptsAll(asList("i", "input"), "comma separated list of paths to models (.qb or directories)") 16 | .withRequiredArg().ofType(File.class).withValuesSeparatedBy(',').required(); 17 | parser.acceptsAll(asList("o", "out"), "Output Directory").withRequiredArg().ofType(File.class); 18 | parser.acceptsAll( 19 | asList("o2", "textureplanes"), 20 | "2nd level optimisation. Merges coplanar polygons. Increases texture size"); 21 | parser.acceptsAll(asList("s", "squaretextures"), "Produce square textures"); 22 | parser.acceptsAll(asList("t", "mergetextures"), "Use the same texture for all models"); 23 | parser.acceptsAll(asList("r", "scalemc"), "Resize model to mc standard (shrink by factor of 16)"); 24 | } 25 | 26 | protected void main(OptionParser parser, OptionSet options) { 27 | int flags = 0; 28 | if (options.has("o2")) flags |= QBImporter.TEXTUREPLANES; 29 | if (options.has("s")) flags |= QBImporter.SQUARETEXTURE; 30 | if (options.has("t")) flags |= QBImporter.MERGETEXTURES; 31 | if (options.has("r")) flags |= QBImporter.SCALEMC; 32 | 33 | File[] input = options.valuesOf("input").toArray(new File[0]); 34 | File[] outDir = new File[input.length]; 35 | if (options.has("out")) { 36 | File output = (File) options.valueOf("out"); 37 | if (output.isFile()) throw new RuntimeException("Output Path is not a directory"); 38 | if (!output.exists()) output.mkdirs(); 39 | 40 | for (int i = 0; i < input.length; i++) outDir[i] = output; 41 | } else { 42 | for (int i = 0; i < input.length; i++) 43 | outDir[i] = input[i].isDirectory() ? input[i] : input[i].getParentFile(); 44 | } 45 | 46 | for (int i = 0; i < input.length; i++) { 47 | File file = input[i]; 48 | if (file.isDirectory()) { 49 | for (File file2 : file.listFiles()) 50 | if (file2.getName().endsWith(".qb")) convert(file2, outDir[i], flags); 51 | } else convert(file, outDir[i], flags); 52 | } 53 | } 54 | 55 | private void convert(File in, File outDir, int flags) { 56 | System.out.println("Converting: " + in.getName()); 57 | QBImporter.RasterisedModel m = QBImporter.loadQB(in).toRasterisedModel(flags); 58 | m.export(new File(outDir, in.getName().replace(".qb", ".obj")), outDir); 59 | } 60 | 61 | @Override 62 | public String name() { 63 | return "QBConverter"; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/util/Copyable.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.util; 2 | 3 | public interface Copyable { 4 | 5 | public T copy(); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/util/LangProxy.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.util; 2 | 3 | import net.minecraft.util.StatCollector; 4 | 5 | public class LangProxy { 6 | 7 | public final String namespace; 8 | 9 | public LangProxy(String namespace) { 10 | this.namespace = namespace + "."; 11 | } 12 | 13 | public String translate(String key) { 14 | return StatCollector.translateToLocal(namespace + key); 15 | } 16 | 17 | public String format(String key, Object... params) { 18 | return StatCollector.translateToLocalFormatted(namespace + key, params); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/AxisCycle.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | public class AxisCycle { 4 | 5 | public static Transformation[] cycles = new Transformation[] { new RedundantTransformation(), 6 | new VariableTransformation(new Matrix4(0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)) { 7 | 8 | @Override 9 | public void apply(Vector3 vec) { 10 | double d0 = vec.x; 11 | double d1 = vec.y; 12 | double d2 = vec.z; 13 | vec.x = d2; 14 | vec.y = d0; 15 | vec.z = d1; 16 | } 17 | 18 | @Override 19 | public Transformation inverse() { 20 | return cycles[2]; 21 | } 22 | }, new VariableTransformation(new Matrix4(0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1)) { 23 | 24 | @Override 25 | public void apply(Vector3 vec) { 26 | double d0 = vec.x; 27 | double d1 = vec.y; 28 | double d2 = vec.z; 29 | vec.x = d1; 30 | vec.y = d2; 31 | vec.z = d0; 32 | } 33 | 34 | @Override 35 | public Transformation inverse() { 36 | return cycles[1]; 37 | } 38 | } }; 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/ITransformation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | /** 4 | * Abstract supertype for any VectorN transformation 5 | * 6 | * @param The vector type 7 | * @param The transformation type 8 | */ 9 | public abstract class ITransformation { 10 | 11 | /** 12 | * Applies this transformation to vec 13 | */ 14 | public abstract void apply(Vector vec); 15 | 16 | /** 17 | * @param point The point to apply this transformation around 18 | * @return Wraps this transformation in a translation to point and then back from point 19 | */ 20 | public abstract Transformation at(Vector point); 21 | 22 | /** 23 | * Creates a TransformationList composed of this transformation followed by t If this is a TransformationList, the 24 | * transformation will be appended and this returned 25 | */ 26 | public abstract Transformation with(Transformation t); 27 | 28 | /** 29 | * Returns a simplified transformation that performs this, followed by next. If such a transformation does not 30 | * exist, returns null 31 | */ 32 | public Transformation merge(Transformation next) { 33 | return null; 34 | } 35 | 36 | /** 37 | * Returns true if this transformation is redundant, eg. Scale(1, 1, 1), Translation(0, 0, 0) or Rotation(0, a, b, 38 | * c) 39 | */ 40 | public boolean isRedundant() { 41 | return false; 42 | } 43 | 44 | public abstract Transformation inverse(); 45 | 46 | /** 47 | * Scala ++ operator 48 | */ 49 | public Transformation $plus$plus(Transformation t) { 50 | return with(t); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/IrreversibleTransformationException.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | @SuppressWarnings("serial") 4 | public class IrreversibleTransformationException extends RuntimeException { 5 | 6 | public ITransformation t; 7 | 8 | public IrreversibleTransformationException(ITransformation t) { 9 | this.t = t; 10 | } 11 | 12 | @Override 13 | public String getMessage() { 14 | return "The following transformation is irreversible:\n" + t; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/Line3.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | public class Line3 { 4 | 5 | public static final double tol = 0.0001D; 6 | 7 | public Vector3 pt1; 8 | public Vector3 pt2; 9 | 10 | public Line3(Vector3 pt1, Vector3 pt2) { 11 | this.pt1 = pt1; 12 | this.pt2 = pt2; 13 | } 14 | 15 | public Line3() { 16 | this(new Vector3(), new Vector3()); 17 | } 18 | 19 | public static boolean intersection2D(Line3 line1, Line3 line2, Vector3 store) { 20 | // calculate differences 21 | double xD1 = line1.pt2.x - line1.pt1.x; 22 | double zD1 = line1.pt2.z - line1.pt1.z; 23 | double xD2 = line2.pt2.x - line2.pt1.x; 24 | double zD2 = line2.pt2.z - line2.pt1.z; 25 | 26 | double xD3 = line1.pt1.x - line2.pt1.x; 27 | double zD3 = line1.pt1.z - line2.pt1.z; 28 | 29 | double div = zD2 * xD1 - xD2 * zD1; 30 | if (div == 0) // lines are parallel 31 | return false; 32 | double ua = (xD2 * zD3 - zD2 * xD3) / div; 33 | store.set(line1.pt1.x + ua * xD1, 0, line1.pt1.z + ua * zD1); 34 | 35 | if (store.x >= Math.min(line1.pt1.x, line1.pt2.x) - tol && store.x >= Math.min(line2.pt1.x, line2.pt2.x) - tol 36 | && store.z >= Math.min(line1.pt1.z, line1.pt2.z) - tol 37 | && store.z >= Math.min(line2.pt1.z, line2.pt2.z) - tol 38 | && store.x <= Math.max(line1.pt1.x, line1.pt2.x) + tol 39 | && store.x <= Math.max(line2.pt1.x, line2.pt2.x) + tol 40 | && store.z <= Math.max(line1.pt1.z, line1.pt2.z) + tol 41 | && store.z <= Math.max(line2.pt1.z, line2.pt2.z) + tol) 42 | return true; 43 | 44 | return false; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/Quat.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | import codechicken.lib.math.MathHelper; 8 | import codechicken.lib.util.Copyable; 9 | 10 | public class Quat implements Copyable { 11 | 12 | public double x; 13 | public double y; 14 | public double z; 15 | public double s; 16 | 17 | public Quat() { 18 | s = 1; 19 | x = 0; 20 | y = 0; 21 | z = 0; 22 | } 23 | 24 | public Quat(Quat quat) { 25 | x = quat.x; 26 | y = quat.y; 27 | z = quat.z; 28 | s = quat.s; 29 | } 30 | 31 | public Quat(double d, double d1, double d2, double d3) { 32 | x = d1; 33 | y = d2; 34 | z = d3; 35 | s = d; 36 | } 37 | 38 | public Quat set(Quat quat) { 39 | x = quat.x; 40 | y = quat.y; 41 | z = quat.z; 42 | s = quat.s; 43 | 44 | return this; 45 | } 46 | 47 | public Quat set(double d, double d1, double d2, double d3) { 48 | x = d1; 49 | y = d2; 50 | z = d3; 51 | s = d; 52 | 53 | return this; 54 | } 55 | 56 | public static Quat aroundAxis(double ax, double ay, double az, double angle) { 57 | return new Quat().setAroundAxis(ax, ay, az, angle); 58 | } 59 | 60 | public static Quat aroundAxis(Vector3 axis, double angle) { 61 | return aroundAxis(axis.x, axis.y, axis.z, angle); 62 | } 63 | 64 | public Quat setAroundAxis(double ax, double ay, double az, double angle) { 65 | angle *= 0.5; 66 | double d4 = MathHelper.sin(angle); 67 | return set(MathHelper.cos(angle), ax * d4, ay * d4, az * d4); 68 | } 69 | 70 | public Quat setAroundAxis(Vector3 axis, double angle) { 71 | return setAroundAxis(axis.x, axis.y, axis.z, angle); 72 | } 73 | 74 | public Quat multiply(Quat quat) { 75 | double d = s * quat.s - x * quat.x - y * quat.y - z * quat.z; 76 | double d1 = s * quat.x + x * quat.s - y * quat.z + z * quat.y; 77 | double d2 = s * quat.y + x * quat.z + y * quat.s - z * quat.x; 78 | double d3 = s * quat.z - x * quat.y + y * quat.x + z * quat.s; 79 | s = d; 80 | x = d1; 81 | y = d2; 82 | z = d3; 83 | 84 | return this; 85 | } 86 | 87 | public Quat rightMultiply(Quat quat) { 88 | double d = s * quat.s - x * quat.x - y * quat.y - z * quat.z; 89 | double d1 = s * quat.x + x * quat.s + y * quat.z - z * quat.y; 90 | double d2 = s * quat.y - x * quat.z + y * quat.s + z * quat.x; 91 | double d3 = s * quat.z + x * quat.y - y * quat.x + z * quat.s; 92 | s = d; 93 | x = d1; 94 | y = d2; 95 | z = d3; 96 | 97 | return this; 98 | } 99 | 100 | public double mag() { 101 | return Math.sqrt(x * x + y * y + z * z + s * s); 102 | } 103 | 104 | public Quat normalize() { 105 | double d = mag(); 106 | if (d != 0) { 107 | d = 1 / d; 108 | x *= d; 109 | y *= d; 110 | z *= d; 111 | s *= d; 112 | } 113 | 114 | return this; 115 | } 116 | 117 | public Quat copy() { 118 | return new Quat(this); 119 | } 120 | 121 | public void rotate(Vector3 vec) { 122 | double d = -x * vec.x - y * vec.y - z * vec.z; 123 | double d1 = s * vec.x + y * vec.z - z * vec.y; 124 | double d2 = s * vec.y - x * vec.z + z * vec.x; 125 | double d3 = s * vec.z + x * vec.y - y * vec.x; 126 | vec.x = d1 * s - d * x - d2 * z + d3 * y; 127 | vec.y = d2 * s - d * y + d1 * z - d3 * x; 128 | vec.z = d3 * s - d * z - d1 * y + d2 * x; 129 | } 130 | 131 | public String toString() { 132 | MathContext cont = new MathContext(4, RoundingMode.HALF_UP); 133 | return "Quat(" + new BigDecimal(s, cont) 134 | + ", " 135 | + new BigDecimal(x, cont) 136 | + ", " 137 | + new BigDecimal(y, cont) 138 | + ", " 139 | + new BigDecimal(z, cont) 140 | + ")"; 141 | } 142 | 143 | public Rotation rotation() { 144 | return new Rotation(this); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/Rectangle4i.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | public class Rectangle4i { 4 | 5 | public int x; 6 | public int y; 7 | public int w; 8 | public int h; 9 | 10 | public Rectangle4i() {} 11 | 12 | public Rectangle4i(int x, int y, int w, int h) { 13 | this.x = x; 14 | this.y = y; 15 | this.w = w; 16 | this.h = h; 17 | } 18 | 19 | public int x1() { 20 | return x; 21 | } 22 | 23 | public int y1() { 24 | return y; 25 | } 26 | 27 | public int x2() { 28 | return x + w - 1; 29 | } 30 | 31 | public int y2() { 32 | return y + h - 1; 33 | } 34 | 35 | public void set(int x, int y, int w, int h) { 36 | this.x = x; 37 | this.y = y; 38 | this.w = w; 39 | this.h = h; 40 | } 41 | 42 | public Rectangle4i offset(int dx, int dy) { 43 | x += dx; 44 | y += dy; 45 | return this; 46 | } 47 | 48 | @Deprecated 49 | public Rectangle4i with(int px, int py) { 50 | return include(px, py); 51 | } 52 | 53 | public Rectangle4i include(int px, int py) { 54 | if (px < x) expand(px - x, 0); 55 | if (px >= x + w) expand(px - x - w + 1, 0); 56 | if (py < y) expand(0, py - y); 57 | if (py >= y + h) expand(0, py - y - h + 1); 58 | return this; 59 | } 60 | 61 | public Rectangle4i include(Rectangle4i r) { 62 | include(r.x, r.y); 63 | return include(r.x2(), r.y2()); 64 | } 65 | 66 | public Rectangle4i expand(int px, int py) { 67 | if (px > 0) w += px; 68 | else { 69 | x += px; 70 | w -= px; 71 | } 72 | if (py > 0) h += py; 73 | else { 74 | y += py; 75 | h -= py; 76 | } 77 | return this; 78 | } 79 | 80 | public boolean contains(int px, int py) { 81 | return x <= px && px < x + w && y <= py && py < y + h; 82 | } 83 | 84 | public boolean intersects(Rectangle4i r) { 85 | return r.x + r.w > x && r.x < x + w && r.y + r.h > y && r.y < y + h; 86 | } 87 | 88 | public int area() { 89 | return w * h; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/RedundantTransformation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | import cpw.mods.fml.relauncher.Side; 4 | import cpw.mods.fml.relauncher.SideOnly; 5 | 6 | public class RedundantTransformation extends Transformation { 7 | 8 | @Override 9 | public void apply(Vector3 vec) {} 10 | 11 | @Override 12 | public void apply(Matrix4 mat) {} 13 | 14 | @Override 15 | public void applyN(Vector3 normal) {} 16 | 17 | @Override 18 | public Transformation at(Vector3 point) { 19 | return this; 20 | } 21 | 22 | @Override 23 | @SideOnly(Side.CLIENT) 24 | public void glApply() {} 25 | 26 | @Override 27 | public Transformation inverse() { 28 | return this; 29 | } 30 | 31 | @Override 32 | public Transformation merge(Transformation next) { 33 | return next; 34 | } 35 | 36 | @Override 37 | public boolean isRedundant() { 38 | return true; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "Nothing()"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/Scale.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | import org.lwjgl.opengl.GL11; 8 | 9 | import cpw.mods.fml.relauncher.Side; 10 | import cpw.mods.fml.relauncher.SideOnly; 11 | 12 | public class Scale extends Transformation { 13 | 14 | public Vector3 factor; 15 | 16 | public Scale(Vector3 factor) { 17 | this.factor = factor; 18 | } 19 | 20 | public Scale(double factor) { 21 | this(new Vector3(factor, factor, factor)); 22 | } 23 | 24 | public Scale(double x, double y, double z) { 25 | this(new Vector3(x, y, z)); 26 | } 27 | 28 | @Override 29 | public void apply(Vector3 vec) { 30 | vec.multiply(factor); 31 | } 32 | 33 | @Override 34 | public void applyN(Vector3 normal) {} 35 | 36 | @Override 37 | public void apply(Matrix4 mat) { 38 | mat.scale(factor); 39 | } 40 | 41 | @Override 42 | @SideOnly(Side.CLIENT) 43 | public void glApply() { 44 | GL11.glScaled(factor.x, factor.y, factor.z); 45 | } 46 | 47 | @Override 48 | public Transformation inverse() { 49 | return new Scale(1 / factor.x, 1 / factor.y, 1 / factor.z); 50 | } 51 | 52 | @Override 53 | public Transformation merge(Transformation next) { 54 | if (next instanceof Scale) return new Scale(factor.copy().multiply(((Scale) next).factor)); 55 | 56 | return null; 57 | } 58 | 59 | @Override 60 | public boolean isRedundant() { 61 | return factor.equalsT(Vector3.one); 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | MathContext cont = new MathContext(4, RoundingMode.HALF_UP); 67 | return "Scale(" + new BigDecimal(factor.x, cont) 68 | + ", " 69 | + new BigDecimal(factor.y, cont) 70 | + ", " 71 | + new BigDecimal(factor.z, cont) 72 | + ")"; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/SwapYZ.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | public class SwapYZ extends VariableTransformation { 4 | 5 | public SwapYZ() { 6 | super(new Matrix4(1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1)); 7 | } 8 | 9 | @Override 10 | public void apply(Vector3 vec) { 11 | double vz = vec.z; 12 | vec.z = vec.y; 13 | vec.y = vz; 14 | } 15 | 16 | @Override 17 | public Transformation inverse() { 18 | return this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/Transformation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | import codechicken.lib.render.CCRenderState; 4 | import cpw.mods.fml.relauncher.Side; 5 | import cpw.mods.fml.relauncher.SideOnly; 6 | 7 | /** 8 | * Abstract supertype for any 3D vector transformation 9 | */ 10 | public abstract class Transformation extends ITransformation 11 | implements CCRenderState.IVertexOperation { 12 | 13 | public static final int operationIndex = CCRenderState.registerOperation(); 14 | 15 | /** 16 | * Applies this transformation to a normal (doesn't translate) 17 | * 18 | * @param normal The normal to transform 19 | */ 20 | public abstract void applyN(Vector3 normal); 21 | 22 | /** 23 | * Applies this transformation to a matrix as a multiplication on the right hand side. 24 | * 25 | * @param mat The matrix to combine this transformation with 26 | */ 27 | public abstract void apply(Matrix4 mat); 28 | 29 | public Transformation at(Vector3 point) { 30 | return new TransformationList(new Translation(-point.x, -point.y, -point.z), this, point.translation()); 31 | } 32 | 33 | public TransformationList with(Transformation t) { 34 | return new TransformationList(this, t); 35 | } 36 | 37 | @SideOnly(Side.CLIENT) 38 | public abstract void glApply(); 39 | 40 | @Override 41 | public boolean load(CCRenderState state) { 42 | state.pipeline.addRequirement(CCRenderState.normalAttrib().operationID()); 43 | return !isRedundant(); 44 | } 45 | 46 | @Override 47 | public void operate(CCRenderState state) { 48 | apply(state.vert.vec); 49 | if (CCRenderState.normalAttrib().active) applyN(state.normal); 50 | } 51 | 52 | @Override 53 | public int operationID() { 54 | return operationIndex; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/Translation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.math.RoundingMode; 6 | 7 | import org.lwjgl.opengl.GL11; 8 | 9 | import cpw.mods.fml.relauncher.Side; 10 | import cpw.mods.fml.relauncher.SideOnly; 11 | 12 | public class Translation extends Transformation { 13 | 14 | public Vector3 vec; 15 | 16 | public Translation(Vector3 vec) { 17 | this.vec = vec; 18 | } 19 | 20 | public Translation(double x, double y, double z) { 21 | this(new Vector3(x, y, z)); 22 | } 23 | 24 | @Override 25 | public void apply(Vector3 vec) { 26 | vec.add(this.vec); 27 | } 28 | 29 | @Override 30 | public void applyN(Vector3 normal) {} 31 | 32 | @Override 33 | public void apply(Matrix4 mat) { 34 | mat.translate(vec); 35 | } 36 | 37 | @Override 38 | public Transformation at(Vector3 point) { 39 | return this; 40 | } 41 | 42 | @Override 43 | @SideOnly(Side.CLIENT) 44 | public void glApply() { 45 | GL11.glTranslated(vec.x, vec.y, vec.z); 46 | } 47 | 48 | @Override 49 | public Transformation inverse() { 50 | return new Translation(-vec.x, -vec.y, -vec.z); 51 | } 52 | 53 | @Override 54 | public Transformation merge(Transformation next) { 55 | if (next instanceof Translation) return new Translation(vec.copy().add(((Translation) next).vec)); 56 | 57 | return null; 58 | } 59 | 60 | @Override 61 | public boolean isRedundant() { 62 | return vec.equalsT(Vector3.zero); 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | MathContext cont = new MathContext(4, RoundingMode.HALF_UP); 68 | return "Translation(" + new BigDecimal(vec.x, cont) 69 | + ", " 70 | + new BigDecimal(vec.y, cont) 71 | + ", " 72 | + new BigDecimal(vec.z, cont) 73 | + ")"; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/vec/VariableTransformation.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.vec; 2 | 3 | import cpw.mods.fml.relauncher.Side; 4 | import cpw.mods.fml.relauncher.SideOnly; 5 | 6 | public abstract class VariableTransformation extends Transformation { 7 | 8 | public Matrix4 mat; 9 | 10 | public VariableTransformation(Matrix4 mat) { 11 | this.mat = mat; 12 | } 13 | 14 | @Override 15 | public void applyN(Vector3 normal) { 16 | apply(normal); 17 | } 18 | 19 | @Override 20 | public void apply(Matrix4 mat) { 21 | mat.multiply(this.mat); 22 | } 23 | 24 | @Override 25 | @SideOnly(Side.CLIENT) 26 | public void glApply() { 27 | mat.glApply(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/world/ChunkExtension.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.world; 2 | 3 | import java.util.HashSet; 4 | 5 | import net.minecraft.entity.player.EntityPlayerMP; 6 | import net.minecraft.nbt.NBTTagCompound; 7 | import net.minecraft.network.Packet; 8 | import net.minecraft.world.ChunkCoordIntPair; 9 | import net.minecraft.world.chunk.Chunk; 10 | 11 | public abstract class ChunkExtension { 12 | 13 | public final Chunk chunk; 14 | public final ChunkCoordIntPair coord; 15 | public final WorldExtension world; 16 | public HashSet watchedPlayers; 17 | 18 | public ChunkExtension(Chunk chunk, WorldExtension world) { 19 | this.chunk = chunk; 20 | coord = chunk.getChunkCoordIntPair(); 21 | this.world = world; 22 | watchedPlayers = new HashSet(); 23 | } 24 | 25 | public void loadData(NBTTagCompound tag) {} 26 | 27 | public void saveData(NBTTagCompound tag) {} 28 | 29 | public void load() {} 30 | 31 | public void unload() {} 32 | 33 | public final void sendPacketToPlayers(Packet packet) { 34 | for (EntityPlayerMP player : watchedPlayers) player.playerNetServerHandler.sendPacket(packet); 35 | } 36 | 37 | public final void watchPlayer(EntityPlayerMP player) { 38 | watchedPlayers.add(player); 39 | onWatchPlayer(player); 40 | } 41 | 42 | public void onWatchPlayer(EntityPlayerMP player) {} 43 | 44 | public final void unwatchPlayer(EntityPlayerMP player) { 45 | watchedPlayers.remove(player); 46 | onUnWatchPlayer(player); 47 | } 48 | 49 | public void onUnWatchPlayer(EntityPlayerMP player) {} 50 | 51 | public void sendUpdatePackets() {} 52 | 53 | @Override 54 | public int hashCode() { 55 | return coord.chunkXPos ^ coord.chunkZPos; 56 | } 57 | 58 | @Override 59 | public boolean equals(Object o) { 60 | return (o instanceof ChunkExtension && ((ChunkExtension) o).coord.equals(coord)) 61 | || (o instanceof ChunkCoordIntPair && coord.equals(o)) 62 | || (o instanceof Long && (Long) o == (((long) coord.chunkXPos) << 32 | coord.chunkZPos)); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/world/IChunkLoadTile.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.world; 2 | 3 | /** 4 | * Provides a callback for tile entities when a chunk is loaded, as an alternative to validate when the chunk hasn't 5 | * been added to the world. To hook all world join/seperate events. Use this, TileEntity.validate with a 6 | * worldObj.blockExists check, TileEntity.onChunkUnload and TileEntity.invalidate Be sure to call 7 | * TileChunkLoadHook.init() from your mod during initialisation You could easily implement this in your own mod, but 8 | * providing it here reduces the number of times the chunkTileEntityMap needs to be iterated 9 | */ 10 | public interface IChunkLoadTile { 11 | 12 | public void onChunkLoad(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/world/TileChunkLoadHook.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.world; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import net.minecraft.tileentity.TileEntity; 7 | import net.minecraftforge.common.MinecraftForge; 8 | import net.minecraftforge.event.world.ChunkEvent; 9 | 10 | import cpw.mods.fml.common.eventhandler.SubscribeEvent; 11 | 12 | public class TileChunkLoadHook { 13 | 14 | private static boolean init; 15 | 16 | public static void init() { 17 | if (init) return; 18 | init = true; 19 | 20 | MinecraftForge.EVENT_BUS.register(new TileChunkLoadHook()); 21 | } 22 | 23 | @SubscribeEvent 24 | public void onChunkLoad(ChunkEvent.Load event) { 25 | List list = new ArrayList(event.getChunk().chunkTileEntityMap.values()); 26 | for (TileEntity t : list) if (t instanceof IChunkLoadTile) ((IChunkLoadTile) t).onChunkLoad(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/world/WorldExtension.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.world; 2 | 3 | import java.util.HashMap; 4 | 5 | import net.minecraft.entity.player.EntityPlayerMP; 6 | import net.minecraft.nbt.NBTTagCompound; 7 | import net.minecraft.world.World; 8 | import net.minecraft.world.chunk.Chunk; 9 | 10 | public abstract class WorldExtension { 11 | 12 | public final World world; 13 | public HashMap chunkMap = new HashMap(); 14 | 15 | public WorldExtension(World world) { 16 | this.world = world; 17 | } 18 | 19 | public void load() {} 20 | 21 | public void unload() {} 22 | 23 | public void save() {} 24 | 25 | public void preTick() {} 26 | 27 | public void postTick() {} 28 | 29 | protected final void addChunk(ChunkExtension extension) { 30 | chunkMap.put(extension.chunk, extension); 31 | } 32 | 33 | protected final void loadChunk(Chunk chunk) { 34 | chunkMap.get(chunk).load(); 35 | } 36 | 37 | protected final void unloadChunk(Chunk chunk) { 38 | if (chunkMap.get(chunk) != null) chunkMap.get(chunk).unload(); 39 | } 40 | 41 | protected final void loadChunkData(Chunk chunk, NBTTagCompound tag) { 42 | chunkMap.get(chunk).loadData(tag); 43 | } 44 | 45 | protected final void saveChunkData(Chunk chunk, NBTTagCompound tag) { 46 | final ChunkExtension extension = chunkMap.get(chunk); 47 | if (extension != null) extension.saveData(tag); 48 | } 49 | 50 | protected final void remChunk(Chunk chunk) { 51 | chunkMap.remove(chunk); 52 | } 53 | 54 | protected final void watchChunk(Chunk chunk, EntityPlayerMP player) { 55 | chunkMap.get(chunk).watchPlayer(player); 56 | } 57 | 58 | protected final void unwatchChunk(Chunk chunk, EntityPlayerMP player) { 59 | ChunkExtension extension = chunkMap.get(chunk); 60 | if (extension != null) extension.unwatchPlayer(player); 61 | } 62 | 63 | protected final void sendChunkUpdates(Chunk chunk) { 64 | chunkMap.get(chunk).sendUpdatePackets(); 65 | } 66 | 67 | public boolean containsChunk(Chunk chunk) { 68 | return chunkMap.containsKey(chunk); 69 | } 70 | 71 | public ChunkExtension getChunkExtension(int chunkXPos, int chunkZPos) { 72 | if (!world.blockExists(chunkXPos << 4, 128, chunkZPos << 4)) return null; 73 | 74 | return chunkMap.get(world.getChunkFromChunkCoords(chunkXPos, chunkZPos)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/codechicken/lib/world/WorldExtensionInstantiator.java: -------------------------------------------------------------------------------- 1 | package codechicken.lib.world; 2 | 3 | import net.minecraft.world.World; 4 | import net.minecraft.world.chunk.Chunk; 5 | 6 | public abstract class WorldExtensionInstantiator { 7 | 8 | public int instantiatorID; 9 | 10 | public abstract WorldExtension createWorldExtension(World world); 11 | 12 | public abstract ChunkExtension createChunkExtension(Chunk chunk, WorldExtension world); 13 | 14 | public WorldExtension getExtension(World world) { 15 | return WorldExtensionManager.getWorldExtension(world, instantiatorID); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/codechicken/obfuscator/ConstantObfuscator.java: -------------------------------------------------------------------------------- 1 | package codechicken.obfuscator; 2 | 3 | import static org.objectweb.asm.tree.AbstractInsnNode.LDC_INSN; 4 | import static org.objectweb.asm.tree.AbstractInsnNode.METHOD_INSN; 5 | 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | 9 | import org.objectweb.asm.Opcodes; 10 | import org.objectweb.asm.tree.AbstractInsnNode; 11 | import org.objectweb.asm.tree.ClassNode; 12 | import org.objectweb.asm.tree.LdcInsnNode; 13 | import org.objectweb.asm.tree.MethodInsnNode; 14 | import org.objectweb.asm.tree.MethodNode; 15 | 16 | import codechicken.lib.asm.ObfMapping; 17 | 18 | public class ConstantObfuscator implements Opcodes { 19 | 20 | public ObfRemapper obf; 21 | public List descCalls = new LinkedList(); 22 | public List classCalls = new LinkedList(); 23 | 24 | public ConstantObfuscator(ObfRemapper obf, String[] a_classCalls, String[] a_descCalls) { 25 | this.obf = obf; 26 | for (String callDesc : a_classCalls) classCalls.add(ObfMapping.fromDesc(callDesc)); 27 | 28 | for (String callDesc : a_descCalls) descCalls.add(ObfMapping.fromDesc(callDesc)); 29 | } 30 | 31 | public void transform(ClassNode cnode) { 32 | for (MethodNode method : cnode.methods) 33 | for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) 34 | obfuscateInsnSeq(insn); 35 | } 36 | 37 | private void obfuscateInsnSeq(AbstractInsnNode insn) { 38 | if (matchesClass(insn)) { 39 | LdcInsnNode node1 = (LdcInsnNode) insn; 40 | node1.cst = obf.map((String) node1.cst); 41 | } 42 | if (matchesDesc(insn)) { 43 | LdcInsnNode node1 = (LdcInsnNode) insn; 44 | LdcInsnNode node2 = (LdcInsnNode) node1.getNext(); 45 | LdcInsnNode node3 = (LdcInsnNode) node2.getNext(); 46 | ObfMapping mapping = new ObfMapping((String) node1.cst, (String) node2.cst, (String) node3.cst).map(obf); 47 | node1.cst = mapping.s_owner; 48 | node2.cst = mapping.s_name; 49 | node3.cst = mapping.s_desc; 50 | } 51 | } 52 | 53 | private boolean matchesClass(AbstractInsnNode insn) { 54 | if (insn.getType() != LDC_INSN) return false; 55 | insn = insn.getNext(); 56 | if (insn == null || insn.getType() != METHOD_INSN) return false; 57 | for (ObfMapping m : classCalls) if (m.matches((MethodInsnNode) insn)) return true; 58 | return false; 59 | } 60 | 61 | private boolean matchesDesc(AbstractInsnNode insn) { 62 | if (insn.getType() != LDC_INSN) return false; 63 | insn = insn.getNext(); 64 | if (insn == null || insn.getType() != LDC_INSN) return false; 65 | insn = insn.getNext(); 66 | if (insn == null || insn.getType() != LDC_INSN) return false; 67 | insn = insn.getNext(); 68 | if (insn == null || insn.getType() != METHOD_INSN) return false; 69 | for (ObfMapping m : descCalls) if (m.matches((MethodInsnNode) insn)) return true; 70 | return false; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/codechicken/obfuscator/DummyOutputStream.java: -------------------------------------------------------------------------------- 1 | package codechicken.obfuscator; 2 | 3 | import java.io.OutputStream; 4 | 5 | public class DummyOutputStream extends OutputStream { 6 | 7 | public static DummyOutputStream instance = new DummyOutputStream(); 8 | 9 | @Override 10 | public void write(int b) {} 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/codechicken/obfuscator/IHeirachyEvaluator.java: -------------------------------------------------------------------------------- 1 | package codechicken.obfuscator; 2 | 3 | import java.util.List; 4 | 5 | import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry; 6 | 7 | public interface IHeirachyEvaluator { 8 | 9 | /** 10 | * @param desc The mapping descriptor of the class to evaluate heirachy for 11 | * @return A list of parents (srg or obf names) 12 | */ 13 | public List getParents(ObfuscationEntry desc); 14 | 15 | /** 16 | * @param desc The mapping descriptor of the class in question 17 | * @return True if this class does not inherit from any obfuscated class. 18 | */ 19 | public boolean isLibClass(ObfuscationEntry desc); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/codechicken/obfuscator/ILogStreams.java: -------------------------------------------------------------------------------- 1 | package codechicken.obfuscator; 2 | 3 | import java.io.PrintStream; 4 | 5 | public interface ILogStreams { 6 | 7 | public PrintStream err(); 8 | 9 | public PrintStream out(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/codechicken/obfuscator/ObfDirection.java: -------------------------------------------------------------------------------- 1 | package codechicken.obfuscator; 2 | 3 | import codechicken.lib.asm.ObfMapping; 4 | import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry; 5 | 6 | public class ObfDirection { 7 | 8 | public boolean obfuscate; 9 | public boolean srg; 10 | public boolean srg_cst; 11 | 12 | public ObfDirection setObfuscate(boolean obfuscate) { 13 | this.obfuscate = obfuscate; 14 | return this; 15 | } 16 | 17 | public ObfDirection setSearge(boolean srg) { 18 | this.srg = srg; 19 | return this; 20 | } 21 | 22 | public ObfDirection setSeargeConstants(boolean srg_cst) { 23 | this.srg_cst = srg_cst; 24 | return this; 25 | } 26 | 27 | public ObfMapping obfuscate(ObfuscationEntry map) { 28 | return srg ? map.srg : obfuscate ? map.obf : map.mcp; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/codechicken/obfuscator/ObfRemapper.java: -------------------------------------------------------------------------------- 1 | package codechicken.obfuscator; 2 | 3 | import org.objectweb.asm.commons.Remapper; 4 | 5 | import codechicken.obfuscator.ObfuscationMap.ObfuscationEntry; 6 | 7 | public class ObfRemapper extends Remapper { 8 | 9 | public final ObfuscationMap obf; 10 | public ObfDirection dir; 11 | 12 | public ObfRemapper(ObfuscationMap obf, ObfDirection dir) { 13 | this.obf = obf; 14 | this.dir = dir; 15 | } 16 | 17 | @Override 18 | public String map(String name) { 19 | if (name.indexOf('$') >= 0) 20 | return map(name.substring(0, name.indexOf('$'))) + name.substring(name.indexOf('$')); 21 | 22 | ObfuscationEntry map; 23 | if (dir.obfuscate) map = obf.lookupMcpClass(name); 24 | else map = obf.lookupObfClass(name); 25 | 26 | if (map != null) return dir.obfuscate(map).s_owner; 27 | 28 | return name; 29 | } 30 | 31 | @Override 32 | public String mapFieldName(String owner, String name, String desc) { 33 | ObfuscationEntry map; 34 | if (dir.obfuscate) map = obf.lookupMcpField(owner, name); 35 | else map = obf.lookupObfField(owner, name); 36 | 37 | if (map == null) map = obf.lookupSrgField(owner, name); 38 | 39 | if (map != null) return dir.obfuscate(map).s_name; 40 | 41 | return name; 42 | } 43 | 44 | @Override 45 | public String mapMethodName(String owner, String name, String desc) { 46 | if (owner.length() == 0 || owner.charAt(0) == '[') return name; 47 | 48 | ObfuscationEntry map; 49 | if (dir.obfuscate) map = obf.lookupMcpMethod(owner, name, desc); 50 | else map = obf.lookupObfMethod(owner, name, desc); 51 | 52 | if (map == null) map = obf.lookupSrg(name); 53 | 54 | if (map != null) return dir.obfuscate(map).s_name; 55 | 56 | return name; 57 | } 58 | 59 | @Override 60 | public Object mapValue(Object cst) { 61 | if (cst instanceof String) { 62 | if (dir.srg_cst) { 63 | ObfuscationEntry map = obf.lookupSrg((String) cst); 64 | if (map != null) return dir.obfuscate(map).s_name; 65 | } 66 | return cst; 67 | } 68 | 69 | return super.mapValue(cst); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/codechicken/obfuscator/SystemLogStreams.java: -------------------------------------------------------------------------------- 1 | package codechicken.obfuscator; 2 | 3 | import java.io.PrintStream; 4 | 5 | public class SystemLogStreams implements ILogStreams { 6 | 7 | public static SystemLogStreams inst = new SystemLogStreams(); 8 | 9 | @Override 10 | public PrintStream err() { 11 | return System.err; 12 | } 13 | 14 | @Override 15 | public PrintStream out() { 16 | return System.out; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/resources/assets/codechickencore/asm/tweaks.asm: -------------------------------------------------------------------------------- 1 | #A bunch of vanilla tweaks 2 | 3 | list d_environmentallyFriendlyCreepers 4 | ALOAD 0 5 | GETFIELD net/minecraft/entity/monster/EntityCreeper.field_70170_p:Lnet/minecraft/world/World; #worldObj 6 | INVOKEVIRTUAL net/minecraft/world/World.func_82736_K()Lnet/minecraft/world/GameRules; #getGameRules 7 | LDC "mobGriefing" 8 | INVOKEVIRTUAL net/minecraft/world/GameRules.func_82766_b(Ljava/lang/String;)Z #getGameRuleBooleanValue 9 | 10 | list environmentallyFriendlyCreepers 11 | ICONST_0 12 | 13 | list softLeafReplace 14 | ALOAD 0 15 | ALOAD 1 16 | ILOAD 2 17 | ILOAD 3 18 | ILOAD 4 19 | INVOKEVIRTUAL net/minecraft/block/Block.isAir(Lnet/minecraft/world/IBlockAccess;III)Z #forge method 20 | IRETURN 21 | 22 | list n_doFireTick 23 | LDC "doFireTick" 24 | INVOKEVIRTUAL net/minecraft/world/GameRules.func_82766_b(Ljava/lang/String;)Z #getGameRuleBooleanValue 25 | IFEQ LRET 26 | 27 | list doFireTick 28 | ALOAD 1 29 | ILOAD 2 30 | ILOAD 3 31 | ILOAD 4 32 | ALOAD 5 33 | INVOKESTATIC codechicken/core/featurehack/TweakTransformerHelper.quenchFireTick(Lnet/minecraft/world/World;IIILjava/util/Random;)V 34 | LSKIP 35 | 36 | list finiteWater 37 | ALOAD 0 38 | GETFIELD net/minecraft/block/BlockDynamicLiquid.field_149815_a:I 39 | ICONST_2 40 | IF_ICMPLT LEND -------------------------------------------------------------------------------- /src/main/resources/assets/codechickencore/lang/de_DE.lang: -------------------------------------------------------------------------------- 1 | codechickencore.update=Version %s von %s ist verfügbar 2 | -------------------------------------------------------------------------------- /src/main/resources/assets/codechickencore/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | codechickencore.update=Version %s of %s is available -------------------------------------------------------------------------------- /src/main/resources/assets/codechickencore/lang/it_IT.lang: -------------------------------------------------------------------------------- 1 | codechickencore.update=La versione %s di %s è disponibile 2 | -------------------------------------------------------------------------------- /src/main/resources/assets/codechickencore/lang/ru_RU.lang: -------------------------------------------------------------------------------- 1 | codechickencore.update=Версия %s %s доступна 2 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | { 2 | "modListVersion": 2, 3 | "modList": [{ 4 | "modid": "${modId}", 5 | "name": "${modName}", 6 | "description": "Base common code for all chickenbones mods. Supporters: JBoyJr", 7 | "version": "${modVersion}", 8 | "mcversion": "${minecraftVersion}", 9 | "url": "http://www.minecraftforum.net/topic/909223", 10 | "authorList": ["ChickenBones", "GTNH Team"] 11 | }] 12 | } 13 | --------------------------------------------------------------------------------