├── .github └── workflows │ └── buildDokka.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle.kts ├── docs ├── ContributionGuidelines.md ├── Feature_List.md ├── USEFUL_SOURCES.md └── dokka │ ├── Icon.png │ └── logo-styles.css ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── settings.gradle.kts └── src └── main ├── java └── floppaclient │ ├── mixins │ ├── BlockMixin.java │ ├── BlockPaneMixin.java │ ├── CarpetMixin.java │ ├── ChunkMixin.java │ ├── Gui │ │ ├── GuiMixin.java │ │ ├── GuiScreenMixin.java │ │ ├── MixinGuiContainer.java │ │ └── MixinGuiMainMenu.java │ ├── MinecraftAccessor.java │ ├── MixinMinecraft.java │ ├── MixinModList.java │ ├── MixinNetworkManager.java │ ├── MixinPlayerHandler.java │ ├── MixinSoundManager.java │ ├── MixinWorld.java │ ├── MovementInputFromOptionsMixin.java │ ├── PlayerControllerMixin.java │ ├── entity │ │ ├── MixinAbstractClientPlayer.java │ │ ├── MixinEntity.java │ │ ├── MixinEntityLivingBase.java │ │ ├── MixinPlayer.java │ │ ├── MixinPlayerSP.java │ │ └── MixinPlayerSP2.java │ ├── packet │ │ └── C02Accessor.java │ └── render │ │ ├── BlockFluidRendererMixin.java │ │ ├── BlockRendererDispatcherMixin.java │ │ ├── ChestRendererMixin.java │ │ ├── ChunkRendererWorkerMixin.java │ │ ├── EntityRendererMixin.java │ │ ├── ItemRendererMixin.java │ │ ├── RenderChunkMixin.java │ │ ├── RenderGlobalMixin.java │ │ ├── RenderPlayerMixin.java │ │ └── VisGraphAccessor.java │ ├── replacements │ └── render │ │ └── BlockRenderer.java │ └── tweaker │ └── FloppaClientTweaker.java ├── kotlin └── floppaclient │ ├── FloppaClient.kt │ ├── commands │ ├── AddCommand.kt │ ├── AddEtherCommand.kt │ ├── Clip3DCommand.kt │ ├── EditModeCommand.kt │ ├── FloppaClientCommands.kt │ ├── HClipCommand.kt │ ├── RemoveCommand.kt │ ├── RemoveEtherCommand.kt │ ├── VertClipCommand.kt │ ├── WardrobeCommand.kt │ └── WhereCommand.kt │ ├── config │ ├── AutoActionConfig.kt │ ├── ExtrasConfig.kt │ ├── ModuleConfig.kt │ └── jsonutils │ │ ├── BlockPosDeserializer.kt │ │ ├── BlockPosSerializer.kt │ │ ├── IntListDeserializer.kt │ │ ├── SetBlockPosDeserializer.kt │ │ ├── SetBlockPosSerializer.kt │ │ ├── SettingDeserializer.kt │ │ └── SettingSerializer.kt │ ├── events │ ├── Events.kt │ ├── PositionUpdateEvent.kt │ ├── PreKeyInputEvent.kt │ └── PreMouseInputEvent.kt │ ├── floppamap │ ├── core │ │ ├── AutoActionData.kt │ │ ├── Door.kt │ │ ├── DoorType.kt │ │ ├── DungeonPlayer.kt │ │ ├── ExtrasData.kt │ │ ├── Room.kt │ │ ├── RoomConfigData.kt │ │ ├── RoomData.kt │ │ ├── RoomState.kt │ │ ├── RoomType.kt │ │ └── Tile.kt │ ├── dungeon │ │ ├── Dungeon.kt │ │ ├── DungeonScan.kt │ │ ├── MapRender.kt │ │ ├── MapUpdate.kt │ │ ├── MimicDetector.kt │ │ └── RunInformation.kt │ ├── extras │ │ ├── EditMode.kt │ │ ├── Extras.kt │ │ └── ExtrasScan.kt │ └── utils │ │ ├── MapUtils.kt │ │ └── RoomUtils.kt │ ├── forge │ └── FMLLoadingPlugin.kt │ ├── hooks │ └── SoundManagerHook.kt │ ├── module │ ├── AlwaysActive.kt │ ├── Category.kt │ ├── ConfigModule.kt │ ├── Module.kt │ ├── ModuleManager.kt │ ├── RegisterHudElement.kt │ ├── SelfRegisterModule.kt │ ├── impl │ │ ├── dev │ │ │ └── DevModule.kt │ │ ├── dungeon │ │ │ ├── AutoBlaze.kt │ │ │ ├── AutoDevices.kt │ │ │ ├── AutoLeap.kt │ │ │ ├── AutoTerms.kt │ │ │ ├── AutoWater.kt │ │ │ ├── AutoWeirdos.kt │ │ │ ├── CancelChestOpen.kt │ │ │ ├── DungeonKillAura.kt │ │ │ ├── ExtraStats.kt │ │ │ ├── IceSprayAura.kt │ │ │ ├── InstaCrystal.kt │ │ │ ├── M7P5.kt │ │ │ ├── MelodyMessage.kt │ │ │ ├── PartyTracker.kt │ │ │ ├── SecretAura.kt │ │ │ ├── SecretChime.kt │ │ │ ├── TerminalAura.kt │ │ │ ├── TicTacToeSolver.kt │ │ │ └── TrapGearSwap.kt │ │ ├── keybinds │ │ │ ├── AddKeybind.kt │ │ │ └── KeyBind.kt │ │ ├── misc │ │ │ ├── AutoClicker.kt │ │ │ ├── AutoHarp.kt │ │ │ ├── AutoRagnarock.kt │ │ │ ├── AutoSprint.kt │ │ │ ├── AutoWeaponSwap.kt │ │ │ ├── CancelInteract.kt │ │ │ ├── ChatCleaner.kt │ │ │ ├── ClipSettings.kt │ │ │ ├── Enchanting.kt │ │ │ ├── FastMine.kt │ │ │ ├── GhostBlocks.kt │ │ │ ├── InvActions.kt │ │ │ ├── JerryBoxOpener.kt │ │ │ ├── QOL.kt │ │ │ ├── Salvage.kt │ │ │ ├── SecretTriggerbot.kt │ │ │ ├── SellGarbo.kt │ │ │ ├── StonkDelay.kt │ │ │ └── TerminatorClicker.kt │ │ ├── player │ │ │ ├── ArmorSwapper.kt │ │ │ ├── AutoClip.kt │ │ │ ├── AutoEther.kt │ │ │ ├── BarPhase.kt │ │ │ ├── Clip.kt │ │ │ ├── FreeCam.kt │ │ │ ├── HClip.kt │ │ │ ├── HotbarSwapper.kt │ │ │ ├── JerryRocket.kt │ │ │ └── NoRotate.kt │ │ └── render │ │ │ ├── Camera.kt │ │ │ ├── ChestEsp.kt │ │ │ ├── ClickGui.kt │ │ │ ├── CoordinateDisplay.kt │ │ │ ├── DayCounter.kt │ │ │ ├── DoorESP.kt │ │ │ ├── DrawRoutes.kt │ │ │ ├── DungeonESP.kt │ │ │ ├── DungeonMap.kt │ │ │ ├── DungeonWarpTimer.kt │ │ │ ├── EditHud.kt │ │ │ ├── ExtraBlocks.kt │ │ │ ├── FullBright.kt │ │ │ ├── ItemAnimations.kt │ │ │ ├── MapRooms.kt │ │ │ ├── RunOverview.kt │ │ │ └── XRay.kt │ └── settings │ │ ├── DoNotRegister.kt │ │ ├── Setting.kt │ │ ├── Visibility.kt │ │ └── impl │ │ ├── ActionSetting.kt │ │ ├── BooleanSetting.kt │ │ ├── ColorSetting.kt │ │ ├── DummySetting.kt │ │ ├── NumberSetting.kt │ │ ├── SelectorSetting.kt │ │ ├── StringSelectorSetting.kt │ │ └── StringSetting.kt │ ├── shaders │ ├── Shader.kt │ ├── impl │ │ └── Chroma2D.kt │ └── uniforms │ │ ├── Uniform.kt │ │ └── impl │ │ └── Uniform1F.kt │ ├── ui │ ├── clickgui │ │ ├── ClickGUI.kt │ │ ├── Panel.kt │ │ ├── advanced │ │ │ ├── AdvancedMenu.kt │ │ │ └── elements │ │ │ │ ├── AdvancedElement.kt │ │ │ │ ├── AdvancedElementType.kt │ │ │ │ └── menu │ │ │ │ ├── AdvancedElementAction.kt │ │ │ │ ├── AdvancedElementCheckBox.kt │ │ │ │ ├── AdvancedElementColor.kt │ │ │ │ ├── AdvancedElementKeyBind.kt │ │ │ │ ├── AdvancedElementSelector.kt │ │ │ │ ├── AdvancedElementSlider.kt │ │ │ │ ├── AdvancedElementStringSelector.kt │ │ │ │ └── AdvancedElementTextField.kt │ │ ├── elements │ │ │ ├── Element.kt │ │ │ ├── ElementType.kt │ │ │ ├── ModuleButton.kt │ │ │ └── menu │ │ │ │ ├── ElementAction.kt │ │ │ │ ├── ElementCheckBox.kt │ │ │ │ ├── ElementColor.kt │ │ │ │ ├── ElementKeyBind.kt │ │ │ │ ├── ElementSelector.kt │ │ │ │ ├── ElementSlider.kt │ │ │ │ ├── ElementStringSelector.kt │ │ │ │ └── ElementTextField.kt │ │ └── util │ │ │ ├── ColorUtil.kt │ │ │ └── FontUtil.kt │ └── hud │ │ ├── EditHudGUI.kt │ │ └── HudElement.kt │ └── utils │ ├── ChatUtils.kt │ ├── ClipTools.kt │ ├── DataHandler.kt │ ├── GeometryUtils.kt │ ├── HypixelApiUtils.kt │ ├── LocationManager.kt │ ├── ScoreboardUtils.kt │ ├── TabListUtils.kt │ ├── Utils.kt │ ├── fakeactions │ ├── FakeAction.kt │ ├── FakeActionManager.kt │ ├── FakeActionUtils.kt │ └── FakeInventoryActionManager.kt │ ├── inventory │ ├── InventoryUtils.kt │ ├── ItemUtils.kt │ └── SkyblockItem.kt │ └── render │ ├── HUDRenderUtils.kt │ └── WorldRenderUtils.kt └── resources ├── assets └── floppaclient │ ├── floppamap │ ├── default │ │ ├── cross.png │ │ ├── green_check.png │ │ ├── question.png │ │ └── white_check.png │ ├── neu │ │ ├── cross.png │ │ ├── green_check.png │ │ ├── question.png │ │ └── white_check.png │ └── rooms.json │ ├── gui │ ├── HueScale.png │ ├── Icon.png │ └── cursor.png │ └── shaders │ └── chroma2d │ ├── chroma2d.frag │ └── chroma2d.vert ├── mcmod.info └── mixins.floppaclient.json /.github/workflows/buildDokka.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time 6 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle 7 | 8 | name: Build Documentation with Dokka using Gradle 9 | run-name: ${{ github.actor }} is creating the Documentation 10 | 11 | on: 12 | push: 13 | branches: [ "master" ] 14 | # pull_request: 15 | # branches: [ "master" ] 16 | 17 | permissions: 18 | contents: read 19 | 20 | jobs: 21 | build-Documentation: 22 | 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v3 27 | - name: Set up JDK 17 28 | uses: actions/setup-java@v3 29 | with: 30 | java-version: '17' 31 | distribution: 'temurin' 32 | - name: Grant Gradle Permission 33 | run: chmod +x gradlew 34 | - name: Build Documentation 35 | uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 36 | with: 37 | arguments: dokkaCustomFormat 38 | - name: Upload Documentation 39 | uses: actions/upload-artifact@v2 40 | with: 41 | name: Documentation 42 | path: build/dokka/customFormat/ 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | eclipse 3 | bin 4 | *.launch 5 | .settings 6 | .metadata 7 | .classpath 8 | .project 9 | 10 | # vscode 11 | .vscode 12 | 13 | # idea 14 | out 15 | classes 16 | *.ipr 17 | *.iws 18 | *.iml 19 | .idea 20 | 21 | # gradle 22 | build 23 | .gradle 24 | 25 | #Netbeans 26 | .nb-gradle 27 | .nb-gradle-properties 28 | 29 | # other 30 | run 31 | .DS_Store 32 | Thumbs.db 33 | Resources 34 | Resources/proguard-rules.pro 35 | ZKM 36 | releases -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Floppa-Client 2 | 3 | Floppa Client is a 1.8.9 Minecraft Forge mod that provides a collection of qol features for Hypixel Skyblock 4 | with a focus on Dungeons. 5 | 6 | ## General Information 7 | 8 | Some features in this mod violate the 9 | [Hypixel Server Rules](https://support.hypixel.net/hc/en-us/articles/6472550754962-Allowed-Modifications). 10 | Usage of the mod is at your own risk. 11 | If you are looking for an allowed modification check out [Aton Addons](https://github.com/FloppaCoding/AtonAddons). 12 | 13 | Open the Gui with /floppaclient (or /fcl or /fc). 14 | 15 | See [Feature List](docs/Feature_List.md) for information about the features of this mod. 16 | 17 | ## Making your own Modules 18 | To get started with coding on your own, check out the [wiki](https://github.com/FloppaCoding/FloppaClient/wiki). 19 | You can either make external Modules or contribute to the main mod. 20 | 21 | ## Credit to other Projects 22 | A special thank goes to [Harry282](https://github.com/Harry282), his projects allowed me to get started with making my own 23 | forge mods. 24 |
25 | [For the list of sources click here.](docs/USEFUL_SOURCES.md "Credits") 26 | 27 | -------------------------------------------------------------------------------- /docs/ContributionGuidelines.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | * [Code Standards](#Code-Standards) 4 | * [Philosophy](#philosophy) 5 | * [Requirements](#requirements) 6 | 7 | ## Code Standards 8 | 9 | ### Philosophy 10 | The priority when writing your code should be readability. 11 | 12 | ### Requirements 13 | 14 | #### Comments 15 | All Classes you make should have a documentation comment that gives at least a short summary of what that class is 16 | for and contain a tag which declares the author. This looks like: 17 | 18 | /** 19 | * A class for storing information about ... and handling ... 20 | * 21 | * @author AuthorName 22 | */ 23 | class MyClass() { //... } 24 | 25 | Additionally, documentation comments for at least the public methods are also very welcome. 26 | A good rule of thumb is that if the functionality and usage of something is not trivial from just the name, you 27 | should add a comment explaining it. 28 | 29 | #### Naming conventions 30 | 31 | + Classes and Objects should have a capitalized name with camel case. Example: MyClass. 32 | + variables and methods should start with a lower case letter and use camel case. Example: myMethod 33 | + constants and enums should use all caps and underscores for separating words. Example: MY_CONSTANT 34 | + Do not abbreviate words. 35 | 36 | A general rule to follow is to give your variables as descriptive names as possible. 37 | 38 | 39 | -------------------------------------------------------------------------------- /docs/USEFUL_SOURCES.md: -------------------------------------------------------------------------------- 1 | # Sources 2 | 3 | ## Code sources 4 | 5 | A list of Open Source projects that were very helpful for the development of this project. 6 | 7 | - The Dungeon map is based on [Funny Map](https://github.com/Harry282/FunnyMap) which in turn is based on [Illegal Map](https://github.com/UnclaimedBloom6/IllegalMap). 8 | - [Skytils](https://github.com/Skytils/SkytilsMod) was a very useful source to look up things in general. 9 | - The coordinate HUD is based on [Danker's Skyblock Mod](https://github.com/bowser0000/SkyblockMod). 10 | - The chroma shader is based on [this](https://www.shadertoy.com/view/MsS3Wc) Shadertoy post. 11 | 12 | 13 | ## Other useful resources 14 | 15 | - [A website for looking up minecraft obfuscation mappings](https://mcp.thiakil.com/#/search). Make sure to set the 16 | version to 1.8.9 in the top right corner. 17 | - [A tool to test minecraft color codes.](https://theclickspeed.com/minecraft-color-codes/) 18 | - [Mixin Cheatsheet](https://github.com/2xsaiko/mixin-cheatsheet). 19 | - [Mixin Examples](https://fabricmc.net/wiki/tutorial:mixin_examples). These examples are for fabric, but it works 20 | the same in forge. 21 | - [Online regex tester](https://regex101.com) 22 | - [Regex Cheatsheet](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet). 23 | - [GitHub Markdown Cheatsheet](https://github.com/tchapi/markdown-cheatsheet/blob/master/README.md). 24 | - [KDoc Markdown Syntax](https://daringfireball.net/projects/markdown/syntax#overview). 25 | -------------------------------------------------------------------------------- /docs/dokka/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/docs/dokka/Icon.png -------------------------------------------------------------------------------- /docs/dokka/logo-styles.css: -------------------------------------------------------------------------------- 1 | .library-name a { 2 | position: relative; 3 | margin-left: 55px; 4 | } 5 | 6 | .library-name a::before { 7 | content: ''; 8 | background-image: url('../images/Icon.png'); 9 | background-repeat: no-repeat; 10 | background-size: contain; 11 | position: absolute; 12 | width: 55px; 13 | height: 50px; 14 | top: -18px; 15 | left: -55px; 16 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | org.gradle.caching=true 3 | org.gradle.jvmargs=-Xmx2G 4 | loom.platform=forge 5 | org.gradle.configureondemand=true 6 | org.gradle.parallel=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/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-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /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 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk17 3 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://maven.fabricmc.net") 5 | maven("https://maven.architectury.dev/") 6 | maven("https://maven.minecraftforge.net") 7 | maven("https://repo.essential.gg/repository/maven-public") 8 | } 9 | resolutionStrategy { 10 | eachPlugin { 11 | when (requested.id.id) { 12 | "gg.essential.loom" -> useModule("gg.essential:architectury-loom:${requested.version}") 13 | } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/BlockMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.module.impl.render.XRay; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.state.IBlockState; 6 | import net.minecraft.entity.Entity; 7 | import net.minecraft.util.AxisAlignedBB; 8 | import net.minecraft.util.BlockPos; 9 | import net.minecraft.util.EnumFacing; 10 | import net.minecraft.util.EnumWorldBlockLayer; 11 | import net.minecraft.world.IBlockAccess; 12 | import net.minecraft.world.World; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.Shadow; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 18 | 19 | import java.util.List; 20 | 21 | @Mixin(Block.class) 22 | public abstract class BlockMixin { 23 | private final Block block = (Block) (Object) this; 24 | 25 | @Shadow 26 | public void addCollisionBoxesToList(World worldIn, BlockPos pos, IBlockState state, AxisAlignedBB mask, List list, Entity collidingEntity) {} 27 | 28 | @Shadow public abstract void setBlockBounds(float minX, float minY, float minZ, float maxX, float maxY, float maxZ); 29 | 30 | @Inject(method = "shouldSideBeRendered", at = @At("RETURN"), cancellable = true) 31 | private void onShouldSideBeRendered(IBlockAccess worldIn, BlockPos pos, EnumFacing side, CallbackInfoReturnable cir) { 32 | if(XRay.INSTANCE.getEnabled()) { 33 | cir.setReturnValue(XRay.INSTANCE.modifyRenderdSideHook(block, cir.getReturnValue())); 34 | } 35 | } 36 | 37 | @Inject(method = "canRenderInLayer", at = @At("HEAD"), cancellable = true, remap = false) 38 | private void tweakCanRender(EnumWorldBlockLayer layer, CallbackInfoReturnable cir){ 39 | if (XRay.INSTANCE.getEnabled()) { 40 | cir.setReturnValue(EnumWorldBlockLayer.TRANSLUCENT == layer); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/CarpetMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.module.impl.misc.QOL; 4 | import net.minecraft.block.BlockCarpet; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | @Mixin(BlockCarpet.class) 11 | public abstract class CarpetMixin extends BlockMixin { 12 | @Inject(method = {"setBlockBoundsFromMeta"}, at = @At("HEAD"), cancellable = true) 13 | public void setBounds(int meta, CallbackInfo ci){ 14 | if (QOL.INSTANCE.ignoreCarpet()) { 15 | this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.0f, 1.0F); 16 | ci.cancel(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/ChunkMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.events.BlockStateChangeEvent; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.util.BlockPos; 6 | import net.minecraft.world.chunk.Chunk; 7 | import net.minecraftforge.common.MinecraftForge; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 13 | 14 | @Mixin(Chunk.class) 15 | abstract class ChunkMixin { 16 | @Shadow public abstract IBlockState getBlockState(BlockPos pos); 17 | 18 | @Inject(method = "setBlockState", at = @At("HEAD"), cancellable = true) 19 | public void onBlockSet(BlockPos pos, IBlockState state, CallbackInfoReturnable cir) { 20 | IBlockState old = this.getBlockState(pos); 21 | if (state != old) { 22 | if (MinecraftForge.EVENT_BUS.post(new BlockStateChangeEvent(pos, old, state))) 23 | cir.setReturnValue(null); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/Gui/GuiMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.Gui; 2 | 3 | import net.minecraft.client.gui.Gui; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | 7 | @Mixin(value = {Gui.class}) 8 | public abstract class GuiMixin { 9 | @Shadow 10 | public static void drawRect(int left, int top, int right, int bottom, int color) {} 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/Gui/GuiScreenMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.Gui; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.GuiScreen; 5 | import net.minecraft.client.gui.GuiYesNoCallback; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | 9 | import java.io.IOException; 10 | 11 | @Mixin(value = {GuiScreen.class}) 12 | public abstract class GuiScreenMixin extends GuiMixin implements GuiYesNoCallback { 13 | @Shadow 14 | public Minecraft mc; 15 | @Shadow 16 | public int width; 17 | @Shadow 18 | public int height; 19 | 20 | @Shadow 21 | public abstract void drawScreen(int mouseX, int mouseY, float partialTicks); 22 | 23 | @Shadow 24 | protected abstract void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/Gui/MixinGuiContainer.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.Gui; 2 | 3 | import floppaclient.events.*; 4 | import net.minecraft.client.gui.GuiScreen; 5 | import net.minecraft.client.gui.inventory.GuiContainer; 6 | import net.minecraft.inventory.Container; 7 | import net.minecraft.inventory.Slot; 8 | import net.minecraftforge.client.event.GuiScreenEvent; 9 | import net.minecraftforge.common.MinecraftForge; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.Shadow; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 16 | 17 | @Mixin(value = {GuiContainer.class}, priority = 800) 18 | public abstract class MixinGuiContainer extends GuiScreenMixin { 19 | 20 | private final GuiContainer gui = (GuiContainer) (Object) this; 21 | 22 | @Shadow 23 | public Container inventorySlots; 24 | 25 | @Inject(method = "drawSlot", at = @At("HEAD"), cancellable = true) 26 | private void onDrawSlot(Slot slot, CallbackInfo ci) { 27 | if (MinecraftForge.EVENT_BUS.post(new GuiContainerEvent.DrawSlotEvent(inventorySlots, gui, slot))) 28 | ci.cancel(); 29 | } 30 | 31 | @Inject(method = "handleMouseClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/PlayerControllerMP;windowClick(IIIILnet/minecraft/entity/player/EntityPlayer;)Lnet/minecraft/item/ItemStack;"), cancellable = true) 32 | private void onMouseClick(Slot slot, int slotId, int clickedButton, int clickType, CallbackInfo ci) { 33 | if (MinecraftForge.EVENT_BUS.post(new GuiContainerEvent.SlotClickEvent(inventorySlots, gui, slot, slotId))) 34 | ci.cancel(); 35 | } 36 | 37 | @Inject(method = {"drawScreen"}, at = @At("HEAD"), cancellable = true) 38 | public void drawContainer(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { 39 | if (MinecraftForge.EVENT_BUS.post(new DrawContainerEvent(mouseX, mouseY))){ 40 | //At this point the screen will not be drawn 41 | // The forge event has to be forged so that auto terms still work 42 | MinecraftForge.EVENT_BUS.post(new GuiScreenEvent.BackgroundDrawnEvent((GuiScreen) (Object) this)); 43 | ci.cancel(); 44 | } 45 | } 46 | 47 | @Inject(method = {"drawScreen"}, at = @At("RETURN")) 48 | public void drawContainerLast(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { 49 | MinecraftForge.EVENT_BUS.post(new DrawContainerLastEvent(mouseX, mouseY)); 50 | } 51 | 52 | @Inject(method = {"mouseClicked"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;mouseClicked(III)V", shift = At.Shift.AFTER), cancellable = true) 53 | public void guiClicked(int mouseX, int mouseY, int mouseButton, CallbackInfo ci) { 54 | if (MinecraftForge.EVENT_BUS.post(new ContainerMouseClickedEvent(mouseX, mouseY, mouseButton))) ci.cancel(); 55 | } 56 | 57 | @Inject(method = {"checkHotbarKeys"}, at = @At("HEAD"), cancellable = true) 58 | public void guiTyped(int keyCode, CallbackInfoReturnable cir){ 59 | if (MinecraftForge.EVENT_BUS.post(new ContainerKeyTypedEvent(keyCode))) cir.setReturnValue(true); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/Gui/MixinGuiMainMenu.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.Gui; 2 | 3 | import net.minecraft.client.gui.GuiMainMenu; 4 | import net.minecraft.client.gui.GuiScreen; 5 | import net.minecraft.client.gui.GuiYesNoCallback; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | import java.util.Calendar; 13 | import java.util.Date; 14 | 15 | @Mixin(value = {GuiMainMenu.class}, priority = 1001) 16 | public abstract class MixinGuiMainMenu extends GuiScreen implements GuiYesNoCallback { 17 | @Shadow 18 | private String splashText; 19 | 20 | @Inject(method = {""}, at = {@At("RETURN")}) 21 | public void initMainMenu(CallbackInfo callbackInfo) { 22 | Calendar calendar = Calendar.getInstance(); 23 | calendar.setTime(new Date()); 24 | int day = calendar.get(Calendar.DAY_OF_WEEK); 25 | if (day == 6) { 26 | this.splashText = "Floppa Friday!"; 27 | }else { 28 | this.splashText = "MILF (Man I love Floppa)"; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/MinecraftAccessor.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.util.Timer; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | import org.spongepowered.asm.mixin.gen.Invoker; 8 | 9 | 10 | @Mixin(Minecraft.class) 11 | public interface MinecraftAccessor { 12 | @Accessor 13 | Timer getTimer(); 14 | 15 | @Invoker("clickMouse") 16 | void clickMouse(); 17 | 18 | @Invoker("rightClickMouse") 19 | void rightClickMouse(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/MixinMinecraft.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.events.ClickEvent; 4 | import floppaclient.events.PreKeyInputEvent; 5 | import floppaclient.events.PreMouseInputEvent; 6 | import floppaclient.module.impl.misc.CancelInteract; 7 | import floppaclient.module.impl.misc.InvActions; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.multiplayer.WorldClient; 10 | import net.minecraft.util.BlockPos; 11 | import net.minecraftforge.common.MinecraftForge; 12 | import org.lwjgl.input.Keyboard; 13 | import org.lwjgl.input.Mouse; 14 | import org.lwjgl.opengl.Display; 15 | import org.spongepowered.asm.mixin.Mixin; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.Redirect; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 20 | 21 | @Mixin(Minecraft.class) 22 | public class MixinMinecraft { 23 | @Inject(method = "clickMouse", at = @At("HEAD"), cancellable = true) 24 | private void onLeftClick(CallbackInfo ci) { 25 | if (MinecraftForge.EVENT_BUS.post(new ClickEvent.LeftClickEvent())) ci.cancel(); 26 | } 27 | 28 | @Inject(method = "rightClickMouse", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;rightClickDelayTimer:I", shift = At.Shift.AFTER), cancellable = true) 29 | private void onRightClick(CallbackInfo ci) { 30 | if (MinecraftForge.EVENT_BUS.post(new ClickEvent.RightClickEvent())) ci.cancel(); 31 | } 32 | 33 | @Inject(method = "middleClickMouse", at = @At("HEAD"), cancellable = true) 34 | private void onMiddleClick(CallbackInfo ci) { 35 | if (MinecraftForge.EVENT_BUS.post(new ClickEvent.MiddleClickEvent())) ci.cancel(); 36 | } 37 | 38 | @Redirect(method = {"rightClickMouse"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/WorldClient;isAirBlock(Lnet/minecraft/util/BlockPos;)Z")) 39 | public boolean shouldCancleInteract(WorldClient instance, BlockPos blockPos) { 40 | return CancelInteract.INSTANCE.shouldPriotizeAbilityHook(instance, blockPos); 41 | } 42 | 43 | @Inject(method = {"runTick"}, at = {@At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;dispatchKeypresses()V")}) 44 | public void keyPresses(CallbackInfo ci) { 45 | int k = (Keyboard.getEventKey() == 0) ? (Keyboard.getEventCharacter() + 256) : Keyboard.getEventKey(); 46 | char character = Keyboard.getEventCharacter(); 47 | if (Keyboard.getEventKeyState()) { 48 | MinecraftForge.EVENT_BUS.post(new PreKeyInputEvent(k, character)); 49 | } 50 | } 51 | 52 | @Inject(method = {"runTick"}, at = {@At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButton()I")}) 53 | public void mouseKeyPresses(CallbackInfo ci) { 54 | int k = Mouse.getEventButton(); 55 | if (Mouse.getEventButtonState()) { 56 | MinecraftForge.EVENT_BUS.post(new PreMouseInputEvent(k)); 57 | } 58 | } 59 | 60 | @Inject(method = {"setIngameNotInFocus"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/util/MouseHelper;ungrabMouseCursor()V", shift = At.Shift.BEFORE), cancellable = true) 61 | public void skipUngrab(CallbackInfo ci){ 62 | if (InvActions.INSTANCE.shouldSkipUngrabMouse()) { 63 | Mouse.setCursorPosition(Display.getWidth() / 2, Display.getHeight() / 2); 64 | ci.cancel(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/MixinModList.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraftforge.fml.common.ModContainer; 5 | import net.minecraftforge.fml.common.network.handshake.FMLHandshakeMessage; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | import floppaclient.FloppaClient; 12 | 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | @Mixin(value = FMLHandshakeMessage.ModList.class, remap = false) 17 | public class MixinModList { 18 | 19 | @Shadow 20 | private Map modTags; 21 | 22 | @Inject(method = "(Ljava/util/List;)V", at = @At("RETURN")) 23 | private void removeMod(List modList, CallbackInfo ci) { 24 | if (!Minecraft.getMinecraft().isIntegratedServerRunning()) { 25 | modTags.remove(FloppaClient.MOD_ID); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/MixinNetworkManager.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.events.PacketSentEvent; 4 | import floppaclient.events.ReceiveChatPacketEvent; 5 | import floppaclient.events.TeleportEventPre; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import net.minecraft.network.NetworkManager; 8 | import net.minecraft.network.Packet; 9 | import net.minecraft.network.play.server.S02PacketChat; 10 | import net.minecraft.network.play.server.S08PacketPlayerPosLook; 11 | import net.minecraftforge.common.MinecraftForge; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | import org.spongepowered.asm.mixin.injection.Inject; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | import floppaclient.events.ReceivePacketEvent; 17 | 18 | @Mixin(value = {NetworkManager.class}, priority = 800) 19 | public class MixinNetworkManager { 20 | @Inject(method = "channelRead0*", at = @At("HEAD"), cancellable = true) 21 | private void onReceivePacket(ChannelHandlerContext context, Packet packet, CallbackInfo ci) { 22 | boolean shouldCancel = false; 23 | 24 | if (packet instanceof S08PacketPlayerPosLook) { 25 | if (MinecraftForge.EVENT_BUS.post(new TeleportEventPre((S08PacketPlayerPosLook) packet))) 26 | shouldCancel = true; 27 | } 28 | if (packet instanceof S02PacketChat) { 29 | MinecraftForge.EVENT_BUS.post(new ReceiveChatPacketEvent((S02PacketChat) packet)); 30 | } 31 | if (MinecraftForge.EVENT_BUS.post(new ReceivePacketEvent(packet))) 32 | shouldCancel = true; 33 | if (shouldCancel) 34 | ci.cancel(); 35 | } 36 | 37 | @Inject(method = {"sendPacket(Lnet/minecraft/network/Packet;)V"}, at = {@At("HEAD")}, cancellable = true) 38 | private void onSendPacket(Packet packet, CallbackInfo ci) { 39 | if (MinecraftForge.EVENT_BUS.post(new PacketSentEvent(packet))) 40 | ci.cancel(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/MixinPlayerHandler.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.events.ExplosionHandledEvent; 4 | import floppaclient.events.TeleportEventPost; 5 | import floppaclient.events.VelocityUpdateEvent; 6 | import net.minecraft.client.network.NetHandlerPlayClient; 7 | import net.minecraft.network.play.server.S08PacketPlayerPosLook; 8 | import net.minecraft.network.play.server.S12PacketEntityVelocity; 9 | import net.minecraft.network.play.server.S27PacketExplosion; 10 | import net.minecraftforge.common.MinecraftForge; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | @Mixin(value = {NetHandlerPlayClient.class}, priority = 800) 17 | public abstract class MixinPlayerHandler { 18 | @Inject(method = {"handleExplosion"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/Explosion;doExplosionB(Z)V", shift = At.Shift.AFTER), cancellable = true) 19 | private void handleExplosionMomentum(S27PacketExplosion packet, CallbackInfo ci) { 20 | if(MinecraftForge.EVENT_BUS.post(new ExplosionHandledEvent(packet))) ci.cancel(); 21 | } 22 | 23 | @Inject(method = "handleEntityVelocity", at = @At("HEAD"), cancellable = true) 24 | public void handleEntityVelocity(S12PacketEntityVelocity packet, CallbackInfo ci) { 25 | if (MinecraftForge.EVENT_BUS.post(new VelocityUpdateEvent(packet))) ci.cancel(); 26 | } 27 | 28 | @Inject(method = "handlePlayerPosLook", at = @At("RETURN")) 29 | public void handlePlayerPosLook(S08PacketPlayerPosLook packetIn, CallbackInfo ci) { 30 | MinecraftForge.EVENT_BUS.post(new TeleportEventPost(packetIn)); 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/MixinSoundManager.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.events.PlaySoundEventPre; 4 | import floppaclient.hooks.SoundManagerHook; 5 | import net.minecraft.client.audio.ISound; 6 | import net.minecraft.client.audio.SoundCategory; 7 | import net.minecraft.client.audio.SoundManager; 8 | import net.minecraft.client.audio.SoundPoolEntry; 9 | import net.minecraftforge.common.MinecraftForge; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 15 | 16 | /** 17 | * Taken from Skytils 18 | */ 19 | @Mixin(value = {SoundManager.class}, priority = 900) 20 | public class MixinSoundManager { 21 | 22 | @Inject(method = "getNormalizedVolume", at = @At("HEAD"), cancellable = true) 23 | private void bypassPlayerVolume(ISound sound, SoundPoolEntry entry, SoundCategory category, CallbackInfoReturnable cir) { 24 | SoundManagerHook.bypassCategoryVolume(sound, entry, category, cir); 25 | } 26 | 27 | @Inject(method = "playSound", at = @At("HEAD")) 28 | public void onPlaySound(ISound p_sound, CallbackInfo ci) { 29 | MinecraftForge.EVENT_BUS.post(new PlaySoundEventPre(p_sound)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/MixinWorld.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.events.EntityRemovedEvent; 4 | import net.minecraft.entity.Entity; 5 | import net.minecraft.world.World; 6 | import net.minecraftforge.common.MinecraftForge; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(World.class) 13 | public class MixinWorld { 14 | @Inject(method = "removeEntity", at = @At("HEAD")) 15 | public void onEntityRemoved(Entity entityIn, CallbackInfo ci) { 16 | MinecraftForge.EVENT_BUS.post(new EntityRemovedEvent(entityIn)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/MovementInputFromOptionsMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins; 2 | 3 | import floppaclient.module.impl.player.FreeCam; 4 | import net.minecraft.util.MovementInput; 5 | import net.minecraft.util.MovementInputFromOptions; 6 | import org.lwjgl.input.Keyboard; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(MovementInputFromOptions.class) 13 | public abstract class MovementInputFromOptionsMixin extends MovementInput { 14 | 15 | @Inject(method = "updatePlayerMoveState", at = @At("HEAD"), cancellable = true) 16 | public void supressMovement(CallbackInfo ci) { 17 | if (FreeCam.INSTANCE.shouldTweakMovement()) { 18 | 19 | this.moveStrafe = 0.0F; 20 | this.moveForward = 0.0F; 21 | 22 | if (Keyboard.isKeyDown(Keyboard.KEY_UP)) 23 | { 24 | ++this.moveForward; 25 | } 26 | 27 | if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) 28 | { 29 | --this.moveForward; 30 | } 31 | 32 | if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) 33 | { 34 | ++this.moveStrafe; 35 | } 36 | 37 | if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) 38 | { 39 | --this.moveStrafe; 40 | } 41 | 42 | ci.cancel(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/entity/MixinAbstractClientPlayer.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.entity; 2 | 3 | import net.minecraft.client.entity.AbstractClientPlayer; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | 6 | @Mixin({AbstractClientPlayer.class}) 7 | public abstract class MixinAbstractClientPlayer extends MixinPlayer { 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/entity/MixinEntity.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.entity; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | 8 | @Mixin(value = {Entity.class}, priority = 800) 9 | public abstract class MixinEntity { 10 | 11 | @Shadow public boolean noClip; 12 | 13 | @Shadow public abstract boolean interactFirst(EntityPlayer playerIn); 14 | 15 | @Shadow 16 | public float rotationPitch; 17 | 18 | @Shadow 19 | public boolean onGround; 20 | 21 | @Shadow 22 | public float rotationYaw; 23 | 24 | @Shadow 25 | public double posX; 26 | 27 | @Shadow 28 | public double posY; 29 | 30 | @Shadow 31 | public double posZ; 32 | 33 | @Shadow 34 | public abstract boolean equals(Object paramObject); 35 | 36 | @Shadow 37 | public abstract boolean isSprinting(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/entity/MixinEntityLivingBase.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.entity; 2 | 3 | 4 | import floppaclient.module.impl.render.ItemAnimations; 5 | import net.minecraft.entity.EntityLivingBase; 6 | import net.minecraft.potion.Potion; 7 | import net.minecraft.potion.PotionEffect; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 13 | 14 | @Mixin({EntityLivingBase.class}) 15 | public abstract class MixinEntityLivingBase extends MixinEntity { 16 | 17 | @Shadow public abstract boolean isPotionActive(Potion potionIn); 18 | 19 | @Shadow public abstract PotionEffect getActivePotionEffect(Potion potionIn); 20 | 21 | @Inject(method = {"getArmSwingAnimationEnd()I"}, at = @At("HEAD"), cancellable = true) 22 | public void adjustSwingLength(CallbackInfoReturnable cir) { 23 | if (!ItemAnimations.INSTANCE.getEnabled()) return; 24 | int length = ItemAnimations.INSTANCE.getIgnoreHaste().getEnabled() ? 6 : this.isPotionActive(Potion.digSpeed) ? 25 | 6 - (1 + this.getActivePotionEffect(Potion.digSpeed).getAmplifier()) : 26 | (this.isPotionActive(Potion.digSlowdown) ? 27 | 6 + (1 + this.getActivePotionEffect(Potion.digSlowdown).getAmplifier()) * 2 : 28 | 6); 29 | cir.setReturnValue(Math.max((int)(length* Math.exp(-ItemAnimations.INSTANCE.getSpeed().getValue())), 1)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/entity/MixinPlayer.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.entity; 2 | 3 | 4 | import floppaclient.module.impl.misc.QOL; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 10 | 11 | @Mixin({EntityPlayer.class}) 12 | public abstract class MixinPlayer extends MixinEntityLivingBase { 13 | @Inject(method = {"isEntityInsideOpaqueBlock"}, at = @At("HEAD"), cancellable = true) 14 | public void inOpaque(CallbackInfoReturnable cir){ 15 | if (QOL.INSTANCE.cancelHeadInBlock()){ 16 | cir.setReturnValue(false); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/entity/MixinPlayerSP2.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.entity; 2 | 3 | import floppaclient.events.PositionUpdateEvent; 4 | import net.minecraft.client.entity.EntityPlayerSP; 5 | import net.minecraftforge.common.MinecraftForge; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(value = {EntityPlayerSP.class}, priority = 799) 13 | public abstract class MixinPlayerSP2 extends MixinAbstractClientPlayer { 14 | 15 | @Shadow 16 | private boolean serverSneakState; 17 | 18 | @Shadow private double lastReportedPosX; 19 | 20 | @Shadow private double lastReportedPosY; 21 | 22 | @Shadow private double lastReportedPosZ; 23 | 24 | @Shadow private float lastReportedYaw; 25 | 26 | @Shadow private float lastReportedPitch; 27 | 28 | @Inject(method = {"onUpdateWalkingPlayer"}, at = {@At("RETURN")}) 29 | private void postPlayerWalkUpdate(CallbackInfo ci) { 30 | MinecraftForge.EVENT_BUS.post(new PositionUpdateEvent.Post(this.lastReportedPosX, this.lastReportedPosY, this.lastReportedPosZ, this.lastReportedYaw, this.lastReportedPitch, this.onGround, this.serverSneakState, this.serverSneakState)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/packet/C02Accessor.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.packet; 2 | 3 | import net.minecraft.network.Packet; 4 | import net.minecraft.network.play.INetHandlerPlayServer; 5 | import net.minecraft.network.play.client.C02PacketUseEntity; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.gen.Accessor; 8 | 9 | @Mixin({C02PacketUseEntity.class}) 10 | public interface C02Accessor extends Packet { 11 | @Accessor 12 | void setEntityId(int paramInt); 13 | 14 | @Accessor 15 | void setAction(C02PacketUseEntity.Action paramAction); 16 | } -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/BlockFluidRendererMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import floppaclient.module.impl.render.XRay; 4 | import net.minecraft.client.renderer.BlockFluidRenderer; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.ModifyArg; 8 | 9 | @Mixin(BlockFluidRenderer.class) 10 | abstract public class BlockFluidRendererMixin { 11 | @ModifyArg(method = "renderFluid", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/WorldRenderer;color(FFFF)Lnet/minecraft/client/renderer/WorldRenderer;"), index = 3) 12 | private float changeAlpha(float oldAlpha) { 13 | if (XRay.INSTANCE.getEnabled() && XRay.INSTANCE.shouldTweakFluids()) { 14 | return XRay.INSTANCE.getAlphaFloat(); 15 | } 16 | return oldAlpha; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/BlockRendererDispatcherMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import floppaclient.module.impl.render.XRay; 4 | import floppaclient.replacements.render.BlockRenderer; 5 | import net.minecraft.block.state.IBlockState; 6 | import net.minecraft.client.renderer.BlockFluidRenderer; 7 | import net.minecraft.client.renderer.BlockRendererDispatcher; 8 | import net.minecraft.client.renderer.WorldRenderer; 9 | import net.minecraft.client.resources.IResourceManagerReloadListener; 10 | import net.minecraft.client.resources.model.IBakedModel; 11 | import net.minecraft.crash.CrashReport; 12 | import net.minecraft.crash.CrashReportCategory; 13 | import net.minecraft.util.BlockPos; 14 | import net.minecraft.util.ReportedException; 15 | import net.minecraft.world.IBlockAccess; 16 | import org.spongepowered.asm.mixin.Final; 17 | import org.spongepowered.asm.mixin.Mixin; 18 | import org.spongepowered.asm.mixin.Shadow; 19 | import org.spongepowered.asm.mixin.Unique; 20 | import org.spongepowered.asm.mixin.injection.At; 21 | import org.spongepowered.asm.mixin.injection.Inject; 22 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 23 | 24 | @Mixin(BlockRendererDispatcher.class) 25 | abstract public class BlockRendererDispatcherMixin implements IResourceManagerReloadListener { 26 | @Shadow @Final private BlockFluidRenderer fluidRenderer; 27 | 28 | @Unique final private BlockRenderer blockRenderer = new BlockRenderer(); 29 | 30 | @Shadow public abstract IBakedModel getModelFromBlockState(IBlockState state, IBlockAccess worldIn, BlockPos pos); 31 | 32 | @Inject(method = "renderBlock", at = @At("HEAD"), cancellable = true) 33 | private void onRenderBlock(IBlockState state, BlockPos pos, IBlockAccess blockAccess, WorldRenderer worldRendererIn, CallbackInfoReturnable cir) { 34 | if (XRay.INSTANCE.getEnabled()) { 35 | 36 | try 37 | { 38 | int i = state.getBlock().getRenderType(); 39 | 40 | if (i == -1) 41 | { 42 | cir.setReturnValue(false); 43 | } 44 | else 45 | { 46 | switch (i) 47 | { 48 | case 1: 49 | cir.setReturnValue(this.fluidRenderer.renderFluid(blockAccess, state, pos, worldRendererIn)); 50 | return; 51 | case 2: 52 | cir.setReturnValue(false); 53 | return; 54 | case 3: 55 | IBakedModel ibakedmodel = this.getModelFromBlockState(state, blockAccess, pos); 56 | 57 | cir.setReturnValue( this.blockRenderer.renderModel(blockAccess, ibakedmodel, state, pos, worldRendererIn)); 58 | return; 59 | default: 60 | cir.setReturnValue(false); 61 | } 62 | } 63 | } 64 | catch (Throwable throwable) 65 | { 66 | CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Tesselating block in world"); 67 | CrashReportCategory crashreportcategory = crashreport.makeCategory("Block being tesselated"); 68 | CrashReportCategory.addBlockInfo(crashreportcategory, pos, state.getBlock(), state.getBlock().getMetaFromState(state)); 69 | throw new ReportedException(crashreport); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/ChestRendererMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import floppaclient.module.impl.render.ChestEsp; 4 | import floppaclient.utils.render.WorldRenderUtils; 5 | import net.minecraft.client.renderer.GlStateManager; 6 | import net.minecraft.client.renderer.tileentity.TileEntityChestRenderer; 7 | import net.minecraft.tileentity.TileEntityChest; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | @Mixin(TileEntityChestRenderer.class) 14 | abstract class ChestRendererMixin { 15 | 16 | @Inject(method = {"renderTileEntityAt(Lnet/minecraft/tileentity/TileEntityChest;DDDFI)V"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;enableDepth()V", shift = At.Shift.AFTER)) 17 | public void onRender(TileEntityChest te, double x, double y, double z, float partialTicks, int destroyStage, CallbackInfo ci){ 18 | if (ChestEsp.INSTANCE.isPhaseMode() && ChestEsp.INSTANCE.isDrawingWorld()){ 19 | // Polygon offset is a pretty scuffed way of doing this, since it is meant only for small offsets, 20 | // but it works and is really simple. Stencil would probably be the proper way. 21 | GlStateManager.enablePolygonOffset(); 22 | GlStateManager.doPolygonOffset(0,-7_000_000); 23 | } 24 | } 25 | 26 | @Inject(method = {"renderTileEntityAt(Lnet/minecraft/tileentity/TileEntityChest;DDDFI)V"}, at = @At("RETURN")) 27 | public void onRenderReturn(TileEntityChest te, double x, double y, double z, float partialTicks, int destroyStage, CallbackInfo ci){ 28 | if (ChestEsp.INSTANCE.isBoxMode() && ChestEsp.INSTANCE.isDrawingWorld()) 29 | WorldRenderUtils.INSTANCE.drawBoxAtBlock(x, y, z, ChestEsp.INSTANCE.getBoxColor(), ChestEsp.INSTANCE.getBoxThickness(), false); 30 | if (ChestEsp.INSTANCE.isPhaseMode() && ChestEsp.INSTANCE.isDrawingWorld()){ 31 | GlStateManager.disablePolygonOffset(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/ChunkRendererWorkerMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import floppaclient.module.impl.player.FreeCam; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.renderer.chunk.ChunkRenderWorker; 6 | import net.minecraft.entity.Entity; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Redirect; 10 | 11 | /** 12 | * The mixins in here are used for 13 | * {@link FreeCam}. 14 | * @author Aton 15 | */ 16 | @Mixin(ChunkRenderWorker.class) 17 | abstract public class ChunkRendererWorkerMixin implements Runnable { 18 | @Redirect(method = "processTask", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;getRenderViewEntity()Lnet/minecraft/entity/Entity;")) 19 | public Entity tweakRenderViewEntity(Minecraft instance) { 20 | if (FreeCam.INSTANCE.shouldTweakViewEntity()) { 21 | return FreeCam.INSTANCE.tweakRenderViewEntityHook(); 22 | }else { 23 | return instance.getRenderViewEntity(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/ItemRendererMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import floppaclient.module.impl.misc.QOL; 4 | import floppaclient.module.impl.render.ItemAnimations; 5 | import net.minecraft.client.entity.AbstractClientPlayer; 6 | import net.minecraft.client.entity.EntityPlayerSP; 7 | import net.minecraft.client.renderer.ItemRenderer; 8 | import net.minecraft.item.ItemStack; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.Redirect; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | @Mixin(value = {ItemRenderer.class}) 17 | public class ItemRendererMixin { 18 | 19 | @Shadow private ItemStack itemToRender; 20 | 21 | @Inject(method = {"transformFirstPersonItem(FF)V"}, at = @At("HEAD"), cancellable = true) 22 | public void itemTransform(float equipProgress, float swingProgress, CallbackInfo ci) { 23 | if (ItemAnimations.INSTANCE.itemTransforHook(equipProgress, swingProgress)) ci.cancel(); 24 | } 25 | 26 | @Inject(method = {"doItemUsedTransformations"}, at = @At("HEAD"), cancellable = true) 27 | public void useTransform(float swingProgress, CallbackInfo ci){ 28 | if (ItemAnimations.INSTANCE.scaledSwing(swingProgress)) ci.cancel(); 29 | } 30 | 31 | @Inject(method = {"performDrinking"}, at = @At("HEAD"), cancellable = true) 32 | public void drinkTransform(AbstractClientPlayer clientPlayer, float partialTicks, CallbackInfo ci){ 33 | if (ItemAnimations.INSTANCE.scaledDrinking(clientPlayer, partialTicks, itemToRender)) ci.cancel(); 34 | } 35 | 36 | @Redirect(method = {"renderOverlays"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;isBurning()Z")) 37 | public boolean shouldRenderFireOverlay(EntityPlayerSP instance){ 38 | return QOL.INSTANCE.shouldDisplayBurnOverlayHook(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/RenderChunkMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import floppaclient.module.impl.render.XRay; 4 | import net.minecraft.client.renderer.chunk.RenderChunk; 5 | import net.minecraft.client.renderer.chunk.SetVisibility; 6 | import net.minecraft.client.renderer.chunk.VisGraph; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Redirect; 10 | 11 | @Mixin(RenderChunk.class) 12 | abstract public class RenderChunkMixin { 13 | @Redirect(method = "rebuildChunk", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/chunk/VisGraph;computeVisibility()Lnet/minecraft/client/renderer/chunk/SetVisibility;")) 14 | private SetVisibility tweakVisibility(VisGraph instance) { 15 | if (XRay.INSTANCE.getEnabled()) { 16 | if (((VisGraphAccessor) instance).getField_178611_f() < 4096) { 17 | ((VisGraphAccessor) instance).setField_178611_f(4090); 18 | } 19 | } 20 | return instance.computeVisibility(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/RenderGlobalMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import floppaclient.module.impl.player.FreeCam; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.renderer.RenderGlobal; 6 | import net.minecraft.client.resources.IResourceManagerReloadListener; 7 | import net.minecraft.entity.Entity; 8 | import net.minecraft.world.IWorldAccess; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Redirect; 12 | 13 | @Mixin(RenderGlobal.class) 14 | abstract public class RenderGlobalMixin implements IWorldAccess, IResourceManagerReloadListener { 15 | @Redirect(method = "renderEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;getRenderViewEntity()Lnet/minecraft/entity/Entity;")) 16 | public Entity tweakViewEntity(Minecraft instance) { 17 | if (FreeCam.INSTANCE.shouldTweakViewEntity()) { 18 | return FreeCam.INSTANCE.tweakRenderViewEntityHook(); 19 | }else { 20 | return instance.getRenderViewEntity(); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/RenderPlayerMixin.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import floppaclient.FloppaClient; 4 | import floppaclient.module.impl.player.FreeCam; 5 | import net.minecraft.client.renderer.entity.RenderManager; 6 | import net.minecraft.client.renderer.entity.RenderPlayer; 7 | import net.minecraft.entity.Entity; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Redirect; 11 | 12 | @Mixin(RenderPlayer.class) 13 | abstract public class RenderPlayerMixin { 14 | 15 | @Redirect(method = "doRender(Lnet/minecraft/client/entity/AbstractClientPlayer;DDDFF)V", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/RenderManager;livingPlayer:Lnet/minecraft/entity/Entity;")) 16 | public Entity tweakViewEntity(RenderManager instance) { 17 | if (FreeCam.INSTANCE.shouldTweakViewEntity()) { 18 | return FloppaClient.mc.thePlayer; 19 | }else { 20 | return instance.livingPlayer; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/mixins/render/VisGraphAccessor.java: -------------------------------------------------------------------------------- 1 | package floppaclient.mixins.render; 2 | 3 | import net.minecraft.client.renderer.chunk.VisGraph; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(VisGraph.class) 8 | public interface VisGraphAccessor { 9 | @Accessor int getField_178611_f(); 10 | @Accessor void setField_178611_f(int translucentBlockCount); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/floppaclient/tweaker/FloppaClientTweaker.java: -------------------------------------------------------------------------------- 1 | package floppaclient.tweaker; 2 | 3 | import gg.essential.loader.stage0.EssentialSetupTweaker; 4 | import net.minecraft.launchwrapper.LaunchClassLoader; 5 | 6 | @SuppressWarnings("unused") 7 | public class FloppaClientTweaker extends EssentialSetupTweaker { 8 | 9 | public static LaunchClassLoader launchClassLoader; 10 | 11 | @Override 12 | public void injectIntoClassLoader(LaunchClassLoader classLoader) { 13 | super.injectIntoClassLoader(classLoader); 14 | launchClassLoader = classLoader; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/commands/AddCommand.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.commands 2 | 3 | import floppaclient.utils.DataHandler 4 | import floppaclient.utils.ChatUtils.modMessage 5 | import net.minecraft.command.CommandBase 6 | import net.minecraft.command.ICommandSender 7 | 8 | 9 | class AddCommand : CommandBase() { 10 | override fun getCommandName(): String { 11 | return "addclip" 12 | } 13 | 14 | override fun getCommandAliases(): List { 15 | return listOf( 16 | "addc", 17 | "adc" 18 | ) 19 | } 20 | 21 | override fun getCommandUsage(sender: ICommandSender): String { 22 | return "/$commandName" 23 | } 24 | 25 | override fun getRequiredPermissionLevel(): Int { 26 | return 0 27 | } 28 | 29 | override fun processCommand(sender: ICommandSender, args: Array) { 30 | try { 31 | DataHandler.addClip(args.map { it.toDouble() }) 32 | } catch (e: Throwable){ 33 | modMessage("§cArguments error.") 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/commands/AddEtherCommand.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.commands 2 | 3 | import floppaclient.utils.DataHandler 4 | import floppaclient.utils.ChatUtils.modMessage 5 | import net.minecraft.command.CommandBase 6 | import net.minecraft.command.ICommandSender 7 | 8 | 9 | class AddEtherCommand : CommandBase() { 10 | override fun getCommandName(): String { 11 | return "addether" 12 | } 13 | 14 | override fun getCommandAliases(): List { 15 | return listOf( 16 | "add", 17 | "ad", 18 | "adde" 19 | ) 20 | } 21 | 22 | override fun getCommandUsage(sender: ICommandSender): String { 23 | return "/$commandName" 24 | } 25 | 26 | override fun getRequiredPermissionLevel(): Int { 27 | return 0 28 | } 29 | 30 | override fun processCommand(sender: ICommandSender, args: Array) { 31 | try { 32 | DataHandler.addEther(args.map { it.toDouble() }) 33 | } catch (e: Throwable){ 34 | modMessage("§cArguments error.") 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/commands/Clip3DCommand.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.commands 2 | 3 | import floppaclient.utils.ChatUtils 4 | import floppaclient.utils.ClipTools 5 | import floppaclient.utils.GeometryUtils 6 | import net.minecraft.command.CommandBase 7 | import net.minecraft.command.ICommandSender 8 | 9 | class Clip3DCommand : CommandBase() { 10 | override fun getCommandName(): String { 11 | return "clip3d" 12 | } 13 | 14 | override fun getCommandAliases(): List { 15 | return listOf( 16 | "3dclip", 17 | "dclip" 18 | ) 19 | } 20 | 21 | override fun getCommandUsage(sender: ICommandSender): String { 22 | return "/$commandName" 23 | } 24 | 25 | override fun getRequiredPermissionLevel(): Int { 26 | return 0 27 | } 28 | 29 | override fun processCommand(sender: ICommandSender, args: Array) { 30 | val y = try { 31 | args[0].toDouble() 32 | } catch (e: java.lang.NumberFormatException) { 33 | ChatUtils.modMessage("§cArguments error.") 34 | return 35 | } 36 | ClipTools.dClip(y, GeometryUtils.yaw(), GeometryUtils.pitch()) 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/commands/HClipCommand.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.commands 2 | 3 | import floppaclient.utils.ChatUtils 4 | import floppaclient.utils.ClipTools 5 | import net.minecraft.command.CommandBase 6 | import net.minecraft.command.ICommandSender 7 | 8 | class HClipCommand : CommandBase() { 9 | override fun getCommandName(): String { 10 | return "hclip" 11 | } 12 | 13 | override fun getCommandUsage(sender: ICommandSender): String { 14 | return "/$commandName" 15 | } 16 | 17 | override fun getRequiredPermissionLevel(): Int { 18 | return 0 19 | } 20 | 21 | override fun processCommand(sender: ICommandSender, args: Array) { 22 | val values = try { 23 | args.map { it.toDouble() } 24 | } catch (e: java.lang.NumberFormatException) { 25 | ChatUtils.modMessage("§cArguments error.") 26 | return 27 | } 28 | when(values.size) { 29 | 1 -> { 30 | ClipTools.hClip(values[0]) 31 | } 32 | 2 -> { 33 | ClipTools.hClip(values[0], yOffs = values[1]) 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/commands/RemoveCommand.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.commands 2 | 3 | import floppaclient.utils.ChatUtils 4 | import floppaclient.utils.DataHandler 5 | import net.minecraft.command.CommandBase 6 | import net.minecraft.command.ICommandSender 7 | 8 | 9 | class RemoveCommand : CommandBase() { 10 | override fun getCommandName(): String { 11 | return "removeclip" 12 | } 13 | 14 | override fun getCommandAliases(): List { 15 | return listOf( 16 | "remc", 17 | "rmc" 18 | ) 19 | } 20 | 21 | override fun getCommandUsage(sender: ICommandSender): String { 22 | return "/$commandName" 23 | } 24 | 25 | override fun getRequiredPermissionLevel(): Int { 26 | return 0 27 | } 28 | 29 | override fun processCommand(sender: ICommandSender, args: Array) { 30 | try { 31 | DataHandler.removeClip(args.map { it.toDouble() }) 32 | } catch (e: Throwable){ 33 | ChatUtils.modMessage("&cArguments error.") 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/commands/RemoveEtherCommand.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.commands 2 | 3 | import floppaclient.utils.ChatUtils 4 | import floppaclient.utils.DataHandler 5 | import net.minecraft.command.CommandBase 6 | import net.minecraft.command.ICommandSender 7 | 8 | 9 | class RemoveEtherCommand : CommandBase() { 10 | override fun getCommandName(): String { 11 | return "removeether" 12 | } 13 | 14 | override fun getCommandAliases(): List { 15 | return listOf( 16 | "rem", 17 | "rm" 18 | ) 19 | } 20 | 21 | override fun getCommandUsage(sender: ICommandSender): String { 22 | return "/$commandName" 23 | } 24 | 25 | override fun getRequiredPermissionLevel(): Int { 26 | return 0 27 | } 28 | 29 | override fun processCommand(sender: ICommandSender, args: Array) { 30 | try { 31 | DataHandler.removeEther(args.map { it.toDouble() }) 32 | } catch (e: Throwable){ 33 | ChatUtils.modMessage("&cArguments error.") 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/commands/VertClipCommand.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.commands 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.utils.ChatUtils 5 | import floppaclient.utils.ClipTools 6 | import net.minecraft.command.CommandBase 7 | import net.minecraft.command.ICommandSender 8 | import net.minecraft.util.BlockPos 9 | 10 | class VertClipCommand : CommandBase() { 11 | override fun getCommandName(): String { 12 | return "vertclip" 13 | } 14 | 15 | override fun getCommandUsage(sender: ICommandSender): String { 16 | return "/$commandName" 17 | } 18 | 19 | override fun getRequiredPermissionLevel(): Int { 20 | return 0 21 | } 22 | 23 | override fun processCommand(sender: ICommandSender, args: Array) { 24 | if (args.isEmpty()){ 25 | val pos = BlockPos(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ).down() 26 | val x = pos.x 27 | val z = pos.z 28 | for (y in pos.y downTo 3){ 29 | val newPos = BlockPos(x,y,z) 30 | 31 | if(mc.theWorld.getBlockState(newPos).block.material.isSolid) continue 32 | if(mc.theWorld.getBlockState(newPos.down()).block.material.isSolid) continue 33 | for (y2 in y-2 downTo 1) { 34 | val newPos2 = BlockPos(x, y2, z) 35 | if(mc.theWorld.getBlockState(newPos2).block.material.isSolid) { 36 | ClipTools.teleport(x+0.5,y - 1.0, z + 0.5) 37 | return 38 | } 39 | } 40 | break 41 | } 42 | } 43 | else if (args[0] == "ground"){ 44 | val pos = BlockPos(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ).down() 45 | val x = pos.x 46 | val z = pos.z 47 | for (y in pos.y downTo 3){ 48 | val newPos = BlockPos(x,y,z) 49 | 50 | if(mc.theWorld.getBlockState(newPos).block.material.isSolid) continue 51 | if(mc.theWorld.getBlockState(newPos.down()).block.material.isSolid) continue 52 | for (y2 in y-2 downTo 1) { 53 | val newPos2 = BlockPos(x, y2, z) 54 | if(mc.theWorld.getBlockState(newPos2).block.material.isSolid) { 55 | mc.thePlayer.motionY = 0.0 56 | ClipTools.teleport(x+0.5,y2 + 1.05, z + 0.5) 57 | return 58 | } 59 | } 60 | break 61 | } 62 | } 63 | else if(args[0] == "floor"){ 64 | val pos = BlockPos(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ).down() 65 | val x = pos.x 66 | val z = pos.z 67 | for (y in pos.y downTo 1){ 68 | val newPos = BlockPos(x,y,z) 69 | 70 | if(mc.theWorld.getBlockState(newPos).block.material.isSolid) { 71 | mc.thePlayer.motionY = 0.0 72 | ClipTools.teleport(mc.thePlayer.posX,y + 1.05, mc.thePlayer.posZ) 73 | return 74 | } 75 | } 76 | } 77 | else { 78 | val y = try { 79 | args[0].toDouble() 80 | } catch (e: java.lang.NumberFormatException) { 81 | ChatUtils.modMessage("§cArguments error.") 82 | return 83 | } 84 | ClipTools.clip(0.0, y, 0.0) 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/commands/WardrobeCommand.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.commands 2 | 3 | import floppaclient.FloppaClient.Companion.inSkyblock 4 | import floppaclient.FloppaClient.Companion.mc 5 | import floppaclient.utils.ChatUtils 6 | import floppaclient.utils.ChatUtils.modMessage 7 | import net.minecraft.command.CommandBase 8 | import net.minecraft.command.ICommandSender 9 | import net.minecraft.inventory.ContainerChest 10 | 11 | object WardrobeCommand : CommandBase() { 12 | 13 | private var thread: Thread? = null 14 | 15 | override fun getCommandName(): String { 16 | return "fwardrobe" 17 | } 18 | 19 | override fun getCommandAliases(): List { 20 | return listOf( 21 | "fwd" 22 | ) 23 | } 24 | 25 | override fun getRequiredPermissionLevel(): Int { 26 | return 0 27 | } 28 | 29 | override fun getCommandUsage(sender: ICommandSender?): String { 30 | return "/$commandName" 31 | } 32 | 33 | override fun processCommand(sender: ICommandSender?, args: Array) { 34 | if (!inSkyblock) return 35 | if (args.isEmpty()) { 36 | modMessage("Specify slot") 37 | return 38 | } 39 | val slot = args[0].toInt() 40 | if (slot !in 1..9) return modMessage("Invalid slot") 41 | 42 | ChatUtils.sendChat("/wardrobe") 43 | if (thread == null || !thread!!.isAlive) { 44 | thread = Thread({ 45 | for (i in 0..100) { 46 | if (mc.thePlayer.openContainer is ContainerChest && mc.thePlayer.openContainer?.inventorySlots?.get(0)?.inventory?.name?.startsWith("Wardrobe") == true) { 47 | mc.playerController.windowClick( 48 | mc.thePlayer.openContainer.windowId, 49 | 35+slot, 50 | 0, 51 | 0, 52 | mc.thePlayer 53 | ) 54 | mc.thePlayer.closeScreen() 55 | return@Thread 56 | } 57 | Thread.sleep(20) 58 | } 59 | modMessage("§aWarobe failed, timed out") 60 | }, "Auto Wardrobe") 61 | thread!!.start() 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/config/jsonutils/BlockPosDeserializer.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.config.jsonutils 2 | 3 | import com.google.gson.JsonDeserializationContext 4 | import com.google.gson.JsonDeserializer 5 | import com.google.gson.JsonElement 6 | import net.minecraft.util.BlockPos 7 | import java.lang.reflect.Type 8 | 9 | class BlockPosDeserializer : JsonDeserializer { 10 | override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): BlockPos { 11 | var blockPos = BlockPos(0,0,0) 12 | 13 | if (json?.isJsonPrimitive == true) { 14 | json.asJsonPrimitive.let{ primitive -> 15 | // drop first and last element as those are " 16 | val coordList = (primitive.toString().dropLast(1).drop(1) 17 | .takeIf(String::isNotEmpty) 18 | ?.split(", ") 19 | ?: listOf()) 20 | .map { it.toIntOrNull() ?: 0 } 21 | if(coordList.size >= 3) { 22 | blockPos = BlockPos(coordList[0], coordList[1], coordList[2]) 23 | } 24 | } 25 | } 26 | return blockPos 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/config/jsonutils/BlockPosSerializer.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.config.jsonutils 2 | 3 | import com.google.gson.JsonElement 4 | import com.google.gson.JsonPrimitive 5 | import com.google.gson.JsonSerializationContext 6 | import com.google.gson.JsonSerializer 7 | import net.minecraft.util.BlockPos 8 | import java.lang.reflect.Type 9 | 10 | class BlockPosSerializer : JsonSerializer { 11 | override fun serialize(src: BlockPos?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { 12 | src?.let { 13 | return JsonPrimitive("${it.x}, ${it.y}, ${it.z}") 14 | } 15 | 16 | return JsonPrimitive("") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/config/jsonutils/IntListDeserializer.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.config.jsonutils 2 | 3 | import com.google.gson.JsonDeserializationContext 4 | import com.google.gson.JsonDeserializer 5 | import com.google.gson.JsonElement 6 | import java.lang.reflect.Type 7 | 8 | class IntListDeserializer : JsonDeserializer> { 9 | override fun deserialize( 10 | json: JsonElement?, 11 | typeOfT: Type?, 12 | context: JsonDeserializationContext? 13 | ): MutableList { 14 | return if (json?.isJsonPrimitive == true) { 15 | // for some reason conversion of the json, that is of type JsonString, which is JsonPrimitive, to JsonArray is needed 16 | (json.toString().substringAfter("[").substringBefore("]") 17 | .takeIf(String::isNotEmpty) 18 | ?.split(", ") 19 | ?.toMutableList() 20 | ?: mutableListOf()) 21 | .map { it.toIntOrNull() ?: 0 } 22 | .toMutableList() 23 | // Gson().fromJson(json, typeOfT) 24 | // object : TypeToken>(){}.type 25 | 26 | } else { 27 | mutableListOf() 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/config/jsonutils/SetBlockPosDeserializer.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.config.jsonutils 2 | 3 | import com.google.gson.JsonDeserializationContext 4 | import com.google.gson.JsonDeserializer 5 | import com.google.gson.JsonElement 6 | import net.minecraft.util.BlockPos 7 | import java.lang.reflect.Type 8 | 9 | class SetBlockPosDeserializer : JsonDeserializer> { 10 | override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): MutableSet { 11 | val blockSet = mutableSetOf() 12 | 13 | if (json?.isJsonArray == true) { 14 | json.asJsonArray.forEach{ element -> 15 | // drop first and last element as those are " 16 | val coordList = (element.toString().dropLast(1).drop(1) 17 | .takeIf(String::isNotEmpty) 18 | ?.split(", ") 19 | ?: listOf()) 20 | .map { it.toIntOrNull() ?: 0 } 21 | if(coordList.size >= 3) { 22 | blockSet.add(BlockPos(coordList[0], coordList[1], coordList[2])) 23 | } 24 | } 25 | } 26 | return blockSet 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/config/jsonutils/SetBlockPosSerializer.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.config.jsonutils 2 | 3 | import com.google.gson.JsonArray 4 | import com.google.gson.JsonElement 5 | import com.google.gson.JsonPrimitive 6 | import com.google.gson.JsonSerializationContext 7 | import com.google.gson.JsonSerializer 8 | import net.minecraft.util.BlockPos 9 | import java.lang.reflect.Type 10 | 11 | class SetBlockPosSerializer : JsonSerializer> { 12 | override fun serialize(src: MutableSet?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { 13 | val jsonArray = JsonArray() 14 | 15 | src?.forEach { 16 | jsonArray.add(JsonPrimitive("${it.x}, ${it.y}, ${it.z}")) 17 | } 18 | 19 | return jsonArray 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/config/jsonutils/SettingDeserializer.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.config.jsonutils 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.impl.BooleanSetting 5 | import floppaclient.module.settings.impl.NumberSetting 6 | import floppaclient.module.settings.impl.StringSetting 7 | import com.google.gson.JsonDeserializationContext 8 | import com.google.gson.JsonDeserializer 9 | import com.google.gson.JsonElement 10 | import com.google.gson.JsonPrimitive 11 | import floppaclient.module.settings.impl.DummySetting 12 | import java.lang.reflect.Type 13 | 14 | class SettingDeserializer: JsonDeserializer> { 15 | override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Setting<*> { 16 | if (json?.isJsonObject == true) { 17 | if (json.asJsonObject.entrySet().isEmpty()) return DummySetting("Undefined") 18 | 19 | /** 20 | * The JsonObject for a Setting should only have one property. If more properties will be needed, this 21 | * deserializer has to be updated. 22 | * For now only the first element is used. 23 | */ 24 | val name = json.asJsonObject.entrySet().first().key 25 | val value = json.asJsonObject.entrySet().first().value 26 | 27 | if (value.isJsonPrimitive) { 28 | when { 29 | (value as JsonPrimitive).isBoolean -> return BooleanSetting(name, value.asBoolean) 30 | value.isNumber -> return NumberSetting(name, value.asDouble) 31 | value.isString -> return StringSetting(name, value.asString) 32 | } 33 | } 34 | } 35 | return DummySetting("Undefined") 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/config/jsonutils/SettingSerializer.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.config.jsonutils 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.impl.* 5 | import com.google.gson.JsonElement 6 | import com.google.gson.JsonObject 7 | import com.google.gson.JsonSerializationContext 8 | import com.google.gson.JsonSerializer 9 | import java.lang.reflect.Type 10 | 11 | class SettingSerializer : JsonSerializer> { 12 | override fun serialize(src: Setting<*>?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { 13 | return JsonObject().apply { 14 | when (src) { 15 | is BooleanSetting -> this.addProperty(src.name, src.enabled) 16 | is NumberSetting -> this.addProperty(src.name, src.value) 17 | is StringSelectorSetting -> this.addProperty(src.name, src.selected) 18 | is SelectorSetting -> this.addProperty(src.name, src.selected) 19 | is StringSetting -> this.addProperty(src.name, src.text) 20 | is ColorSetting -> this.addProperty(src.name, src.value.rgb) 21 | is ActionSetting -> this.addProperty(src.name, "Action Setting") 22 | } 23 | } 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/events/PositionUpdateEvent.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.events 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Cancelable 4 | import net.minecraftforge.fml.common.eventhandler.Event 5 | 6 | @Cancelable 7 | open class PositionUpdateEvent constructor( 8 | var x: Double, 9 | var y: Double, 10 | var z: Double, 11 | var yaw: Float, 12 | var pitch: Float, 13 | var onGround: Boolean, 14 | var sprinting: Boolean, 15 | var sneaking: Boolean 16 | ) : Event() { 17 | 18 | 19 | @Cancelable 20 | class Pre(x: Double, y: Double, z: Double, yaw: Float, pitch: Float, onGround: Boolean, sprinting: Boolean, sneaking: Boolean) : PositionUpdateEvent(x, y, z, yaw, pitch, onGround, sprinting, sneaking) 21 | 22 | @Cancelable 23 | class Post(x: Double, y: Double, z: Double, yaw: Float, pitch: Float, onGround: Boolean, sprinting: Boolean, sneaking: Boolean) : PositionUpdateEvent(x, y, z, yaw, pitch, onGround, sprinting, sneaking) 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/events/PreKeyInputEvent.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.events 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event 4 | 5 | /** 6 | * This event is mixed in to fire before the vanilla key binds are evaluated. 7 | * The forge event fires after those. 8 | */ 9 | class PreKeyInputEvent constructor( 10 | val key: Int, 11 | val character: Char 12 | ) : Event() { 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/events/PreMouseInputEvent.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.events 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event 4 | 5 | /** 6 | * This event is mixed in to fire before the vanilla key binds are evaluated. 7 | * The forge event fires after those. 8 | */ 9 | class PreMouseInputEvent constructor( 10 | val button: Int 11 | ): Event() { 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/AutoActionData.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | import net.minecraft.util.BlockPos 4 | 5 | data class AutoActionData( 6 | // Room core, or the first in room list if there are multiple 7 | val baseCore: Int, 8 | // Map of Clip start position to clip route 9 | val clips: MutableMap, MutableList> = mutableMapOf(), 10 | // Map of Auto Ether start position to target 11 | val etherwarps: MutableMap, BlockPos> = mutableMapOf(), 12 | ) 13 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/Door.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | import floppaclient.module.impl.render.MapRooms 4 | import java.awt.Color 5 | 6 | class Door(x: Int, z: Int, val type: DoorType) : Tile(x, z) { 7 | var opened = false 8 | 9 | override val color: Color 10 | get() = when (this.type) { 11 | DoorType.BLOOD -> MapRooms.colorBloodDoor.value 12 | DoorType.ENTRANCE -> MapRooms.colorEntranceDoor.value 13 | DoorType.WITHER -> if (opened) MapRooms.colorOpenWitherDoor.value else MapRooms.colorWitherDoor.value 14 | else -> MapRooms.colorRoomDoor.value 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/DoorType.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | enum class DoorType { 4 | BLOOD, 5 | ENTRANCE, 6 | NORMAL, 7 | WITHER 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/ExtrasData.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | import net.minecraft.util.BlockPos 4 | 5 | data class ExtrasData( 6 | // Room core, or the first in room list if there are multiple 7 | val baseCore: Int, 8 | val preBlocks: MutableMap> = mutableMapOf() 9 | ) 10 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/Room.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | import floppaclient.floppamap.dungeon.Dungeon 4 | import floppaclient.module.impl.render.DungeonMap 5 | import floppaclient.module.impl.render.MapRooms 6 | import java.awt.Color 7 | 8 | class Room(x: Int, z: Int, var data: RoomData) : Tile(x, z) { 9 | 10 | constructor(x: Int, z: Int, configData: RoomConfigData) : this(x, z, RoomData(configData = configData)) 11 | 12 | /** 13 | * Core of this tile. 14 | */ 15 | var core: Int? = null 16 | var isSeparator = false 17 | 18 | /** 19 | * Marks this tile as "unique". 20 | * Unique is only relevant for rooms consisting of multiple tiles. All 1x1 rooms are unique by default. 21 | * For rooms with multiple tiles the first Tile in [Dungeon.dungeonList] will be the unique one. 22 | * This corresponds to the most west and north tile of a room. (west prioritized over north) 23 | * The unique tile is the one which has the checkmark on the map. 24 | */ 25 | var isUnique: Boolean = false 26 | 27 | override val color: Color 28 | get() = if (DungeonMap.legitMode.enabled && this.state == RoomState.QUESTION_MARK && !visited) 29 | MapRooms.colorUnexplored.value 30 | else when (data.type) { 31 | RoomType.UNKNOWN -> MapRooms.colorUnexplored.value 32 | RoomType.BLOOD -> MapRooms.colorBlood.value 33 | RoomType.CHAMPION -> MapRooms.colorMiniboss.value 34 | RoomType.ENTRANCE -> MapRooms.colorEntrance.value 35 | RoomType.FAIRY -> MapRooms.colorFairy.value 36 | RoomType.PUZZLE -> MapRooms.colorPuzzle.value 37 | RoomType.RARE -> MapRooms.colorRare.value 38 | RoomType.TRAP -> MapRooms.colorTrap.value 39 | else -> if (data.hasMimic) MapRooms.colorRoomMimic.value else MapRooms.colorRoom.value 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/RoomConfigData.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | /** 4 | * Data for rooms retrieved from rooms.json. 5 | * 6 | * Not to be confused with [RoomData] which contains all data for the room. 7 | */ 8 | data class RoomConfigData( 9 | val name: String, 10 | val type: RoomType, 11 | val secrets: Int, 12 | val size: Int, 13 | val cores: List, 14 | val crypts: Int, 15 | val trappedChests: Int 16 | ) 17 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/RoomData.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | /** 4 | * This class is meant to offer a nice way to store dungeon room data, that can but does not have to be backed up by 5 | * [RoomConfigData] from the dungeon scan. 6 | * @author Aton 7 | */ 8 | class RoomData( 9 | name: String = "Unknown", 10 | type: RoomType = RoomType.UNKNOWN, 11 | ) { 12 | constructor(configData: RoomConfigData) : this() { 13 | this.configData= configData 14 | } 15 | 16 | var hasMimic = false 17 | 18 | var configData: RoomConfigData? = null 19 | 20 | // First the values from config. 21 | var name: String = name 22 | get() = configData?.name ?: field 23 | var type: RoomType = type 24 | get() = configData?.type ?: field 25 | var maxSecrets: Int? = null 26 | get() = configData?.secrets ?: field 27 | var size: Int? = null 28 | get() = configData?.size ?: field 29 | val cores: List? 30 | get() = configData?.cores 31 | val crypts: Int? 32 | get() = configData?.crypts 33 | val trappedChests: Int? 34 | get() = configData?.trappedChests 35 | 36 | // room specific variables. 37 | var currentSecrets = 0 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/RoomState.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | enum class RoomState { 4 | /** White Checked */ 5 | CLEARED, 6 | DISCOVERED, 7 | FAILED, 8 | /** Green Checked */ 9 | GREEN, 10 | UNDISCOVERED, 11 | /** Used for the question mark rooms */ 12 | QUESTION_MARK; 13 | 14 | val revealed: Boolean 15 | get() = this != UNDISCOVERED && this != QUESTION_MARK 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/RoomType.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | enum class RoomType { 4 | BLOOD, 5 | CHAMPION, 6 | ENTRANCE, 7 | FAIRY, 8 | NORMAL, 9 | PUZZLE, 10 | RARE, 11 | TRAP, 12 | BOSS, 13 | UNKNOWN, // For the question mark rooms on the map. 14 | REGION 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/core/Tile.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.core 2 | 3 | import floppaclient.floppamap.dungeon.Dungeon 4 | import java.awt.Color 5 | 6 | abstract class Tile(val x: Int, val z: Int) { 7 | var state = RoomState.UNDISCOVERED 8 | var visited = false 9 | var scanned = true 10 | abstract val color: Color 11 | 12 | /** 13 | * Row in the duneonList. 14 | */ 15 | val row 16 | get() = (z - Dungeon.startZ) shr 4 17 | /** 18 | * Column in the dungeonList 19 | */ 20 | val column 21 | get() = (x - Dungeon.startX) shr 4 22 | } 23 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/dungeon/MimicDetector.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.dungeon 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.floppamap.core.Room 5 | import floppaclient.floppamap.core.RoomData 6 | import floppaclient.module.impl.render.DungeonMap 7 | import floppaclient.utils.ChatUtils.modMessage 8 | import net.minecraft.tileentity.TileEntityChest 9 | import net.minecraft.util.BlockPos 10 | 11 | /** 12 | * Code for finding the room which contains the Mimic. 13 | * 14 | * The mimic is detected by counting the trapped chests that fall within a room and comparing that number against the expected number. 15 | * If there are more chests present, then one has to be the Mimic. 16 | * 17 | * Based on [FunnyMap by Harry282](https://github.com/Harry282/FunnyMap/blob/master/src/main/kotlin/funnymap/features/dungeon/MimicDetector.kt). 18 | * @author Aton 19 | */ 20 | object MimicDetector { 21 | /** 22 | * Scan the Dungeon for the mimic trapped chest. 23 | * 24 | * When it is found [Dungeon.mimicFound] is set to true and the [hasMimic][RoomData.hasMimic] field for the 25 | * corresponding room is also set to true. 26 | */ 27 | fun findMimic() { 28 | val mimicRoomData = findMimicRoom() 29 | if (mimicRoomData != null) { 30 | mimicRoomData.hasMimic = true 31 | if(DungeonMap.mimicInfo.enabled && !DungeonMap.legitMode.enabled) modMessage("Mimic found in ${mimicRoomData.name}") 32 | Dungeon.mimicFound = true 33 | } 34 | } 35 | 36 | /** 37 | * Counts the trapped chests in all rooms and compares that number against the expected value. 38 | * If there are more trapped chests found than expected one of them has to be the mimic. 39 | * @return the room data for the room the mimic was found in or null if no mimic was found. 40 | */ 41 | private fun findMimicRoom(): RoomData? { 42 | mc.theWorld.loadedTileEntityList.filter { it is TileEntityChest && it.chestType == 1 } 43 | .mapNotNull { getRoomFromPos(it.pos) }.groupingBy { it.data }.eachCount() 44 | .forEach { (roomData, trappedChestCount) -> 45 | if(roomData.trappedChests != null && roomData.trappedChests!! < trappedChestCount) { 46 | return roomData 47 | } 48 | } 49 | return null 50 | } 51 | 52 | /** 53 | * Returns the Room which contains [pos]. returns null if the room has not been scanned yet or [pos] is outside the dungeon. 54 | */ 55 | private fun getRoomFromPos(pos: BlockPos): Room? { 56 | // The following operation is a division of the coordinates by the chunk size of 16 rounded down to the next even number. 57 | // This bins all coordinates into a region of 32 blocks, which is the size of a room. 58 | val column = ((pos.x - Dungeon.startX + 15) shr 4) and 0b1110 59 | val row = ((pos.z - Dungeon.startZ + 15) shr 4) and 0b1110 60 | return Dungeon.getDungeonTile(column, row) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/floppamap/utils/MapUtils.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.floppamap.utils 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.floppamap.dungeon.RunInformation 5 | import net.minecraft.item.ItemMap 6 | import net.minecraft.util.Vec4b 7 | import net.minecraft.world.storage.MapData 8 | 9 | object MapUtils { 10 | 11 | var startCorner = Pair(5, 5) 12 | 13 | /** 14 | * Rooms have size 18x18 pixels on the vanilla map in floors 1..3, and 16x16 obove that. 15 | */ 16 | var roomSize = 16 17 | var calibrated = false 18 | var coordMultiplier = 20.0/32.0 19 | 20 | private val colorString: String? 21 | get() { 22 | val mapData = getMapData() ?: return null 23 | return mapData.colors.map{it.toInt().toChar()}.joinToString("") 24 | } 25 | 26 | private val regex16 = Regex("${30.toChar()}{16}") 27 | private val regex18 = Regex("${30.toChar()}{18}") 28 | 29 | fun getMapData(): MapData? { 30 | val map = mc.thePlayer?.inventory?.getStackInSlot(8) ?: return null 31 | if (map.item !is ItemMap || !map.displayName.contains("Magical Map")) return null 32 | return (map.item as ItemMap).getMapData(map, mc.theWorld) 33 | } 34 | 35 | 36 | /** 37 | * Returns the room size of dungeon rooms in pixels. Based on the size of the start room in the map item. 38 | */ 39 | fun getRoomSizeFromMap(): Int? { 40 | val mapColorString = colorString ?: return null 41 | 42 | return if(regex18.find(mapColorString) != null) 18 43 | else if(regex16.find(mapColorString) != null) 16 44 | else null 45 | } 46 | 47 | /** 48 | * Returns the Start corner of the dungeon. This requires the rooms size to be set correctly first. 49 | */ 50 | fun getStartCornerFromMap(): Pair? { 51 | 52 | if (RunInformation.currentFloor?.floorNumber == 1) return Pair(22, 11) 53 | 54 | val mapColorString = colorString ?: return null 55 | 56 | val greenCorner = regex18.find(mapColorString)?.range?.first 57 | ?: regex16.find(mapColorString)?.range?.first 58 | ?: return null 59 | 60 | // make sure to update that value before using this function 61 | val increment = roomSize + 4 62 | val greenX = greenCorner.mod( 128) 63 | val greenZ = greenCorner shr 7 // Division by 128 64 | 65 | val startX = greenX.mod(increment) 66 | val startZ = greenZ.mod(increment) 67 | return Pair(startX, startZ) 68 | } 69 | 70 | val Vec4b.mapX 71 | get() = (this.func_176112_b() + 128) shr 1 72 | 73 | val Vec4b.mapZ 74 | get() = (this.func_176113_c() + 128) shr 1 75 | 76 | val Vec4b.yaw 77 | get() = this.func_176111_d() * 22.5f 78 | } 79 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/forge/FMLLoadingPlugin.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.forge 2 | 3 | import net.minecraftforge.common.ForgeVersion 4 | import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin 5 | import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin.MCVersion 6 | import org.spongepowered.asm.launch.MixinBootstrap 7 | import org.spongepowered.asm.mixin.MixinEnvironment 8 | import org.spongepowered.asm.mixin.Mixins 9 | 10 | @MCVersion(ForgeVersion.mcVersion) 11 | class FMLLoadingPlugin : IFMLLoadingPlugin { 12 | 13 | override fun getASMTransformerClass(): Array = emptyArray() 14 | 15 | override fun getModContainerClass(): String? = null 16 | 17 | override fun getSetupClass(): String? = null 18 | 19 | override fun injectData(data: Map) {} 20 | 21 | override fun getAccessTransformerClass(): String? = null 22 | 23 | init { 24 | MixinBootstrap.init() 25 | Mixins.addConfiguration("mixins.floppaclient.json") 26 | MixinEnvironment.getCurrentEnvironment().obfuscationContext = "searge" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/hooks/SoundManagerHook.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.hooks 2 | 3 | import floppaclient.utils.Utils 4 | import net.minecraft.client.audio.ISound 5 | import net.minecraft.client.audio.SoundCategory 6 | import net.minecraft.client.audio.SoundPoolEntry 7 | import net.minecraft.util.MathHelper 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable 9 | 10 | /** 11 | * Taken from Skytils 12 | */ 13 | object SoundManagerHook { 14 | 15 | @JvmStatic 16 | fun bypassCategoryVolume( 17 | sound: ISound, 18 | entry: SoundPoolEntry, 19 | category: SoundCategory, 20 | cir: CallbackInfoReturnable 21 | ) { 22 | if (Utils.shouldBypassVolume) cir.returnValue = MathHelper.clamp_float(sound.volume, 0f, 1f) 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/AlwaysActive.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module 2 | 3 | /** 4 | * [Module] classes with this annotation will be registered to the Event Bus on game start-up and will not be 5 | * unregistered [onDisable][Module.onDisable]. 6 | * 7 | * @author Aton 8 | */ 9 | @Retention(AnnotationRetention.RUNTIME) 10 | @Target(AnnotationTarget.CLASS) 11 | annotation class AlwaysActive 12 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/Category.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module 2 | 3 | enum class Category { 4 | DUNGEON, RENDER, PLAYER, MISC, KEY_BIND 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/ConfigModule.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module 2 | 3 | import floppaclient.module.settings.Setting 4 | 5 | /** 6 | * A dummy implementation of the [Module] class. 7 | * 8 | * This class is made to be used as a dummy class for gson to use when reading the module config. 9 | * @author Aton 10 | */ 11 | class ConfigModule(name: String, 12 | keyCode: Int = 0, 13 | category: Category = Category.MISC, 14 | toggled: Boolean = false, 15 | settings: ArrayList> = ArrayList(), 16 | description: String = "" 17 | ) : Module(name, keyCode, category, toggled, settings, description) -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/RegisterHudElement.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module 2 | 3 | /** 4 | * Annotate your [HUDElements][floppaclient.ui.hud.HudElement] with this to register them. 5 | * 6 | * This annotation tells the [ModuleManager] to take care of registering the hud element for you. 7 | * It only works for objects inheriting from [HudElement][floppaclient.ui.hud.HudElement] declared within your module. 8 | */ 9 | @Retention(AnnotationRetention.RUNTIME) 10 | @Target(AnnotationTarget.CLASS) 11 | annotation class RegisterHudElement() 12 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/SelfRegisterModule.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module 2 | 3 | /** 4 | * [Module] classes with this annotation will automatically get loaded on game launch. 5 | * They do not have to be within [ModuleManager.modules]. 6 | * @author Aton 7 | */ 8 | @Retention(AnnotationRetention.RUNTIME) 9 | @Target(AnnotationTarget.CLASS) 10 | annotation class SelfRegisterModule 11 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/dungeon/CancelChestOpen.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.dungeon 2 | 3 | import floppaclient.FloppaClient.Companion.inDungeons 4 | import floppaclient.FloppaClient.Companion.mc 5 | import floppaclient.events.ReceivePacketEvent 6 | import floppaclient.module.Category 7 | import floppaclient.module.Module 8 | import floppaclient.utils.Utils.equalsOneOf 9 | import net.minecraft.network.play.client.C0DPacketCloseWindow 10 | import net.minecraft.network.play.server.S2DPacketOpenWindow 11 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 12 | 13 | /** 14 | * Module aimed to insta close secret chests in dungeons. 15 | * 16 | * @author Aton 17 | */ 18 | object CancelChestOpen : Module( 19 | "Cancel Chest Open", 20 | category = Category.DUNGEON, 21 | description = "Cancels secret chests from opening." 22 | ){ 23 | @SubscribeEvent 24 | fun onOpenWindow(event: ReceivePacketEvent){ 25 | if (!inDungeons || event.packet !is S2DPacketOpenWindow) return 26 | if (event.packet.windowTitle.unformattedText.equalsOneOf("Chest", "Large Chest") ) { 27 | event.isCanceled = true 28 | mc.netHandler.networkManager.sendPacket( C0DPacketCloseWindow(event.packet.windowId)) 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/dungeon/ExtraStats.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.dungeon 2 | 3 | import floppaclient.FloppaClient.Companion.inDungeons 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.utils.ChatUtils 7 | import net.minecraft.util.StringUtils.stripControlCodes 8 | import net.minecraftforge.client.event.ClientChatReceivedEvent 9 | import net.minecraftforge.fml.common.eventhandler.EventPriority 10 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 11 | 12 | /** 13 | * Show extra stats at the end of a dungeon run. 14 | * @author Aton 15 | */ 16 | object ExtraStats : Module( 17 | "Extra Stats", 18 | category = Category.DUNGEON, 19 | description = "Automatically clicks > EXTRA STATS < at the end of a run." 20 | ){ 21 | /** 22 | * Checks incoming chat messages for the extra stats message and if found runs the command. 23 | */ 24 | @SubscribeEvent(priority = EventPriority.HIGHEST, receiveCanceled = true) 25 | fun onChat(event: ClientChatReceivedEvent) { 26 | if ( !inDungeons || event.type.toInt() == 2) return 27 | when (stripControlCodes(event.message.unformattedText)) { 28 | " > EXTRA STATS <" -> { 29 | ChatUtils.command("showextrastats") 30 | return 31 | } 32 | } 33 | } 34 | } 35 | 36 | //"§r §6> §e§lEXTRA STATS §6<" 37 | //" > EXTRA STATS <" -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/dungeon/MelodyMessage.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.dungeon 2 | 3 | import floppaclient.floppamap.dungeon.Dungeon 4 | import floppaclient.floppamap.dungeon.RunInformation 5 | import floppaclient.module.Category 6 | import floppaclient.module.Module 7 | import floppaclient.module.impl.dungeon.AutoTerms.currentTerminal 8 | import floppaclient.module.settings.impl.NumberSetting 9 | import floppaclient.module.settings.impl.StringSetting 10 | import floppaclient.utils.ChatUtils.sendChat 11 | import net.minecraft.client.gui.inventory.GuiChest 12 | import net.minecraftforge.client.event.GuiOpenEvent 13 | import net.minecraftforge.fml.common.eventhandler.EventPriority 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 15 | import net.minecraftforge.fml.common.gameevent.TickEvent 16 | 17 | /** 18 | * Send a chat message to let your teammates know that you got the melody terminal. 19 | * @author Aton 20 | */ 21 | object MelodyMessage : Module( 22 | "Melody Message", 23 | category = Category.DUNGEON, 24 | description = "Automatically sends a message in chat when you open the melody terminal." 25 | ){ 26 | 27 | private val message = StringSetting("Message", "Melody on me!", 40, description = "The message that will be sent.") 28 | private var cooldown = NumberSetting("Cooldwon Ticks", 30.0, 10.0, 200.0, 10.0, description = "Increase this if the message gets spammed, should not be needed.") 29 | 30 | /** 31 | * Used to create a cooldown for the melody open message. 32 | * The terminal reopens the gui at least once per second. 33 | */ 34 | private var melodyTicks = 0 35 | 36 | init { 37 | this.addSettings( 38 | message, 39 | cooldown 40 | ) 41 | } 42 | 43 | @SubscribeEvent(priority = EventPriority.LOW) 44 | fun onGuiOpen(event: GuiOpenEvent) { 45 | if (event.gui !is GuiChest || !RunInformation.isInFloor(7) || !Dungeon.inBoss) return 46 | if (currentTerminal == AutoTerms.TerminalType.TIMING) { 47 | if (melodyTicks <= 0) { 48 | sendChat("/pc ${message.text}") 49 | } 50 | melodyTicks = cooldown.value.toInt() 51 | } 52 | } 53 | 54 | @SubscribeEvent 55 | fun onTick(event: TickEvent.ClientTickEvent) { 56 | if (event.phase != TickEvent.Phase.START) return 57 | if (melodyTicks > 0) melodyTicks-- 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/dungeon/TerminalAura.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.dungeon 2 | 3 | import floppaclient.FloppaClient 4 | import floppaclient.FloppaClient.Companion.mc 5 | import floppaclient.events.PositionUpdateEvent 6 | import floppaclient.floppamap.dungeon.RunInformation 7 | import floppaclient.module.Category 8 | import floppaclient.module.Module 9 | import floppaclient.module.settings.impl.BooleanSetting 10 | import floppaclient.module.settings.impl.NumberSetting 11 | import floppaclient.utils.Utils.isInTerminal 12 | import floppaclient.utils.fakeactions.FakeActionUtils 13 | import net.minecraft.entity.item.EntityArmorStand 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 15 | 16 | /** 17 | * Module that opens floor 7 terminals and collects the crystals for you. 18 | * @author Aton 19 | */ 20 | object TerminalAura : Module( 21 | "Terminal Aura", 22 | category = Category.DUNGEON, 23 | description = "Automatically opens a terminal when in range. Also picks up and places crystals." 24 | ){ 25 | 26 | private val reach = NumberSetting("Reach",5.0,3.0,10.0,0.1, description = "Maximum distance to the terminal for activation. Hypixel has a range check of 5.") 27 | private val cooldown = NumberSetting("Cooldown",200.0,20.0,1000.0,20.0, description = "Minimum delay in between clicks. §4 This has to be higher than your ping, or terminals will be opened twice, which will reset them.") 28 | private val onGround = BooleanSetting("On Ground", false, description = "If enabled will only click when on ground.") 29 | private val inLava = BooleanSetting("In Lava",false, description = "If enabled will also try to open terminals when in lava.") 30 | 31 | private var lastClicked = System.currentTimeMillis() 32 | 33 | init { 34 | this.addSettings( 35 | reach, 36 | cooldown, 37 | onGround, 38 | inLava 39 | ) 40 | } 41 | 42 | @SubscribeEvent 43 | fun onPositionUpdatePost(event: PositionUpdateEvent.Post) { 44 | if (!FloppaClient.inDungeons || mc.thePlayer == null || !RunInformation.inF7Boss() || isInTerminal()) return 45 | 46 | if(System.currentTimeMillis() - lastClicked < cooldown.value) return 47 | 48 | if (mc.thePlayer.isInLava && !inLava.enabled) return 49 | if (!mc.thePlayer.onGround && onGround.enabled ) return 50 | 51 | val term = mc.theWorld.getLoadedEntityList() 52 | .filterIsInstance() 53 | .filter { entity -> entity.name.contains("CLICK HERE") } 54 | .filter { entity -> mc.thePlayer.getDistance(entity.posX, entity.posY - mc.thePlayer.eyeHeight, entity.posZ) < this.reach.value } 55 | .minByOrNull { entity -> mc.thePlayer.getDistance(entity.posX, entity.posY - mc.thePlayer.eyeHeight, entity.posZ) } 56 | ?: return 57 | 58 | FakeActionUtils.interactWithEntity(term) 59 | lastClicked = System.currentTimeMillis() 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/dungeon/TrapGearSwap.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.dungeon 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.events.RoomChangeEvent 5 | import floppaclient.module.Category 6 | import floppaclient.module.Module 7 | import floppaclient.module.settings.impl.BooleanSetting 8 | import floppaclient.utils.fakeactions.FakeActionUtils 9 | import net.minecraftforge.event.world.WorldEvent 10 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 11 | 12 | /** 13 | * Module to automatically equip the needed gear when entering new trap room. 14 | * @author Aton 15 | */ 16 | object TrapGearSwap : Module( 17 | "Trap Gear Swap", 18 | category = Category.DUNGEON, 19 | description = "Automatically swaps to a rabbit hat when entering new trap and swaps back to your previous helmet upon leaving the room. " + 20 | "Can be configured to swap out your boots for Spring Boots instead.\n" + 21 | "§eRequires Auto Scan to be enabled in Dungeon Map! " 22 | ){ 23 | private val springBoots = BooleanSetting("Spring Boots", false, description = "Will swap your boots for Spring Boots instead of swapping your helmet for a Rabbit Hat.") 24 | 25 | init { 26 | this.addSettings( 27 | springBoots 28 | ) 29 | } 30 | 31 | var previousName: String? = null 32 | 33 | @SubscribeEvent 34 | fun onRoomChange(event: RoomChangeEvent){ 35 | // When entering trap 36 | val itemName = if (event.newRoomPair?.first?.data?.name == "New Trap") { 37 | previousName = mc.thePlayer?.getEquipmentInSlot(if (springBoots.enabled) 1 else 4)?.displayName ?: return 38 | if (springBoots.enabled){ 39 | "SPRING_BOOTS" 40 | }else { 41 | "Rabbit Hat" 42 | } 43 | }else if (event.oldRoomPair?.first?.data?.name == "New Trap") { 44 | previousName ?: return 45 | }else return 46 | 47 | FakeActionUtils.swapArmorItem(itemName, ignoreCase = false) 48 | } 49 | 50 | @SubscribeEvent 51 | fun onWorldLoad(event: WorldEvent.Load) { 52 | previousName = null 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/keybinds/AddKeybind.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.keybinds 2 | 3 | import floppaclient.module.Category 4 | import floppaclient.module.Module 5 | import floppaclient.module.ModuleManager 6 | import floppaclient.ui.clickgui.ClickGUI 7 | import floppaclient.ui.clickgui.elements.ModuleButton 8 | 9 | object AddKeybind : Module( 10 | "Add New Key Bind", 11 | category = Category.KEY_BIND, 12 | description = "Adds a new key bind you can customize.", 13 | toggled = true 14 | ){ 15 | override fun onEnable() {} 16 | 17 | override fun onDisable() { 18 | val bind = ModuleManager.addNewKeybind() 19 | toggle() 20 | ClickGUI.panels.find { it.category === Category.KEY_BIND }?.let { 21 | it.moduleButtons.add(ModuleButton(bind, it)) 22 | } 23 | } 24 | 25 | override fun onKeyBind() {} 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/keybinds/KeyBind.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.keybinds 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.ModuleManager 7 | import floppaclient.module.settings.Setting.Companion.withDependency 8 | import floppaclient.module.settings.Visibility 9 | import floppaclient.module.settings.impl.ActionSetting 10 | import floppaclient.module.settings.impl.BooleanSetting 11 | import floppaclient.module.settings.impl.StringSelectorSetting 12 | import floppaclient.module.settings.impl.StringSetting 13 | import floppaclient.utils.ChatUtils 14 | import floppaclient.utils.inventory.InventoryUtils.isHolding 15 | import floppaclient.utils.fakeactions.FakeActionUtils 16 | 17 | class KeyBind(name: String) : Module(name, category = Category.KEY_BIND){ 18 | private val modes = arrayListOf("Use Item","Command","Chat message") 19 | 20 | val bindName = StringSetting("Name", this.name, description = "The name of this Key Bind that will be shown on the toggle button in the GUI.") 21 | private val mode = StringSelectorSetting("Mode", modes[0], modes, description = "Action performed by the Bey Bind. Use Command for client side commands and Chat Message for server side commands.\nE.g. to open the Storage select Chat Message and type /storage in the action field.") 22 | private val command = StringSetting("Command","",50, description = "Command to be executed when command mode is selected. §eNo / needed!") 23 | .withDependency { this.mode.index == 1 } 24 | private val message = StringSetting("Message","",50, description = "Chat message to be sent when message mode is selected. §eFor server commands a / is needed.") 25 | .withDependency { this.mode.index == 2 } 26 | private val item = StringSetting("Item","",50, description = "Name of the Item to be used when use item mode is selected.") 27 | .withDependency { this.mode.index == 0 } 28 | private val condition = StringSetting("Condition", description = "Only perform the action when holding the specified item. Only used for use item mode.") 29 | .withDependency { this.mode.index == 0 } 30 | private val fromInventory = BooleanSetting("From Inv", description = "Allows you to use items from your inventory.") 31 | .withDependency { this.mode.index == 0 } 32 | private val removeButton = ActionSetting("Remove Key Bind", visibility = Visibility.ADVANCED_ONLY, description = "Removes the Key Bind."){ 33 | ModuleManager.removeKeyBind(this@KeyBind) 34 | } 35 | // Used by the config loader to determine whether a setting is a keybind 36 | private val flag = BooleanSetting("THIS_IS_A_KEY_BIND", visibility = Visibility.HIDDEN) 37 | 38 | init { 39 | this.addSettings( 40 | bindName, 41 | mode, 42 | command, 43 | message, 44 | item, 45 | condition, 46 | fromInventory, 47 | removeButton, 48 | flag 49 | ) 50 | } 51 | 52 | override fun onKeyBind() { 53 | if (!this.enabled) return 54 | performAction() 55 | } 56 | 57 | private fun performAction(){ 58 | when(mode.selected){ 59 | "Command" -> { 60 | ChatUtils.command(command.text, true) 61 | } 62 | "Chat message" -> { 63 | ChatUtils.sendChat(message.text) 64 | } 65 | "Use Item" -> { 66 | if (condition.text == "" || mc.thePlayer.isHolding(condition.text, ignoreCase = true)) { 67 | FakeActionUtils.useItem(item.text,true, fromInventory.enabled, ignoreCase = true) 68 | } 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/AutoHarp.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.FloppaClient 4 | import floppaclient.FloppaClient.Companion.mc 5 | import floppaclient.module.Category 6 | import floppaclient.module.Module 7 | import net.minecraft.client.gui.inventory.GuiChest 8 | import net.minecraft.init.Blocks 9 | import net.minecraft.inventory.ContainerChest 10 | import net.minecraft.item.ItemBlock 11 | import net.minecraftforge.client.event.GuiOpenEvent 12 | import net.minecraftforge.client.event.GuiScreenEvent 13 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 14 | 15 | /** 16 | * Module to automatically do the Melody's Harp minigame. 17 | * 18 | * @author Aton 19 | */ 20 | object AutoHarp : Module( 21 | "Auto Harp", 22 | category = Category.MISC, 23 | description = "Automatically Completes Melody's Harp" 24 | ){ 25 | private var inHarp = false 26 | private var lastInv = 0 27 | 28 | @SubscribeEvent 29 | fun onGuiOpen(event: GuiOpenEvent) { 30 | if (event.gui !is GuiChest || !FloppaClient.inSkyblock) return 31 | val container = (event.gui as GuiChest).inventorySlots 32 | if (container is ContainerChest) { 33 | val chestName = container.lowerChestInventory.displayName.unformattedText 34 | if (chestName.startsWith("Harp -")) { 35 | inHarp = true 36 | } 37 | } 38 | } 39 | 40 | @SubscribeEvent 41 | fun onRender(event: GuiScreenEvent.BackgroundDrawnEvent) { 42 | if (!inHarp || mc.thePlayer == null) return 43 | val container = mc.thePlayer.openContainer ?: return 44 | if (container !is ContainerChest) return 45 | val inventoryName = container.inventorySlots?.get(0)?.inventory?.name 46 | if (inventoryName == null || !inventoryName.startsWith("Harp -")) { 47 | inHarp = false 48 | return 49 | } 50 | val newHash = container.inventorySlots.subList(0,36).joinToString("") { it?.stack?.displayName ?: "" }.hashCode() 51 | if (lastInv == newHash) return 52 | lastInv = newHash 53 | for (ii in 0..6) { 54 | val slot = container.inventorySlots[37 + ii] 55 | if ((slot.stack?.item as? ItemBlock)?.block === Blocks.quartz_block) { 56 | mc.playerController.windowClick( 57 | container.windowId, 58 | slot.slotNumber, 59 | 2, 60 | 3, 61 | mc.thePlayer 62 | ) 63 | break 64 | } 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/AutoRagnarock.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.FloppaClient.Companion.inDungeons 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.settings.impl.BooleanSetting 7 | import floppaclient.utils.ChatUtils.modMessage 8 | import floppaclient.utils.fakeactions.FakeActionUtils 9 | import net.minecraft.util.StringUtils 10 | import net.minecraftforge.client.event.ClientChatReceivedEvent 11 | import net.minecraftforge.fml.common.eventhandler.EventPriority 12 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 13 | 14 | /** 15 | * Module to automatically get the bonus form the Fagnarock axe when activating the Withercloak sword. 16 | * @author Aton 17 | */ 18 | object AutoRagnarock : Module( 19 | "Auto Ragnarock", 20 | category = Category.MISC, 21 | description = "Automatically swaps to and right clicks the ragnarock axe if it is found in your hotbar upon " + 22 | "activating creeper veil." + 23 | "Will only activate outside of dungeons" 24 | ) { 25 | 26 | private val chatMessage = BooleanSetting("Chat message", true) 27 | 28 | init { 29 | this.addSettings(chatMessage) 30 | } 31 | 32 | @SubscribeEvent(priority = EventPriority.HIGHEST) 33 | fun onChat(event: ClientChatReceivedEvent) { 34 | if (inDungeons || event.type.toInt() == 2) return 35 | when (StringUtils.stripControlCodes(event.message.unformattedText)) { 36 | "Creeper Veil Activated!" -> { 37 | val used = FakeActionUtils.clickItem("Ragnarock Axe",true,false) 38 | if (chatMessage.enabled && used) modMessage("Ragnarock Axe activated.") 39 | return 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/AutoSprint.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.events.PositionUpdateEvent 5 | import floppaclient.module.Category 6 | import floppaclient.module.Module 7 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 8 | 9 | /** 10 | * Module that makes you always sprint. 11 | * @author Aton 12 | */ 13 | object AutoSprint : Module( 14 | "Auto Sprint", 15 | category = Category.MISC, 16 | description = "A simple auto sprint module that toggles sprinting when moving forwards and not collided " + 17 | "with anything." 18 | ) { 19 | @SubscribeEvent 20 | fun onPositionUpdate(event: PositionUpdateEvent.Pre) { 21 | if (!mc.thePlayer.isCollidedHorizontally && mc.thePlayer.moveForward > 0) { 22 | mc.thePlayer.isSprinting = true 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/CancelInteract.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.FloppaClient.Companion.inDungeons 4 | import floppaclient.FloppaClient.Companion.mc 5 | import floppaclient.module.Category 6 | import floppaclient.module.Module 7 | import floppaclient.module.settings.impl.BooleanSetting 8 | import floppaclient.utils.inventory.ItemUtils.hasAbility 9 | import floppaclient.utils.inventory.InventoryUtils.isHolding 10 | import net.minecraft.block.Block 11 | import net.minecraft.client.multiplayer.WorldClient 12 | import net.minecraft.init.Blocks 13 | import net.minecraft.util.BlockPos 14 | 15 | /** 16 | * Cancels block interactions to allow for items to be used. 17 | * 18 | * @author Aton 19 | */ 20 | object CancelInteract : Module( 21 | "Cancel Interact", 22 | category = Category.MISC, 23 | description = "Cancels the interaction with certain blocks, so that the item can be used instead. " + 24 | "The following rules will be followed in that priority: \n" + 25 | "Will never cancel interaction with chests, levers, buttons.\n" + 26 | "Will always cancel interactions with pearls. \n" + 27 | "Will cancel interaction with blacklisted blocks. This can be limited to only take place when holding an " + 28 | "item with ability." 29 | ){ 30 | private val onlyInDungen = BooleanSetting("Only In Dungeon", true, description = "Only enable this module in dungeons.") 31 | private val onlyWithAbility = BooleanSetting("Only Ability", false, description = "Check whether the item has an ability before cancelling interactions.") 32 | 33 | /** 34 | * Block which should always be interacted with. 35 | */ 36 | private val interactionWhielist = setOf( 37 | Blocks.lever, 38 | Blocks.chest, 39 | Blocks.trapped_chest, 40 | Blocks.stone_button, 41 | Blocks.wooden_button 42 | ) 43 | 44 | /** 45 | * Set containing all the block which interactions should be cancelled with. 46 | */ 47 | private val interactionBlakclist = setOf( 48 | //Fences and cobble wall 49 | Blocks.cobblestone_wall, 50 | Blocks.oak_fence, 51 | Blocks.dark_oak_fence, 52 | Blocks.acacia_fence, 53 | Blocks.birch_fence, 54 | Blocks.jungle_fence, 55 | Blocks.nether_brick_fence, 56 | Blocks.spruce_fence, 57 | Blocks.birch_fence_gate, 58 | Blocks.acacia_fence_gate, 59 | Blocks.dark_oak_fence_gate, 60 | Blocks.oak_fence_gate, 61 | Blocks.jungle_fence_gate, 62 | Blocks.spruce_fence_gate, 63 | // Hopper 64 | Blocks.hopper, 65 | ) 66 | 67 | init { 68 | this.addSettings( 69 | onlyInDungen, 70 | onlyWithAbility 71 | ) 72 | } 73 | 74 | /** 75 | * Redirected to by the MinecraftMixin. Replaces the check for whether the targeted block is air. 76 | * When true is retured the item ability will be used, with false an interactionm with the block will be performed. 77 | */ 78 | fun shouldPriotizeAbilityHook(instance: WorldClient, blockPos: BlockPos): Boolean { 79 | // When the module is not enabled preform the vanilla action. 80 | if (this.enabled && (inDungeons || !onlyInDungen.enabled)) { 81 | if (interactionWhielist.contains(instance.getBlockState(blockPos).block)) return false 82 | if (mc.thePlayer.isHolding("Ender Pearl")) return true 83 | if (!onlyWithAbility.enabled || mc.thePlayer.heldItem.hasAbility ) 84 | return interactionBlakclist.contains(instance.getBlockState(blockPos).block) || instance.isAirBlock( 85 | blockPos 86 | ) 87 | } 88 | return instance.isAirBlock(blockPos) 89 | } 90 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/ClipSettings.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.module.Category 4 | import floppaclient.module.Module 5 | import floppaclient.module.settings.impl.BooleanSetting 6 | import floppaclient.module.settings.impl.NumberSetting 7 | 8 | /** 9 | * A config module with the purpose to offer finer control over the auto clip behaviour. 10 | * 11 | * @author Aton 12 | */ 13 | object ClipSettings : Module( 14 | "Clip Settings", 15 | category = Category.MISC, 16 | description = "Advanced settings for Autoclip. Since Autoclip is anyways shot dead dont worry about this." 17 | ){ 18 | val baseClipDistance = NumberSetting("base Clip Distance",9.5, 0.0, 10.0,0.1, description = "Distance of the individual steps used for all far clips. Default 9.5.") 19 | val clipDelay1 = NumberSetting("First Delay", 010.0,10.0, 1000.0, 10.0, description = "First delay for far clip in mc. Default 10.") 20 | val clipDelay2 = NumberSetting("Second Delay", 060.0,10.0, 1000.0, 10.0, description = "Second delay for far clip in mc. Default 60, Possibly better 50.") 21 | val clipDelay3 = NumberSetting("Third Delay", 120.0,10.0, 1000.0, 10.0, description = "Third delay for far clip in mc. Default 120, Possibly better 100.") 22 | val clipDelay4 = NumberSetting("Fourth Delay", 190.0,10.0, 1000.0, 10.0, description = "Fourth delay for far clip in mc. Default 190, Possibly better 160.") 23 | val clipDelay5 = NumberSetting("Fifth Delay", 270.0,10.0, 1000.0, 10.0, description = "Fifth delay for far clip in mc. Default 270, Possibly better 230.") 24 | val clipDelay6 = NumberSetting("Sixth Delay", 360.0,10.0, 1000.0, 10.0, description = "Sixth delay for far clip in mc. Default 360, Possibly better 310.") 25 | val clipDelay7 = NumberSetting("Seventh Delay", 470.0,10.0, 1000.0, 10.0, description = "Seventh delay for far clip in mc. Default 470, Possibly better 400.") 26 | val clipDelay8 = NumberSetting("Eighth Delay", 580.0,10.0, 1000.0, 10.0, description = "Eighth delay for far clip in mc. Default 580, Possibly better 500.") 27 | val clipDelay9 = NumberSetting("Ninth Delay", 700.0,10.0, 1000.0, 10.0, description = "Ninth delay for far clip in mc. Default 700., Possibly better 610") 28 | val debugMessages = BooleanSetting("Debug Messages", false, description = "Debug messages for development.") 29 | 30 | init { 31 | this.addSettings( 32 | baseClipDistance, 33 | clipDelay1, 34 | clipDelay2, 35 | clipDelay3, 36 | clipDelay4, 37 | clipDelay5, 38 | clipDelay6, 39 | clipDelay7, 40 | clipDelay8, 41 | clipDelay9, 42 | debugMessages 43 | ) 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/FastMine.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.module.Category 4 | import floppaclient.module.Module 5 | import floppaclient.module.settings.Setting.Companion.withDependency 6 | import floppaclient.module.settings.impl.BooleanSetting 7 | import floppaclient.module.settings.impl.NumberSetting 8 | import floppaclient.module.settings.impl.StringSelectorSetting 9 | 10 | /** 11 | * This module makes blocks break faster. 12 | * 13 | * @author Aton 14 | * @see floppaclient.mixins.PlayerControllerMixin 15 | */ 16 | object FastMine : Module( 17 | "Fast Mine", 18 | category = Category.MISC, 19 | description = "Breaks blocks sooner when mining them, allowing for effectively faster mining. Also has some options to reduce the delay in between block breaking." 20 | ){ 21 | private val mode = StringSelectorSetting("Mode", "Vanilla", arrayListOf("Vanilla", "Skyblock", "None"), description = "Choose this according to where you are mining. In regions with custom mining like the Crystal Hollows select §oSkyblock§r everywhere else select §oVanilla§r. Select §oNone§r if you only want to use the other features in the module.") 22 | private val threshold = NumberSetting("Threshold", 0.7, 0.7, 1.0, 0.01, description = "Effectively reduces the time it takes to break the block by this factor.") 23 | .withDependency { this.mode.index == 0 } 24 | private val ticks = NumberSetting("Ticks", 20.0, 1.0, 100.0, 1.0, description = "The amount of ticks after which the block you are mining should break.") 25 | .withDependency { this.mode.index == 1 } 26 | private val modifyDelay = BooleanSetting("Modify Hit Delay", false, description = "Modifies the hit delay of 5 ticks before the next block can be mined. This allows for bypassing the vanilla softcap.") 27 | private val newHitDelay = NumberSetting("New Delay", 0.0, 0.0, 5.0, 1.0, description = "New delay in ticks until the next block can be broken. The vanilla value is 5.") 28 | .withDependency { this.modifyDelay.enabled } 29 | private val noReset = BooleanSetting("No Reset", false, description = "Prevents the block breaking progress from resetting when the NBT data of the held item gets updated. This can happen because of the Compact enchant or drill fuel updating.") 30 | 31 | 32 | 33 | init { 34 | this.addSettings( 35 | mode, 36 | threshold, 37 | ticks, 38 | modifyDelay, 39 | newHitDelay, 40 | noReset 41 | ) 42 | } 43 | 44 | /** 45 | * @see floppaclient.mixins.PlayerControllerMixin.tweakBlockDamage 46 | */ 47 | fun getThreshold(): Float{ 48 | return threshold.value.toFloat() 49 | } 50 | 51 | /** 52 | * @see floppaclient.mixins.PlayerControllerMixin.tweakBlockDamage 53 | */ 54 | fun shouldTweakVanillaMining(): Boolean { 55 | return this.enabled && mode.isSelected("Vanilla") 56 | } 57 | 58 | /** 59 | * @see floppaclient.mixins.PlayerControllerMixin.preBreakBlock 60 | */ 61 | fun shouldPreBreakBlock(miningTicks: Float, blockDamage: Float) : Boolean { 62 | return this.enabled && mode.isSelected("Skyblock") && blockDamage < 1f && miningTicks >= ticks.value.toFloat() 63 | } 64 | 65 | /** 66 | * @see floppaclient.mixins.PlayerControllerMixin.tweakHitDelay 67 | */ 68 | fun shouldRemoveHitDelay(hitDelay: Int) : Boolean { 69 | return this.enabled && modifyDelay.enabled && hitDelay <= (5.0 - this.newHitDelay.value) 70 | } 71 | 72 | /** 73 | * @see floppaclient.mixins.PlayerControllerMixin.shouldTagsBeEqual 74 | */ 75 | fun shouldPreventReset() : Boolean { 76 | return this.enabled && noReset.enabled 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/GhostBlocks.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.FloppaClient.Companion.display 4 | import floppaclient.FloppaClient.Companion.mc 5 | import floppaclient.module.Category 6 | import floppaclient.module.Module 7 | import floppaclient.module.settings.impl.BooleanSetting 8 | import floppaclient.module.settings.impl.NumberSetting 9 | import net.minecraft.init.Blocks 10 | import net.minecraft.tileentity.TileEntitySkull 11 | import net.minecraft.util.BlockPos 12 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 13 | import net.minecraftforge.fml.common.gameevent.TickEvent 14 | import org.lwjgl.input.Keyboard 15 | import org.lwjgl.input.Mouse 16 | 17 | /** 18 | * Set blocks to air client side 19 | * @author Aton 20 | */ 21 | object GhostBlocks : Module( 22 | "Ghost Blocks", 23 | category = Category.MISC, 24 | description = "Creates ghost blocks where you are looking when the key bind is pressed." 25 | ){ 26 | private val ghostBlockSkulls = BooleanSetting("Ghost Skulls", true, description = "If enabled skulls will also be turned into ghost blocks.") 27 | private val gbRange = NumberSetting("Range", 4.5,4.5,60.0,0.5, description = "Maximum range at which ghost blocks will be created.") 28 | 29 | init { 30 | this.addSettings( 31 | ghostBlockSkulls, 32 | gbRange 33 | ) 34 | } 35 | 36 | private val blacklist = listOf( 37 | Blocks.stone_button, 38 | Blocks.chest, 39 | Blocks.trapped_chest, 40 | Blocks.lever 41 | ) 42 | 43 | /** 44 | * Prevent the key bind from toggling the module, so that it can be used here. 45 | */ 46 | override fun onKeyBind() { } 47 | 48 | @SubscribeEvent 49 | fun onTick(event: TickEvent.ClientTickEvent) { 50 | if (event.phase != TickEvent.Phase.START || display != null) return 51 | if (this.keyCode > 0 && !Keyboard.isKeyDown(this.keyCode)) return 52 | if (this.keyCode < 0 && !Mouse.isButtonDown(this.keyCode + 100)) return 53 | if (!mc.inGameHasFocus) return 54 | 55 | val lookingAt = mc.thePlayer?.rayTrace(gbRange.value, 1f) 56 | toAir(lookingAt?.blockPos) 57 | } 58 | 59 | private fun toAir(blockPos: BlockPos?): Boolean { 60 | if (blockPos != null) { 61 | val block = mc.theWorld.getBlockState(blockPos).block 62 | if (!blacklist.contains(block) && (block !== Blocks.skull || (ghostBlockSkulls.enabled 63 | && (mc.theWorld.getTileEntity(blockPos) as? TileEntitySkull)?.playerProfile?.id?.toString() != "26bb1a8d-7c66-31c6-82d5-a9c04c94fb02"))) { 64 | mc.theWorld.setBlockToAir(blockPos) 65 | return true 66 | } 67 | } 68 | return false 69 | } 70 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/QOL.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.impl.player.BarPhase 7 | import floppaclient.module.settings.impl.BooleanSetting 8 | import net.minecraft.potion.Potion 9 | 10 | /** 11 | * Collection of general qol features. 12 | * @author Aton 13 | */ 14 | object QOL : Module( 15 | "QOL", 16 | category = Category.MISC, 17 | description = "Collection of general qol features." 18 | ) { 19 | private val noBlind = BooleanSetting("No Blindness", true, description = "Prevents the blindness effect from influencing your vision.") 20 | private val noBurn = BooleanSetting("No Fire Overlay", true, description = "Hides the burning overlay in first person.") 21 | private val noPushOut = BooleanSetting("No Push Out Block", true, description = "Prevents you from being pushed out of blocks.") 22 | private val noHeadInBlock = BooleanSetting("Cancel in Block", true, description = "Removes the in Block Overlay and prevents the perspective from resetting when in a block.") 23 | private val noCarpet = BooleanSetting("No Carpet", true, description = "Removes carpet hitboxes.") 24 | 25 | init { 26 | this.addSettings( 27 | noBlind, 28 | noBurn, 29 | noPushOut, 30 | noHeadInBlock, 31 | noCarpet 32 | ) 33 | } 34 | // Also look in BarPhase 35 | const val minCoord = 0.446f 36 | const val maxCoord = 0.5455f 37 | 38 | /** 39 | * Called by the EntityRendererMixin when it redirects the blindness check. 40 | */ 41 | fun blindnessHook(): Boolean = 42 | if (this.enabled && noBlind.enabled) false else mc.thePlayer.isPotionActive(Potion.blindness) 43 | 44 | /** 45 | * Referenced by the ItemRenderer Mixin to determine whether the fire overlay should be rendered. 46 | */ 47 | fun shouldDisplayBurnOverlayHook(): Boolean = 48 | if (this.enabled && noBurn.enabled) false else mc.thePlayer.isBurning 49 | 50 | /** 51 | * Referenced by the EntityPlayerSPMixin to determine whether the player should be pushed out of a block 52 | */ 53 | fun preventPushOut(noClip: Boolean): Boolean { 54 | return noClip || (this.enabled && noPushOut.enabled) 55 | } 56 | 57 | /** 58 | * Referenced in the EntityPlayer Mixin to determine whether the head in block should be forced to be false. 59 | * This affects the perspective toggle in a block, the overlay and suffocation damage. 60 | */ 61 | fun cancelHeadInBlock(): Boolean { 62 | return this.enabled && noHeadInBlock.enabled 63 | } 64 | 65 | /** 66 | * Referenced by the CarpetMixin to determine whether the bounding box should be set to 0. 67 | */ 68 | fun ignoreCarpet(): Boolean { 69 | return this.enabled && noCarpet.enabled 70 | } 71 | 72 | /** 73 | * Referenced by the PaneMixin to determine whether the collision box should be shrunk. 74 | */ 75 | fun modifyPane(): Boolean{ 76 | return BarPhase.enabled 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/StonkDelay.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.FloppaClient.Companion.inSkyblock 4 | import floppaclient.FloppaClient.Companion.mc 5 | import floppaclient.events.BlockDestroyEvent 6 | import floppaclient.events.BlockStateChangeEvent 7 | import floppaclient.module.Category 8 | import floppaclient.module.Module 9 | import floppaclient.module.settings.impl.BooleanSetting 10 | import floppaclient.module.settings.impl.NumberSetting 11 | import floppaclient.utils.Utils.removeIf 12 | import net.minecraft.block.state.IBlockState 13 | import net.minecraft.util.BlockPos 14 | import net.minecraftforge.event.world.WorldEvent 15 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 16 | import net.minecraftforge.fml.common.gameevent.TickEvent 17 | import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent 18 | 19 | object StonkDelay : Module( 20 | "Stonk Delay", 21 | category = Category.MISC, 22 | description = "Delays mined blocks being placed back." 23 | ){ 24 | private val delay = NumberSetting("Delay", 500.0, 0.0, 2000.0, 10.0, description = "The minimum delay in ms before mined blocks can be placed back.") 25 | private val ghost = BooleanSetting("Ghost", false, description = "Will create ghost blocks instead of actually mining the block.") 26 | 27 | init { 28 | this.addSettings( 29 | delay, 30 | ghost 31 | ) 32 | } 33 | 34 | private val buffer = mutableMapOf() 35 | 36 | @SubscribeEvent 37 | fun onBlockDestroyed(event: BlockDestroyEvent) { 38 | if (!inSkyblock) return 39 | buffer[event.pos] = BrokenBlock(event.pos, event.state, System.currentTimeMillis()) 40 | } 41 | 42 | @SubscribeEvent 43 | fun onBlockUpdate(event: BlockStateChangeEvent) { 44 | if (buffer.isEmpty()) return 45 | buffer[event.pos]?.run { 46 | if (this.placing || event.newState.block != this.state.block) return@run false 47 | this.state = event.newState 48 | if (!ghost.enabled) this.shouldPutBack = true 49 | event.isCanceled = true 50 | return@run true 51 | } 52 | } 53 | 54 | @SubscribeEvent 55 | fun onTick(event: ClientTickEvent) { 56 | if(event.phase != TickEvent.Phase.START || buffer.isEmpty()) return 57 | val time = System.currentTimeMillis() 58 | buffer.removeIf{ (_, data) -> 59 | data.tryPlaceBack(time) 60 | } 61 | } 62 | 63 | @SubscribeEvent 64 | fun onUnload(event: WorldEvent.Unload) { 65 | buffer.clear() 66 | } 67 | 68 | internal class BrokenBlock(val pos: BlockPos, var state: IBlockState, private val breakTime: Long) { 69 | /** 70 | * Tells the filter that this block should be allowed to be placed 71 | */ 72 | var placing = false 73 | /** 74 | * By default, blocks will not be placed back, only if they actually get replaced. 75 | */ 76 | var shouldPutBack = false 77 | /** 78 | * If enough time has passed places back the buffered Block. 79 | * @return True when a block was placed, or it is timed out, false otherwise. 80 | */ 81 | fun tryPlaceBack(now: Long): Boolean { 82 | return if (now >= breakTime + delay.value.toLong()) { 83 | if (shouldPutBack) { 84 | placing = true 85 | mc.theWorld.setBlockState(pos, state) 86 | } 87 | true 88 | }else false 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/misc/TerminatorClicker.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.misc 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.settings.impl.NumberSetting 7 | import floppaclient.utils.inventory.InventoryUtils.isHolding 8 | import floppaclient.utils.inventory.SkyblockItem 9 | import net.minecraft.entity.player.EntityPlayer 10 | import net.minecraft.world.World 11 | import net.minecraftforge.client.event.RenderWorldLastEvent 12 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 13 | 14 | /** 15 | * Spams right click when holding down RMB wile terminator in hand. STOP CARPEL TUNNEL! 16 | * @author Aton. 17 | */ 18 | object TerminatorClicker : Module( 19 | "Terminator Clicker", 20 | category = Category.MISC, 21 | description = "Automatically shoots the held shortbow when holding right click with it. " + 22 | "The clicks from this happen additionally to the 5 cps auto clicker from vanilla minecraft." 23 | ){ 24 | private val sleep = NumberSetting("Sleep ms",50.0,10.0,100.0,5.0, description = "Delay in between clicks.") 25 | 26 | private var nextTermClick: Long = 0L 27 | init { 28 | this.addSettings( 29 | sleep 30 | ) 31 | } 32 | 33 | @SubscribeEvent 34 | fun onRenderWorldLast(event: RenderWorldLastEvent) { 35 | if (mc.gameSettings.keyBindUseItem.isKeyDown) { 36 | val held = mc.thePlayer.inventory.getCurrentItem() 37 | if (held != null) { 38 | if (mc.thePlayer.isHolding(SkyblockItem.Attribute.SHORTBOW)) { 39 | val nowMillis = System.currentTimeMillis() 40 | if (nowMillis >= nextTermClick) { 41 | if (mc.playerController.sendUseItem( 42 | mc.thePlayer as EntityPlayer, 43 | mc.theWorld as World, 44 | held 45 | ) 46 | ) mc.entityRenderer.itemRenderer.resetEquippedProgress2() 47 | val overshoot = (nowMillis - nextTermClick).takeIf { it < 200 } ?: 0L 48 | nextTermClick = nowMillis + (sleep.value.toLong() - overshoot).coerceAtLeast(0L) 49 | } 50 | } 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/player/ArmorSwapper.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.player 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.settings.Setting 7 | import floppaclient.module.settings.impl.StringSetting 8 | import floppaclient.utils.fakeactions.FakeActionUtils 9 | 10 | /** 11 | * Module to swap the equipped armor with the press of a button. 12 | * @author Aton 13 | */ 14 | object ArmorSwapper : Module( 15 | "Armor Swapper", 16 | category = Category.PLAYER, 17 | description = "Swaps out the the specified items with the armor you are wearing." 18 | ) { 19 | private val item0 = 20 | StringSetting("Item 0", "", description = "Name of an item to be swapped, leave empty to do nothing.") 21 | private val item1 = 22 | StringSetting("Item 1", "", description = "Name of an item to be swapped, leave empty to do nothing.") 23 | private val item2 = 24 | StringSetting("Item 2", "", description = "Name of an item to be swapped, leave empty to do nothing.") 25 | private val item3 = 26 | StringSetting("Item 3", "", description = "Name of an item to be swapped, leave empty to do nothing.") 27 | private val item4 = 28 | StringSetting("Item 4", "", description = "Name of an item to be swapped, leave empty to do nothing.") 29 | private val item5 = 30 | StringSetting("Item 5", "", description = "Name of an item to be swapped, leave empty to do nothing.") 31 | private val item6 = 32 | StringSetting("Item 6", "", description = "Name of an item to be swapped, leave empty to do nothing.") 33 | private val item7 = 34 | StringSetting("Item 7", "", description = "Name of an item to be swapped, leave empty to do nothing.") 35 | 36 | private val items = arrayOf>( 37 | item0, 38 | item1, 39 | item2, 40 | item3, 41 | item4, 42 | item5, 43 | item6, 44 | item7, 45 | ) 46 | 47 | init { 48 | this.addSettings(*items) 49 | } 50 | 51 | override fun onKeyBind() { 52 | if (this.enabled) { 53 | 54 | // Swap slots. No direct reference to the FakeInventoryActionManager needed here. swapArmorItem takes care of that. 55 | /** Used to keep track of swapped items, the 4 right most bits correspond to the swapped slots. */ 56 | var swappedSlots = 0b0000 57 | if (mc.thePlayer.inventory.itemStack == null) { 58 | for (item in items) { 59 | if (swappedSlots == 0b1111) break 60 | val itemName = (item as StringSetting).text 61 | if (itemName == "") continue 62 | 63 | val swappedIndex = FakeActionUtils.swapArmorItem(itemName, swappedSlots) ?: continue 64 | 65 | // Update alr swapped pieces 66 | val swapNum = 0b1 shl swappedIndex 67 | swappedSlots = swappedSlots or swapNum 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/player/Clip.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.player 2 | 3 | import floppaclient.module.Category 4 | import floppaclient.module.Module 5 | import floppaclient.module.settings.impl.BooleanSetting 6 | import floppaclient.module.settings.impl.NumberSetting 7 | import floppaclient.utils.ClipTools.dClip 8 | import floppaclient.utils.GeometryUtils.pitch 9 | import floppaclient.utils.GeometryUtils.yaw 10 | 11 | /** 12 | * Clip module for changing the player position client side. 13 | * @author Aton 14 | */ 15 | object Clip : Module( 16 | "3D Clip", 17 | category = Category.PLAYER, 18 | description = "Clips you with the specified settings." 19 | ){ 20 | private val allow3DClip = BooleanSetting("Use 3D Clip", true, description = "Toggles between purely horizontal and omnidirectional clip for the clip key bind.") 21 | private val clipDistance = NumberSetting("Clip Distance",9.5, 0.0, 10.0,0.1, description = "Distance that the clip key bind will teleport you. Default 9.5.") 22 | 23 | init { 24 | this.addSettings( 25 | allow3DClip, 26 | clipDistance 27 | ) 28 | } 29 | 30 | override fun onKeyBind() { 31 | if (this.enabled) { 32 | if (allow3DClip.enabled) { 33 | dClip(clipDistance.value, yaw(), pitch()) 34 | }else { 35 | dClip(clipDistance.value) 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/player/HClip.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.player 2 | 3 | import floppaclient.module.Category 4 | import floppaclient.module.Module 5 | import floppaclient.module.settings.impl.NumberSetting 6 | import floppaclient.utils.ClipTools 7 | import floppaclient.utils.GeometryUtils 8 | 9 | object HClip : Module( 10 | "H Clip", 11 | category = Category.PLAYER, 12 | description = "Changes your position. From testing it seems like you need a y offset value of at least -1.7 and the maximum distance you can go is 7.9." 13 | ){ 14 | private val hDist = NumberSetting("Distance", 7.5,0.0,9.9,0.1, description = "Horizontal distance.") 15 | private val yOffs = NumberSetting("Y Offset", -1.7,-5.0,2.0,0.1, description = "Vertical offset.") 16 | 17 | init { 18 | this.addSettings( 19 | hDist, 20 | yOffs 21 | ) 22 | } 23 | 24 | override fun onKeyBind() { 25 | if (this.enabled) { 26 | ClipTools.hClip(hDist.value, GeometryUtils.yaw(), yOffs.value) 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/player/HotbarSwapper.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.player 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.settings.Setting 7 | import floppaclient.module.settings.impl.BooleanSetting 8 | import floppaclient.utils.fakeactions.FakeInventoryActionManager 9 | import net.minecraft.client.gui.inventory.GuiContainer 10 | import net.minecraft.client.gui.inventory.GuiInventory 11 | import net.minecraft.inventory.Slot 12 | 13 | object HotbarSwapper : Module( 14 | "Hotbar Swapper", 15 | category = Category.PLAYER, 16 | description = "Swaps out the the items in the specified slots in your hotbar with the slots above them when you press the key bind." 17 | ){ 18 | private val slot0 = BooleanSetting("Slot 0",false, description = "Toggle whether this slot should be swapped.") 19 | private val slot1 = BooleanSetting("Slot 1",false, description = "Toggle whether this slot should be swapped.") 20 | private val slot2 = BooleanSetting("Slot 2",false, description = "Toggle whether this slot should be swapped.") 21 | private val slot3 = BooleanSetting("Slot 3",false, description = "Toggle whether this slot should be swapped.") 22 | private val slot4 = BooleanSetting("Slot 4",false, description = "Toggle whether this slot should be swapped.") 23 | private val slot5 = BooleanSetting("Slot 5",false, description = "Toggle whether this slot should be swapped.") 24 | private val slot6 = BooleanSetting("Slot 6",false, description = "Toggle whether this slot should be swapped.") 25 | private val slot7 = BooleanSetting("Slot 7",false, description = "Toggle whether this slot should be swapped.") 26 | 27 | private val slots = arrayOf>( 28 | slot0, 29 | slot1, 30 | slot2, 31 | slot3, 32 | slot4, 33 | slot5, 34 | slot6, 35 | slot7, 36 | ) 37 | 38 | init{ 39 | this.addSettings(*slots) 40 | } 41 | 42 | override fun onKeyBind() { 43 | if (this.enabled) { 44 | 45 | // Swap slots 46 | val swapHotbar: (GuiInventory) -> Unit = { inventory -> 47 | if (mc.thePlayer.inventory.itemStack == null) { 48 | for (i in slots.indices) { 49 | if ((slots[i] as BooleanSetting).enabled) { 50 | val slot = (inventory as GuiContainer).inventorySlots.inventorySlots[27 + i] as Slot 51 | val slotId = slot.slotNumber 52 | mc.playerController.windowClick( 53 | (inventory as GuiContainer).inventorySlots.windowId, slotId, i, 2, mc.thePlayer 54 | ) 55 | } 56 | } 57 | } 58 | } 59 | FakeInventoryActionManager.addAction(swapHotbar) 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/player/JerryRocket.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.player 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.events.VelocityUpdateEvent 5 | import floppaclient.module.Category 6 | import floppaclient.module.Module 7 | import floppaclient.utils.inventory.InventoryUtils.isHolding 8 | import floppaclient.utils.inventory.SkyblockItem 9 | import net.minecraftforge.fml.common.eventhandler.EventPriority 10 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 11 | 12 | /** 13 | * The only way is up! 14 | * @author Aton 15 | */ 16 | object JerryRocket : Module( 17 | "Jerry Rocket", 18 | category = Category.PLAYER, 19 | description = "Cancels horizontal kb when holding the jerry chine gun." 20 | ){ 21 | 22 | @SubscribeEvent(priority = EventPriority.HIGH) 23 | fun handleEntityVelocity(event: VelocityUpdateEvent){ 24 | if (mc.theWorld.getEntityByID(event.packet.entityID) == mc.thePlayer) { 25 | if (mc.thePlayer.isHolding(SkyblockItem.JERRY_GUN) && event.packet.motionY == 4800) { 26 | mc.thePlayer.motionY = event.packet.motionY/8000.0 27 | event.isCanceled = true 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/render/Camera.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.render 2 | 3 | import floppaclient.FloppaClient 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.settings.impl.BooleanSetting 7 | import floppaclient.module.settings.impl.NumberSetting 8 | import net.minecraft.util.Vec3 9 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 10 | import net.minecraftforge.fml.common.gameevent.InputEvent 11 | 12 | /** 13 | * Module to modify the camera behaviour. 14 | * 15 | * @author Aton 16 | */ 17 | object Camera : Module( 18 | "Camera", 19 | category = Category.RENDER, 20 | description = "Modifies the behaviour of the Camera." 21 | ){ 22 | private val thirdPDist by NumberSetting("Distance", 4.0, 1.0,10.0,0.1, description = "Distance of the third person view camera.") 23 | private val clip by BooleanSetting("Camera Clip", true, description = "Lets the camera clip through blocks.") 24 | private val noFrontView by BooleanSetting("No Front View", false, description = "Skips the front view when toggling perspective.") 25 | 26 | /** 27 | * Called by the EntityRendererMixin when it checks the thirdPersonDistance. 28 | * Returns the value of the setting when the module is enabled, null otherwise. 29 | */ 30 | fun thirdPersonDistanceHook(): Float? { 31 | return if (this.enabled) 32 | thirdPDist.toFloat() 33 | else 34 | null 35 | } 36 | 37 | /** 38 | * Redirected to by the EntityRendererMixin. Returns a high distance to clip the camera if that is enabled. 39 | */ 40 | fun cameraClipHook(instance: Vec3, vec: Vec3): Double { 41 | return if (this.enabled && clip) 42 | thirdPDist 43 | else 44 | instance.distanceTo(vec) 45 | } 46 | 47 | @SubscribeEvent 48 | fun onKey(event: InputEvent.KeyInputEvent) { 49 | if (!noFrontView) return 50 | /** adds +1 tp the perspective setting to skip front view, does not override the vanilla toggle 51 | * isKeyDown has to be used here instead of isKeyPressed because the vanilla function is called first.*/ 52 | if (FloppaClient.mc.gameSettings.keyBindTogglePerspective.isKeyDown) { 53 | if(FloppaClient.mc.gameSettings.thirdPersonView >= 2) { //front view 54 | FloppaClient.mc.gameSettings.thirdPersonView = 0 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/render/ChestEsp.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.render 2 | 3 | import floppaclient.module.Category 4 | import floppaclient.module.Module 5 | import floppaclient.module.settings.impl.ColorSetting 6 | import floppaclient.module.settings.impl.NumberSetting 7 | import floppaclient.module.settings.impl.StringSelectorSetting 8 | import java.awt.Color 9 | 10 | /** 11 | * Render chests trough walls. 12 | * 13 | * @author Aton 14 | */ 15 | object ChestEsp : Module( 16 | "Chest ESP", 17 | category = Category.RENDER, 18 | description = "Highlights chests through walls." 19 | ){ 20 | private val mode = StringSelectorSetting("Mode", "Box", arrayListOf("Box", "Phase"), description = "Determines how the chest wil be visualized.") 21 | private val color = ColorSetting("Box Color", Color(255,0,0), description = "Color of the box when box mode is selected.") 22 | private val thickness = NumberSetting("Thickness", 1.0, 0.0,5.0, 0.1, description = "Line width of the box when box mode is selected.") 23 | 24 | /** 25 | * Referenced by the ChestRendererMixin to determine whether the chest is drawn in the world or something in a hud. 26 | * Set by 27 | */ 28 | var isDrawingWorld = false 29 | 30 | init { 31 | this.addSettings( 32 | mode, 33 | color, 34 | thickness 35 | ) 36 | } 37 | 38 | /** 39 | * Accessed by the ChestRenderer Mixin. 40 | */ 41 | fun isPhaseMode(): Boolean { 42 | return this.enabled && mode.isSelected("Phase") 43 | } 44 | 45 | /** 46 | * Accessed by the CestRenderer Mixin. 47 | */ 48 | fun isBoxMode(): Boolean { 49 | return this.enabled && mode.isSelected("Box") 50 | } 51 | 52 | /** 53 | * Accessed by the CestRenderer Mixin. 54 | */ 55 | fun getBoxColor(): Color { 56 | return color.value 57 | } 58 | 59 | /** 60 | * Accessed by the CestRenderer Mixin. 61 | */ 62 | fun getBoxThickness(): Float { 63 | return thickness.value.toFloat() 64 | } 65 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/render/CoordinateDisplay.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.render 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.RegisterHudElement 7 | import floppaclient.module.settings.impl.BooleanSetting 8 | import floppaclient.ui.hud.HudElement 9 | import net.minecraft.entity.player.EntityPlayer 10 | import net.minecraft.util.MovingObjectPosition 11 | import kotlin.math.floor 12 | import kotlin.math.roundToInt 13 | 14 | /** 15 | * Render a coordinate hud on your screen 16 | * @author Aton 17 | */ 18 | object CoordinateDisplay : Module( 19 | "Coordinate HUD", 20 | category = Category.RENDER, 21 | description = "Renders your coordinates on your screen." 22 | ) { 23 | private val showLookingAt by BooleanSetting("Looking At", false, description = "Displays the coordinates of the block you are looking at in a second line.") 24 | 25 | @RegisterHudElement 26 | object CoordinateHUD : HudElement(this, 0, 150, 27 | mc.fontRendererObj.getStringWidth("123 / 12 / 123 (12.3 / 12.3)"), 28 | mc.fontRendererObj.FONT_HEIGHT * 2 + 1, 29 | ) { 30 | override fun renderHud() { 31 | 32 | val player: EntityPlayer = mc.thePlayer 33 | 34 | var xDir = ((player.rotationYaw % 360 + 360) % 360).toDouble() 35 | if (xDir > 180) xDir -= 360.0 36 | xDir = (xDir * 10.0).roundToInt().toDouble() / 10.0 37 | val yDir = (player.rotationPitch * 10.0).roundToInt().toDouble() / 10.0 38 | 39 | val coordText = 40 | "${floor(player.posX).toInt()} / ${floor(player.posY).toInt()} / ${floor(player.posZ).toInt()} ($xDir / $yDir)" 41 | 42 | mc.fontRendererObj.drawString(coordText, 0, 0, 0xffffff) 43 | 44 | // handle looking at 45 | if (showLookingAt) { 46 | val la = mc.objectMouseOver 47 | 48 | if (la != null && la.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { 49 | val laText = "Looking at: ${la.blockPos.x} / ${la.blockPos.y} / ${la.blockPos.z}" 50 | mc.fontRendererObj.drawString(laText, 0, mc.fontRendererObj.FONT_HEIGHT + 1, 0xffffff) 51 | } 52 | } 53 | 54 | this.width = mc.fontRendererObj.getStringWidth(coordText) 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/render/DayCounter.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.render 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.module.settings.Visibility 7 | import floppaclient.module.settings.impl.BooleanSetting 8 | import floppaclient.module.settings.impl.NumberSetting 9 | import floppaclient.ui.hud.HudElement 10 | import floppaclient.module.RegisterHudElement 11 | 12 | /** 13 | * Displays a hud showing the age of servers in both (Minecraft) days and minutes. 14 | * @author Stivais 15 | */ 16 | 17 | object DayCounter : Module( 18 | "Day Counter", 19 | category = Category.RENDER, 20 | description = "Renders the server's day." 21 | ) { 22 | private val accurateDay = BooleanSetting("Advanced", false, description = "Displays more information.") 23 | 24 | private val xHud = NumberSetting("x", default = 0.0, visibility = Visibility.HIDDEN) 25 | private val yHud = NumberSetting("y", default = 150.0, visibility = Visibility.HIDDEN) 26 | private val scaleHud = NumberSetting("scale", 1.0, 0.1, 4.0, 0.01, Visibility.HIDDEN) 27 | 28 | init { 29 | this.addSettings( 30 | accurateDay, 31 | xHud, 32 | yHud, 33 | scaleHud 34 | ) 35 | } 36 | 37 | @RegisterHudElement 38 | object DayCounter : HudElement( 39 | xHud, 40 | yHud, 41 | mc.fontRendererObj.getStringWidth("Day (32)"), 42 | mc.fontRendererObj.FONT_HEIGHT * 2 + 1, 43 | scaleHud 44 | ) { 45 | override fun renderHud() { 46 | val time = mc.theWorld.worldTime 47 | 48 | val dayText = "Day: ${(time / 24000).toInt()}" 49 | 50 | mc.fontRendererObj.drawString(dayText, 0, 0, 0xffffff) 51 | this.width = mc.fontRendererObj.getStringWidth(dayText) 52 | 53 | if (accurateDay.enabled) { 54 | val adText = "Server age: ${(time / 1200).toInt()} Minutes" 55 | 56 | mc.fontRendererObj.drawString(adText, 0, (mc.fontRendererObj.FONT_HEIGHT + 1), 0xffffff) 57 | this.width = mc.fontRendererObj.getStringWidth(adText) 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/render/DoorESP.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.render 2 | 3 | import floppaclient.FloppaClient.Companion.inDungeons 4 | import floppaclient.floppamap.core.Door 5 | import floppaclient.floppamap.core.DoorType 6 | import floppaclient.floppamap.core.RoomState 7 | import floppaclient.floppamap.dungeon.Dungeon 8 | import floppaclient.module.Category 9 | import floppaclient.module.Module 10 | import floppaclient.module.settings.impl.ColorSetting 11 | import floppaclient.utils.render.WorldRenderUtils 12 | import net.minecraftforge.client.event.RenderWorldLastEvent 13 | import net.minecraftforge.fml.common.eventhandler.EventPriority 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 15 | import net.minecraftforge.fml.common.gameevent.TickEvent 16 | import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent 17 | import java.awt.Color 18 | 19 | object DoorESP : Module( 20 | "Door ESP", 21 | category = Category.RENDER, 22 | description = "Renders an outline for Dungeon Wither Doors." 23 | ){ 24 | private val color = ColorSetting("Color", Color(255,0,0 ), false, description = "Color of the outline.") 25 | 26 | init { 27 | this.addSettings( 28 | color 29 | ) 30 | } 31 | 32 | private var doors = listOf() 33 | 34 | @SubscribeEvent(priority = EventPriority.HIGH) 35 | fun onTick(event: ClientTickEvent) { 36 | if (event.phase != TickEvent.Phase.START) return 37 | if (!inDungeons) return 38 | doors = Dungeon.getDungeonTileList().filter { 39 | (it.type == DoorType.WITHER || it.type == DoorType.BLOOD) && !it.opened 40 | && (it.state == RoomState.DISCOVERED || it.visited) 41 | } 42 | } 43 | 44 | @SubscribeEvent 45 | fun onRenderWorld(event: RenderWorldLastEvent) { 46 | if (!inDungeons) return 47 | doors.forEach { 48 | WorldRenderUtils.drawCustomSizedBoxAt(it.x-1.0, 69.0, it.z - 1.0, 3.0, color.value, phase = true) 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/render/EditHud.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.render 2 | 3 | import floppaclient.FloppaClient 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | import floppaclient.ui.hud.EditHudGUI 7 | 8 | /** 9 | * Open the edit hid gui. 10 | * @author Aton 11 | */ 12 | object EditHud : Module( 13 | "Edit Hud", 14 | category = Category.RENDER, 15 | description = "Opens the eidt hud gui." 16 | ){ 17 | 18 | /** 19 | * Overridden to prevent the chat message from being sent. 20 | */ 21 | override fun onKeyBind() { 22 | this.toggle() 23 | } 24 | 25 | /** 26 | * Automatically disable it again and open the gui 27 | */ 28 | override fun onEnable() { 29 | FloppaClient.display = EditHudGUI 30 | toggle() 31 | super.onEnable() 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/render/ExtraBlocks.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.render 2 | 3 | import floppaclient.module.Category 4 | import floppaclient.module.Module 5 | import floppaclient.module.settings.impl.StringSelectorSetting 6 | 7 | /** 8 | * Map extras block settings module. 9 | * 10 | * The actual implementation is in floppaclient.floppamap 11 | */ 12 | object ExtraBlocks : Module( 13 | "Extras", 14 | category = Category.RENDER, 15 | description = "Create coordinate blocks. Use edit mode with /em (block)." 16 | ){ 17 | 18 | val defaultStairs = StringSelectorSetting("Default Stairs","jungle", arrayListOf( 19 | "birch", 20 | "acacia", 21 | "stone_brick", 22 | "brick", 23 | "sandstone", 24 | "dark_oak", 25 | "nether_brick", 26 | "jungle", 27 | "oak", 28 | "quartz", 29 | "red_sandstone", 30 | "stone", 31 | "spruce"), 32 | description = "Stairs type that will be selected with /em stairs or /em stair." 33 | ) 34 | val defaultFence = StringSelectorSetting("Default Fence","birch", arrayListOf( 35 | "oak", 36 | "dark_oak", 37 | "acacia", 38 | "birch", 39 | "jungle", 40 | "nether_brick", 41 | "spruce"), 42 | description = "Fence type that will be selected with /em fence." 43 | ) 44 | val defaultSlab = StringSelectorSetting("Default Slab","stone", arrayListOf( 45 | "stone", 46 | "oak"), 47 | description = "Slab type that will be selected with /em slab." 48 | ) 49 | 50 | init { 51 | this.addSettings( 52 | defaultStairs, 53 | defaultFence, 54 | defaultSlab 55 | ) 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/impl/render/FullBright.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.impl.render 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.module.Category 5 | import floppaclient.module.Module 6 | 7 | /** 8 | * A simple full bright module that lets players see in the dark. 9 | * This module works by setting a gamma value higher than available in the game settings. 10 | * 11 | * @author Aton 12 | */ 13 | object FullBright : Module( 14 | "Full Bright", 15 | category = Category.RENDER, 16 | description = "Lets you see in the dark." 17 | ) { 18 | private var oldGamma = 1f 19 | 20 | override fun onEnable() { 21 | oldGamma = mc.gameSettings.gammaSetting 22 | mc.gameSettings.gammaSetting = 100f 23 | } 24 | 25 | override fun onDisable() { 26 | mc.gameSettings.gammaSetting = oldGamma 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/DoNotRegister.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings 2 | 3 | /** 4 | * This annotation can be used for properties in [Module][floppaclient.module.Module] classes which delegate to a [Setting] class. 5 | * It prevents the delegation from registering the Setting to the Module. 6 | * @author Aton 7 | */ 8 | @Retention(AnnotationRetention.RUNTIME) 9 | @Target(AnnotationTarget.PROPERTY) 10 | annotation class DoNotRegister 11 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/Visibility.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings 2 | 3 | /** 4 | * This enum will determine where a setting should be visible. 5 | * 6 | * It can be used as a two bit binary number where the left bit determines the visibility in the advanced gui 7 | * and the right bit determines the visibility in the click gui. 8 | * 9 | * @author Aton 10 | */ 11 | enum class Visibility { 12 | HIDDEN, CLICK_GUI_ONLY, ADVANCED_ONLY, VISIBLE; 13 | 14 | /** 15 | * Checks whether the 2nd bit is 1. 16 | */ 17 | val visibleInAdvanced: Boolean 18 | get() = this.ordinal and 0b10 > 0 19 | 20 | /** 21 | * Checks whether the 1st bit is 1. 22 | */ 23 | val visibleInClickGui: Boolean 24 | get() = this.ordinal and 0b01 > 0 25 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/impl/ActionSetting.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings.impl 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.Visibility 5 | 6 | /** 7 | * A clickable setting for Modules that runs code on click. 8 | * 9 | * Represented by a button in the GUI which when clicked will invoke [value]. 10 | * @author Aton 11 | */ 12 | class ActionSetting( 13 | name: String, 14 | visibility: Visibility = Visibility.VISIBLE, 15 | description: String? = null, 16 | override val default: () -> Unit = {} 17 | ) : Setting<() -> Unit>(name, visibility, description) { 18 | 19 | override var value: () -> Unit = default 20 | 21 | var action: () -> Unit by this::value 22 | 23 | fun doAction() { 24 | action() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/impl/BooleanSetting.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings.impl 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.Visibility 5 | 6 | /** 7 | * A boolean Setting for modules. 8 | * 9 | * Can be used to toggle aspects of a Module. 10 | * Represented by a toggle button in the GUI. 11 | * @author Aton 12 | */ 13 | class BooleanSetting ( 14 | name: String, 15 | override val default: Boolean = false, 16 | visibility: Visibility = Visibility.VISIBLE, 17 | description: String? = null, 18 | ): Setting(name, visibility, description) { 19 | 20 | override var value: Boolean = default 21 | set(value) { 22 | field = processInput(value) 23 | 24 | } 25 | 26 | var enabled: Boolean by this::value 27 | 28 | fun toggle() { 29 | enabled = !enabled 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/impl/DummySetting.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings.impl 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.Visibility 5 | 6 | /** 7 | * A direct subclass of [Setting] which does not provide any backing field. 8 | * 9 | * **Do not use this as a Setting for your Module!** 10 | * 11 | * This class is meant to be used as a placeholder when no other Setting is applicable. 12 | * Doing this allows you to avoid using the nullable type *Setting?*. 13 | * 14 | * Used for pasrsing the config file and for displaying the Module Keybind in the advanced gui. 15 | * @author Aton 16 | */ 17 | class DummySetting( 18 | name: String, 19 | visibility: Visibility = Visibility.VISIBLE, 20 | description: String? = null, 21 | ) : Setting(name, visibility, description) { 22 | /** 23 | * Always is null. 24 | * Not intended to be used. 25 | */ 26 | override val default: Any? 27 | get() = null 28 | 29 | /** 30 | * Always is null. 31 | * Not intended to be used. 32 | */ 33 | override var value: Any? 34 | get() = null 35 | set(_) {} 36 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/impl/NumberSetting.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings.impl 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.Visibility 5 | import net.minecraft.util.MathHelper 6 | import kotlin.math.round 7 | 8 | /** 9 | * A Double Setting for Modules. 10 | * 11 | * Represented in the GUI by a slider. 12 | * To use a different type adjust the [increment] and use the toInt() etc. methods. 13 | */ 14 | class NumberSetting( 15 | name: String, 16 | override val default: Double = 1.0, 17 | val min: Double = -10000.0, 18 | val max: Double = 10000.0, 19 | val increment: Double = 1.0, 20 | visibility: Visibility = Visibility.VISIBLE, 21 | description: String? = null, 22 | ) : Setting(name, visibility, description) { 23 | 24 | override var value: Double = default 25 | set(newVal) { 26 | field = MathHelper.clamp_double(roundToIncrement(processInput(newVal)), min, max) 27 | } 28 | 29 | private fun roundToIncrement(x: Double): Double { 30 | return round(x / increment) * increment 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/impl/SelectorSetting.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings.impl 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.Visibility 5 | 6 | /** 7 | * A setting which allows for a selection out of a given set of options. 8 | * 9 | * In most cases it is more convenient to use the factory function which acts as a constructor which omits the [options] 10 | * parameter. 11 | * 12 | * @author Aton 13 | */ 14 | class SelectorSetting( 15 | name: String, 16 | override val default: T, 17 | val options: Array, 18 | visibility: Visibility = Visibility.VISIBLE, 19 | description: String? = null, 20 | ) : Setting(name, visibility, description) where T : Options, T: Enum { 21 | 22 | override var value: T = default 23 | set(input) { 24 | field = processInput(input) 25 | } 26 | 27 | var index: Int 28 | get() = value.ordinal 29 | set(newVal) { 30 | // guarantees that index is in bounds and enables cycling behaviour 31 | value = options[if (newVal > options.size - 1) 0 else if ( newVal < 0) options.size - 1 else newVal] 32 | } 33 | 34 | /** 35 | * [displayName][Options.displayName] of the selected Enum. 36 | * Can be used to set [value] based on the displayName of the Enum. 37 | * This is required for loading data from the config. 38 | * If possible [value] should be directly instead. 39 | */ 40 | var selected: String 41 | get() = value.displayName 42 | set(input) { 43 | value = options.find { it.displayName.equals(input, ignoreCase = true) } ?: return 44 | } 45 | 46 | fun isSelected(option: Options): Boolean { 47 | return this.value === option 48 | } 49 | } 50 | 51 | /** 52 | * This factory function provides a more convenient Constructor for [SelectorSetting] 53 | * where [options][SelectorSetting.options] can be omitted. 54 | * The options are inferred from the provided [default] value. All available constants will be used. 55 | * 56 | * If you want to limit the options to be a subset of the available constants, use the main constructor and specify those explicitly. 57 | */ 58 | inline fun SelectorSetting(name: String, 59 | default: L, 60 | visibility: Visibility = Visibility.VISIBLE, 61 | description: String? = null 62 | ) : SelectorSetting where L : Options, L: Enum = 63 | SelectorSetting(name, default, enumValues(), visibility, description) 64 | 65 | interface Options { 66 | val displayName: String 67 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/impl/StringSelectorSetting.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings.impl 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.Visibility 5 | import net.minecraft.util.MathHelper 6 | 7 | @Deprecated("Outdated use the enum selector setting instead.") 8 | class StringSelectorSetting( 9 | name: String, 10 | private val defaultSelected: String, 11 | var options: ArrayList, 12 | visibility: Visibility = Visibility.VISIBLE, 13 | description: String? = null, 14 | ) : Setting(name, visibility, description){ 15 | 16 | override val default: Int = optionIndex(defaultSelected) 17 | override var value: Int 18 | get() = index 19 | set(value) {index = value} 20 | 21 | var index: Int = optionIndex(defaultSelected) 22 | set(value) { 23 | /** guarantees that index is in bounds and enables cycling behaviour */ 24 | val newVal = processInput(value) 25 | field = if (newVal > options.size - 1) 0 else if ( newVal < 0) options.size - 1 else newVal 26 | } 27 | 28 | var selected: String 29 | set(value) { 30 | index = optionIndex(value) 31 | } 32 | get() { 33 | return options[index] 34 | } 35 | 36 | /** 37 | * Finds the index of given option in the option list. 38 | * Ignores the case of the strings and returns 0 if not found. 39 | */ 40 | private fun optionIndex(string: String): Int { 41 | return MathHelper.clamp_int(this.options.map { it.lowercase() }.indexOf(string.lowercase()), 0, options.size - 1) 42 | } 43 | 44 | fun isSelected(string: String): Boolean { 45 | return this.selected.equals(string, ignoreCase = true) 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/module/settings/impl/StringSetting.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.module.settings.impl 2 | 3 | import floppaclient.module.settings.Setting 4 | import floppaclient.module.settings.Visibility 5 | 6 | /** 7 | * Provides a Setting which stores a String. 8 | * 9 | * This Setting is represented by a text field in the gui. 10 | * @author Aton 11 | */ 12 | class StringSetting( 13 | name: String, 14 | override val default: String = "", 15 | val length: Int = 30, 16 | visibility: Visibility = Visibility.VISIBLE, 17 | description: String? = null, 18 | ) : Setting(name, visibility, description) { 19 | 20 | override var value: String = default 21 | set(newStr) { 22 | val tempStr = processInput(newStr) 23 | field = if (tempStr.length > length) { 24 | tempStr.substring(0, length - 1) 25 | }else 26 | tempStr 27 | } 28 | 29 | var text: String by this::value 30 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/shaders/impl/Chroma2D.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.shaders.impl 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import floppaclient.FloppaClient.Companion.totalTicks 5 | import floppaclient.module.impl.render.ClickGui 6 | import floppaclient.shaders.Shader 7 | import floppaclient.shaders.uniforms.impl.Uniform1F 8 | import floppaclient.utils.Utils.timer 9 | import kotlin.math.exp 10 | 11 | /** 12 | * This shader will put a 2d chroma effect over anything that is rendered. 13 | * The color of the rendered vertices is overwritten. 14 | */ 15 | object Chroma2D: Shader("chroma2d/chroma2d") { 16 | 17 | /* 18 | The scaling for the values is not super straightforward, but makes configuring the chroma effect very smooth. 19 | */ 20 | 21 | private val chromaSize = Uniform1F(this, "chromaSize") { 22 | (exp( ClickGui.chromaSize.value.toFloat() * 0.5f ) -1f) / 30f 23 | } 24 | private val chromaSpeed = Uniform1F(this, "chromaTime") { 25 | if (ClickGui.chromaSpeed.value == 0.0) 26 | 0f 27 | else 28 | ((totalTicks + mc.timer.renderPartialTicks) / 20.0 * (1- exp(ClickGui.chromaSpeed.value)) ).toFloat() 29 | } 30 | private val chromaAngle = Uniform1F(this, "chromaAngle") { 31 | (ClickGui.chromaAngle.value.toFloat() + 90f) * 0.017453292f 32 | } 33 | 34 | init { 35 | this.registerUniforms( 36 | chromaSize, 37 | chromaSpeed, 38 | chromaAngle 39 | ) 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/shaders/uniforms/Uniform.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.shaders.uniforms 2 | 3 | import floppaclient.shaders.Shader 4 | import org.lwjgl.opengl.GL20 5 | 6 | /** 7 | * Uniforms are used to communicate variables with shaders at runtime. 8 | * This class offers some utilities to use that functionality. 9 | */ 10 | abstract class Uniform(shader: Shader, name: String) { 11 | 12 | /** 13 | * Stores the last value that was updated to the GPU, is used to only update the value to the GPU if it was changed. 14 | */ 15 | abstract var lastValue: T? 16 | 17 | /** 18 | * Reference to the impl. Used somewhat similar to a pointer. 19 | */ 20 | protected val uninformID: Int = GL20.glGetUniformLocation(shader.programID, name) 21 | 22 | /** 23 | * Updates the value of this impl to the GPU. 24 | * The value(s) is(are) loaded from the specified source in the respective constructors. 25 | */ 26 | abstract fun update() 27 | 28 | //TODO generalize the check that tests whether the value should be updated here. 29 | // The current implementation is pretty bad, it requires the generic in the Superclass, but it is never used there. 30 | // Either remove the generic here and only implement it in the members or fix it to be generalized properly 31 | //TODO also might need some readjustments to supporter other typos of Uniform. 32 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/shaders/uniforms/impl/Uniform1F.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.shaders.uniforms.impl 2 | 3 | import floppaclient.shaders.Shader 4 | import floppaclient.shaders.uniforms.Uniform 5 | import org.lwjgl.opengl.GL20 6 | 7 | class Uniform1F(shader: Shader, name: String, private val source: () -> Float) : Uniform(shader, name) { 8 | 9 | override var lastValue: Float? = null 10 | 11 | override fun update() { 12 | val newVal = source() 13 | if (newVal != lastValue) { 14 | GL20.glUniform1f(this.uninformID, newVal) 15 | lastValue = newVal 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/advanced/elements/AdvancedElement.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.advanced.elements 2 | 3 | import floppaclient.module.Module 4 | import floppaclient.module.settings.Setting 5 | import floppaclient.ui.clickgui.advanced.AdvancedMenu 6 | import floppaclient.ui.clickgui.util.ColorUtil 7 | import floppaclient.ui.clickgui.util.FontUtil 8 | import net.minecraft.client.gui.Gui 9 | import net.minecraft.client.renderer.GlStateManager 10 | import java.awt.Color 11 | 12 | /** 13 | * Class for all setting elements in the advanced menu to inherit from 14 | * 15 | * @author Aton 16 | */ 17 | abstract class AdvancedElement>( 18 | val parent: AdvancedMenu, 19 | val module: Module, 20 | val setting: S, 21 | val type: AdvancedElementType, 22 | ) { 23 | var x = 0 24 | var y = 0 25 | /** Width of the entire element consisting of the setting and description. */ 26 | var width = 150 27 | /** Height of the entire element consisting of the setting and description. Essentially the height of the higher one of the two */ 28 | var height = 15 29 | /** Width of the Setting without the description text. */ 30 | var settingWidth = 116 31 | /** Height of the Setting without the description text. */ 32 | var settingHeight = 15 33 | 34 | var comboextended = false 35 | 36 | var listening = false 37 | 38 | fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) { 39 | GlStateManager.pushMatrix() 40 | GlStateManager.translate(x.toFloat(), y.toFloat(), 0f) 41 | 42 | //Rendering the box behind the element. 43 | val temp = ColorUtil.clickGUIColor 44 | val color = if (listening) { 45 | Color(temp.red, temp.green, temp.blue, 200).rgb 46 | }else { 47 | Color(ColorUtil.elementColor, true).darker().rgb 48 | } 49 | Gui.drawRect(0, 0, width, height, Color(ColorUtil.bgColor, true).brighter().rgb) 50 | Gui.drawRect(0, 0, settingWidth, settingHeight, color) 51 | 52 | // Render the element. 53 | val l1 = renderElement(mouseX, mouseY, partialTicks) 54 | 55 | // Render the descriton right of the Setting 56 | val l2 = renderDescription() 57 | this.settingHeight = l1 58 | this.height = l1.coerceAtLeast(l2) 59 | 60 | GlStateManager.popMatrix() 61 | } 62 | 63 | open fun renderElement(mouseX: Int, mouseY: Int, partialTicks: Float) : Int{ return settingHeight } 64 | 65 | open fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int): Boolean { 66 | return false 67 | } 68 | 69 | open fun mouseReleased(mouseX: Int, mouseY: Int, state: Int) {} 70 | 71 | /** 72 | * Overridden in the elements to enable key detection. Returns true when an action was taken. 73 | */ 74 | open fun keyTyped(typedChar: Char, keyCode: Int): Boolean { return false } 75 | 76 | fun renderDescription() : Int{ 77 | var descriptionHeight = 0 78 | setting.description?.let { 79 | FontUtil.drawSplitString( 80 | it, settingWidth + 10, 81 | 2, width - settingWidth - 10, ColorUtil.textcolor 82 | ) 83 | descriptionHeight = FontUtil.getSplitHeight(it, width - settingWidth - 10) 84 | } 85 | return descriptionHeight + 4 86 | } 87 | 88 | fun setDimensions(x: Int, y: Int, width: Int, height: Int){ 89 | this.x = x 90 | this.y = y 91 | this.width = width 92 | this.height = height 93 | } 94 | 95 | fun setPosition(x: Int, y: Int){ 96 | this.x = x 97 | this.y = y 98 | } 99 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/advanced/elements/AdvancedElementType.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.advanced.elements 2 | 3 | /** 4 | * Enum for the advanced setting element type 5 | * 6 | * @author Aton 7 | */ 8 | enum class AdvancedElementType { 9 | CHECK_BOX, KEY_BIND, SELECTOR, COLOR, SLIDER, TEXT_FIELD, ACTION 10 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/advanced/elements/menu/AdvancedElementAction.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.advanced.elements.menu 2 | 3 | import floppaclient.module.Module 4 | import floppaclient.module.settings.impl.ActionSetting 5 | import floppaclient.ui.clickgui.advanced.AdvancedMenu 6 | import floppaclient.ui.clickgui.advanced.elements.AdvancedElement 7 | import floppaclient.ui.clickgui.advanced.elements.AdvancedElementType 8 | import floppaclient.ui.clickgui.util.FontUtil 9 | 10 | /** 11 | * Provides the Button for action settings in the advanced gui. 12 | * 13 | * @author Aton 14 | */ 15 | class AdvancedElementAction(parent: AdvancedMenu, module: Module, setting: ActionSetting) : 16 | AdvancedElement(parent, module, setting, AdvancedElementType.ACTION) { 17 | 18 | /** 19 | * Render the element 20 | */ 21 | override fun renderElement(mouseX: Int, mouseY: Int, partialTicks: Float) : Int{ 22 | FontUtil.drawString(setting.name, 1, 2, -0x1) 23 | return this.settingHeight 24 | } 25 | 26 | /** 27 | * Handles mouse clicks for this element and returns true if an action was performed. 28 | * Used to activate the elements action. 29 | */ 30 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int): Boolean { 31 | if (mouseButton == 0 && isButtonHovered(mouseX, mouseY)) { 32 | setting.doAction() 33 | return true 34 | } 35 | return super.mouseClicked(mouseX, mouseY, mouseButton) 36 | } 37 | 38 | /** 39 | * Checks whether this element is hovered 40 | */ 41 | private fun isButtonHovered(mouseX: Int, mouseY: Int): Boolean { 42 | return mouseX >= parent.x + x && mouseX <= parent.x + x + settingWidth && mouseY >= parent.y + y && mouseY <= parent.y + y + settingHeight 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/advanced/elements/menu/AdvancedElementCheckBox.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.advanced.elements.menu 2 | 3 | import floppaclient.module.Module 4 | import floppaclient.module.settings.impl.BooleanSetting 5 | import floppaclient.ui.clickgui.advanced.AdvancedMenu 6 | import floppaclient.ui.clickgui.advanced.elements.AdvancedElement 7 | import floppaclient.ui.clickgui.advanced.elements.AdvancedElementType 8 | import floppaclient.ui.clickgui.util.ColorUtil 9 | import floppaclient.ui.clickgui.util.ColorUtil.textcolor 10 | import floppaclient.ui.clickgui.util.FontUtil 11 | import net.minecraft.client.gui.Gui 12 | import java.awt.Color 13 | 14 | /** 15 | * Provides a checkbox element for the advanced gui. 16 | * 17 | * @author Aton 18 | */ 19 | class AdvancedElementCheckBox( 20 | parent: AdvancedMenu, module: Module, setting: BooleanSetting, 21 | ) : AdvancedElement(parent, module, setting, AdvancedElementType.CHECK_BOX) { 22 | 23 | 24 | /** 25 | * Render the element 26 | */ 27 | override fun renderElement(mouseX: Int, mouseY: Int, partialTicks: Float) : Int{ 28 | val temp = ColorUtil.clickGUIColor 29 | val color = Color(temp.red, temp.green, temp.blue, 200).rgb 30 | 31 | /** Rendering the name and the checkbox */ 32 | FontUtil.drawString(setting.name, 1, 2, textcolor) 33 | Gui.drawRect( 34 | (settingWidth - 13), 2, settingWidth - 1, 13, 35 | if (setting.enabled) color else -0x1000000 36 | ) 37 | if (isCheckHovered(mouseX, mouseY)) Gui.drawRect( 38 | settingWidth - 13, 2, settingWidth -1, 39 | 13, 0x55111111 40 | ) 41 | return this.settingHeight 42 | } 43 | 44 | /** 45 | * Handles mouse clicks for this element and returns true if an action was performed 46 | */ 47 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int): Boolean { 48 | if (mouseButton == 0 && isCheckHovered(mouseX, mouseY)) { 49 | setting.toggle() 50 | return true 51 | } 52 | return super.mouseClicked(mouseX, mouseY, mouseButton) 53 | } 54 | 55 | /** 56 | * Checks whether this element is hovered 57 | */ 58 | private fun isCheckHovered(mouseX: Int, mouseY: Int): Boolean { 59 | return mouseX >= parent.x + x + settingWidth - 13 && mouseX <= parent.x + x + settingWidth - 1 && mouseY >= parent.y + y + 2 && mouseY <= parent.y + y + settingHeight - 2 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/advanced/elements/menu/AdvancedElementKeyBind.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.advanced.elements.menu 2 | 3 | import floppaclient.module.Module 4 | import floppaclient.module.settings.impl.DummySetting 5 | import floppaclient.ui.clickgui.advanced.AdvancedMenu 6 | import floppaclient.ui.clickgui.advanced.elements.AdvancedElement 7 | import floppaclient.ui.clickgui.advanced.elements.AdvancedElementType 8 | import floppaclient.ui.clickgui.util.FontUtil 9 | import org.lwjgl.input.Keyboard 10 | import org.lwjgl.input.Mouse 11 | 12 | /** 13 | * Provides a key bind element. 14 | * 15 | * @author Aton 16 | */ 17 | class AdvancedElementKeyBind(parent: AdvancedMenu, module: Module) : 18 | AdvancedElement(parent, module, DummySetting("KeyBind"), AdvancedElementType.KEY_BIND) { 19 | 20 | private val keyBlackList = intArrayOf() 21 | 22 | /** 23 | * Render the element 24 | */ 25 | override fun renderElement(mouseX: Int, mouseY: Int, partialTicks: Float): Int { 26 | val displayName = "Key Bind" 27 | 28 | val keyName = if (module.keyCode > 0) 29 | Keyboard.getKeyName(module.keyCode) ?: "Err" 30 | else if (module.keyCode < 0) 31 | Mouse.getButtonName(module.keyCode + 100) 32 | else 33 | ".." 34 | val displayValue = "[$keyName]" 35 | 36 | // Rendering the text and the keybind. 37 | FontUtil.drawString(displayName, 1, 2, -0x1) 38 | FontUtil.drawString(displayValue, this.settingWidth - FontUtil.getStringWidth(displayValue), 2, -0x1) 39 | return this.settingHeight 40 | } 41 | 42 | /** 43 | * Handles mouse clicks for this element and returns true if an action was performed. 44 | * Used to interact with the element and to register mouse binds. 45 | */ 46 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int): Boolean { 47 | if (mouseButton == 0 && isCheckHovered(mouseX, mouseY)) { 48 | listening = !listening 49 | return true 50 | } else if (listening) { 51 | module.keyCode = -100 + mouseButton 52 | listening = false 53 | } 54 | return super.mouseClicked(mouseX, mouseY, mouseButton) 55 | } 56 | 57 | /** 58 | * Register key strokes. Used to set the key bind. 59 | */ 60 | override fun keyTyped(typedChar: Char, keyCode: Int): Boolean { 61 | if (listening) { 62 | if (keyCode == Keyboard.KEY_ESCAPE || keyCode == Keyboard.KEY_BACK) { 63 | module.keyCode = Keyboard.KEY_NONE 64 | listening = false 65 | } else if (keyCode == Keyboard.KEY_NUMPADENTER || keyCode == Keyboard.KEY_RETURN) { 66 | listening = false 67 | } else if (!keyBlackList.contains(keyCode)) { 68 | module.keyCode = keyCode 69 | listening = false 70 | } 71 | return true 72 | } 73 | return super.keyTyped(typedChar, keyCode) 74 | } 75 | 76 | /** 77 | * Checks whether this element is hovered 78 | */ 79 | private fun isCheckHovered(mouseX: Int, mouseY: Int): Boolean { 80 | return mouseX >= parent.x + x && mouseX <= parent.x + x + settingWidth && mouseY >= parent.y + y && mouseY <= parent.y + y + settingHeight 81 | } 82 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/elements/ElementType.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.elements 2 | 3 | /** 4 | * Enum for the setting element type 5 | * 6 | * @author Aton 7 | */ 8 | enum class ElementType { 9 | CHECK_BOX, KEY_BIND, SELECTOR, COLOR, SLIDER, TEXT_FIELD, ACTION 10 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/elements/menu/ElementAction.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.elements.menu 2 | 3 | import floppaclient.module.settings.impl.ActionSetting 4 | import floppaclient.ui.clickgui.elements.Element 5 | import floppaclient.ui.clickgui.elements.ElementType 6 | import floppaclient.ui.clickgui.elements.ModuleButton 7 | import floppaclient.ui.clickgui.util.FontUtil 8 | 9 | /** 10 | * Provides the Menu Button for action settings. 11 | * 12 | * @author Aton 13 | */ 14 | class ElementAction(parent: ModuleButton, setting: ActionSetting) : 15 | Element(parent, setting, ElementType.ACTION) { 16 | 17 | override fun renderElement(mouseX: Int, mouseY: Int, partialTicks: Float): Int { 18 | FontUtil.drawString(displayName, 1, 2) 19 | return super.renderElement(mouseX, mouseY, partialTicks) 20 | } 21 | 22 | /** 23 | * Handles mouse clicks for this element and returns true if an action was performed. 24 | * Used to activate the elements action. 25 | */ 26 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int): Boolean { 27 | if (mouseButton == 0 && isButtonHovered(mouseX, mouseY) ) { 28 | (setting as? ActionSetting)?.doAction() 29 | return true 30 | } 31 | return super.mouseClicked(mouseX, mouseY, mouseButton) 32 | } 33 | 34 | /** 35 | * Checks whether this element is hovered 36 | */ 37 | private fun isButtonHovered(mouseX: Int, mouseY: Int): Boolean { 38 | return mouseX >= xAbsolute && mouseX <= xAbsolute + width && mouseY >= yAbsolute && mouseY <= yAbsolute + height 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/elements/menu/ElementCheckBox.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.elements.menu 2 | 3 | import floppaclient.module.settings.impl.BooleanSetting 4 | import floppaclient.ui.clickgui.elements.Element 5 | import floppaclient.ui.clickgui.elements.ElementType 6 | import floppaclient.ui.clickgui.elements.ModuleButton 7 | import floppaclient.ui.clickgui.util.ColorUtil 8 | import floppaclient.ui.clickgui.util.FontUtil 9 | import net.minecraft.client.gui.Gui 10 | 11 | /** 12 | * Provides a checkbox element. 13 | * 14 | * @author Aton 15 | */ 16 | class ElementCheckBox(parent: ModuleButton, setting: BooleanSetting) : 17 | Element(parent, setting, ElementType.CHECK_BOX) { 18 | 19 | override fun renderElement(mouseX: Int, mouseY: Int, partialTicks: Float): Int { 20 | val buttonColor = if (setting.enabled) 21 | ColorUtil.clickGUIColor.rgb 22 | else ColorUtil.buttonColor 23 | 24 | /** Rendering the name and the checkbox */ 25 | FontUtil.drawString(displayName, 1, 3) 26 | Gui.drawRect(width -13, 2, width - 1, 13, buttonColor) 27 | if (isCheckHovered(mouseX, mouseY)) 28 | Gui.drawRect(width -13, 2, width - 1, 13, ColorUtil.boxHoverColor) 29 | 30 | return super.renderElement(mouseX, mouseY, partialTicks) 31 | } 32 | 33 | /** 34 | * Handles mouse clicks for this element and returns true if an action was performed 35 | */ 36 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int): Boolean { 37 | if (mouseButton == 0 && isCheckHovered(mouseX, mouseY)) { 38 | setting.toggle() 39 | return true 40 | } 41 | return super.mouseClicked(mouseX, mouseY, mouseButton) 42 | } 43 | 44 | /** 45 | * Checks whether this element is hovered 46 | */ 47 | private fun isCheckHovered(mouseX: Int, mouseY: Int): Boolean { 48 | return mouseX >= xAbsolute + width - 13 && mouseX <= xAbsolute + width - 1 && mouseY >= yAbsolute + 2 && mouseY <= yAbsolute + height - 2 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/elements/menu/ElementKeyBind.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.elements.menu 2 | 3 | import floppaclient.module.Module 4 | import floppaclient.module.settings.impl.DummySetting 5 | import floppaclient.ui.clickgui.elements.Element 6 | import floppaclient.ui.clickgui.elements.ElementType 7 | import floppaclient.ui.clickgui.elements.ModuleButton 8 | import floppaclient.ui.clickgui.util.FontUtil 9 | import org.lwjgl.input.Keyboard 10 | import org.lwjgl.input.Mouse 11 | 12 | /** 13 | * Provides a key bind element. 14 | * 15 | * @author Aton 16 | */ 17 | class ElementKeyBind(parent: ModuleButton, val mod: Module) : 18 | Element(parent, DummySetting("Key Bind"), ElementType.KEY_BIND) { 19 | 20 | private val keyBlackList = intArrayOf() 21 | 22 | 23 | override fun renderElement(mouseX: Int, mouseY: Int, partialTicks: Float): Int { 24 | val keyName = if (mod.keyCode > 0) 25 | Keyboard.getKeyName(mod.keyCode) ?: "Err" 26 | else if (mod.keyCode < 0) 27 | Mouse.getButtonName(mod.keyCode + 100) 28 | else 29 | ".." 30 | val displayValue = "[$keyName]" 31 | 32 | FontUtil.drawString(displayName, 1, 2) 33 | FontUtil.drawString(displayValue, width - FontUtil.getStringWidth(displayValue), 2) 34 | 35 | return super.renderElement(mouseX, mouseY, partialTicks) 36 | } 37 | 38 | /** 39 | * Handles mouse clicks for this element and returns true if an action was performed. 40 | * Used to interact with the element and to register mouse binds. 41 | */ 42 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int): Boolean { 43 | if (mouseButton == 0 && isCheckHovered(mouseX, mouseY)) { 44 | listening = !listening 45 | return true 46 | } else if (listening) { 47 | mod.keyCode = -100 + mouseButton 48 | listening = false 49 | } 50 | return super.mouseClicked(mouseX, mouseY, mouseButton) 51 | } 52 | 53 | /** 54 | * Register key strokes. Used to set the key bind. 55 | */ 56 | override fun keyTyped(typedChar: Char, keyCode: Int): Boolean { 57 | if (listening) { 58 | if (keyCode == Keyboard.KEY_ESCAPE || keyCode == Keyboard.KEY_BACK) { 59 | mod.keyCode = Keyboard.KEY_NONE 60 | listening = false 61 | } else if (keyCode == Keyboard.KEY_NUMPADENTER || keyCode == Keyboard.KEY_RETURN) { 62 | listening = false 63 | } else if (!keyBlackList.contains(keyCode)) { 64 | mod.keyCode = keyCode 65 | listening = false 66 | } 67 | return true 68 | } 69 | return super.keyTyped(typedChar, keyCode) 70 | } 71 | 72 | /** 73 | * Checks whether this element is hovered 74 | */ 75 | private fun isCheckHovered(mouseX: Int, mouseY: Int): Boolean { 76 | return mouseX >= xAbsolute && mouseX <= xAbsolute + width && mouseY >= yAbsolute && mouseY <= yAbsolute + height 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/util/ColorUtil.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.util 2 | 3 | import floppaclient.module.impl.render.ClickGui 4 | import gg.essential.elementa.utils.withAlpha 5 | import java.awt.Color 6 | 7 | /** 8 | * Provides color for the click gui. 9 | * 10 | * @author Aton 11 | */ 12 | object ColorUtil { 13 | val clickGUIColor: Color 14 | get() = ClickGui.color.value 15 | 16 | val elementColor: Int 17 | get() = if (ClickGui.design.isSelected("New")) 18 | newColor 19 | else if (ClickGui.design.isSelected("JellyLike")) 20 | jellyColor 21 | else 22 | 0 23 | 24 | val bgColor: Int 25 | get() = if (ClickGui.design.isSelected("New")) 26 | newColor 27 | else if (ClickGui.design.isSelected("JellyLike")) 28 | Color(255,255,255,50).rgb 29 | else 30 | 0 31 | 32 | val outlineColor : Int 33 | get() = clickGUIColor.darker().rgb 34 | 35 | val hoverColor: Int 36 | get() { 37 | val temp = clickGUIColor.darker() 38 | val scale = 0.5 39 | return Color(((temp.red*scale).toInt()), (temp.green*scale).toInt(), (temp.blue*scale).toInt()).rgb 40 | } 41 | 42 | val tabColor: Int 43 | get() = clickGUIColor.withAlpha(150).rgb 44 | 45 | fun sliderColor(dragging: Boolean): Int = clickGUIColor.withAlpha(if (dragging) 250 else 200).rgb 46 | 47 | fun sliderKnobColor(dragging: Boolean): Int = clickGUIColor.withAlpha(if (dragging) 255 else 230).rgb 48 | 49 | 50 | 51 | const val jellyColor = -0x44eaeaeb 52 | const val newColor = -0xdcdcdd 53 | const val moduleButtonColor = -0xe5e5e6 54 | const val textcolor = -0x101011 55 | 56 | const val jellyPanelColor = -0x555556 57 | 58 | const val tabColorBg = 0x77000000 59 | const val dropDownColor = -0x55ededee 60 | const val boxHoverColor = 0x55111111 61 | const val sliderBackground = -0xefeff0 62 | 63 | const val buttonColor = -0x1000000 64 | 65 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/ui/clickgui/util/FontUtil.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.ui.clickgui.util 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import net.minecraft.client.gui.FontRenderer 5 | import net.minecraft.util.StringUtils 6 | import java.util.* 7 | 8 | /** 9 | * Provides methods for rending text. 10 | * 11 | * @author Aton 12 | */ 13 | object FontUtil { 14 | private var fontRenderer: FontRenderer? = null 15 | fun setupFontUtils() { 16 | fontRenderer = mc.fontRendererObj 17 | } 18 | 19 | fun getStringWidth(text: String?): Int { 20 | return fontRenderer!!.getStringWidth(StringUtils.stripControlCodes(text)) 21 | } 22 | 23 | fun getSplitHeight(text: String, wrapWidth: Int): Int { 24 | var dy = 0 25 | for (s in mc.fontRendererObj.listFormattedStringToWidth(text, wrapWidth)) { 26 | dy += mc.fontRendererObj.FONT_HEIGHT 27 | } 28 | return dy 29 | } 30 | 31 | val fontHeight: Int 32 | get() = fontRenderer!!.FONT_HEIGHT 33 | 34 | fun drawString(text: String, x: Double, y: Double, color: Int = ColorUtil.textcolor) { 35 | drawString(text, x.toInt(), y.toInt(), color) 36 | } 37 | 38 | fun drawString(text: String, x: Int, y: Int, color: Int = ColorUtil.textcolor) { 39 | fontRenderer!!.drawString(text, x, y, color) 40 | } 41 | 42 | fun drawStringWithShadow(text: String, x: Double, y: Double, color: Int = ColorUtil.textcolor) { 43 | fontRenderer?.drawStringWithShadow(text, x.toFloat(), y.toFloat(), color) 44 | } 45 | 46 | fun drawCenteredString(text: String, x: Double, y: Double, color: Int = ColorUtil.textcolor) { 47 | drawString(text, x - fontRenderer!!.getStringWidth(text) / 2, y, color) 48 | } 49 | 50 | fun drawCenteredStringWithShadow(text: String, x: Double, y: Double, color: Int = ColorUtil.textcolor) { 51 | drawStringWithShadow(text, x - fontRenderer!!.getStringWidth(text) / 2, y, color) 52 | } 53 | 54 | fun drawTotalCenteredString(text: String, x: Double, y: Double, color: Int = ColorUtil.textcolor) { 55 | drawString(text, x - fontRenderer!!.getStringWidth(text) / 2, y - fontRenderer!!.FONT_HEIGHT / 2, color) 56 | } 57 | 58 | fun drawTotalCenteredStringWithShadow(text: String, x: Double, y: Double, color: Int = ColorUtil.textcolor) { 59 | drawStringWithShadow( 60 | text, 61 | x - fontRenderer!!.getStringWidth(text) / 2, 62 | y - fontRenderer!!.FONT_HEIGHT / 2f, 63 | color 64 | ) 65 | } 66 | 67 | /** 68 | * Draws a string with line wrapping. 69 | */ 70 | fun drawSplitString(text: String, x: Int, y: Int, wrapWidth: Int, color: Int = ColorUtil.textcolor) { 71 | fontRenderer?.drawSplitString(text, x, y, wrapWidth, color) 72 | } 73 | 74 | /** 75 | * Returns a copy of the String where the first letter is capitalized. 76 | */ 77 | fun String.forceCapitalize(): String { 78 | return this.substring(0, 1).uppercase(Locale.getDefault()) + this.substring(1, this.length) 79 | } 80 | 81 | /** 82 | * Returns a copy of the String where the only first letter is capitalized. 83 | */ 84 | fun String.capitalizeOnlyFirst(): String { 85 | return this.substring(0, 1).uppercase(Locale.getDefault()) + this.substring(1, this.length).lowercase() 86 | } 87 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/utils/HypixelApiUtils.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.utils 2 | 3 | import floppaclient.module.impl.render.ClickGui 4 | import com.google.gson.JsonParser 5 | import org.apache.http.client.methods.HttpGet 6 | import org.apache.http.impl.client.HttpClients 7 | import org.apache.http.util.EntityUtils 8 | 9 | /** 10 | * # Methods for accessing the Hypixel API. 11 | * 12 | * Getting a response from an http query takes some time. 13 | * Therefore the methods in here should only be used suspended in coroutines that do not block the main thread. 14 | * To ensure that none of the methods are used on accident in the main thread they have the *suspend* keyword. 15 | * This only allows them to be used in a coroutine. In general the IO dispatcher is the best choice for these coroutines. 16 | * The following shows an example of how to use [getSecrets]. 17 | * 18 | * scope.launch(Dispatchers.IO) { 19 | * val uuid = mc.thePlayer.uniqueID.toString() 20 | * val secrets = HypixelApiUtils.getSecrets(uuid) 21 | * modMessage("$secrets") 22 | * } 23 | * @author Aton 24 | */ 25 | object HypixelApiUtils { 26 | 27 | /** 28 | * Get the total amount of secrets a player has collected. 29 | * Only use this method in a coroutine to not freeze the main thread. 30 | * 31 | * Based on a method provided by [Harry282](https://github.com/Harry282 "Github") 32 | */ 33 | suspend fun getSecrets(uuid: String): Int? { 34 | val response = fetch("https://api.hypixel.net/player?key=${ClickGui.apiKey.text}&uuid=${uuid}") 35 | return if (response == null) null else try { 36 | val jsonObject = JsonParser().parse(response).asJsonObject 37 | if (jsonObject.getAsJsonPrimitive("success")?.asBoolean == true) { 38 | jsonObject.getAsJsonObject("player")?.getAsJsonObject("achievements") 39 | ?.getAsJsonPrimitive("skyblock_treasure_hunter")?.asInt 40 | }else 41 | null 42 | }catch (_: Exception){ 43 | null 44 | } 45 | } 46 | 47 | @Suppress("RedundantSuspendModifier") 48 | private suspend fun fetch(uri: String): String? { 49 | HttpClients.createMinimal().use { 50 | try { 51 | val httpGet = HttpGet(uri) 52 | return EntityUtils.toString(it.execute(httpGet).entity) 53 | }catch (_: Exception) { 54 | return null 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/utils/ScoreboardUtils.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.utils 2 | 3 | import net.minecraft.scoreboard.ScorePlayerTeam 4 | import net.minecraft.util.StringUtils.stripControlCodes 5 | import floppaclient.FloppaClient.Companion.mc 6 | 7 | object ScoreboardUtils { 8 | fun cleanSB(scoreboard: String?): String { 9 | return stripControlCodes(scoreboard).toCharArray().filter { it.code in 21..126 }.joinToString("") 10 | } 11 | 12 | val sidebarLines: List 13 | get() { 14 | val scoreboard = mc.theWorld?.scoreboard ?: return emptyList() 15 | val objective = scoreboard.getObjectiveInDisplaySlot(1) ?: return emptyList() 16 | var scores = scoreboard.getSortedScores(objective) 17 | scores = scores.filter { 18 | it?.playerName?.startsWith("#") == false 19 | }.let { 20 | if (it.size > 15) it.drop(15) else it 21 | } 22 | return scores.map { 23 | ScorePlayerTeam.formatPlayerName(scoreboard.getPlayersTeam(it.playerName), it.playerName) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/utils/TabListUtils.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.utils 2 | 3 | import floppaclient.FloppaClient 4 | import com.google.common.collect.ComparisonChain 5 | import net.minecraft.client.network.NetworkPlayerInfo 6 | import net.minecraft.world.WorldSettings 7 | 8 | object TabListUtils { 9 | 10 | private val tabListOrder = Comparator { o1, o2 -> 11 | if (o1 == null) return@Comparator -1 12 | if (o2 == null) return@Comparator 0 13 | return@Comparator ComparisonChain.start().compareTrueFirst( 14 | o1.gameType != WorldSettings.GameType.SPECTATOR, 15 | o2.gameType != WorldSettings.GameType.SPECTATOR 16 | ).compare( 17 | o1.playerTeam?.registeredName ?: "", 18 | o2.playerTeam?.registeredName ?: "" 19 | ).compare(o1.gameProfile.name, o2.gameProfile.name).result() 20 | } 21 | 22 | val tabList: List> 23 | get() = (FloppaClient.mc.thePlayer?.sendQueue?.playerInfoMap?.sortedWith(tabListOrder) ?: emptyList()) 24 | .map { Pair(it, FloppaClient.mc.ingameGUI.tabList.getPlayerName(it)) } 25 | 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/utils/fakeactions/FakeAction.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.utils.fakeactions 2 | 3 | data class FakeAction( 4 | var fakeYaw: Float = 0f, 5 | var fakePitch: Float = 0f, 6 | 7 | // right click if true left click otherwise 8 | var rightClick:Boolean = true, 9 | 10 | var itemSlot: Int = 0, 11 | 12 | var forceSneak: Boolean = false, 13 | /** 14 | * Determines whether the item should be swung client side on left click. 15 | */ 16 | var swingItem: Boolean = true, 17 | /** 18 | * Will be run right after the fake action 19 | */ 20 | var extraActionFun: () -> Unit = {} 21 | ){ 22 | /** 23 | * Additional action that will be performed after the fake action. 24 | */ 25 | fun extraAction(){ 26 | extraActionFun() 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/floppaclient/utils/fakeactions/FakeInventoryActionManager.kt: -------------------------------------------------------------------------------- 1 | package floppaclient.utils.fakeactions 2 | 3 | import floppaclient.FloppaClient.Companion.mc 4 | import net.minecraft.client.gui.GuiScreen 5 | import net.minecraft.client.gui.inventory.GuiInventory 6 | import net.minecraft.network.play.client.C16PacketClientStatus 7 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 8 | import net.minecraftforge.fml.common.gameevent.TickEvent 9 | import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent 10 | 11 | /** 12 | * A Utility class for performing item movements in the players inventory all within a single game tick. 13 | * 14 | * Use [addAction] to queue an interaction with the player inventory. 15 | * 16 | * All added actions will be executed at the end of the tick if possible and cleared. 17 | * 18 | * @author Aton 19 | */ 20 | object FakeInventoryActionManager { 21 | 22 | private val actions: MutableList<(GuiInventory) -> Unit> = mutableListOf() 23 | 24 | /** 25 | * Performs the inventory action and skips the rendering of the inventory. 26 | */ 27 | @SubscribeEvent 28 | fun inTick(event: ClientTickEvent) { 29 | if (event.phase != TickEvent.Phase.END) return 30 | if (actions.isEmpty()) return 31 | val inventory = GuiInventory(mc.thePlayer) 32 | if (!mc.playerController.isRidingHorse) { 33 | val inventoryOpened = if (mc.currentScreen != (inventory as GuiScreen)) { 34 | mc.netHandler 35 | .addToSendQueue(C16PacketClientStatus(C16PacketClientStatus.EnumState.OPEN_INVENTORY_ACHIEVEMENT)) 36 | mc.displayGuiScreen(inventory) 37 | true 38 | }else false 39 | 40 | // perform all the actions 41 | actions.forEach { it(inventory) } 42 | 43 | if (inventoryOpened) mc.thePlayer.closeScreen() 44 | } 45 | actions.clear() 46 | return 47 | } 48 | 49 | /** 50 | * Add an action to the list of actions that should be performed. 51 | */ 52 | fun addAction(action: (GuiInventory) -> Unit) { 53 | actions.add(action) 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/floppamap/default/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/floppamap/default/cross.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/floppamap/default/green_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/floppamap/default/green_check.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/floppamap/default/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/floppamap/default/question.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/floppamap/default/white_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/floppamap/default/white_check.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/floppamap/neu/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/floppamap/neu/cross.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/floppamap/neu/green_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/floppamap/neu/green_check.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/floppamap/neu/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/floppamap/neu/question.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/floppamap/neu/white_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/floppamap/neu/white_check.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/gui/HueScale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/gui/HueScale.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/gui/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/gui/Icon.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/gui/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FloppaCoding/FloppaClient/28f8c2d3f5d9e98207a9028bae3f557bd00f3c09/src/main/resources/assets/floppaclient/gui/cursor.png -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/shaders/chroma2d/chroma2d.frag: -------------------------------------------------------------------------------- 1 | #version 400 2 | 3 | uniform float chromaSize; 4 | uniform float chromaTime; 5 | uniform float chromaAngle; 6 | 7 | varying vec4 vertColor; 8 | 9 | // 10 | // Taken from 11 | // https://www.shadertoy.com/view/MsS3Wc 12 | // by Inigo Quilez under MIT License 13 | 14 | // Smooth HSV to RGB conversion 15 | vec3 hsv2rgb_smooth( in vec3 c ) 16 | { 17 | vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 ); 18 | rgb = rgb*rgb*(3.0-2.0*rgb); // cubic smoothing 19 | return c.z * mix( vec3(1.0), rgb, c.y); 20 | } 21 | 22 | void main() { 23 | float hue = mod( (sin(chromaAngle) * gl_FragCoord.x + cos(chromaAngle) * gl_FragCoord.y) * chromaSize + chromaTime, 1.0); 24 | gl_FragColor = vec4(hsv2rgb_smooth(vec3(hue, 1.0, 1.0)), vertColor.a); 25 | } -------------------------------------------------------------------------------- /src/main/resources/assets/floppaclient/shaders/chroma2d/chroma2d.vert: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | attribute vec3 position; 4 | 5 | varying vec4 outColor; 6 | 7 | void main() { 8 | gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0); 9 | outColor = gl_Color; 10 | } -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "fc", 4 | "name": "Floppa Client", 5 | "description": "MILF (Man i love Floppa).", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "", 9 | "updateUrl": "", 10 | "authorList": [ 11 | "Aton" 12 | ] 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /src/main/resources/mixins.floppaclient.json: -------------------------------------------------------------------------------- 1 | { 2 | "minVersion": "0.6", 3 | "compatibilityLevel": "JAVA_8", 4 | "package": "floppaclient.mixins", 5 | "refmap": "mixins.floppaclient.refmap.json", 6 | "mixins": [ 7 | "BlockMixin", 8 | "BlockPaneMixin", 9 | "CarpetMixin", 10 | "ChunkMixin", 11 | "MixinWorld", 12 | "entity.MixinEntity", 13 | "entity.MixinEntityLivingBase", 14 | "entity.MixinPlayer", 15 | "packet.C02Accessor" 16 | ], 17 | "client": [ 18 | "MinecraftAccessor", 19 | "MixinMinecraft", 20 | "MixinModList", 21 | "MixinNetworkManager", 22 | "MixinPlayerHandler", 23 | "MixinSoundManager", 24 | "MovementInputFromOptionsMixin", 25 | "PlayerControllerMixin", 26 | "entity.MixinAbstractClientPlayer", 27 | "entity.MixinPlayerSP", 28 | "entity.MixinPlayerSP2", 29 | "Gui.GuiMixin", 30 | "Gui.GuiScreenMixin", 31 | "Gui.MixinGuiContainer", 32 | "Gui.MixinGuiMainMenu", 33 | "render.BlockFluidRendererMixin", 34 | "render.BlockRendererDispatcherMixin", 35 | "render.ChestRendererMixin", 36 | "render.ChunkRendererWorkerMixin", 37 | "render.EntityRendererMixin", 38 | "render.ItemRendererMixin", 39 | "render.RenderChunkMixin", 40 | "render.RenderGlobalMixin", 41 | "render.RenderPlayerMixin", 42 | "render.VisGraphAccessor" 43 | ] 44 | } 45 | --------------------------------------------------------------------------------