├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── mod-incompatibility.md ├── .gitignore ├── COPYING ├── README.md ├── Testing ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src └── main ├── java └── com │ └── yyon │ └── grapplinghook │ ├── blocks │ └── modifierblock │ │ ├── BlockGrappleModifier.java │ │ ├── GuiModifier.java │ │ └── TileEntityGrappleModifier.java │ ├── client │ ├── ClientControllerManager.java │ ├── ClientEventHandlers.java │ ├── ClientProxy.java │ ├── ClientProxyInterface.java │ ├── ClientSetup.java │ ├── CrosshairRenderer.java │ └── NonConflictingKeyBinding.java │ ├── common │ ├── CommonEventHandlers.java │ └── CommonSetup.java │ ├── config │ ├── GrappleConfig.java │ └── GrappleConfigUtils.java │ ├── controllers │ ├── AirfrictionController.java │ ├── ForcefieldController.java │ └── GrappleController.java │ ├── enchantments │ ├── DoublejumpEnchantment.java │ ├── SlidingEnchantment.java │ └── WallrunEnchantment.java │ ├── entities │ └── grapplehook │ │ ├── GrapplehookEntity.java │ │ ├── RenderGrapplehookEntity.java │ │ └── SegmentHandler.java │ ├── grapplemod.java │ ├── integrations │ └── JeiIntegrations.java │ ├── items │ ├── EnderStaffItem.java │ ├── ForcefieldItem.java │ ├── GrapplehookItem.java │ ├── KeypressItem.java │ ├── LongFallBoots.java │ └── upgrades │ │ ├── BaseUpgradeItem.java │ │ ├── DoubleUpgradeItem.java │ │ ├── ForcefieldUpgradeItem.java │ │ ├── LimitsUpgradeItem.java │ │ ├── MagnetUpgradeItem.java │ │ ├── MotorUpgradeItem.java │ │ ├── RocketUpgradeItem.java │ │ ├── RopeUpgradeItem.java │ │ ├── StaffUpgradeItem.java │ │ ├── SwingUpgradeItem.java │ │ └── ThrowUpgradeItem.java │ ├── network │ ├── BaseMessageClient.java │ ├── BaseMessageServer.java │ ├── DetachSingleHookMessage.java │ ├── GrappleAttachMessage.java │ ├── GrappleAttachPosMessage.java │ ├── GrappleDetachMessage.java │ ├── GrappleEndMessage.java │ ├── GrappleModifierMessage.java │ ├── KeypressMessage.java │ ├── LoggedInMessage.java │ ├── PlayerMovementMessage.java │ └── SegmentMessage.java │ ├── server │ └── ServerControllerManager.java │ └── utils │ ├── GrappleCustomization.java │ ├── GrapplemodUtils.java │ └── Vec.java └── resources ├── META-INF └── mods.toml ├── assets └── grapplemod │ ├── blockstates │ └── block_grapple_modifier.json │ ├── lang │ ├── en_us.json │ ├── fr_fr.json │ ├── pt_br.json │ └── ru_ru.json │ ├── models │ ├── block │ │ └── block_grapple_modifier.json │ └── item │ │ ├── baseupgradeitem.json │ │ ├── block_grapple_modifier.json │ │ ├── doublejumpboots.json │ │ ├── doublemotorhook.json │ │ ├── doublemotorhookrope.json │ │ ├── doubleupgradeitem.json │ │ ├── enderhook.json │ │ ├── forcefieldupgradeitem.json │ │ ├── grapplinghook.json │ │ ├── hook.json │ │ ├── launcheritem.json │ │ ├── limitsupgradeitem.json │ │ ├── longfallboots.json │ │ ├── magnethook.json │ │ ├── magnetupgradeitem.json │ │ ├── motorhook.json │ │ ├── motorhookrope.json │ │ ├── motorupgradeitem.json │ │ ├── repeller.json │ │ ├── repelleron.json │ │ ├── rocketdoublemotorhook.json │ │ ├── rocketdoublemotorhookrope.json │ │ ├── rockethook.json │ │ ├── rockethookrope.json │ │ ├── rocketupgradeitem.json │ │ ├── rope.json │ │ ├── ropeupgradeitem.json │ │ ├── smarthook.json │ │ ├── smarthookrope.json │ │ ├── staffupgradeitem.json │ │ ├── swingupgradeitem.json │ │ ├── throwupgradeitem.json │ │ └── wallrunboots.json │ ├── sounds.json │ ├── sounds │ ├── enderstaff.ogg │ ├── jump1.ogg │ ├── jump2.ogg │ ├── jump3.ogg │ ├── jump4.ogg │ ├── rocket.ogg │ ├── slide1.ogg │ ├── slide2.ogg │ └── slide3.ogg │ └── textures │ ├── block │ └── grapplemodifier.png │ ├── entity │ ├── hook.png │ ├── hook.png.bak │ └── rope.png │ ├── gui │ ├── guimodifier_bg.png │ └── jei_modifier_bg.png │ └── items │ ├── baseupgradeitem.png │ ├── doubleupgradeitem.png │ ├── enderhook-export.png │ ├── enderhook.png │ ├── forcefieldupgradeitem.png │ ├── grapplinghook.png │ ├── hook.png │ ├── hookshot.png │ ├── hookshotrope.png │ ├── launcheritem.png │ ├── limitsupgradeitem.png │ ├── longfallboots.png │ ├── magnetbow.png │ ├── magnetupgradeitem.png │ ├── motorupgradeitem.png │ ├── multihook.png │ ├── multihookrope.png │ ├── odm.png │ ├── odmrope.png │ ├── repeller.png │ ├── repelleron.png │ ├── rocket.png │ ├── rocketrope.png │ ├── rocketupgradeitem.png │ ├── rope.png │ ├── ropeupgradeitem.png │ ├── smarthook.png │ ├── smarthookrope.png │ ├── staffupgradeitem.png │ ├── swingupgradeitem.png │ ├── throwupgradeitem.png │ └── wallrunboots.png ├── data └── grapplemod │ └── recipes │ ├── baseupgradeitem.json │ ├── block_grapple_modifier.json │ ├── doublemotorhook.json │ ├── doubleupgradeitem.json │ ├── enderhook.json │ ├── forcefieldupgradeitem.json │ ├── grapplebow.json │ ├── launcher.json │ ├── limitsupgradeitem.json │ ├── magnethook.json │ ├── magnetupgradeitem.json │ ├── motorhook.json │ ├── motorupgradeitem.json │ ├── repeller.json │ ├── rocketdoublemotorhook.json │ ├── rockethook.json │ ├── rocketupgradeitem.json │ ├── ropeupgradeitem.json │ ├── smarthook.json │ ├── staffupgradeitem.json │ ├── swingupgradeitem.json │ └── throwupgradeitem.json ├── grapplemod.mixins.json ├── icon.png └── pack.mcmeta /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Video / Screenshots** 14 | If applicable, add screenshots to help explain your problem. 15 | 16 | **Version** 17 | Mod version and Minecraft version 18 | 19 | **Output Log** 20 | An example log when the problem occurred. (Getting the log with the default Minecraft launcher: https://instant-structures-mod.com/tutorials/game-output-log/) 21 |
22 | example log 23 |
24 | 25 | **To Reproduce** 26 | If you can, steps to reproduce the behavior, e.g.: 27 | 1. Go to '...' 28 | 2. Click on '....' 29 | 3. Scroll down to '....' 30 | 4. See error 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/mod-incompatibility.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Mod Incompatibility 3 | about: Create a report to help us improve 4 | title: "[INCOMPATIBILITY]" 5 | labels: mod incompatibility 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Video / Screenshots** 14 | If applicable, add screenshots to help explain your problem. 15 | 16 | **Version** 17 | Grappling hook and other mod versions and Minecraft version 18 | 19 | **Output Log** 20 | An example log when the problem occurred. (Getting the log with the default Minecraft launcher: https://instant-structures-mod.com/tutorials/game-output-log/) 21 |
22 | example log 23 |
24 | 25 | **To Reproduce** 26 | If you can, steps to reproduce the behavior, e.g.: 27 | 1. Go to '...' 28 | 2. Click on '....' 29 | 3. Scroll down to '....' 30 | 4. See error 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | bin 3 | *.launch 4 | .settings 5 | .metadata 6 | .classpath 7 | .project 8 | 9 | # idea 10 | out 11 | *.ipr 12 | *.iws 13 | *.iml 14 | .idea 15 | 16 | # gradle 17 | build 18 | .gradle 19 | 20 | # other 21 | eclipse 22 | run 23 | /mcmodsrepo/ 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Grappling Hook Mod for Minecraft 2 | 3 | A mod which adds grappling hooks. The aim of this mod is to provide a fun way to get around large builds like cities. 4 | 5 | This mod is for Forge only. No fabric version is planned at the moment. 6 | 7 | 1.16.5/1.18.2 versions requires Cloth Config API: https://www.curseforge.com/minecraft/mc-mods/cloth-config-forge 8 | 9 | ## Mod Description & Downloads 10 | 11 | [https://www.curseforge.com/minecraft/mc-mods/grappling-hook-mod](https://www.curseforge.com/minecraft/mc-mods/grappling-hook-mod) 12 | 13 | ## Setup for Developing 14 | 15 | 1. Download the latest Minecraft Forge Mdk for the correct version of Minecraft from [https://files.minecraftforge.net/net/minecraftforge/forge/](https://files.minecraftforge.net/net/minecraftforge/forge/) 16 | 2. Clone this repository into the src folder (e.g. `rm -r src; git clone git@github.com:yyon/grapplemod.git src`) 17 | 3. Copy or symlink build.gradle and gradle.properties into the root of the Mdk 18 | 4. Follow standard Forge Development setup (e.g. `./gradlew build`, see [https://mcforge.readthedocs.io/en/latest/gettingstarted/](https://mcforge.readthedocs.io/en/latest/gettingstarted/)) 19 | 20 | ## Project Structure 21 | 22 | Currently, the versions of this mod for Minecraft 1.12, 1.16, and 1.18 are on branches 1.12, 1.16.5, and 1.18 respectively. 23 | 24 | ### Code Structure Overview 25 | 26 | - main/java/com/yyon/grapplinghook/client: Client-side code. Initialization in ClientSetup.java and event handlers in ClientEventHandlers.java. All non-client-side code must call ClientProxy.java code through ClientProxyInterface.java. 27 | - main/java/com/yyon/grapplinghook/common: Code that runs on both client-side and server-side. Initializiation in CommonSetup.java and event handlers in CommonEventHandlers.java. 28 | - main/java/com/yyon/grapplinghook/server: Server-side code. 29 | - main/java/com/yyon/grapplinghook/blocks: All Minecraft blocks added by this mod. 30 | - main/java/com/yyon/grapplinghook/items: All Minecraft items added by this mod. 31 | - main/java/com/yyon/grapplinghook/entities: All Minecraft entities added by this mod. 32 | - main/java/com/yyon/grapplinghook/enchantments: All Minecraft enchantments added by this mod. 33 | - main/java/com/yyon/grapplinghook/controllers: Code for physics / controlling player movement while on a grappling hook, etc. 34 | - main/java/com/yyon/grapplinghook/network: Custom network packets which are sent between client and server 35 | - main/java/com/yyon/grapplinghook/config: Configuration parameters provided by this mod that allows users to configure the parameters through a config file or cloth config 36 | - main/java/com/yyon/grapplinghook/integrations: Integration of this mod with other mods 37 | - main/java/com/yyon/grapplinghook/utils: Miscellaneous utilities 38 | 39 | ## Credits 40 | 41 | 1.18 update by Nyfaria 42 | 43 | Textures by Mayesnake 44 | 45 | Bug fixes: 46 | 47 | - Random832 (Prevent tick from running when shootingEntity is null) 48 | 49 | - LachimHeigrim (Fix for #37: removed forgotten debug prints) 50 | 51 | Languages: 52 | 53 | - Blueberryy (Russian) 54 | 55 | - Neerwan (French) 56 | 57 | - Eufranio (Brazillian Portugese) 58 | 59 | Sound Effects: 60 | 61 | - Iwan Gabovitch (Double jump sound effects (modified by me): https://opengameart.org/content/swish-bamboo-stick-weapon-swhoshes - Copyright Iwan Gabovitch 2009 Under the CC0 1.0 Universal license) 62 | 63 | - Outroelison (Ender staff sound effect (modified by me): https://freesound.org/people/outroelison/sounds/150950/ - Copyright outroelison 2012 under the CC0 1.0 Universal License) 64 | 65 | Bug finding: 66 | 67 | - Shivaxi 68 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | // These repositories are only for Gradle plugins, put any other repositories in the repository block further below 4 | maven { url = 'https://maven.minecraftforge.net' } 5 | maven { url = 'https://maven.parchmentmc.org' } 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true 10 | classpath 'org.parchmentmc:librarian:1.+' 11 | classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7.+' 12 | } 13 | } 14 | plugins { 15 | id 'com.github.johnrengelman.shadow' version '7.1.0' 16 | } 17 | apply plugin: 'net.minecraftforge.gradle' 18 | apply plugin: 'org.parchmentmc.librarian.forgegradle' 19 | apply plugin: 'org.spongepowered.mixin' 20 | apply from: 'https://raw.githubusercontent.com/SizableShrimp/ForgeUpdatesRemapper/main/remapper.gradle' 21 | // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. 22 | apply plugin: 'eclipse' 23 | apply plugin: 'maven-publish' 24 | 25 | version = "${minecraft_version}-${mod_version}" 26 | group = mod_base_package // http://maven.apache.org/guides/mini/guide-naming-conventions.html 27 | archivesBaseName = mod_archive_base 28 | 29 | // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. 30 | java.toolchain.languageVersion = JavaLanguageVersion.of(17) 31 | 32 | println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) 33 | minecraft { 34 | 35 | mappings channel: mappings_channel, version: mappings_version 36 | 37 | accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. 38 | 39 | runs { 40 | client { 41 | workingDirectory project.file('run') 42 | 43 | 44 | property 'forge.logging.markers', 'REGISTRIES' 45 | 46 | 47 | property 'forge.logging.console.level', 'debug' 48 | 49 | 50 | if (project.hasProperty('mc_uuid')) { 51 | 52 | args '--uuid', project.getProperty('mc_uuid') 53 | } 54 | if (project.hasProperty('mc_username')) { 55 | // Your Minecraft in-game username, not email 56 | args '--username', project.getProperty('mc_username') 57 | } 58 | if (project.hasProperty('mc_accessToken')) { 59 | 60 | args '--accessToken', project.getProperty('mc_accessToken') 61 | } 62 | 63 | mods { 64 | "${mod_id}" { 65 | source sourceSets.main 66 | } 67 | } 68 | } 69 | 70 | server { 71 | workingDirectory project.file('run') 72 | 73 | property 'forge.logging.markers', 'REGISTRIES' 74 | 75 | property 'forge.logging.console.level', 'debug' 76 | 77 | mods { 78 | "${mod_id}" { 79 | source sourceSets.main 80 | } 81 | } 82 | } 83 | 84 | data { 85 | workingDirectory project.file('run') 86 | 87 | property 'forge.logging.markers', 'REGISTRIES' 88 | 89 | property 'forge.logging.console.level', 'debug' 90 | 91 | args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') 92 | 93 | mods { 94 | "${mod_id}" { 95 | source sourceSets.main 96 | } 97 | } 98 | } 99 | } 100 | } 101 | 102 | sourceSets.main.resources { srcDir 'src/generated/resources' } 103 | 104 | repositories { 105 | maven { url 'https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/' } 106 | maven { 107 | name = '100Media' 108 | url = 'https://maven.100media.dev/' 109 | } 110 | maven { url "https://maven.shedaniel.me/" } 111 | mavenLocal() 112 | } 113 | 114 | mixin { 115 | add sourceSets.main, "${mod_id}.refmap.json" 116 | 117 | config "${mod_id}.mixins.json" 118 | 119 | debug.export = true 120 | } 121 | 122 | configurations { 123 | implementation.extendsFrom shadow 124 | } 125 | 126 | dependencies { 127 | 128 | minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" 129 | 130 | // Mixin annotation processor - generates the refmap 131 | annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor" 132 | 133 | // Capability Syncer 134 | shadow fg.deobf("dev._100media.capabilitysyncer:capabilitysyncer:${capabilitysyncer_version}") 135 | implementation fg.deobf("me.shedaniel.cloth:cloth-config-forge:8.0.75") 136 | } 137 | 138 | // This block of code expands all the gradle properties in the specified resource targets. 139 | // It copies them into the targets and expands all the defined properties. 140 | def resourceTargets = ['META-INF/mods.toml', 'pack.mcmeta', "${mod_id}.mixins.json".toString()] 141 | def intoTargets = ["$rootDir/out/production/resources/", "$rootDir/out/production/${project.name}.main/", "$rootDir/bin/main/"] 142 | def replaceProperties = [mod_id: mod_id, mod_name: mod_name, mod_version: mod_version, 143 | mod_authors: mod_authors, mod_description: mod_description, 144 | minecraft_version_range: minecraft_version_range, forge_version_range: forge_version_range, 145 | loader_version_range: loader_version_range] 146 | processResources { 147 | inputs.properties replaceProperties 148 | replaceProperties.put 'project', project 149 | 150 | filesMatching(resourceTargets) { 151 | expand replaceProperties 152 | } 153 | 154 | intoTargets.each { target -> 155 | if (file(target).exists()) { 156 | copy { 157 | from(sourceSets.main.resources) { 158 | include resourceTargets 159 | expand replaceProperties 160 | } 161 | into target 162 | } 163 | } 164 | } 165 | } 166 | 167 | jar { 168 | manifest { 169 | attributes([ 170 | 'Specification-Title': mod_id, 171 | 'Specification-Vendor': mod_authors, 172 | 'Specification-Version': '1', // We are version 1 of ourselves 173 | 'Implementation-Title': project.name, 174 | 'Implementation-Version': mod_version, 175 | 'Implementation-Vendor': mod_authors, 176 | 'Implementation-Timestamp': new Date().format('yyyy-MM-dd\'T\'HH:mm:ssZ') 177 | ]) 178 | } 179 | } 180 | 181 | def relocateTargets = ['dev._100media.capabilitysyncer'] 182 | shadowJar { 183 | archiveClassifier = '' 184 | configurations = [project.configurations.shadow] 185 | relocateTargets.forEach { 186 | relocate it, "${project.group}.relocated.$it" 187 | } 188 | finalizedBy 'reobfShadowJar' 189 | } 190 | 191 | artifacts { 192 | shadowJar 193 | } 194 | 195 | reobf { 196 | shadowJar {} 197 | } 198 | 199 | afterEvaluate { 200 | jar.finalizedBy reobfJar 201 | reobfShadowJar.dependsOn shadowJar 202 | } 203 | 204 | // Example configuration to allow publishing using the maven-publish plugin 205 | // This is the preferred method to reobfuscate your jar file 206 | jar.finalizedBy('reobfJar') 207 | // However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing 208 | // publish.dependsOn('reobfJar') 209 | 210 | publishing { 211 | publications { 212 | mavenJava(MavenPublication) { 213 | artifact jar 214 | } 215 | } 216 | repositories { 217 | maven { 218 | url "file://${project.projectDir}/mcmodsrepo" 219 | } 220 | } 221 | } 222 | 223 | 224 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | org.gradle.daemon=false 5 | 6 | minecraft_version=1.19.2 7 | minecraft_version_range=[1.19,1.20) 8 | forge_version=43.1.1 9 | forge_version_range=[43,) 10 | loader_version_range=[43,) 11 | mappings_channel=parchment 12 | mappings_version=2022.08.28-1.19.2 13 | 14 | mod_id=grapplemod 15 | mod_name=Grappling Hook Mod 16 | mod_version=1.19.2-v13 17 | mod_base_package=com.yyon.grapplinghook 18 | mod_authors=Yyon, Nyfaria, and Mayesnake 19 | mod_description=GrapplingHook 20 | mod_archive_base=grappling_hook_mod 21 | 22 | # Dependencies 23 | mixin_version=0.8.5 24 | capabilitysyncer_version=1.19-3.0.1 25 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/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-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/blocks/modifierblock/BlockGrappleModifier.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.blocks.modifierblock; 2 | 3 | import com.yyon.grapplinghook.client.ClientProxyInterface; 4 | import com.yyon.grapplinghook.common.CommonSetup; 5 | import com.yyon.grapplinghook.config.GrappleConfig; 6 | import com.yyon.grapplinghook.items.GrapplehookItem; 7 | import com.yyon.grapplinghook.items.upgrades.BaseUpgradeItem; 8 | import com.yyon.grapplinghook.utils.GrappleCustomization; 9 | import com.yyon.grapplinghook.utils.Vec; 10 | import net.minecraft.core.BlockPos; 11 | import net.minecraft.nbt.CompoundTag; 12 | import net.minecraft.nbt.ListTag; 13 | import net.minecraft.network.chat.Component; 14 | import net.minecraft.world.InteractionHand; 15 | import net.minecraft.world.InteractionResult; 16 | import net.minecraft.world.entity.player.Player; 17 | import net.minecraft.world.entity.projectile.FireworkRocketEntity; 18 | import net.minecraft.world.item.FireworkRocketItem; 19 | import net.minecraft.world.item.Item; 20 | import net.minecraft.world.item.ItemStack; 21 | import net.minecraft.world.item.Items; 22 | import net.minecraft.world.item.enchantment.Enchantment; 23 | import net.minecraft.world.item.enchantment.EnchantmentHelper; 24 | import net.minecraft.world.item.enchantment.Enchantments; 25 | import net.minecraft.world.level.Level; 26 | import net.minecraft.world.level.block.BaseEntityBlock; 27 | import net.minecraft.world.level.block.Block; 28 | import net.minecraft.world.level.block.RenderShape; 29 | import net.minecraft.world.level.block.entity.BlockEntity; 30 | import net.minecraft.world.level.block.state.BlockState; 31 | import net.minecraft.world.level.material.Material; 32 | import net.minecraft.world.level.storage.loot.LootContext; 33 | import net.minecraft.world.level.storage.loot.parameters.LootContextParams; 34 | import net.minecraft.world.phys.BlockHitResult; 35 | import org.jetbrains.annotations.Nullable; 36 | 37 | import java.util.ArrayList; 38 | import java.util.List; 39 | import java.util.Map; 40 | 41 | public class BlockGrappleModifier extends BaseEntityBlock { 42 | 43 | public BlockGrappleModifier() { 44 | super(Block.Properties.of(Material.STONE).strength(1.5f)); 45 | } 46 | 47 | 48 | @Nullable 49 | @Override 50 | public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 51 | return new TileEntityGrappleModifier(pos,state); 52 | } 53 | 54 | @Override 55 | public List getDrops(BlockState state, LootContext.Builder lootctx) { 56 | List drops = new ArrayList(); 57 | drops.add(new ItemStack(this.asItem())); 58 | BlockEntity ent = lootctx.getOptionalParameter(LootContextParams.BLOCK_ENTITY); 59 | if (ent == null || !(ent instanceof TileEntityGrappleModifier)) { 60 | return drops; 61 | } 62 | TileEntityGrappleModifier tileent = (TileEntityGrappleModifier) ent; 63 | 64 | for (GrappleCustomization.upgradeCategories category : GrappleCustomization.upgradeCategories.values()) { 65 | if (tileent.unlockedCategories.containsKey(category) && tileent.unlockedCategories.get(category)) { 66 | drops.add(new ItemStack(category.getItem())); 67 | } 68 | } 69 | return drops; 70 | } 71 | 72 | @Override 73 | public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player playerIn, InteractionHand hand, BlockHitResult raytraceresult) { 74 | ItemStack helditemstack = playerIn.getItemInHand(InteractionHand.MAIN_HAND); 75 | Item helditem = helditemstack.getItem(); 76 | 77 | if (helditem instanceof BaseUpgradeItem) { 78 | if (!worldIn.isClientSide) { 79 | BlockEntity ent = worldIn.getBlockEntity(pos); 80 | TileEntityGrappleModifier tileent = (TileEntityGrappleModifier) ent; 81 | 82 | GrappleCustomization.upgradeCategories category = ((BaseUpgradeItem) helditem).category; 83 | if (category != null) { 84 | if (tileent.isUnlocked(category)) { 85 | playerIn.sendSystemMessage(Component.literal("Already has upgrade: " + category.getName())); 86 | } else { 87 | if (!playerIn.isCreative()) { 88 | playerIn.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); 89 | } 90 | 91 | tileent.unlockCategory(category); 92 | 93 | playerIn.sendSystemMessage(Component.literal("Applied upgrade: " + category.getName())); 94 | } 95 | } 96 | } 97 | } else if (helditem instanceof GrapplehookItem) { 98 | if (!worldIn.isClientSide) { 99 | BlockEntity ent = worldIn.getBlockEntity(pos); 100 | TileEntityGrappleModifier tileent = (TileEntityGrappleModifier) ent; 101 | 102 | GrappleCustomization custom = tileent.customization; 103 | CommonSetup.grapplingHookItem.get().setCustomOnServer(helditemstack, custom, playerIn); 104 | 105 | playerIn.sendSystemMessage(Component.literal("Applied configuration")); 106 | } 107 | } else if (helditem == Items.DIAMOND_BOOTS) { 108 | if (!worldIn.isClientSide) { 109 | if (GrappleConfig.getConf().longfallboots.longfallbootsrecipe) { 110 | boolean gaveitem = false; 111 | if (helditemstack.isEnchanted()) { 112 | Map enchantments = EnchantmentHelper.getEnchantments(helditemstack); 113 | if (enchantments.containsKey(Enchantments.FALL_PROTECTION)) { 114 | if (enchantments.get(Enchantments.FALL_PROTECTION) >= 4) { 115 | ItemStack newitemstack = new ItemStack(CommonSetup.longFallBootsItem.get()); 116 | EnchantmentHelper.setEnchantments(enchantments, newitemstack); 117 | playerIn.setItemInHand(InteractionHand.MAIN_HAND, newitemstack); 118 | gaveitem = true; 119 | } 120 | } 121 | } 122 | if (!gaveitem) { 123 | playerIn.sendSystemMessage(Component.literal("Right click with diamond boots enchanted with feather falling IV to get long fall boots")); 124 | } 125 | } else { 126 | playerIn.sendSystemMessage(Component.literal("Making long fall boots this way was disabled in the config. It probably has been replaced by a crafting recipe.")); 127 | } 128 | } 129 | } else if (helditem == Items.DIAMOND) { 130 | this.easterEgg(state, worldIn, pos, playerIn, hand, raytraceresult); 131 | } else { 132 | if (worldIn.isClientSide) { 133 | BlockEntity ent = worldIn.getBlockEntity(pos); 134 | TileEntityGrappleModifier tileent = (TileEntityGrappleModifier) ent; 135 | 136 | ClientProxyInterface.proxy.openModifierScreen(tileent); 137 | } 138 | } 139 | return InteractionResult.SUCCESS; 140 | } 141 | 142 | @Override 143 | public RenderShape getRenderShape(BlockState pState) { 144 | return RenderShape.MODEL; 145 | } 146 | 147 | public void easterEgg(BlockState state, Level worldIn, BlockPos pos, Player playerIn, InteractionHand hand, 148 | BlockHitResult raytraceresult) { 149 | int spacing = 3; 150 | Vec[] positions = new Vec[] {new Vec(-spacing*2, 0, 0), new Vec(-spacing, 0, 0), new Vec(0, 0, 0), new Vec(spacing, 0, 0), new Vec(2*spacing, 0, 0)}; 151 | int[] colors = new int[] {0x5bcffa, 0xf5abb9, 0xffffff, 0xf5abb9, 0x5bcffa}; 152 | 153 | for (int i = 0; i < positions.length; i++) { 154 | Vec newpos = new Vec(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5); 155 | Vec toPlayer = Vec.positionVec(playerIn).sub(newpos); 156 | double angle = toPlayer.length() == 0 ? 0 : toPlayer.getYaw(); 157 | newpos = newpos.add(positions[i].rotateYaw(Math.toRadians(angle))); 158 | 159 | CompoundTag explosion = new CompoundTag(); 160 | explosion.putByte("Type", (byte) FireworkRocketItem.Shape.SMALL_BALL.getId()); 161 | explosion.putBoolean("Trail", true); 162 | explosion.putBoolean("Flicker", false); 163 | explosion.putIntArray("Colors", new int[] {colors[i]}); 164 | explosion.putIntArray("FadeColors", new int[] {}); 165 | ListTag list = new ListTag(); 166 | list.add(explosion); 167 | CompoundTag fireworks = new CompoundTag(); 168 | fireworks.put("Explosions", list); 169 | CompoundTag nbt = new CompoundTag(); 170 | nbt.put("Fireworks", fireworks); 171 | ItemStack stack = new ItemStack(Items.FIREWORK_ROCKET); 172 | stack.setTag(nbt); 173 | FireworkRocketEntity firework = new FireworkRocketEntity(worldIn, playerIn, newpos.x, newpos.y, newpos.z, stack); 174 | CompoundTag fireworksave = new CompoundTag(); 175 | firework.addAdditionalSaveData(fireworksave); 176 | fireworksave.putInt("LifeTime", 15); 177 | firework.readAdditionalSaveData(fireworksave); 178 | worldIn.addFreshEntity(firework); 179 | } 180 | } 181 | 182 | 183 | } 184 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/blocks/modifierblock/TileEntityGrappleModifier.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.blocks.modifierblock; 2 | 3 | import com.yyon.grapplinghook.common.CommonSetup; 4 | import com.yyon.grapplinghook.network.GrappleModifierMessage; 5 | import com.yyon.grapplinghook.utils.GrappleCustomization; 6 | import com.yyon.grapplinghook.utils.GrappleCustomization.upgradeCategories; 7 | import net.minecraft.core.BlockPos; 8 | import net.minecraft.nbt.CompoundTag; 9 | import net.minecraft.network.Connection; 10 | import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; 11 | import net.minecraft.world.level.block.entity.BlockEntity; 12 | import net.minecraft.world.level.block.state.BlockState; 13 | 14 | import javax.annotation.Nullable; 15 | import java.util.HashMap; 16 | 17 | public class TileEntityGrappleModifier extends BlockEntity { 18 | public HashMap unlockedCategories = new HashMap(); 19 | public GrappleCustomization customization; 20 | 21 | public TileEntityGrappleModifier(BlockPos pos, BlockState state) { 22 | super(CommonSetup.grappleModifierTileEntityType.get(),pos,state); 23 | this.customization = new GrappleCustomization(); 24 | } 25 | 26 | public void unlockCategory(upgradeCategories category) { 27 | unlockedCategories.put(category, true); 28 | this.sendUpdates(); 29 | this.getLevel().sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 3); 30 | } 31 | 32 | public void setCustomizationClient(GrappleCustomization customization) { 33 | this.customization = customization; 34 | CommonSetup.network.sendToServer(new GrappleModifierMessage(this.worldPosition, this.customization)); 35 | this.sendUpdates(); 36 | } 37 | 38 | public void setCustomizationServer(GrappleCustomization customization) { 39 | this.customization = customization; 40 | this.sendUpdates(); 41 | } 42 | 43 | private void sendUpdates() { 44 | this.setChanged(); 45 | } 46 | 47 | public boolean isUnlocked(upgradeCategories category) { 48 | return this.unlockedCategories.containsKey(category) && this.unlockedCategories.get(category); 49 | } 50 | 51 | @Override 52 | public void saveAdditional(CompoundTag nbtTagCompound) { 53 | super.saveAdditional(nbtTagCompound); 54 | 55 | CompoundTag unlockedNBT = nbtTagCompound.getCompound("unlocked"); 56 | 57 | for (GrappleCustomization.upgradeCategories category : GrappleCustomization.upgradeCategories.values()) { 58 | String num = String.valueOf(category.toInt()); 59 | boolean unlocked = this.isUnlocked(category); 60 | 61 | unlockedNBT.putBoolean(num, unlocked); 62 | } 63 | 64 | nbtTagCompound.put("unlocked", unlockedNBT); 65 | nbtTagCompound.put("customization", this.customization.writeNBT()); 66 | } 67 | 68 | @Override 69 | public void load(CompoundTag parentNBTTagCompound) { 70 | super.load(parentNBTTagCompound); // The super call is required to load the tiles location 71 | 72 | CompoundTag unlockedNBT = parentNBTTagCompound.getCompound("unlocked"); 73 | 74 | for (GrappleCustomization.upgradeCategories category : GrappleCustomization.upgradeCategories.values()) { 75 | String num = String.valueOf(category.toInt()); 76 | boolean unlocked = unlockedNBT.getBoolean(num); 77 | 78 | this.unlockedCategories.put(category, unlocked); 79 | } 80 | 81 | CompoundTag custom = parentNBTTagCompound.getCompound("customization"); 82 | this.customization.loadNBT(custom); 83 | } 84 | 85 | 86 | // When the world loads from disk, the server needs to send the TileEntity information to the client 87 | // it uses getUpdatePacket(), getUpdateTag(), onDataPacket(), and handleUpdateTag() to do this: 88 | // getUpdatePacket() and onDataPacket() are used for one-at-a-time TileEntity updates 89 | // getUpdateTag() and handleUpdateTag() are used by vanilla to collate together into a single chunk update packet 90 | // Not really required for this example since we only use the timer on the client, but included anyway for illustration 91 | @Override 92 | @Nullable 93 | public ClientboundBlockEntityDataPacket getUpdatePacket() 94 | { 95 | CompoundTag nbtTagCompound = new CompoundTag(); 96 | this.saveAdditional(nbtTagCompound); 97 | int tileEntityType = 42; // arbitrary number; only used for vanilla TileEntities. You can use it, or not, as you want. 98 | return ClientboundBlockEntityDataPacket.create(this); 99 | } 100 | 101 | @Override 102 | public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { 103 | BlockState blockState = this.level.getBlockState(this.worldPosition); 104 | this.load(pkt.getTag()); // read from the nbt in the packet 105 | } 106 | 107 | /* Creates a tag containing all of the TileEntity information, used by vanilla to transmit from server to client 108 | */ 109 | @Override 110 | public CompoundTag getUpdateTag() 111 | { 112 | CompoundTag nbtTagCompound = new CompoundTag(); 113 | this.saveAdditional(nbtTagCompound); 114 | return nbtTagCompound; 115 | } 116 | 117 | @Override 118 | public void handleUpdateTag(CompoundTag tag) { 119 | this.load(tag); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/client/ClientEventHandlers.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.client; 2 | 3 | import com.yyon.grapplinghook.common.CommonSetup; 4 | import com.yyon.grapplinghook.config.GrappleConfig; 5 | import com.yyon.grapplinghook.controllers.AirfrictionController; 6 | import com.yyon.grapplinghook.controllers.ForcefieldController; 7 | import com.yyon.grapplinghook.controllers.GrappleController; 8 | import com.yyon.grapplinghook.items.KeypressItem; 9 | import com.yyon.grapplinghook.utils.Vec; 10 | import net.minecraft.client.Minecraft; 11 | import net.minecraft.client.player.Input; 12 | import net.minecraft.core.BlockPos; 13 | import net.minecraft.world.InteractionHand; 14 | import net.minecraft.world.entity.player.Player; 15 | import net.minecraft.world.item.Item; 16 | import net.minecraft.world.item.ItemStack; 17 | import net.minecraft.world.level.block.state.BlockState; 18 | import net.minecraft.world.phys.BlockHitResult; 19 | import net.minecraft.world.phys.HitResult; 20 | import net.minecraftforge.client.event.ClientPlayerNetworkEvent.LoggingOut; 21 | import net.minecraftforge.client.event.InputEvent.Key; 22 | import net.minecraftforge.client.event.MovementInputUpdateEvent; 23 | import net.minecraftforge.client.event.ViewportEvent.ComputeCameraAngles; 24 | import net.minecraftforge.common.MinecraftForge; 25 | import net.minecraftforge.event.TickEvent; 26 | import net.minecraftforge.event.level.BlockEvent.BreakEvent; 27 | import net.minecraftforge.eventbus.api.EventPriority; 28 | import net.minecraftforge.eventbus.api.SubscribeEvent; 29 | 30 | public class ClientEventHandlers { 31 | public static ClientEventHandlers instance = null; 32 | 33 | public ClientEventHandlers() { 34 | MinecraftForge.EVENT_BUS.register(this); 35 | } 36 | 37 | public boolean prevKeys[] = {false, false, false, false, false}; 38 | 39 | @SubscribeEvent 40 | public void onClientTick(TickEvent.ClientTickEvent event) { 41 | Player player = Minecraft.getInstance().player; 42 | if (player != null) { 43 | if (!Minecraft.getInstance().isPaused()) { 44 | ClientControllerManager.instance.onClientTick(player); 45 | 46 | if (Minecraft.getInstance().screen == null) { 47 | // keep in same order as enum from KeypressItem 48 | boolean keys[] = {ClientSetup.key_enderlaunch.isDown(), ClientSetup.key_leftthrow.isDown(), ClientSetup.key_rightthrow.isDown(), ClientSetup.key_boththrow.isDown(), ClientSetup.key_rocket.isDown()}; 49 | 50 | for (int i = 0; i < keys.length; i++) { 51 | boolean iskeydown = keys[i]; 52 | boolean prevkey = prevKeys[i]; 53 | 54 | if (iskeydown != prevkey) { 55 | KeypressItem.Keys key = KeypressItem.Keys.values()[i]; 56 | 57 | ItemStack stack = getKeypressStack(player); 58 | if (stack != null) { 59 | if (!isLookingAtModifierBlock(player)) { 60 | if (iskeydown) { 61 | ((KeypressItem) stack.getItem()).onCustomKeyDown(stack, player, key, true); 62 | } else { 63 | ((KeypressItem) stack.getItem()).onCustomKeyUp(stack, player, key, true); 64 | } 65 | } 66 | } 67 | } 68 | 69 | prevKeys[i] = iskeydown; 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | @SubscribeEvent 77 | public void onBlockBreak(BreakEvent event) { 78 | if (event.getPos() != null) { 79 | if (ClientControllerManager.controllerPos.containsKey(event.getPos())) { 80 | GrappleController control = ClientControllerManager.controllerPos.get(event.getPos()); 81 | 82 | control.unattach(); 83 | 84 | ClientControllerManager.controllerPos.remove(event.getPos()); 85 | } 86 | } 87 | } 88 | 89 | @SubscribeEvent 90 | public void onPlayerLoggedOutEvent(LoggingOut e) { 91 | GrappleConfig.setServerOptions(null); 92 | } 93 | 94 | @SubscribeEvent 95 | public void onKeyInputEvent(Key event) { 96 | Player player = Minecraft.getInstance().player; 97 | if (!Minecraft.getInstance().isRunning() || player == null) { 98 | return; 99 | } 100 | 101 | GrappleController controller = null; 102 | if (ClientControllerManager.controllers.containsKey(player.getId())) { 103 | controller = ClientControllerManager.controllers.get(player.getId()); 104 | } 105 | 106 | if (Minecraft.getInstance().options.keyJump.isDown()) { 107 | if (controller != null) { 108 | if (controller instanceof AirfrictionController && ((AirfrictionController) controller).wasSliding) { 109 | controller.slidingJump(); 110 | } 111 | } 112 | } 113 | 114 | ClientControllerManager.instance.checkSlide(Minecraft.getInstance().player); 115 | } 116 | 117 | @SubscribeEvent(priority=EventPriority.LOW) 118 | public void onInputUpdate(MovementInputUpdateEvent event) { 119 | Player player = Minecraft.getInstance().player; 120 | if (!Minecraft.getInstance().isRunning() || player == null) { 121 | return; 122 | } 123 | 124 | int id = player.getId(); 125 | if (ClientControllerManager.controllers.containsKey(id)) { 126 | Input input = event.getInput(); 127 | GrappleController control = ClientControllerManager.controllers.get(id); 128 | control.receivePlayerMovementMessage(input.leftImpulse, input.forwardImpulse, input.jumping, input.shiftKeyDown); 129 | 130 | boolean overrideMovement = true; 131 | if (Minecraft.getInstance().player.isOnGround()) { 132 | if (!(control instanceof AirfrictionController) && !(control instanceof ForcefieldController)) { 133 | overrideMovement = false; 134 | } 135 | } 136 | 137 | if (overrideMovement) { 138 | input.jumping = false; 139 | input.down = false; 140 | input.up = false; 141 | input.left = false; 142 | input.right = false; 143 | input.forwardImpulse = 0; 144 | input.leftImpulse = 0; 145 | // input.sneak = false; // fix alternate throw angles 146 | } 147 | } 148 | } 149 | 150 | public float currentCameraTilt = 0; 151 | 152 | @SubscribeEvent 153 | public void onCameraSetup(ComputeCameraAngles event) { 154 | Player player = Minecraft.getInstance().player; 155 | if (!Minecraft.getInstance().isRunning() || player == null) { 156 | return; 157 | } 158 | 159 | int id = player.getId(); 160 | int targetCameraTilt = 0; 161 | if (ClientControllerManager.controllers.containsKey(id)) { 162 | GrappleController controller = ClientControllerManager.controllers.get(id); 163 | if (controller instanceof AirfrictionController) { 164 | AirfrictionController afcontroller = (AirfrictionController) controller; 165 | if (afcontroller.wasWallrunning) { 166 | Vec walldirection = afcontroller.getWallDirection(); 167 | if (walldirection != null) { 168 | Vec lookdirection = Vec.lookVec(player); 169 | int dir = lookdirection.cross(walldirection).y > 0 ? 1 : -1; 170 | targetCameraTilt = dir; 171 | } 172 | } 173 | } 174 | } 175 | 176 | if (currentCameraTilt != targetCameraTilt) { 177 | float cameraDiff = targetCameraTilt - currentCameraTilt; 178 | if (cameraDiff != 0) { 179 | float anim_s = GrappleConfig.getClientConf().camera.wallrun_camera_animation_s; 180 | float speed = (anim_s == 0) ? 9999 : 1.0f / (anim_s * 20.0f); 181 | if (speed > Math.abs(cameraDiff)) { 182 | currentCameraTilt = targetCameraTilt; 183 | } else { 184 | currentCameraTilt += speed * (cameraDiff > 0 ? 1 : -1); 185 | } 186 | } 187 | } 188 | 189 | if (currentCameraTilt != 0) { 190 | event.setRoll(event.getRoll() + currentCameraTilt*GrappleConfig.getClientConf().camera.wallrun_camera_tilt_degrees); 191 | } 192 | } 193 | 194 | public ItemStack getKeypressStack(Player player) { 195 | if (player != null) { 196 | ItemStack stack = player.getItemInHand(InteractionHand.MAIN_HAND); 197 | if (stack != null) { 198 | Item item = stack.getItem(); 199 | if (item instanceof KeypressItem) { 200 | return stack; 201 | } 202 | } 203 | 204 | stack = player.getItemInHand(InteractionHand.OFF_HAND); 205 | if (stack != null) { 206 | Item item = stack.getItem(); 207 | if (item instanceof KeypressItem) { 208 | return stack; 209 | } 210 | } 211 | } 212 | return null; 213 | } 214 | 215 | public boolean isLookingAtModifierBlock(Player player) { 216 | HitResult raytraceresult = Minecraft.getInstance().hitResult; 217 | if (raytraceresult != null && raytraceresult.getType() == HitResult.Type.BLOCK) { 218 | BlockHitResult bray = (BlockHitResult) raytraceresult; 219 | BlockPos pos = bray.getBlockPos(); 220 | BlockState state = player.level.getBlockState(pos); 221 | 222 | return (state.getBlock() == CommonSetup.grappleModifierBlock.get()); 223 | } 224 | return false; 225 | } 226 | 227 | 228 | } 229 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/client/ClientProxyInterface.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.client; 2 | 3 | import com.yyon.grapplinghook.blocks.modifierblock.TileEntityGrappleModifier; 4 | import com.yyon.grapplinghook.controllers.GrappleController; 5 | import com.yyon.grapplinghook.network.BaseMessageClient; 6 | import com.yyon.grapplinghook.utils.GrappleCustomization; 7 | import com.yyon.grapplinghook.utils.Vec; 8 | import net.minecraft.core.BlockPos; 9 | import net.minecraft.core.NonNullList; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.world.entity.Entity; 12 | import net.minecraft.world.entity.player.Player; 13 | import net.minecraft.world.item.CreativeModeTab; 14 | import net.minecraft.world.item.ItemStack; 15 | import net.minecraft.world.level.Level; 16 | import net.minecraftforge.fml.DistExecutor; 17 | import net.minecraftforge.network.NetworkEvent; 18 | 19 | public abstract class ClientProxyInterface { 20 | public static ClientProxyInterface proxy = DistExecutor.unsafeRunForDist(() -> ClientProxy::new, () -> () -> null); 21 | 22 | public abstract void resetLauncherTime(int playerid); 23 | 24 | public abstract void launchPlayer(Player player); 25 | 26 | public enum McKeys { 27 | keyBindUseItem, 28 | keyBindForward, 29 | keyBindLeft, 30 | keyBindBack, 31 | keyBindRight, 32 | keyBindJump, 33 | keyBindSneak, 34 | keyBindAttack 35 | } 36 | public abstract String getKeyname(McKeys keyenum); 37 | 38 | public abstract boolean isKeyDown(McKeys keybindjump); 39 | 40 | public abstract void openModifierScreen(TileEntityGrappleModifier tileent); 41 | 42 | public abstract String localize(String string); 43 | 44 | public abstract void startRocket(Player player, GrappleCustomization custom); 45 | 46 | public abstract void updateRocketRegen(double rocket_active_time, double rocket_refuel_ratio); 47 | 48 | public abstract double getRocketFunctioning(); 49 | 50 | public abstract boolean isWallRunning(Entity entity, Vec motion); 51 | 52 | public abstract boolean isSliding(Entity entity, Vec motion); 53 | 54 | public abstract GrappleController createControl(int id, int hookEntityId, int entityid, Level world, Vec pos, BlockPos blockpos, GrappleCustomization custom); 55 | 56 | public abstract void playSlideSound(Entity entity); 57 | 58 | public abstract void playWallrunJumpSound(Entity entity); 59 | 60 | public abstract void playDoubleJumpSound(Entity entity); 61 | 62 | public abstract void onMessageReceivedClient(BaseMessageClient baseMessage, NetworkEvent.Context ctx); 63 | 64 | public abstract void fillGrappleVariants(CreativeModeTab tab, NonNullList items); 65 | 66 | public enum GrappleKeys { 67 | key_boththrow, 68 | key_leftthrow, 69 | key_rightthrow, 70 | key_motoronoff, 71 | key_jumpanddetach, 72 | key_slow, 73 | key_climb, 74 | key_climbup, 75 | key_climbdown, 76 | key_enderlaunch, 77 | key_rocket, 78 | key_slide 79 | } 80 | public abstract boolean isKeyDown(GrappleKeys key); 81 | 82 | public abstract GrappleController unregisterController(int entityId); 83 | 84 | public abstract double getTimeSinceLastRopeJump(Level world); 85 | 86 | public abstract void resetRopeJumpTime(Level level); 87 | 88 | public abstract boolean isMovingSlowly(Entity entity); 89 | 90 | public abstract void playSound(ResourceLocation loc, float volume); 91 | 92 | public abstract int getWallrunTicks(); 93 | 94 | public abstract void setWallrunTicks(int newWallrunTicks); 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/client/ClientSetup.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.client; 2 | 3 | import com.mojang.blaze3d.platform.InputConstants; 4 | import com.yyon.grapplinghook.common.CommonSetup; 5 | import com.yyon.grapplinghook.controllers.AirfrictionController; 6 | import com.yyon.grapplinghook.controllers.ForcefieldController; 7 | import com.yyon.grapplinghook.entities.grapplehook.GrapplehookEntity; 8 | import com.yyon.grapplinghook.entities.grapplehook.RenderGrapplehookEntity; 9 | import net.minecraft.client.KeyMapping; 10 | import net.minecraft.client.multiplayer.ClientLevel; 11 | import net.minecraft.client.renderer.entity.EntityRenderer; 12 | import net.minecraft.client.renderer.entity.EntityRendererProvider; 13 | import net.minecraft.client.renderer.entity.EntityRenderers; 14 | import net.minecraft.client.renderer.item.ItemProperties; 15 | import net.minecraft.client.renderer.item.ItemPropertyFunction; 16 | import net.minecraft.resources.ResourceLocation; 17 | import net.minecraft.world.entity.LivingEntity; 18 | import net.minecraft.world.item.ItemStack; 19 | import net.minecraftforge.api.distmarker.Dist; 20 | import net.minecraftforge.client.ConfigScreenHandler; 21 | import net.minecraftforge.client.event.RegisterKeyMappingsEvent; 22 | import net.minecraftforge.eventbus.api.SubscribeEvent; 23 | import net.minecraftforge.fml.ModLoadingContext; 24 | import net.minecraftforge.fml.common.Mod; 25 | import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; 26 | import org.lwjgl.glfw.GLFW; 27 | 28 | import javax.annotation.Nullable; 29 | import java.util.ArrayList; 30 | 31 | @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) 32 | public class ClientSetup { 33 | public static ClientSetup instance = null; 34 | 35 | public ClientSetup() { 36 | } 37 | 38 | public CrosshairRenderer crosshairRenderer; 39 | public ClientEventHandlers clientEventHandlers; 40 | public ClientControllerManager clientControllerManager; 41 | 42 | public static ArrayList keyBindings = new ArrayList(); 43 | 44 | public static KeyMapping createKeyBinding(KeyMapping k) { 45 | keyBindings.add(k); 46 | return k; 47 | } 48 | 49 | public static KeyMapping key_boththrow = createKeyBinding(new NonConflictingKeyBinding("key.boththrow.desc", InputConstants.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_2, "key.grapplemod.category")); 50 | public static KeyMapping key_leftthrow = createKeyBinding(new NonConflictingKeyBinding("key.leftthrow.desc", InputConstants.UNKNOWN.getValue(), "key.grapplemod.category")); 51 | public static KeyMapping key_rightthrow = createKeyBinding(new NonConflictingKeyBinding("key.rightthrow.desc", InputConstants.UNKNOWN.getValue(), "key.grapplemod.category")); 52 | public static KeyMapping key_motoronoff = createKeyBinding(new NonConflictingKeyBinding("key.motoronoff.desc", GLFW.GLFW_KEY_LEFT_SHIFT, "key.grapplemod.category")); 53 | public static KeyMapping key_jumpanddetach = createKeyBinding(new NonConflictingKeyBinding("key.jumpanddetach.desc", GLFW.GLFW_KEY_SPACE, "key.grapplemod.category")); 54 | public static KeyMapping key_slow = createKeyBinding(new NonConflictingKeyBinding("key.slow.desc", GLFW.GLFW_KEY_LEFT_SHIFT, "key.grapplemod.category")); 55 | public static KeyMapping key_climb = createKeyBinding(new NonConflictingKeyBinding("key.climb.desc", GLFW.GLFW_KEY_LEFT_SHIFT, "key.grapplemod.category")); 56 | public static KeyMapping key_climbup = createKeyBinding(new NonConflictingKeyBinding("key.climbup.desc", InputConstants.UNKNOWN.getValue(), "key.grapplemod.category")); 57 | public static KeyMapping key_climbdown = createKeyBinding(new NonConflictingKeyBinding("key.climbdown.desc", InputConstants.UNKNOWN.getValue(), "key.grapplemod.category")); 58 | public static KeyMapping key_enderlaunch = createKeyBinding(new NonConflictingKeyBinding("key.enderlaunch.desc", InputConstants.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_1, "key.grapplemod.category")); 59 | public static KeyMapping key_rocket = createKeyBinding(new NonConflictingKeyBinding("key.rocket.desc", InputConstants.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_1, "key.grapplemod.category")); 60 | public static KeyMapping key_slide = createKeyBinding(new NonConflictingKeyBinding("key.slide.desc", GLFW.GLFW_KEY_LEFT_SHIFT, "key.grapplemod.category")); 61 | 62 | @SubscribeEvent 63 | public static void clientSetup(final FMLClientSetupEvent event) { 64 | instance = new ClientSetup(); 65 | instance.onClientSetup(); 66 | } 67 | 68 | private static class GrapplehookEntityRenderFactory implements EntityRendererProvider { 69 | @Override 70 | public EntityRenderer create(Context manager) { 71 | return new RenderGrapplehookEntity<>(manager, CommonSetup.grapplingHookItem.get()); 72 | } 73 | } 74 | 75 | @SubscribeEvent 76 | public static void registerKeyBinding(RegisterKeyMappingsEvent event){ 77 | keyBindings.forEach(event::register); 78 | } 79 | 80 | public void onClientSetup() { 81 | // // register all the key bindings 82 | // for (int i = 0; i < keyBindings.size(); ++i) 83 | // { 84 | // ClientRegistry.registerKeyBinding(keyBindings.get(i)); 85 | // } 86 | 87 | EntityRenderers.register(CommonSetup.grapplehookEntityType.get(), new GrapplehookEntityRenderFactory()); 88 | 89 | ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, 90 | () -> new ConfigScreenHandler.ConfigScreenFactory(((ClientProxy) ClientProxyInterface.proxy)::onConfigScreen)); 91 | 92 | this.registerPropertyOverride(); 93 | 94 | crosshairRenderer = new CrosshairRenderer(); 95 | clientControllerManager = new ClientControllerManager(); 96 | clientEventHandlers = new ClientEventHandlers(); 97 | } 98 | 99 | public void registerPropertyOverride() { 100 | ItemProperties.register(CommonSetup.grapplingHookItem.get(), new ResourceLocation("rocket"), new ItemPropertyFunction() { 101 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 102 | return CommonSetup.grapplingHookItem.get().getPropertyRocket(stack, world, entity) ? 1 : 0; 103 | } 104 | }); 105 | ItemProperties.register(CommonSetup.grapplingHookItem.get(), new ResourceLocation("double"), new ItemPropertyFunction() { 106 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 107 | return CommonSetup.grapplingHookItem.get().getPropertyDouble(stack, world, entity) ? 1 : 0; 108 | } 109 | }); 110 | ItemProperties.register(CommonSetup.grapplingHookItem.get(), new ResourceLocation("motor"), new ItemPropertyFunction() { 111 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 112 | return CommonSetup.grapplingHookItem.get().getPropertyMotor(stack, world, entity) ? 1 : 0; 113 | } 114 | }); 115 | ItemProperties.register(CommonSetup.grapplingHookItem.get(), new ResourceLocation("smart"), new ItemPropertyFunction() { 116 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 117 | return CommonSetup.grapplingHookItem.get().getPropertySmart(stack, world, entity) ? 1 : 0; 118 | } 119 | }); 120 | ItemProperties.register(CommonSetup.grapplingHookItem.get(), new ResourceLocation("enderstaff"), new ItemPropertyFunction() { 121 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 122 | return CommonSetup.grapplingHookItem.get().getPropertyEnderstaff(stack, world, entity) ? 1 : 0; 123 | } 124 | }); 125 | ItemProperties.register(CommonSetup.grapplingHookItem.get(), new ResourceLocation("magnet"), new ItemPropertyFunction() { 126 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 127 | return CommonSetup.grapplingHookItem.get().getPropertyMagnet(stack, world, entity) ? 1 : 0; 128 | } 129 | }); 130 | ItemProperties.register(CommonSetup.grapplingHookItem.get(), new ResourceLocation("attached"), new ItemPropertyFunction() { 131 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 132 | if (entity == null) {return 0;} 133 | return (ClientControllerManager.controllers.containsKey(entity.getId()) && !(ClientControllerManager.controllers.get(entity.getId()) instanceof AirfrictionController)) ? 1 : 0; 134 | } 135 | }); 136 | ItemProperties.register(CommonSetup.forcefieldItem.get(), new ResourceLocation("attached"), new ItemPropertyFunction() { 137 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 138 | if (entity == null) {return 0;} 139 | return (ClientControllerManager.controllers.containsKey(entity.getId()) && ClientControllerManager.controllers.get(entity.getId()) instanceof ForcefieldController) ? 1 : 0; 140 | } 141 | }); 142 | ItemProperties.register(CommonSetup.grapplingHookItem.get(), new ResourceLocation("hook"), new ItemPropertyFunction() { 143 | public float call(ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int seed) { 144 | return CommonSetup.grapplingHookItem.get().getPropertyHook(stack, world, entity) ? 1 : 0; 145 | } 146 | }); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/client/CrosshairRenderer.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.client; 2 | 3 | import com.mojang.blaze3d.platform.GlStateManager; 4 | import com.mojang.blaze3d.platform.Window; 5 | import com.mojang.blaze3d.systems.RenderSystem; 6 | import com.mojang.blaze3d.vertex.*; 7 | import com.yyon.grapplinghook.common.CommonSetup; 8 | import com.yyon.grapplinghook.items.GrapplehookItem; 9 | import com.yyon.grapplinghook.utils.GrappleCustomization; 10 | import net.minecraft.client.Minecraft; 11 | import net.minecraft.client.Options; 12 | import net.minecraft.client.player.LocalPlayer; 13 | import net.minecraft.client.renderer.GameRenderer; 14 | import net.minecraft.world.InteractionHand; 15 | import net.minecraft.world.item.ItemStack; 16 | import net.minecraftforge.client.event.RenderGuiOverlayEvent; 17 | import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay; 18 | import net.minecraftforge.common.MinecraftForge; 19 | import net.minecraftforge.eventbus.api.SubscribeEvent; 20 | 21 | public class CrosshairRenderer { 22 | public Minecraft mc; 23 | 24 | float zLevel = -90.0F; 25 | 26 | public CrosshairRenderer() { 27 | MinecraftForge.EVENT_BUS.register(this); 28 | this.mc = Minecraft.getInstance(); 29 | } 30 | 31 | @SubscribeEvent 32 | public void onRenderGameOverlayPost(RenderGuiOverlayEvent.Post event) { 33 | PoseStack mStack = event.getPoseStack(); 34 | 35 | Options gamesettings = this.mc.options; 36 | if (!gamesettings.getCameraType().isFirstPerson()) return; 37 | if (this.mc.player.isSpectator()) return; 38 | if (gamesettings.renderDebug && !gamesettings.hideGui && !this.mc.player.isReducedDebugInfo() && !gamesettings.reducedDebugInfo().get()) return; 39 | 40 | if (event.getOverlay() == VanillaGuiOverlay.CROSSHAIR.type()) { 41 | LocalPlayer player = this.mc.player; 42 | ItemStack grapplehookItemStack = null; 43 | if ((player.getItemInHand(InteractionHand.MAIN_HAND) != null && player.getItemInHand(InteractionHand.MAIN_HAND).getItem() instanceof GrapplehookItem)) { 44 | grapplehookItemStack = player.getItemInHand(InteractionHand.MAIN_HAND); 45 | } else if ((player.getItemInHand(InteractionHand.OFF_HAND) != null && player.getItemInHand(InteractionHand.OFF_HAND).getItem() instanceof GrapplehookItem)) { 46 | grapplehookItemStack = player.getItemInHand(InteractionHand.OFF_HAND); 47 | } 48 | 49 | if (grapplehookItemStack != null) { 50 | GrappleCustomization custom = ((GrapplehookItem) CommonSetup.grapplingHookItem.get()).getCustomization(grapplehookItemStack); 51 | double angle = Math.toRadians(custom.angle); 52 | double verticalangle = Math.toRadians(custom.verticalthrowangle); 53 | if (player.isCrouching()) { 54 | angle = Math.toRadians(custom.sneakingangle); 55 | verticalangle = Math.toRadians(custom.sneakingverticalthrowangle); 56 | } 57 | 58 | if (!custom.doublehook) { 59 | angle = 0; 60 | } 61 | 62 | Window resolution = event.getWindow(); 63 | int w = resolution.getGuiScaledWidth(); 64 | int h = resolution.getGuiScaledHeight(); 65 | 66 | double fov = Math.toRadians(gamesettings.fov().get()); 67 | fov *= player.getFieldOfViewModifier(); 68 | double l = ((double) h/2) / Math.tan(fov/2); 69 | 70 | if (!((verticalangle == 0) && (!custom.doublehook || angle == 0))) { 71 | int offset = (int) (Math.tan(angle) * l); 72 | int verticaloffset = (int) (-Math.tan(verticalangle) * l); 73 | 74 | drawCrosshair(mStack, w / 2 + offset, h / 2 + verticaloffset); 75 | if (angle != 0) { 76 | drawCrosshair(mStack, w / 2 - offset, h / 2 + verticaloffset); 77 | } 78 | } 79 | 80 | if (custom.rocket && custom.rocket_vertical_angle != 0) { 81 | int verticaloffset = (int) (-Math.tan(Math.toRadians(custom.rocket_vertical_angle)) * l); 82 | drawCrosshair(mStack, w / 2, h / 2 + verticaloffset); 83 | } 84 | } 85 | 86 | double rocketFuel = ClientControllerManager.instance.rocketFuel; 87 | 88 | if (rocketFuel < 1) { 89 | Window resolution = event.getWindow(); 90 | int w = resolution.getGuiScaledWidth(); 91 | int h = resolution.getGuiScaledHeight(); 92 | 93 | int totalbarlength = w / 8; 94 | 95 | RenderSystem.getModelViewStack().pushPose(); 96 | // RenderSystem.disableDepthTest(); 97 | // RenderSystem.disableTexture(); 98 | 99 | this.drawRect(w / 2 - totalbarlength / 2, h * 3 / 4, totalbarlength, 2, 50, 100); 100 | this.drawRect(w / 2 - totalbarlength / 2, h * 3 / 4, (int) (totalbarlength * rocketFuel), 2, 200, 255); 101 | 102 | // RenderSystem.enableTexture(); 103 | RenderSystem.getModelViewStack().popPose(); 104 | } 105 | } 106 | } 107 | 108 | private void drawCrosshair(PoseStack mStack, int x, int y) { 109 | RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.ONE_MINUS_DST_COLOR, GlStateManager.DestFactor.ONE_MINUS_SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); 110 | Minecraft.getInstance().gui.blit(mStack, (int) (x - (15.0F/2)), (int) (y - (15.0F/2)), 0, 0, 15, 15); 111 | RenderSystem.defaultBlendFunc(); 112 | } 113 | 114 | public void drawTexturedModalRect(int x, int y, int textureX, int textureY, int width, int height) 115 | { 116 | float f = 0.00390625F; 117 | float f1 = 0.00390625F; 118 | Tesselator tessellator = RenderSystem.renderThreadTesselator(); 119 | BufferBuilder bufferbuilder = tessellator.getBuilder(); 120 | bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); 121 | bufferbuilder.vertex((double)(x + 0), (double)(y + height), (double)this.zLevel).uv(((float)(textureX + 0) * f), ((float)(textureY + height) * f1)).endVertex(); 122 | bufferbuilder.vertex((double)(x + width), (double)(y + height), (double)this.zLevel).uv(((float)(textureX + width) * f), ((float)(textureY + height) * f1)).endVertex(); 123 | bufferbuilder.vertex((double)(x + width), (double)(y + 0), (double)this.zLevel).uv(((float)(textureX + width) * f), ((float)(textureY + 0) * f1)).endVertex(); 124 | bufferbuilder.vertex((double)(x + 0), (double)(y + 0), (double)this.zLevel).uv(((float)(textureX + 0) * f), ((float)(textureY + 0) * f1)).endVertex(); 125 | tessellator.end(); 126 | } 127 | public void drawRect(int x, int y, int width, int height, int g, int a) 128 | { 129 | RenderSystem.setShader(GameRenderer::getPositionColorShader); 130 | BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder(); 131 | // GL11.glLineWidth(4.0F); 132 | bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); 133 | bufferbuilder.vertex((double)(x + 0), (double)(y + height), (double)this.zLevel).color(g, g, g, a).endVertex(); 134 | bufferbuilder.vertex((double)(x + width), (double)(y + height), (double)this.zLevel).color(g, g, g, a).endVertex(); 135 | bufferbuilder.vertex((double)(x + width), (double)(y + 0), (double)this.zLevel).color(g, g, g, a).endVertex(); 136 | bufferbuilder.vertex((double)(x + 0), (double)(y + 0), (double)this.zLevel).color(g, g, g, a).endVertex(); 137 | // bufferbuilder.end(); 138 | BufferUploader.drawWithShader(bufferbuilder.end()); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/client/NonConflictingKeyBinding.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.client; 2 | 3 | import com.mojang.blaze3d.platform.InputConstants; 4 | import net.minecraft.client.KeyMapping; 5 | import net.minecraftforge.client.settings.IKeyConflictContext; 6 | 7 | public class NonConflictingKeyBinding extends KeyMapping { 8 | public NonConflictingKeyBinding(String description, int keyCode, String category) { 9 | super(description, keyCode, category); 10 | this.setNonConflict(); 11 | } 12 | 13 | // boolean isActive = false; 14 | private void setNonConflict() { 15 | this.setKeyConflictContext(new IKeyConflictContext() { 16 | @Override 17 | public boolean isActive() { 18 | return false; 19 | } 20 | @Override 21 | public boolean conflicts(IKeyConflictContext other) { 22 | return false; 23 | } 24 | }); 25 | } 26 | 27 | public NonConflictingKeyBinding(String description, InputConstants.Type type, int keyCode, String category) { 28 | super(description, type, keyCode, category); 29 | this.setNonConflict(); 30 | } 31 | 32 | public boolean same(KeyMapping p_197983_1_) { 33 | return false; 34 | } 35 | public boolean hasKeyCodeModifierConflict(KeyMapping other) { 36 | return true; 37 | } 38 | 39 | public boolean isDown = false; 40 | 41 | public boolean isDown() { 42 | return isDown; 43 | } 44 | 45 | @Override 46 | public void setDown(boolean value) { 47 | this.isDown = value; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/common/CommonEventHandlers.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.common; 2 | 3 | import com.yyon.grapplinghook.config.GrappleConfig; 4 | import com.yyon.grapplinghook.entities.grapplehook.GrapplehookEntity; 5 | import com.yyon.grapplinghook.items.GrapplehookItem; 6 | import com.yyon.grapplinghook.items.LongFallBoots; 7 | import com.yyon.grapplinghook.network.GrappleDetachMessage; 8 | import com.yyon.grapplinghook.network.LoggedInMessage; 9 | import com.yyon.grapplinghook.server.ServerControllerManager; 10 | import com.yyon.grapplinghook.utils.GrapplemodUtils; 11 | import me.shedaniel.autoconfig.AutoConfig; 12 | import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer; 13 | import net.minecraft.server.level.ServerPlayer; 14 | import net.minecraft.world.InteractionHand; 15 | import net.minecraft.world.damagesource.DamageSource; 16 | import net.minecraft.world.entity.Entity; 17 | import net.minecraft.world.entity.player.Player; 18 | import net.minecraft.world.item.Item; 19 | import net.minecraft.world.item.ItemStack; 20 | import net.minecraftforge.common.MinecraftForge; 21 | import net.minecraftforge.event.entity.living.LivingDeathEvent; 22 | import net.minecraftforge.event.entity.living.LivingFallEvent; 23 | import net.minecraftforge.event.entity.living.LivingHurtEvent; 24 | import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent; 25 | import net.minecraftforge.event.level.BlockEvent.BreakEvent; 26 | import net.minecraftforge.event.server.ServerStartedEvent; 27 | import net.minecraftforge.eventbus.api.SubscribeEvent; 28 | import net.minecraftforge.network.PacketDistributor; 29 | 30 | import java.util.HashSet; 31 | 32 | public class CommonEventHandlers { 33 | public CommonEventHandlers() { 34 | MinecraftForge.EVENT_BUS.register(this); 35 | 36 | AutoConfig.register(GrappleConfig.class, Toml4jConfigSerializer::new); 37 | } 38 | 39 | @SubscribeEvent 40 | public void onBlockBreak(BreakEvent event) { 41 | Player player = event.getPlayer(); 42 | if (player != null) { 43 | ItemStack stack = player.getItemInHand(InteractionHand.MAIN_HAND); 44 | if (stack != null) { 45 | Item item = stack.getItem(); 46 | if (item instanceof GrapplehookItem) { 47 | event.setCanceled(true); 48 | return; 49 | } 50 | } 51 | } 52 | } 53 | 54 | @SubscribeEvent 55 | public void onLivingDeath(LivingDeathEvent event) { 56 | if (!event.getEntity().level.isClientSide) { 57 | Entity entity = event.getEntity(); 58 | int id = entity.getId(); 59 | boolean isconnected = ServerControllerManager.allGrapplehookEntities.containsKey(id); 60 | if (isconnected) { 61 | HashSet grapplehookEntities = ServerControllerManager.allGrapplehookEntities.get(id); 62 | for (GrapplehookEntity hookEntity: grapplehookEntities) { 63 | hookEntity.removeServer(); 64 | } 65 | grapplehookEntities.clear(); 66 | 67 | ServerControllerManager.attached.remove(id); 68 | 69 | if (GrapplehookItem.grapplehookEntitiesLeft.containsKey(entity)) { 70 | GrapplehookItem.grapplehookEntitiesLeft.remove(entity); 71 | } 72 | if (GrapplehookItem.grapplehookEntitiesRight.containsKey(entity)) { 73 | GrapplehookItem.grapplehookEntitiesRight.remove(entity); 74 | } 75 | 76 | GrapplemodUtils.sendToCorrectClient(new GrappleDetachMessage(id), id, entity.level); 77 | } 78 | } 79 | } 80 | 81 | @SubscribeEvent 82 | public void onLivingHurtEvent(LivingHurtEvent event) { 83 | if (event.getEntity() != null && event.getEntity() instanceof Player) { 84 | Player player = (Player)event.getEntity(); 85 | 86 | for (ItemStack armor : player.getArmorSlots()) { 87 | if (armor != null && armor.getItem() instanceof LongFallBoots) 88 | { 89 | if (event.getSource() == DamageSource.FLY_INTO_WALL) { 90 | // this cancels the fall event so you take no damage 91 | event.setCanceled(true); 92 | } 93 | } 94 | } 95 | } 96 | } 97 | 98 | @SubscribeEvent 99 | public void onLivingFallEvent(LivingFallEvent event) { 100 | if (event.getEntity() != null && event.getEntity() instanceof Player) { 101 | Player player = (Player)event.getEntity(); 102 | 103 | for (ItemStack armor : player.getArmorSlots()) { 104 | if (armor != null && armor.getItem() instanceof LongFallBoots) 105 | { 106 | // this cancels the fall event so you take no damage 107 | event.setCanceled(true); 108 | } 109 | } 110 | } 111 | } 112 | 113 | @SubscribeEvent 114 | public void onServerStart(ServerStartedEvent event) { 115 | if (GrappleConfig.getConf().other.override_allowflight) { 116 | event.getServer().setFlightAllowed(true); 117 | } 118 | } 119 | 120 | @SubscribeEvent 121 | public void onPlayerLoggedInEvent(PlayerLoggedInEvent e) { 122 | if (e.getEntity() instanceof ServerPlayer) { 123 | CommonSetup.network.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) e.getEntity()), new LoggedInMessage(GrappleConfig.getConf())); 124 | } else { 125 | System.out.println("Not an PlayerEntityMP"); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/common/CommonSetup.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.common; 2 | 3 | import com.yyon.grapplinghook.blocks.modifierblock.BlockGrappleModifier; 4 | import com.yyon.grapplinghook.blocks.modifierblock.TileEntityGrappleModifier; 5 | import com.yyon.grapplinghook.enchantments.DoublejumpEnchantment; 6 | import com.yyon.grapplinghook.enchantments.SlidingEnchantment; 7 | import com.yyon.grapplinghook.enchantments.WallrunEnchantment; 8 | import com.yyon.grapplinghook.entities.grapplehook.GrapplehookEntity; 9 | import com.yyon.grapplinghook.items.EnderStaffItem; 10 | import com.yyon.grapplinghook.items.ForcefieldItem; 11 | import com.yyon.grapplinghook.items.GrapplehookItem; 12 | import com.yyon.grapplinghook.items.LongFallBoots; 13 | import com.yyon.grapplinghook.items.upgrades.*; 14 | import com.yyon.grapplinghook.network.*; 15 | import net.minecraft.resources.ResourceLocation; 16 | import net.minecraft.world.entity.EntityType; 17 | import net.minecraft.world.entity.MobCategory; 18 | import net.minecraft.world.item.*; 19 | import net.minecraft.world.item.enchantment.Enchantment; 20 | import net.minecraft.world.level.block.Block; 21 | import net.minecraft.world.level.block.entity.BlockEntityType; 22 | import net.minecraftforge.api.distmarker.Dist; 23 | import net.minecraftforge.api.distmarker.OnlyIn; 24 | import net.minecraftforge.eventbus.api.SubscribeEvent; 25 | import net.minecraftforge.fml.common.Mod; 26 | import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; 27 | import net.minecraftforge.network.NetworkDirection; 28 | import net.minecraftforge.network.NetworkRegistry; 29 | import net.minecraftforge.network.simple.SimpleChannel; 30 | import net.minecraftforge.registries.DeferredRegister; 31 | import net.minecraftforge.registries.ForgeRegistries; 32 | import net.minecraftforge.registries.RegisterEvent; 33 | import net.minecraftforge.registries.RegistryObject; 34 | 35 | import java.util.Optional; 36 | import java.util.function.Supplier; 37 | 38 | @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) 39 | public class CommonSetup { 40 | public static final CreativeModeTab tabGrapplemod = new CreativeModeTab("grapplemod") { 41 | @OnlyIn(Dist.CLIENT) 42 | public ItemStack makeIcon() { 43 | return new ItemStack(grapplingHookItem.get()); 44 | } 45 | }; 46 | public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, "grapplemod"); 47 | public static final DeferredRegister ENCHANTMENTS = DeferredRegister.create(ForgeRegistries.ENCHANTMENTS, "grapplemod"); 48 | public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, "grapplemod"); 49 | public static final DeferredRegister> BLOCK_ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, "grapplemod"); 50 | public static final DeferredRegister> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, "grapplemod"); 51 | 52 | public static RegistryObject grapplingHookItem = ITEMS.register("grapplinghook", GrapplehookItem::new); 53 | public static RegistryObject enderStaffItem = ITEMS.register("launcheritem", EnderStaffItem::new); 54 | public static RegistryObject forcefieldItem = ITEMS.register("repeller", ForcefieldItem::new); 55 | 56 | public static RegistryObject baseUpgradeItem = ITEMS.register("baseupgradeitem", BaseUpgradeItem::new); 57 | public static RegistryObject doubleUpgradeItem = ITEMS.register("doubleupgradeitem", DoubleUpgradeItem::new); 58 | public static RegistryObject forcefieldUpgradeItem = ITEMS.register("forcefieldupgradeitem", ForcefieldUpgradeItem::new); 59 | public static RegistryObject magnetUpgradeItem = ITEMS.register("magnetupgradeitem", MagnetUpgradeItem::new); 60 | public static RegistryObject motorUpgradeItem = ITEMS.register("motorupgradeitem", MotorUpgradeItem::new); 61 | public static RegistryObject ropeUpgradeItem = ITEMS.register("ropeupgradeitem", RopeUpgradeItem::new); 62 | public static RegistryObject staffUpgradeItem = ITEMS.register("staffupgradeitem", StaffUpgradeItem::new); 63 | public static RegistryObject swingUpgradeItem = ITEMS.register("swingupgradeitem", SwingUpgradeItem::new); 64 | public static RegistryObject throwUpgradeItem = ITEMS.register("throwupgradeitem", ThrowUpgradeItem::new); 65 | public static RegistryObject limitsUpgradeItem = ITEMS.register("limitsupgradeitem", LimitsUpgradeItem::new); 66 | public static RegistryObject rocketUpgradeItem = ITEMS.register("rocketupgradeitem", RocketUpgradeItem::new); 67 | 68 | public static RegistryObject longFallBootsItem = ITEMS.register("longfallboots", ()->new LongFallBoots(ArmorMaterials.DIAMOND, 3)); 69 | 70 | public static RegistryObject wallrunEnchantment = ENCHANTMENTS.register("wallrunenchantment", WallrunEnchantment::new); 71 | public static RegistryObject doubleJumpEnchantment = ENCHANTMENTS.register("doublejumpenchantment", DoublejumpEnchantment::new); 72 | public static RegistryObject slidingEnchantment = ENCHANTMENTS.register("slidingenchantment", SlidingEnchantment::new); 73 | 74 | public static SimpleChannel network; // used to transmit your network messages 75 | public static final ResourceLocation simpleChannelRL = new ResourceLocation("grapplemod", "channel"); 76 | 77 | public static RegistryObject grappleModifierBlock = BLOCKS.register("block_grapple_modifier", BlockGrappleModifier::new); 78 | public static RegistryObject grappleModifierBlockItem = ITEMS.register("block_grapple_modifier", ()->new BlockItem(grappleModifierBlock.get(),new Item.Properties().stacksTo(64).tab(tabGrapplemod))); 79 | 80 | 81 | 82 | public static CommonEventHandlers eventHandlers = new CommonEventHandlers();; 83 | 84 | @SubscribeEvent 85 | public static void init(FMLCommonSetupEvent event) { 86 | network = NetworkRegistry.newSimpleChannel(simpleChannelRL, () -> "1.0", 87 | version -> true, 88 | version -> true); 89 | int id = 0; 90 | network.registerMessage(id++, PlayerMovementMessage.class, PlayerMovementMessage::encode, PlayerMovementMessage::new, PlayerMovementMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_SERVER)); 91 | network.registerMessage(id++, GrappleEndMessage.class, GrappleEndMessage::encode, GrappleEndMessage::new, GrappleEndMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_SERVER)); 92 | network.registerMessage(id++, GrappleModifierMessage.class, GrappleModifierMessage::encode, GrappleModifierMessage::new, GrappleModifierMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_SERVER)); 93 | network.registerMessage(id++, KeypressMessage.class, KeypressMessage::encode, KeypressMessage::new, KeypressMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_SERVER)); 94 | network.registerMessage(id++, GrappleAttachMessage.class, GrappleAttachMessage::encode, GrappleAttachMessage::new, GrappleAttachMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); 95 | network.registerMessage(id++, GrappleDetachMessage.class, GrappleDetachMessage::encode, GrappleDetachMessage::new, GrappleDetachMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); 96 | network.registerMessage(id++, DetachSingleHookMessage.class, DetachSingleHookMessage::encode, DetachSingleHookMessage::new, DetachSingleHookMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); 97 | network.registerMessage(id++, GrappleAttachPosMessage.class, GrappleAttachPosMessage::encode, GrappleAttachPosMessage::new, GrappleAttachPosMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); 98 | network.registerMessage(id++, SegmentMessage.class, SegmentMessage::encode, SegmentMessage::new, SegmentMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); 99 | network.registerMessage(id++, LoggedInMessage.class, LoggedInMessage::encode, LoggedInMessage::new, LoggedInMessage::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); 100 | } 101 | 102 | 103 | 104 | public static RegistryObject> grappleModifierTileEntityType = BLOCK_ENTITY_TYPES.register("block_grapple_modifier",()->BlockEntityType.Builder.of(TileEntityGrappleModifier::new, grappleModifierBlock.get()).build(null)); 105 | 106 | public static RegistryObject> grapplehookEntityType = ENTITY_TYPES.register("grapplehook", ()->EntityType.Builder.of(GrapplehookEntity::new, MobCategory.MISC) 107 | .sized(0.25F, 0.25F) 108 | .build("grapplemod:grapplehook")); 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/config/GrappleConfigUtils.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.config; 2 | 3 | import net.minecraft.resources.ResourceLocation; 4 | import net.minecraft.world.item.enchantment.Enchantment.Rarity; 5 | import net.minecraft.world.level.block.Block; 6 | import net.minecraftforge.registries.ForgeRegistries; 7 | 8 | import java.util.HashSet; 9 | 10 | public class GrappleConfigUtils { 11 | private static boolean anyBlocks = true; 12 | private static HashSet grapplingBlocks; 13 | private static boolean removeBlocks = false; 14 | private static HashSet grapplingBreaksBlocks; 15 | private static boolean anyBreakBlocks = false; 16 | 17 | public static HashSet stringToBlocks(String s) { 18 | HashSet blocks = new HashSet(); 19 | 20 | if (s.equals("") || s.equals("none") || s.equals("any")) { 21 | return blocks; 22 | } 23 | 24 | String[] blockstr = s.split(","); 25 | 26 | for(String str:blockstr){ 27 | str = str.trim(); 28 | String modid; 29 | String name; 30 | if (str.contains(":")) { 31 | String[] splitstr = str.split(":"); 32 | modid = splitstr[0]; 33 | name = splitstr[1]; 34 | } else { 35 | modid = "minecraft"; 36 | name = str; 37 | } 38 | 39 | Block b = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(modid, name)); 40 | 41 | blocks.add(b); 42 | } 43 | 44 | return blocks; 45 | } 46 | 47 | public static void updateGrapplingBlocks() { 48 | String s = GrappleConfig.getConf().grapplinghook.blocks.grapplingBlocks; 49 | if (s.equals("any") || s.equals("")) { 50 | s = GrappleConfig.getConf().grapplinghook.blocks.grapplingNonBlocks; 51 | if (s.equals("none") || s.equals("")) { 52 | anyBlocks = true; 53 | } else { 54 | anyBlocks = false; 55 | removeBlocks = true; 56 | } 57 | } else { 58 | anyBlocks = false; 59 | removeBlocks = false; 60 | } 61 | 62 | if (!anyBlocks) { 63 | grapplingBlocks = stringToBlocks(s); 64 | } 65 | 66 | grapplingBreaksBlocks = stringToBlocks(GrappleConfig.getConf().grapplinghook.blocks.grappleBreakBlocks); 67 | anyBreakBlocks = grapplingBreaksBlocks.size() != 0; 68 | 69 | } 70 | 71 | private static String prevGrapplingBlocks = null; 72 | private static String prevGrapplingNonBlocks = null; 73 | public static boolean attachesBlock(Block block) { 74 | if (!GrappleConfig.getConf().grapplinghook.blocks.grapplingBlocks.equals(prevGrapplingBlocks) || !GrappleConfig.getConf().grapplinghook.blocks.grapplingNonBlocks.equals(prevGrapplingNonBlocks)) { 75 | updateGrapplingBlocks(); 76 | } 77 | 78 | if (anyBlocks) { 79 | return true; 80 | } 81 | 82 | boolean inlist = grapplingBlocks.contains(block); 83 | 84 | if (removeBlocks) { 85 | return !inlist; 86 | } else { 87 | return inlist; 88 | } 89 | } 90 | 91 | private static String prevGrapplingBreakBlocks = null; 92 | public static boolean breaksBlock(Block block) { 93 | if (!GrappleConfig.getConf().grapplinghook.blocks.grappleBreakBlocks.equals(prevGrapplingBreakBlocks)) { 94 | updateGrapplingBlocks(); 95 | } 96 | 97 | if (!anyBreakBlocks) { 98 | return false; 99 | } 100 | 101 | return grapplingBreaksBlocks.contains(block); 102 | } 103 | 104 | public static Rarity getRarityFromInt(int rarity_int) { 105 | Rarity[] rarities = (new Rarity[] {Rarity.VERY_RARE, Rarity.RARE, Rarity.UNCOMMON, Rarity.COMMON}); 106 | if (rarity_int < 0) {rarity_int = 0;} 107 | if (rarity_int >= rarities.length) {rarity_int = rarities.length-1;} 108 | return rarities[rarity_int]; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/controllers/AirfrictionController.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.controllers; 2 | 3 | import com.yyon.grapplinghook.client.ClientProxyInterface; 4 | import com.yyon.grapplinghook.config.GrappleConfig; 5 | import com.yyon.grapplinghook.utils.GrappleCustomization; 6 | import com.yyon.grapplinghook.utils.Vec; 7 | import net.minecraft.world.entity.Entity; 8 | import net.minecraft.world.entity.LivingEntity; 9 | import net.minecraft.world.level.Level; 10 | 11 | /* 12 | * This file is part of GrappleMod. 13 | 14 | GrappleMod is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | 19 | GrappleMod is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | 24 | You should have received a copy of the GNU General Public License 25 | along with GrappleMod. If not, see . 26 | */ 27 | 28 | public class AirfrictionController extends GrappleController { 29 | public double playerMovementMult = 0.5; 30 | 31 | public int ignoreGroundCounter = 0; 32 | public boolean wasSliding = false; 33 | public boolean wasWallrunning = false; 34 | public boolean wasRocket = false; 35 | public boolean firstTickSinceCreated = true; 36 | 37 | public AirfrictionController(int grapplehookEntityId, int entityId, Level world, Vec pos, int id, GrappleCustomization custom) { 38 | super(grapplehookEntityId, entityId, world, pos, id, custom); 39 | } 40 | 41 | @Override 42 | public void updatePlayerPos() { 43 | Entity entity = this.entity; 44 | 45 | if (entity == null) {return;} 46 | 47 | if (entity.getVehicle() != null) { 48 | this.unattach(); 49 | this.updateServerPos(); 50 | return; 51 | } 52 | 53 | Vec additionalmotion = new Vec(0,0,0); 54 | 55 | if (GrappleConfig.getConf().other.dont_override_movement_in_air && !entity.isOnGround() && !wasSliding && !wasWallrunning && !wasRocket && !firstTickSinceCreated) { 56 | motion = Vec.motionVec(entity); 57 | this.unattach(); 58 | return; 59 | } 60 | 61 | if (this.attached) { 62 | boolean issliding = ClientProxyInterface.proxy.isSliding(entity, motion); 63 | 64 | if (issliding && !wasSliding) { 65 | playSlideSound(); 66 | } 67 | 68 | if (this.ignoreGroundCounter <= 0) { 69 | this.normalGround(issliding); 70 | this.normalCollisions(issliding); 71 | } 72 | 73 | this.applyAirFriction(); 74 | 75 | if (this.entity.isInWater() || this.entity.isInLava()) { 76 | this.unattach(); 77 | return; 78 | } 79 | 80 | boolean doesrocket = false; 81 | if (this.custom != null) { 82 | if (this.custom.rocket) { 83 | Vec rocket = this.rocket(entity); 84 | this.motion.add_ip(rocket); 85 | if (rocket.length() > 0) { 86 | doesrocket = true; 87 | } 88 | } 89 | } 90 | 91 | if (issliding) { 92 | this.applySlidingFriction(); 93 | } 94 | 95 | boolean wallrun = this.applyWallrun(); 96 | 97 | if (!issliding && !wasSliding) { 98 | if (wallrun) { 99 | motion = motion.removeAlong(new Vec(0,1,0)); 100 | if (this.wallDirection != null) { 101 | motion = motion.removeAlong(this.wallDirection); 102 | } 103 | 104 | Vec new_movement = this.playerMovement.changeLen(GrappleConfig.getConf().enchantments.wallrun.wallrun_speed*1.5); 105 | if (this.wallDirection != null) { 106 | new_movement = new_movement.removeAlong(this.wallDirection); 107 | } 108 | if (new_movement.length() > GrappleConfig.getConf().enchantments.wallrun.wallrun_speed) { 109 | new_movement.changeLen_ip(GrappleConfig.getConf().enchantments.wallrun.wallrun_speed); 110 | } 111 | Vec current_motion_along = this.motion.removeAlong(new Vec(0,1,0)); 112 | Vec new_motion_along = this.motion.add(new_movement).removeAlong(new Vec(0,1,0)); 113 | if (this.wallDirection != null) { 114 | current_motion_along = current_motion_along.removeAlong(this.wallDirection); 115 | new_motion_along = new_motion_along.removeAlong(this.wallDirection); 116 | } 117 | if (current_motion_along.length() <= GrappleConfig.getConf().enchantments.wallrun.wallrun_max_speed || current_motion_along.dot(new_movement) < 0) { 118 | motion.add_ip(new_movement); 119 | if (new_motion_along.length() > GrappleConfig.getConf().enchantments.wallrun.wallrun_max_speed) { 120 | this.motion.changeLen_ip(GrappleConfig.getConf().enchantments.wallrun.wallrun_max_speed); 121 | } 122 | } 123 | additionalmotion.add_ip(wallrunPressAgainstWall()); 124 | } else { 125 | double max_motion = GrappleConfig.getConf().other.airstrafe_max_speed; 126 | double accel = GrappleConfig.getConf().other.airstrafe_acceleration; 127 | Vec motion_horizontal = motion.removeAlong(new Vec(0,1,0)); 128 | double prev_motion = motion_horizontal.length(); 129 | Vec new_motion_horizontal = motion_horizontal.add(this.playerMovement.changeLen(accel)); 130 | double angle = motion_horizontal.angle(new_motion_horizontal); 131 | if (new_motion_horizontal.length() > max_motion && new_motion_horizontal.length() > prev_motion) { 132 | double ninety_deg = Math.PI / 2; 133 | double new_max_motion = max_motion; 134 | if (angle < ninety_deg && prev_motion > max_motion) { 135 | new_max_motion = prev_motion + ((max_motion - prev_motion) * (angle / (Math.PI / 2))); 136 | } 137 | new_motion_horizontal.changeLen_ip(new_max_motion); 138 | } 139 | motion.x = new_motion_horizontal.x; 140 | motion.z = new_motion_horizontal.z; 141 | } 142 | } 143 | 144 | if (entity instanceof LivingEntity) { 145 | LivingEntity entityliving = (LivingEntity) entity; 146 | if (entityliving.isFallFlying()) { 147 | this.unattach(); 148 | } 149 | } 150 | 151 | Vec gravity = new Vec(0, -0.05, 0); 152 | 153 | if (!wallrun) { 154 | motion.add_ip(gravity); 155 | } 156 | 157 | Vec newmotion; 158 | 159 | newmotion = motion.add(additionalmotion); 160 | 161 | // if (wallrun) { 162 | // newmotion.add_ip(this.walldirection); 163 | // } 164 | 165 | newmotion.setMotion(entity); 166 | 167 | this.updateServerPos(); 168 | 169 | if (entity.isOnGround()) { 170 | if (!issliding) { 171 | if (!wallrun) { 172 | if (!doesrocket) { 173 | if (ignoreGroundCounter <= 0) { 174 | this.unattach(); 175 | } 176 | } else { 177 | motion = Vec.motionVec(entity); 178 | } 179 | } 180 | } 181 | } 182 | if (ignoreGroundCounter > 0) { ignoreGroundCounter--; } 183 | 184 | wasSliding = issliding; 185 | wasWallrunning = wallrun; 186 | wasRocket = doesrocket; 187 | firstTickSinceCreated = false; 188 | } 189 | } 190 | 191 | public void receiveEnderLaunch(double x, double y, double z) { 192 | super.receiveEnderLaunch(x, y, z); 193 | this.ignoreGroundCounter = 2; 194 | } 195 | 196 | public void slidingJump() { 197 | super.slidingJump(); 198 | this.ignoreGroundCounter = 2; 199 | } 200 | 201 | public void playSlideSound() { 202 | ClientProxyInterface.proxy.playSlideSound(this.entity); 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/controllers/ForcefieldController.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.controllers; 2 | 3 | import com.yyon.grapplinghook.utils.Vec; 4 | import net.minecraft.world.entity.Entity; 5 | import net.minecraft.world.level.Level; 6 | 7 | public class ForcefieldController extends GrappleController { 8 | public ForcefieldController(int grapplehookEntityId, int entityId, Level world, Vec pos, int id) { 9 | super(grapplehookEntityId, entityId, world, pos, id, null); 10 | 11 | this.playerMovementMult = 1; 12 | } 13 | 14 | public void updatePlayerPos() { 15 | Entity entity = this.entity; 16 | 17 | if (this.attached) { 18 | if(entity != null) { 19 | if (true) { 20 | this.normalGround(false); 21 | this.normalCollisions(false); 22 | // this.applyAirFriction(); 23 | 24 | Vec playerpos = Vec.positionVec(entity); 25 | 26 | // double dist = oldspherevec.length(); 27 | 28 | if (playerSneak) { 29 | motion.mult_ip(0.95); 30 | } 31 | applyPlayerMovement(); 32 | 33 | Vec blockpush = checkRepel(playerpos, entity.level); 34 | blockpush.mult_ip(0.5); 35 | blockpush = new Vec(blockpush.x*0.5, blockpush.y*2, blockpush.z*0.5); 36 | this.motion.add_ip(blockpush); 37 | 38 | if (!entity.isOnGround()) { 39 | motion.add_ip(0, -0.05, 0); 40 | } 41 | 42 | motion.setMotion(this.entity); 43 | 44 | this.updateServerPos(); 45 | } 46 | } 47 | } 48 | }} 49 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/enchantments/DoublejumpEnchantment.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.enchantments; 2 | 3 | import com.yyon.grapplinghook.config.GrappleConfig; 4 | import com.yyon.grapplinghook.config.GrappleConfigUtils; 5 | import net.minecraft.world.entity.EquipmentSlot; 6 | import net.minecraft.world.item.enchantment.Enchantment; 7 | import net.minecraft.world.item.enchantment.EnchantmentCategory; 8 | 9 | public class DoublejumpEnchantment extends Enchantment { 10 | public DoublejumpEnchantment() { 11 | super(GrappleConfigUtils.getRarityFromInt(GrappleConfig.getConf().enchantments.doublejump.enchant_rarity_double_jump), EnchantmentCategory.ARMOR_FEET, new EquipmentSlot[] {EquipmentSlot.FEET}); 12 | } 13 | 14 | @Override 15 | public int getMinCost(int enchantmentLevel) 16 | { 17 | return 1; 18 | } 19 | 20 | @Override 21 | public int getMaxCost(int enchantmentLevel) 22 | { 23 | return this.getMinCost(enchantmentLevel) + 40; 24 | } 25 | 26 | @Override 27 | public int getMaxLevel() 28 | { 29 | return 1; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/enchantments/SlidingEnchantment.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.enchantments; 2 | 3 | import com.yyon.grapplinghook.config.GrappleConfig; 4 | import com.yyon.grapplinghook.config.GrappleConfigUtils; 5 | import net.minecraft.world.entity.EquipmentSlot; 6 | import net.minecraft.world.item.enchantment.Enchantment; 7 | import net.minecraft.world.item.enchantment.EnchantmentCategory; 8 | 9 | public class SlidingEnchantment extends Enchantment { 10 | public SlidingEnchantment() { 11 | super(GrappleConfigUtils.getRarityFromInt(GrappleConfig.getConf().enchantments.slide.enchant_rarity_sliding), EnchantmentCategory.ARMOR_FEET, new EquipmentSlot[] {EquipmentSlot.FEET}); 12 | } 13 | 14 | @Override 15 | public int getMinCost(int enchantmentLevel) 16 | { 17 | return 1; 18 | } 19 | 20 | @Override 21 | public int getMaxCost(int enchantmentLevel) 22 | { 23 | return this.getMinCost(enchantmentLevel) + 40; 24 | } 25 | 26 | @Override 27 | public int getMaxLevel() 28 | { 29 | return 1; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/enchantments/WallrunEnchantment.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.enchantments; 2 | 3 | import com.yyon.grapplinghook.config.GrappleConfig; 4 | import com.yyon.grapplinghook.config.GrappleConfigUtils; 5 | import net.minecraft.world.entity.EquipmentSlot; 6 | import net.minecraft.world.item.enchantment.Enchantment; 7 | import net.minecraft.world.item.enchantment.EnchantmentCategory; 8 | 9 | public class WallrunEnchantment extends Enchantment { 10 | public WallrunEnchantment() { 11 | super(GrappleConfigUtils.getRarityFromInt(GrappleConfig.getConf().enchantments.wallrun.enchant_rarity_wallrun), EnchantmentCategory.ARMOR_FEET, new EquipmentSlot[] {EquipmentSlot.FEET}); 12 | } 13 | 14 | @Override 15 | public int getMinCost(int enchantmentLevel) 16 | { 17 | return 1; 18 | } 19 | 20 | @Override 21 | public int getMaxCost(int enchantmentLevel) 22 | { 23 | return this.getMinCost(enchantmentLevel) + 40; 24 | } 25 | 26 | @Override 27 | public int getMaxLevel() 28 | { 29 | return 1; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/grapplemod.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook; 2 | 3 | import com.yyon.grapplinghook.common.CommonSetup; 4 | import net.minecraftforge.eventbus.api.IEventBus; 5 | import net.minecraftforge.fml.common.Mod; 6 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 7 | import org.apache.logging.log4j.LogManager; 8 | import org.apache.logging.log4j.Logger; 9 | 10 | /* 11 | * This file is part of GrappleMod. 12 | 13 | GrappleMod is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | GrappleMod is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with GrappleMod. If not, see . 25 | */ 26 | 27 | //TODO 28 | // Pull mobs 29 | // Attach 2 things together 30 | // wallrun on diagonal walls 31 | // smart motor acts erratically when aiming above hook 32 | // key events 33 | 34 | @Mod(grapplemod.MODID) 35 | public class grapplemod { 36 | public static final String MODID = "grapplemod"; 37 | 38 | public static final String VERSION = "1.16.5-v12.2"; 39 | 40 | public static final Logger LOGGER = LogManager.getLogger(); 41 | 42 | public grapplemod() { 43 | IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); 44 | CommonSetup.BLOCKS.register(bus); 45 | CommonSetup.ITEMS.register(bus); 46 | CommonSetup.ENTITY_TYPES.register(bus); 47 | CommonSetup.ENCHANTMENTS.register(bus); 48 | CommonSetup.BLOCK_ENTITY_TYPES.register(bus); 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/integrations/JeiIntegrations.java: -------------------------------------------------------------------------------- 1 | /* 2 | package com.yyon.grapplinghook.integrations; 3 | 4 | import com.mojang.blaze3d.vertex.PoseStack; 5 | import com.yyon.grapplinghook.client.ClientProxyInterface; 6 | import com.yyon.grapplinghook.common.CommonSetup; 7 | import com.yyon.grapplinghook.config.GrappleConfig; 8 | import com.yyon.grapplinghook.utils.GrappleCustomization; 9 | import mezz.jei.api.IModPlugin; 10 | import mezz.jei.api.JeiPlugin; 11 | import mezz.jei.api.constants.VanillaTypes; 12 | import mezz.jei.api.gui.IRecipeLayout; 13 | import mezz.jei.api.gui.drawable.IDrawable; 14 | import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; 15 | import mezz.jei.api.ingredients.IIngredients; 16 | import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter; 17 | import mezz.jei.api.ingredients.subtypes.UidContext; 18 | import mezz.jei.api.recipe.category.IRecipeCategory; 19 | import mezz.jei.api.registration.IRecipeCatalystRegistration; 20 | import mezz.jei.api.registration.IRecipeCategoryRegistration; 21 | import mezz.jei.api.registration.IRecipeRegistration; 22 | import mezz.jei.api.registration.ISubtypeRegistration; 23 | import net.minecraft.client.Minecraft; 24 | import net.minecraft.resources.ResourceLocation; 25 | import net.minecraft.world.item.ItemStack; 26 | import net.minecraft.world.item.Items; 27 | import net.minecraft.world.item.enchantment.Enchantments; 28 | 29 | import java.util.Arrays; 30 | 31 | @JeiPlugin 32 | public class JeiIntegrations implements IModPlugin { 33 | 34 | @Override 35 | public ResourceLocation getPluginUid() { 36 | return new ResourceLocation("grapplemod", "jeiintegration"); 37 | } 38 | 39 | @Override 40 | public void registerItemSubtypes(ISubtypeRegistration registration) { 41 | IModPlugin.super.registerItemSubtypes(registration); 42 | 43 | registration.registerSubtypeInterpreter(CommonSetup.grapplingHookItem, new IIngredientSubtypeInterpreter() { 44 | public String optionalString(boolean value, String desc) { 45 | return value ? "+" : "!"; 46 | } 47 | 48 | @Override 49 | public String apply(ItemStack ingredient, UidContext context) { 50 | GrappleCustomization custom = CommonSetup.grapplingHookItem.getCustomization(ingredient); 51 | return "" + 52 | this.optionalString(custom.motor, "motor") + 53 | this.optionalString(custom.rocket, "rocket") + 54 | this.optionalString(custom.doublehook, "double") + 55 | this.optionalString(custom.smartmotor, "smart") + 56 | this.optionalString(custom.enderstaff, "enderstaff") + 57 | this.optionalString(custom.attract, "attract") + 58 | this.optionalString(custom.repel, "repel") + 59 | ""; 60 | } 61 | }); 62 | } 63 | 64 | class ModifierRecipes { 65 | ItemStack input1, input2, output; 66 | public ModifierRecipes(ItemStack input1, ItemStack output) { 67 | this.input1 = input1; 68 | this.input2 = null; 69 | this.output = output; 70 | } 71 | public ModifierRecipes(ItemStack input1, ItemStack input2, ItemStack output) { 72 | this.input1 = input1; 73 | this.input2 = input2; 74 | this.output = output; 75 | } 76 | }; 77 | 78 | ResourceLocation modifierRecipesLoc = new ResourceLocation("grapplemod", "modifierrecipes"); 79 | 80 | @Override 81 | public void registerCategories(IRecipeCategoryRegistration registration) { 82 | IModPlugin.super.registerCategories(registration); 83 | 84 | registration.addRecipeCategories(new IRecipeCategory() { 85 | 86 | @Override 87 | public ResourceLocation getUid() { 88 | return modifierRecipesLoc; 89 | } 90 | 91 | @Override 92 | public Class getRecipeClass() { 93 | return ModifierRecipes.class; 94 | } 95 | 96 | @Override 97 | public String getTitle() { 98 | return ClientProxyInterface.proxy.localize("block.grapplemod.block_grapple_modifier"); 99 | } 100 | 101 | @Override 102 | public IDrawable getBackground() { 103 | return registration.getJeiHelpers().getGuiHelper().createDrawable(new ResourceLocation("grapplemod", "textures/gui/jei_modifier_bg.png"), 0, 0, 120, 60); 104 | } 105 | 106 | @Override 107 | public IDrawable getIcon() { 108 | return registration.getJeiHelpers().getGuiHelper().createDrawableIngredient(new ItemStack(CommonSetup.grappleModifierBlockItem)); 109 | } 110 | 111 | @Override 112 | public void setIngredients(ModifierRecipes recipe, IIngredients ingredients) { 113 | if (recipe.input2 == null) { 114 | ingredients.setInput(VanillaTypes.ITEM, recipe.input1); 115 | } else { 116 | ingredients.setInputs(VanillaTypes.ITEM, Arrays.asList(recipe.input1, recipe.input2)); 117 | } 118 | ingredients.setOutput(VanillaTypes.ITEM, recipe.output); 119 | } 120 | 121 | @Override 122 | public void setRecipe(IRecipeLayout recipeLayout, ModifierRecipes recipe, IIngredients ingredients) { 123 | IGuiItemStackGroup items = recipeLayout.getItemStacks(); 124 | 125 | items.init(0, true, 12, 9); 126 | items.init(1, true, 34, 9); 127 | items.init(2, false, 85, 9); 128 | 129 | items.set(ingredients); 130 | } 131 | 132 | @Override 133 | public void draw(ModifierRecipes recipe, PoseStack matrixStack, double mouseX, double mouseY) { 134 | IRecipeCategory.super.draw(recipe, matrixStack, mouseX, mouseY); 135 | 136 | if (recipe.input2 != null) { 137 | String text = ClientProxyInterface.proxy.localize("grapplemod.jei_modifier_text"); 138 | int linenum = 0; 139 | for (String line : text.split("\n")) { 140 | Minecraft.getInstance().font.draw(matrixStack, line, 3, 29+11*linenum, 0); 141 | linenum++; 142 | } 143 | } 144 | } 145 | }); 146 | } 147 | 148 | @Override 149 | public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { 150 | IModPlugin.super.registerRecipeCatalysts(registration); 151 | 152 | registration.addRecipeCatalyst(new ItemStack(CommonSetup.grappleModifierBlockItem), modifierRecipesLoc); 153 | } 154 | 155 | ItemStack grappleWithCustom(String option) { 156 | GrappleCustomization custom = new GrappleCustomization(); 157 | custom.setBoolean(option, true); 158 | ItemStack stack = new ItemStack(CommonSetup.grapplingHookItem); 159 | CommonSetup.grapplingHookItem.setCustomOnServer(stack, custom, null); 160 | return stack; 161 | } 162 | 163 | @Override 164 | public void registerRecipes(IRecipeRegistration registration) { 165 | IModPlugin.super.registerRecipes(registration); 166 | 167 | ItemStack ff_diamond_boots = new ItemStack(Items.DIAMOND_BOOTS); 168 | ff_diamond_boots.enchant(Enchantments.FALL_PROTECTION, 4); 169 | registration.addRecipes(Arrays.asList( 170 | new ModifierRecipes(new ItemStack(CommonSetup.motorUpgradeItem), new ItemStack(CommonSetup.grapplingHookItem), this.grappleWithCustom("motor")), 171 | new ModifierRecipes(new ItemStack(CommonSetup.doubleUpgradeItem), new ItemStack(CommonSetup.grapplingHookItem), this.grappleWithCustom("doublehook")), 172 | new ModifierRecipes(new ItemStack(CommonSetup.staffUpgradeItem), new ItemStack(CommonSetup.grapplingHookItem), this.grappleWithCustom("enderstaff")), 173 | new ModifierRecipes(new ItemStack(CommonSetup.forcefieldUpgradeItem), new ItemStack(CommonSetup.grapplingHookItem), this.grappleWithCustom("repel")), 174 | new ModifierRecipes(new ItemStack(CommonSetup.magnetUpgradeItem), new ItemStack(CommonSetup.grapplingHookItem), this.grappleWithCustom("attract")), 175 | new ModifierRecipes(new ItemStack(CommonSetup.rocketUpgradeItem), new ItemStack(CommonSetup.grapplingHookItem), this.grappleWithCustom("rocket")) 176 | ), modifierRecipesLoc); 177 | 178 | 179 | 180 | if (GrappleConfig.getConf().longfallboots.longfallbootsrecipe) { 181 | registration.addRecipes(Arrays.asList( 182 | new ModifierRecipes(ff_diamond_boots, new ItemStack(CommonSetup.longFallBootsItem)) 183 | ), modifierRecipesLoc); 184 | } 185 | } 186 | 187 | 188 | } 189 | */ 190 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/EnderStaffItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items; 2 | 3 | import com.yyon.grapplinghook.client.ClientProxyInterface; 4 | import com.yyon.grapplinghook.common.CommonSetup; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.world.InteractionHand; 7 | import net.minecraft.world.InteractionResultHolder; 8 | import net.minecraft.world.entity.player.Player; 9 | import net.minecraft.world.item.Item; 10 | import net.minecraft.world.item.ItemStack; 11 | import net.minecraft.world.item.TooltipFlag; 12 | import net.minecraft.world.level.Level; 13 | import net.minecraftforge.api.distmarker.Dist; 14 | import net.minecraftforge.api.distmarker.OnlyIn; 15 | 16 | import javax.annotation.Nullable; 17 | import java.util.List; 18 | 19 | /* 20 | * This file is part of GrappleMod. 21 | 22 | GrappleMod is free software: you can redistribute it and/or modify 23 | it under the terms of the GNU General Public License as published by 24 | the Free Software Foundation, either version 3 of the License, or 25 | (at your option) any later version. 26 | 27 | GrappleMod is distributed in the hope that it will be useful, 28 | but WITHOUT ANY WARRANTY; without even the implied warranty of 29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 | GNU General Public License for more details. 31 | 32 | You should have received a copy of the GNU General Public License 33 | along with GrappleMod. If not, see . 34 | */ 35 | 36 | public class EnderStaffItem extends Item { 37 | 38 | public EnderStaffItem() { 39 | super(new Item.Properties().stacksTo(1).tab(CommonSetup.tabGrapplemod)); 40 | } 41 | 42 | public void doRightClick(ItemStack stack, Level worldIn, Player player) { 43 | if (worldIn.isClientSide) { 44 | ClientProxyInterface.proxy.launchPlayer(player); 45 | } 46 | } 47 | 48 | @Override 49 | public InteractionResultHolder use(Level worldIn, Player playerIn, InteractionHand hand) { 50 | ItemStack stack = playerIn.getItemInHand(hand); 51 | this.doRightClick(stack, worldIn, playerIn); 52 | 53 | return InteractionResultHolder.success(stack); 54 | } 55 | 56 | @Override 57 | @OnlyIn(Dist.CLIENT) 58 | public void appendHoverText(ItemStack stack, @Nullable Level world, List list, TooltipFlag par4) { 59 | list.add(Component.literal(ClientProxyInterface.proxy.localize("grappletooltip.launcheritem.desc"))); 60 | list.add(Component.literal("")); 61 | list.add(Component.literal(ClientProxyInterface.proxy.localize("grappletooltip.launcheritemaim.desc"))); 62 | list.add(Component.literal(ClientProxyInterface.proxy.getKeyname(ClientProxyInterface.McKeys.keyBindUseItem) + ClientProxyInterface.proxy.localize("grappletooltip.launcheritemcontrols.desc"))); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/ForcefieldItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items; 2 | 3 | import com.yyon.grapplinghook.client.ClientProxyInterface; 4 | import com.yyon.grapplinghook.common.CommonSetup; 5 | import com.yyon.grapplinghook.controllers.GrappleController; 6 | import com.yyon.grapplinghook.utils.GrapplemodUtils; 7 | import com.yyon.grapplinghook.utils.Vec; 8 | import net.minecraft.network.chat.Component; 9 | import net.minecraft.world.InteractionHand; 10 | import net.minecraft.world.InteractionResultHolder; 11 | import net.minecraft.world.entity.player.Player; 12 | import net.minecraft.world.item.Item; 13 | import net.minecraft.world.item.ItemStack; 14 | import net.minecraft.world.item.TooltipFlag; 15 | import net.minecraft.world.level.Level; 16 | import net.minecraftforge.api.distmarker.Dist; 17 | import net.minecraftforge.api.distmarker.OnlyIn; 18 | 19 | import javax.annotation.Nullable; 20 | import java.util.List; 21 | 22 | public class ForcefieldItem extends Item { 23 | public ForcefieldItem() { 24 | super(new Item.Properties().stacksTo(1).tab(CommonSetup.tabGrapplemod)); 25 | } 26 | 27 | public void doRightClick(ItemStack stack, Level worldIn, Player player) { 28 | if (worldIn.isClientSide) { 29 | int playerid = player.getId(); 30 | GrappleController oldController = ClientProxyInterface.proxy.unregisterController(playerid); 31 | if (oldController == null || oldController.controllerId == GrapplemodUtils.AIRID) { 32 | ClientProxyInterface.proxy.createControl(GrapplemodUtils.REPELID, -1, playerid, worldIn, new Vec(0,0,0), null, null); 33 | } 34 | } 35 | } 36 | 37 | @Override 38 | public InteractionResultHolder use(Level worldIn, Player playerIn, InteractionHand hand) { 39 | ItemStack stack = playerIn.getItemInHand(hand); 40 | this.doRightClick(stack, worldIn, playerIn); 41 | 42 | return InteractionResultHolder.success(stack); 43 | } 44 | 45 | @Override 46 | @OnlyIn(Dist.CLIENT) 47 | public void appendHoverText(ItemStack stack, @Nullable Level world, List list, TooltipFlag par4) { 48 | list.add(Component.literal(ClientProxyInterface.proxy.localize("grappletooltip.repelleritem.desc"))); 49 | list.add(Component.literal(ClientProxyInterface.proxy.localize("grappletooltip.repelleritem2.desc"))); 50 | list.add(Component.literal("")); 51 | list.add(Component.literal(ClientProxyInterface.proxy.getKeyname(ClientProxyInterface.McKeys.keyBindUseItem) + ClientProxyInterface.proxy.localize("grappletooltip.repelleritemon.desc"))); 52 | list.add(Component.literal(ClientProxyInterface.proxy.getKeyname(ClientProxyInterface.McKeys.keyBindUseItem) + ClientProxyInterface.proxy.localize("grappletooltip.repelleritemoff.desc"))); 53 | list.add(Component.literal(ClientProxyInterface.proxy.getKeyname(ClientProxyInterface.McKeys.keyBindSneak) + ClientProxyInterface.proxy.localize("grappletooltip.repelleritemslow.desc"))); 54 | list.add(Component.literal(ClientProxyInterface.proxy.getKeyname(ClientProxyInterface.McKeys.keyBindForward) + ", " + 55 | ClientProxyInterface.proxy.getKeyname(ClientProxyInterface.McKeys.keyBindLeft) + ", " + 56 | ClientProxyInterface.proxy.getKeyname(ClientProxyInterface.McKeys.keyBindBack) + ", " + 57 | ClientProxyInterface.proxy.getKeyname(ClientProxyInterface.McKeys.keyBindRight) + 58 | " " + ClientProxyInterface.proxy.localize("grappletooltip.repelleritemmove.desc"))); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/KeypressItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items; 2 | 3 | import net.minecraft.world.entity.player.Player; 4 | import net.minecraft.world.item.ItemStack; 5 | 6 | 7 | public interface KeypressItem { 8 | enum Keys { 9 | LAUNCHER, THROWLEFT, THROWRIGHT, THROWBOTH, ROCKET 10 | } 11 | 12 | public abstract void onCustomKeyDown(ItemStack stack, Player player, Keys key, boolean ismainhand); 13 | public abstract void onCustomKeyUp(ItemStack stack, Player player, Keys key, boolean ismainhand); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/LongFallBoots.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items; 2 | 3 | import com.yyon.grapplinghook.client.ClientProxyInterface; 4 | import com.yyon.grapplinghook.common.CommonSetup; 5 | import com.yyon.grapplinghook.config.GrappleConfig; 6 | import net.minecraft.core.NonNullList; 7 | import net.minecraft.network.chat.Component; 8 | import net.minecraft.world.entity.EquipmentSlot; 9 | import net.minecraft.world.item.*; 10 | import net.minecraft.world.level.Level; 11 | import net.minecraftforge.api.distmarker.Dist; 12 | import net.minecraftforge.api.distmarker.OnlyIn; 13 | 14 | import javax.annotation.Nullable; 15 | import java.util.List; 16 | 17 | /* 18 | * This file is part of GrappleMod. 19 | 20 | GrappleMod is free software: you can redistribute it and/or modify 21 | it under the terms of the GNU General Public License as published by 22 | the Free Software Foundation, either version 3 of the License, or 23 | (at your option) any later version. 24 | 25 | GrappleMod is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU General Public License for more details. 29 | 30 | You should have received a copy of the GNU General Public License 31 | along with GrappleMod. If not, see . 32 | */ 33 | 34 | public class LongFallBoots extends ArmorItem { 35 | public LongFallBoots(ArmorMaterials material, int type) { 36 | super(material, EquipmentSlot.FEET, new Item.Properties().stacksTo(1).tab(CommonSetup.tabGrapplemod)); 37 | } 38 | 39 | @Override 40 | @OnlyIn(Dist.CLIENT) 41 | public void appendHoverText(ItemStack stack, @Nullable Level world, List list, TooltipFlag par4) { 42 | if (!stack.isEnchanted()) { 43 | if (GrappleConfig.getConf().longfallboots.longfallbootsrecipe) { 44 | list.add(Component.literal(ClientProxyInterface.proxy.localize("grappletooltip.longfallbootsrecipe.desc"))); 45 | } 46 | } 47 | list.add(Component.literal(ClientProxyInterface.proxy.localize("grappletooltip.longfallboots.desc"))); 48 | } 49 | 50 | @Override 51 | public void fillItemCategory(CreativeModeTab tab, NonNullList items) { 52 | if (this.allowedIn(tab)) { 53 | ItemStack stack = new ItemStack(this); 54 | items.add(stack); 55 | 56 | stack = new ItemStack(this); 57 | stack.enchant(CommonSetup.wallrunEnchantment.get(), 1); 58 | stack.enchant(CommonSetup.doubleJumpEnchantment.get(), 1); 59 | stack.enchant(CommonSetup.slidingEnchantment.get(), 1); 60 | items.add(stack); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/BaseUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.common.CommonSetup; 4 | import com.yyon.grapplinghook.utils.GrappleCustomization; 5 | import net.minecraft.world.item.Item; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | public class BaseUpgradeItem extends Item { 9 | public GrappleCustomization.upgradeCategories category = null; 10 | boolean craftingRemaining = false; 11 | 12 | public BaseUpgradeItem(int maxStackSize, GrappleCustomization.upgradeCategories theCategory) { 13 | super(new Item.Properties().stacksTo(maxStackSize).tab(CommonSetup.tabGrapplemod)); 14 | 15 | this.category = theCategory; 16 | 17 | if (theCategory != null) { 18 | this.setCraftingRemainingItem(); 19 | } 20 | } 21 | 22 | public void setCraftingRemainingItem() { 23 | craftingRemaining = true; 24 | } 25 | 26 | @Override 27 | public ItemStack getCraftingRemainingItem(ItemStack itemStack) 28 | { 29 | if (!this.craftingRemaining) 30 | { 31 | return ItemStack.EMPTY; 32 | } 33 | return new ItemStack(this); 34 | } 35 | 36 | @Override 37 | public boolean hasCraftingRemainingItem() { 38 | return this.craftingRemaining; 39 | } 40 | 41 | 42 | public BaseUpgradeItem() { 43 | this(64, null); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/DoubleUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class DoubleUpgradeItem extends BaseUpgradeItem { 6 | public DoubleUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.DOUBLE); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/ForcefieldUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class ForcefieldUpgradeItem extends BaseUpgradeItem { 6 | public ForcefieldUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.FORCEFIELD); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/LimitsUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class LimitsUpgradeItem extends BaseUpgradeItem { 6 | public LimitsUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.LIMITS); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/MagnetUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class MagnetUpgradeItem extends BaseUpgradeItem { 6 | public MagnetUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.MAGNET); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/MotorUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class MotorUpgradeItem extends BaseUpgradeItem { 6 | public MotorUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.MOTOR); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/RocketUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class RocketUpgradeItem extends BaseUpgradeItem { 6 | public RocketUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.ROCKET); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/RopeUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class RopeUpgradeItem extends BaseUpgradeItem { 6 | public RopeUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.ROPE); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/StaffUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class StaffUpgradeItem extends BaseUpgradeItem { 6 | public StaffUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.STAFF); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/SwingUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class SwingUpgradeItem extends BaseUpgradeItem { 6 | public SwingUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.SWING); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/items/upgrades/ThrowUpgradeItem.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.items.upgrades; 2 | 3 | import com.yyon.grapplinghook.utils.GrappleCustomization; 4 | 5 | public class ThrowUpgradeItem extends BaseUpgradeItem { 6 | public ThrowUpgradeItem() { 7 | super(1, GrappleCustomization.upgradeCategories.THROW); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/BaseMessageClient.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.client.ClientProxyInterface; 4 | import com.yyon.grapplinghook.grapplemod; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraftforge.api.distmarker.Dist; 7 | import net.minecraftforge.api.distmarker.OnlyIn; 8 | import net.minecraftforge.fml.LogicalSide; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | import java.util.function.Supplier; 12 | 13 | public abstract class BaseMessageClient { 14 | public BaseMessageClient(FriendlyByteBuf buf) { 15 | this.decode(buf); 16 | } 17 | 18 | public BaseMessageClient() { 19 | } 20 | 21 | public abstract void decode(FriendlyByteBuf buf); 22 | 23 | public abstract void encode(FriendlyByteBuf buf); 24 | 25 | @OnlyIn(Dist.CLIENT) 26 | public abstract void processMessage(NetworkEvent.Context ctx); 27 | 28 | public void onMessageReceived(Supplier ctxSupplier) { 29 | NetworkEvent.Context ctx = ctxSupplier.get(); 30 | LogicalSide sideReceived = ctx.getDirection().getReceptionSide(); 31 | if (sideReceived != LogicalSide.CLIENT) { 32 | grapplemod.LOGGER.warn("message received on wrong side:" + ctx.getDirection().getReceptionSide()); 33 | return; 34 | } 35 | 36 | ctx.setPacketHandled(true); 37 | 38 | ctx.enqueueWork(() -> 39 | ClientProxyInterface.proxy.onMessageReceivedClient(this, ctx) 40 | ); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/BaseMessageServer.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.grapplemod; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraft.server.level.ServerPlayer; 6 | import net.minecraftforge.fml.LogicalSide; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | import java.util.function.Supplier; 10 | 11 | public abstract class BaseMessageServer { 12 | public BaseMessageServer(FriendlyByteBuf buf) { 13 | this.decode(buf); 14 | } 15 | 16 | public BaseMessageServer() { 17 | } 18 | 19 | public abstract void decode(FriendlyByteBuf buf); 20 | 21 | public abstract void encode(FriendlyByteBuf buf); 22 | 23 | public abstract void processMessage(NetworkEvent.Context ctx); 24 | 25 | public void onMessageReceived(Supplier ctxSupplier) { 26 | NetworkEvent.Context ctx = ctxSupplier.get(); 27 | LogicalSide sideReceived = ctx.getDirection().getReceptionSide(); 28 | if (sideReceived != LogicalSide.SERVER) { 29 | grapplemod.LOGGER.warn("message received on wrong side:" + ctx.getDirection().getReceptionSide()); 30 | return; 31 | } 32 | 33 | ctx.setPacketHandled(true); 34 | 35 | final ServerPlayer sendingPlayer = ctx.getSender(); 36 | if (sendingPlayer == null) { 37 | grapplemod.LOGGER.warn("EntityPlayerMP was null when message was received"); 38 | } 39 | 40 | ctx.enqueueWork(() -> processMessage(ctx)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/DetachSingleHookMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.client.ClientControllerManager; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraftforge.api.distmarker.Dist; 6 | import net.minecraftforge.api.distmarker.OnlyIn; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | /* 10 | * This file is part of GrappleMod. 11 | 12 | GrappleMod is free software: you can redistribute it and/or modify 13 | it under the terms of the GNU General Public License as published by 14 | the Free Software Foundation, either version 3 of the License, or 15 | (at your option) any later version. 16 | 17 | GrappleMod is distributed in the hope that it will be useful, 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | GNU General Public License for more details. 21 | 22 | You should have received a copy of the GNU General Public License 23 | along with GrappleMod. If not, see . 24 | */ 25 | 26 | public class DetachSingleHookMessage extends BaseMessageClient { 27 | 28 | public int id; 29 | public int hookid; 30 | 31 | public DetachSingleHookMessage(FriendlyByteBuf buf) { 32 | super(buf); 33 | } 34 | 35 | public DetachSingleHookMessage(int id, int hookid) { 36 | this.id = id; 37 | this.hookid = hookid; 38 | } 39 | 40 | public void decode(FriendlyByteBuf buf) { 41 | this.id = buf.readInt(); 42 | this.hookid = buf.readInt(); 43 | } 44 | 45 | public void encode(FriendlyByteBuf buf) { 46 | buf.writeInt(this.id); 47 | buf.writeInt(this.hookid); 48 | } 49 | 50 | @OnlyIn(Dist.CLIENT) 51 | public void processMessage(NetworkEvent.Context ctx) { 52 | ClientControllerManager.receiveGrappleDetachHook(this.id, this.hookid); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/GrappleAttachMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.client.ClientProxyInterface; 4 | import com.yyon.grapplinghook.entities.grapplehook.GrapplehookEntity; 5 | import com.yyon.grapplinghook.entities.grapplehook.SegmentHandler; 6 | import com.yyon.grapplinghook.utils.GrappleCustomization; 7 | import com.yyon.grapplinghook.utils.Vec; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.core.BlockPos; 10 | import net.minecraft.core.Direction; 11 | import net.minecraft.network.FriendlyByteBuf; 12 | import net.minecraft.world.entity.Entity; 13 | import net.minecraft.world.level.Level; 14 | import net.minecraftforge.api.distmarker.Dist; 15 | import net.minecraftforge.api.distmarker.OnlyIn; 16 | import net.minecraftforge.network.NetworkEvent; 17 | 18 | import java.util.LinkedList; 19 | 20 | /* 21 | * This file is part of GrappleMod. 22 | 23 | GrappleMod is free software: you can redistribute it and/or modify 24 | it under the terms of the GNU General Public License as published by 25 | the Free Software Foundation, either version 3 of the License, or 26 | (at your option) any later version. 27 | 28 | GrappleMod is distributed in the hope that it will be useful, 29 | but WITHOUT ANY WARRANTY; without even the implied warranty of 30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 | GNU General Public License for more details. 32 | 33 | You should have received a copy of the GNU General Public License 34 | along with GrappleMod. If not, see . 35 | */ 36 | 37 | public class GrappleAttachMessage extends BaseMessageClient { 38 | 39 | public int id; 40 | public double x; 41 | public double y; 42 | public double z; 43 | public int controlId; 44 | public int entityId; 45 | public BlockPos blockPos; 46 | public LinkedList segments; 47 | public LinkedList segmentTopSides; 48 | public LinkedList segmentBottomSides; 49 | public GrappleCustomization custom; 50 | 51 | public GrappleAttachMessage(FriendlyByteBuf buf) { 52 | super(buf); 53 | } 54 | 55 | public GrappleAttachMessage(int id, double x, double y, double z, int controlid, int entityid, BlockPos blockpos, LinkedList segments, LinkedList segmenttopsides, LinkedList segmentbottomsides, GrappleCustomization custom) { 56 | this.id = id; 57 | this.x = x; 58 | this.y = y; 59 | this.z = z; 60 | this.controlId = controlid; 61 | this.entityId = entityid; 62 | this.blockPos = blockpos; 63 | this.segments = segments; 64 | this.segmentTopSides = segmenttopsides; 65 | this.segmentBottomSides = segmentbottomsides; 66 | this.custom = custom; 67 | } 68 | 69 | public void decode(FriendlyByteBuf buf) { 70 | this.id = buf.readInt(); 71 | this.x = buf.readDouble(); 72 | this.y = buf.readDouble(); 73 | this.z = buf.readDouble(); 74 | this.controlId = buf.readInt(); 75 | this.entityId = buf.readInt(); 76 | int blockx = buf.readInt(); 77 | int blocky = buf.readInt(); 78 | int blockz = buf.readInt(); 79 | this.blockPos = new BlockPos(blockx, blocky, blockz); 80 | 81 | this.custom = new GrappleCustomization(); 82 | this.custom.readFromBuf(buf); 83 | 84 | int size = buf.readInt(); 85 | this.segments = new LinkedList(); 86 | this.segmentBottomSides = new LinkedList(); 87 | this.segmentTopSides = new LinkedList(); 88 | 89 | segments.add(new Vec(0, 0, 0)); 90 | segmentBottomSides.add(null); 91 | segmentTopSides.add(null); 92 | 93 | for (int i = 1; i < size-1; i++) { 94 | this.segments.add(new Vec(buf.readDouble(), buf.readDouble(), buf.readDouble())); 95 | this.segmentBottomSides.add(buf.readEnum(Direction.class)); 96 | this.segmentTopSides.add(buf.readEnum(Direction.class)); 97 | } 98 | 99 | segments.add(new Vec(0, 0, 0)); 100 | segmentBottomSides.add(null); 101 | segmentTopSides.add(null); 102 | } 103 | 104 | public void encode(FriendlyByteBuf buf) { 105 | buf.writeInt(this.id); 106 | buf.writeDouble(this.x); 107 | buf.writeDouble(this.y); 108 | buf.writeDouble(this.z); 109 | buf.writeInt(this.controlId); 110 | buf.writeInt(this.entityId); 111 | buf.writeInt(this.blockPos.getX()); 112 | buf.writeInt(this.blockPos.getY()); 113 | buf.writeInt(this.blockPos.getZ()); 114 | 115 | this.custom.writeToBuf(buf); 116 | 117 | buf.writeInt(this.segments.size()); 118 | for (int i = 1; i < this.segments.size()-1; i++) { 119 | buf.writeDouble(this.segments.get(i).x); 120 | buf.writeDouble(this.segments.get(i).y); 121 | buf.writeDouble(this.segments.get(i).z); 122 | buf.writeEnum(this.segmentBottomSides.get(i)); 123 | buf.writeEnum(this.segmentTopSides.get(i)); 124 | } 125 | } 126 | 127 | @OnlyIn(Dist.CLIENT) 128 | public void processMessage(NetworkEvent.Context ctx) { 129 | Level world = Minecraft.getInstance().level; 130 | Entity grapple = world.getEntity(this.id); 131 | if (grapple instanceof GrapplehookEntity) { 132 | ((GrapplehookEntity) grapple).clientAttach(this.x, this.y, this.z); 133 | SegmentHandler segmenthandler = ((GrapplehookEntity) grapple).segmentHandler; 134 | segmenthandler.segments = this.segments; 135 | segmenthandler.segmentBottomSides = this.segmentBottomSides; 136 | segmenthandler.segmentTopSides = this.segmentTopSides; 137 | 138 | Entity player = world.getEntity(this.entityId); 139 | segmenthandler.forceSetPos(new Vec(this.x, this.y, this.z), Vec.positionVec(player)); 140 | } else { 141 | } 142 | 143 | ClientProxyInterface.proxy.createControl(this.controlId, this.id, this.entityId, world, new Vec(this.x, this.y, this.z), this.blockPos, this.custom); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/GrappleAttachPosMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.entities.grapplehook.GrapplehookEntity; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraft.world.entity.Entity; 7 | import net.minecraft.world.level.Level; 8 | import net.minecraftforge.api.distmarker.Dist; 9 | import net.minecraftforge.api.distmarker.OnlyIn; 10 | import net.minecraftforge.network.NetworkEvent; 11 | 12 | 13 | /* 14 | * This file is part of GrappleMod. 15 | 16 | GrappleMod is free software: you can redistribute it and/or modify 17 | it under the terms of the GNU General Public License as published by 18 | the Free Software Foundation, either version 3 of the License, or 19 | (at your option) any later version. 20 | 21 | GrappleMod is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | You should have received a copy of the GNU General Public License 27 | along with GrappleMod. If not, see . 28 | */ 29 | 30 | public class GrappleAttachPosMessage extends BaseMessageClient { 31 | 32 | public int id; 33 | public double x; 34 | public double y; 35 | public double z; 36 | 37 | public GrappleAttachPosMessage(FriendlyByteBuf buf) { 38 | super(buf); 39 | } 40 | 41 | public GrappleAttachPosMessage(int id, double x, double y, double z) { 42 | this.id = id; 43 | this.x = x; 44 | this.y = y; 45 | this.z = z; 46 | } 47 | 48 | public void decode(FriendlyByteBuf buf) { 49 | this.id = buf.readInt(); 50 | this.x = buf.readDouble(); 51 | this.y = buf.readDouble(); 52 | this.z = buf.readDouble(); 53 | } 54 | 55 | public void encode(FriendlyByteBuf buf) { 56 | buf.writeInt(this.id); 57 | buf.writeDouble(this.x); 58 | buf.writeDouble(this.y); 59 | buf.writeDouble(this.z); 60 | } 61 | 62 | @OnlyIn(Dist.CLIENT) 63 | public void processMessage(NetworkEvent.Context ctx) { 64 | Level world = Minecraft.getInstance().level; 65 | Entity grapple = world.getEntity(this.id); 66 | if (grapple instanceof GrapplehookEntity) { 67 | ((GrapplehookEntity) grapple).setAttachPos(this.x, this.y, this.z); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/GrappleDetachMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.client.ClientControllerManager; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraftforge.api.distmarker.Dist; 6 | import net.minecraftforge.api.distmarker.OnlyIn; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | /* 10 | * This file is part of GrappleMod. 11 | 12 | GrappleMod is free software: you can redistribute it and/or modify 13 | it under the terms of the GNU General Public License as published by 14 | the Free Software Foundation, either version 3 of the License, or 15 | (at your option) any later version. 16 | 17 | GrappleMod is distributed in the hope that it will be useful, 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | GNU General Public License for more details. 21 | 22 | You should have received a copy of the GNU General Public License 23 | along with GrappleMod. If not, see . 24 | */ 25 | 26 | public class GrappleDetachMessage extends BaseMessageClient { 27 | 28 | public int id; 29 | 30 | public GrappleDetachMessage(FriendlyByteBuf buf) { 31 | super(buf); 32 | } 33 | 34 | public GrappleDetachMessage(int id) { 35 | this.id = id; 36 | } 37 | 38 | public void decode(FriendlyByteBuf buf) { 39 | this.id = buf.readInt(); 40 | } 41 | 42 | public void encode(FriendlyByteBuf buf) { 43 | buf.writeInt(this.id); 44 | } 45 | 46 | @OnlyIn(Dist.CLIENT) 47 | public void processMessage(NetworkEvent.Context ctx) { 48 | ClientControllerManager.receiveGrappleDetach(this.id); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/GrappleEndMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.server.ServerControllerManager; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraft.server.level.ServerPlayer; 6 | import net.minecraft.world.level.Level; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | import java.util.HashSet; 10 | 11 | /* 12 | * This file is part of GrappleMod. 13 | 14 | GrappleMod is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | 19 | GrappleMod is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | 24 | You should have received a copy of the GNU General Public License 25 | along with GrappleMod. If not, see . 26 | */ 27 | 28 | public class GrappleEndMessage extends BaseMessageServer { 29 | 30 | public int entityId; 31 | public HashSet hookEntityIds; 32 | 33 | public GrappleEndMessage(FriendlyByteBuf buf) { 34 | super(buf); 35 | } 36 | 37 | public GrappleEndMessage(int entityId, HashSet hookEntityIds) { 38 | this.entityId = entityId; 39 | this.hookEntityIds = hookEntityIds; 40 | } 41 | 42 | public void decode(FriendlyByteBuf buf) { 43 | this.entityId = buf.readInt(); 44 | int size = buf.readInt(); 45 | this.hookEntityIds = new HashSet(); 46 | for (int i = 0; i < size; i++) { 47 | this.hookEntityIds.add(buf.readInt()); 48 | } 49 | } 50 | 51 | public void encode(FriendlyByteBuf buf) { 52 | buf.writeInt(this.entityId); 53 | buf.writeInt(this.hookEntityIds.size()); 54 | for (int id : this.hookEntityIds) { 55 | buf.writeInt(id); 56 | } 57 | } 58 | 59 | public void processMessage(NetworkEvent.Context ctx) { 60 | int id = this.entityId; 61 | 62 | ServerPlayer player = ctx.getSender(); 63 | if (player == null) { 64 | return; 65 | } 66 | Level w = player.level; 67 | 68 | ServerControllerManager.receiveGrappleEnd(id, w, this.hookEntityIds); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/GrappleModifierMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.blocks.modifierblock.TileEntityGrappleModifier; 4 | import com.yyon.grapplinghook.utils.GrappleCustomization; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.network.FriendlyByteBuf; 7 | import net.minecraft.world.level.Level; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | /* 12 | GrappleMod is free software: you can redistribute it and/or modify 13 | it under the teHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with GrappleMod. If not, see . 19 | */ 20 | 21 | public class GrappleModifierMessage extends BaseMessageServer { 22 | 23 | public BlockPos pos; 24 | public GrappleCustomization custom; 25 | 26 | public GrappleModifierMessage(BlockPos pos, GrappleCustomization custom) { 27 | this.pos = pos; 28 | this.custom = custom; 29 | } 30 | 31 | public GrappleModifierMessage(FriendlyByteBuf buf) { 32 | super(buf); 33 | } 34 | 35 | public void decode(FriendlyByteBuf buf) { 36 | this.pos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); 37 | this.custom = new GrappleCustomization(); 38 | this.custom.readFromBuf(buf); 39 | } 40 | 41 | public void encode(FriendlyByteBuf buf) { 42 | buf.writeInt(this.pos.getX()); 43 | buf.writeInt(this.pos.getY()); 44 | buf.writeInt(this.pos.getZ()); 45 | this.custom.writeToBuf(buf); 46 | } 47 | 48 | public void processMessage(NetworkEvent.Context ctx) { 49 | Level w = ctx.getSender().level; 50 | 51 | BlockEntity ent = w.getBlockEntity(this.pos); 52 | 53 | if (ent != null && ent instanceof TileEntityGrappleModifier) { 54 | ((TileEntityGrappleModifier) ent).setCustomizationServer(this.custom); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/KeypressMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.items.KeypressItem; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraft.server.level.ServerPlayer; 6 | import net.minecraft.world.InteractionHand; 7 | import net.minecraft.world.item.Item; 8 | import net.minecraft.world.item.ItemStack; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | /* 12 | * This file is part of GrappleMod. 13 | 14 | GrappleMod is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | 19 | GrappleMod is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | 24 | You should have received a copy of the GNU General Public License 25 | along with GrappleMod. If not, see . 26 | */ 27 | 28 | public class KeypressMessage extends BaseMessageServer { 29 | 30 | KeypressItem.Keys key; 31 | boolean isDown; 32 | 33 | public KeypressMessage(FriendlyByteBuf buf) { 34 | super(buf); 35 | } 36 | 37 | public KeypressMessage(KeypressItem.Keys thekey, boolean isDown) { 38 | this.key = thekey; 39 | this.isDown = isDown; 40 | } 41 | 42 | public void decode(FriendlyByteBuf buf) { 43 | this.key = KeypressItem.Keys.values()[buf.readInt()]; 44 | this.isDown = buf.readBoolean(); 45 | } 46 | 47 | public void encode(FriendlyByteBuf buf) { 48 | buf.writeInt(this.key.ordinal()); 49 | buf.writeBoolean(this.isDown); 50 | } 51 | 52 | @Override 53 | public void processMessage(NetworkEvent.Context ctx) { 54 | final ServerPlayer player = ctx.getSender(); 55 | 56 | if (player != null) { 57 | ItemStack stack = player.getItemInHand(InteractionHand.MAIN_HAND); 58 | if (stack != null) { 59 | Item item = stack.getItem(); 60 | if (item instanceof KeypressItem) { 61 | if (isDown) { 62 | ((KeypressItem)item).onCustomKeyDown(stack, player, key, true); 63 | } else { 64 | ((KeypressItem)item).onCustomKeyUp(stack, player, key, true); 65 | } 66 | return; 67 | } 68 | } 69 | 70 | stack = player.getItemInHand(InteractionHand.OFF_HAND); 71 | if (stack != null) { 72 | Item item = stack.getItem(); 73 | if (item instanceof KeypressItem) { 74 | if (isDown) { 75 | ((KeypressItem)item).onCustomKeyDown(stack, player, key, false); 76 | } else { 77 | ((KeypressItem)item).onCustomKeyUp(stack, player, key, false); 78 | } 79 | return; 80 | } 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/LoggedInMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.config.GrappleConfig; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraftforge.network.NetworkEvent; 6 | 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.Type; 9 | import java.nio.charset.Charset; 10 | import java.util.Arrays; 11 | import java.util.Comparator; 12 | 13 | /* 14 | * This file is part of GrappleMod. 15 | 16 | GrappleMod is free software: you can redistribute it and/or modify 17 | it under the terms of the GNU General Public License as published by 18 | the Free Software Foundation, either version 3 of the License, or 19 | (at your option) any later version. 20 | 21 | GrappleMod is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | You should have received a copy of the GNU General Public License 27 | along with GrappleMod. If not, see . 28 | */ 29 | 30 | public class LoggedInMessage extends BaseMessageClient { 31 | GrappleConfig.Config conf; 32 | 33 | public LoggedInMessage(FriendlyByteBuf buf) { 34 | super(buf); 35 | } 36 | 37 | public LoggedInMessage(GrappleConfig.Config serverconf) { 38 | this.conf = serverconf; 39 | } 40 | 41 | public void decodeClass(FriendlyByteBuf buf, Class theClass, T theObject) { 42 | Field[] fields = theClass.getDeclaredFields(); 43 | Arrays.sort(fields, new Comparator() { 44 | @Override 45 | public int compare(Field o1, Field o2) { 46 | return o1.getName().compareTo(o2.getName()); 47 | } 48 | }); 49 | 50 | for (Field field : fields) { 51 | Type fieldtype = field.getGenericType(); 52 | try { 53 | if (fieldtype.getTypeName().equals("int")) { 54 | field.setInt(theObject, buf.readInt()); 55 | } else if (fieldtype.getTypeName().equals("double")) { 56 | field.setDouble(theObject, buf.readDouble()); 57 | } else if (fieldtype.getTypeName().equals("boolean")) { 58 | field.setBoolean(theObject, buf.readBoolean()); 59 | } else if (fieldtype.getTypeName().equals("java.lang.String")) { 60 | int len = buf.readInt(); 61 | CharSequence charseq = buf.readCharSequence(len, Charset.defaultCharset()); 62 | field.set(theObject, charseq.toString()); 63 | } else if (field.getType() != null && Object.class.isAssignableFrom(field.getType())) { 64 | Class newClass = field.getType(); 65 | decodeClass(buf, newClass, newClass.cast(field.get(theObject))); 66 | } else { 67 | System.out.println("Unknown Type"); 68 | System.out.println(fieldtype.getTypeName()); 69 | } 70 | } catch (IllegalAccessException e) { 71 | System.out.println(e); 72 | } 73 | } 74 | } 75 | 76 | public void decode(FriendlyByteBuf buf) { 77 | Class confclass = GrappleConfig.Config.class; 78 | this.conf = new GrappleConfig.Config(); 79 | 80 | decodeClass(buf, confclass, this.conf); 81 | } 82 | 83 | public void encodeClass(FriendlyByteBuf buf, Class theClass, T theObject) { 84 | Field[] fields = theClass.getDeclaredFields(); 85 | Arrays.sort(fields, new Comparator() { 86 | @Override 87 | public int compare(Field o1, Field o2) { 88 | return o1.getName().compareTo(o2.getName()); 89 | } 90 | }); 91 | 92 | for (Field field : fields) { 93 | Type fieldtype = field.getGenericType(); 94 | try { 95 | if (fieldtype.getTypeName().equals("int")) { 96 | buf.writeInt(field.getInt(theObject)); 97 | } else if (fieldtype.getTypeName().equals("double")) { 98 | buf.writeDouble(field.getDouble(theObject)); 99 | } else if (fieldtype.getTypeName().equals("boolean")) { 100 | buf.writeBoolean(field.getBoolean(theObject)); 101 | } else if (fieldtype.getTypeName().equals("java.lang.String")) { 102 | String str = (String) field.get(theObject); 103 | buf.writeInt(str.length()); 104 | buf.writeCharSequence(str.subSequence(0, str.length()), Charset.defaultCharset()); 105 | } else if (field.getType() != null && Object.class.isAssignableFrom(field.getType())) { 106 | Class newClass = field.getType(); 107 | encodeClass(buf, newClass, newClass.cast(field.get(theObject))); 108 | } else { 109 | System.out.println("Unknown Type"); 110 | System.out.println(fieldtype.getTypeName()); 111 | } 112 | } catch (IllegalAccessException e) { 113 | System.out.println(e); 114 | } 115 | } 116 | } 117 | 118 | public void encode(FriendlyByteBuf buf) { 119 | Class confclass = GrappleConfig.Config.class; 120 | encodeClass(buf, confclass, this.conf); 121 | } 122 | 123 | @Override 124 | public void processMessage(NetworkEvent.Context ctx) { 125 | GrappleConfig.setServerOptions(this.conf); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/PlayerMovementMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.utils.Vec; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraft.server.level.ServerPlayer; 6 | import net.minecraftforge.network.NetworkEvent; 7 | 8 | /* 9 | * This file is part of GrappleMod. 10 | 11 | GrappleMod is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | GrappleMod is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with GrappleMod. If not, see . 23 | */ 24 | 25 | public class PlayerMovementMessage extends BaseMessageServer { 26 | 27 | public int entityId; 28 | public double x; 29 | public double y; 30 | public double z; 31 | public double mx; 32 | public double my; 33 | public double mz; 34 | 35 | public PlayerMovementMessage(FriendlyByteBuf buf) { 36 | super(buf); 37 | } 38 | 39 | public PlayerMovementMessage(int entityId, double x, double y, double z, double mx, double my, double mz) { 40 | this.entityId = entityId; 41 | this.x = x; 42 | this.y = y; 43 | this.z = z; 44 | this.mx = mx; 45 | this.my = my; 46 | this.mz = mz; 47 | } 48 | 49 | public void decode(FriendlyByteBuf buf) { 50 | try { 51 | this.entityId = buf.readInt(); 52 | this.x = buf.readDouble(); 53 | this.y = buf.readDouble(); 54 | this.z = buf.readDouble(); 55 | this.mx = buf.readDouble(); 56 | this.my = buf.readDouble(); 57 | this.mz = buf.readDouble(); 58 | } catch (Exception e) { 59 | System.out.print("Playermovement error: "); 60 | System.out.println(buf); 61 | } 62 | } 63 | 64 | public void encode(FriendlyByteBuf buf) { 65 | buf.writeInt(entityId); 66 | buf.writeDouble(x); 67 | buf.writeDouble(y); 68 | buf.writeDouble(z); 69 | buf.writeDouble(mx); 70 | buf.writeDouble(my); 71 | buf.writeDouble(mz); 72 | 73 | } 74 | 75 | public void processMessage(NetworkEvent.Context ctx) { 76 | final ServerPlayer referencedPlayer = ctx.getSender(); 77 | 78 | if(referencedPlayer.getId() == this.entityId) { 79 | new Vec(this.x, this.y, this.z).setPos(referencedPlayer); 80 | new Vec(this.mx, this.my, this.mz).setMotion(referencedPlayer); 81 | 82 | referencedPlayer.connection.resetPosition(); 83 | 84 | if (!referencedPlayer.isOnGround()) { 85 | if (this.my >= 0) { 86 | referencedPlayer.fallDistance = 0; 87 | } else { 88 | double gravity = 0.05 * 2; 89 | // d = v^2 / 2g 90 | referencedPlayer.fallDistance = (float) (Math.pow(this.my, 2) / (2 * gravity)); 91 | } 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/network/SegmentMessage.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.network; 2 | 3 | import com.yyon.grapplinghook.entities.grapplehook.GrapplehookEntity; 4 | import com.yyon.grapplinghook.entities.grapplehook.SegmentHandler; 5 | import com.yyon.grapplinghook.utils.Vec; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.core.Direction; 8 | import net.minecraft.network.FriendlyByteBuf; 9 | import net.minecraft.world.entity.Entity; 10 | import net.minecraft.world.level.Level; 11 | import net.minecraftforge.api.distmarker.Dist; 12 | import net.minecraftforge.api.distmarker.OnlyIn; 13 | import net.minecraftforge.network.NetworkEvent; 14 | 15 | /* 16 | * This file is part of GrappleMod. 17 | 18 | GrappleMod is free software: you can redistribute it and/or modify 19 | it under the terms of the GNU General Public License as published by 20 | the Free Software Foundation, either version 3 of the License, or 21 | (at your option) any later version. 22 | 23 | GrappleMod is distributed in the hope that it will be useful, 24 | but WITHOUT ANY WARRANTY; without even the implied warranty of 25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 | GNU General Public License for more details. 27 | 28 | You should have received a copy of the GNU General Public License 29 | along with GrappleMod. If not, see . 30 | */ 31 | 32 | public class SegmentMessage extends BaseMessageClient { 33 | 34 | public int id; 35 | public boolean add; 36 | public int index; 37 | public Vec pos; 38 | public Direction topFacing; 39 | public Direction bottomFacing; 40 | 41 | public SegmentMessage(FriendlyByteBuf buf) { 42 | super(buf); 43 | } 44 | 45 | public SegmentMessage(int id, boolean add, int index, Vec pos, Direction topfacing, Direction bottomfacing) { 46 | this.id = id; 47 | this.add = add; 48 | this.index = index; 49 | this.pos = pos; 50 | this.topFacing = topfacing; 51 | this.bottomFacing = bottomfacing; 52 | } 53 | 54 | public void decode(FriendlyByteBuf buf) { 55 | this.id = buf.readInt(); 56 | this.add = buf.readBoolean(); 57 | this.index = buf.readInt(); 58 | this.pos = new Vec(buf.readDouble(), buf.readDouble(), buf.readDouble()); 59 | this.topFacing = buf.readEnum(Direction.class); 60 | this.bottomFacing = buf.readEnum(Direction.class); 61 | } 62 | 63 | public void encode(FriendlyByteBuf buf) { 64 | buf.writeInt(this.id); 65 | buf.writeBoolean(this.add); 66 | buf.writeInt(this.index); 67 | buf.writeDouble(pos.x); 68 | buf.writeDouble(pos.y); 69 | buf.writeDouble(pos.z); 70 | buf.writeEnum(this.topFacing); 71 | buf.writeEnum(this.bottomFacing); 72 | } 73 | 74 | @OnlyIn(Dist.CLIENT) 75 | public void processMessage(NetworkEvent.Context ctx) { 76 | Level world = Minecraft.getInstance().level; 77 | Entity grapple = world.getEntity(this.id); 78 | if (grapple == null) { 79 | return; 80 | } 81 | 82 | if (grapple instanceof GrapplehookEntity) { 83 | SegmentHandler segmenthandler = ((GrapplehookEntity) grapple).segmentHandler; 84 | if (this.add) { 85 | segmenthandler.actuallyAddSegment(this.index, this.pos, this.bottomFacing, this.topFacing); 86 | } else { 87 | segmenthandler.removeSegment(this.index); 88 | } 89 | } else { 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/server/ServerControllerManager.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.server; 2 | 3 | import com.yyon.grapplinghook.entities.grapplehook.GrapplehookEntity; 4 | import net.minecraft.world.entity.Entity; 5 | import net.minecraft.world.level.Level; 6 | 7 | import java.util.HashMap; 8 | import java.util.HashSet; 9 | 10 | public class ServerControllerManager { 11 | public static HashSet attached = new HashSet(); // server side 12 | public static HashMap> allGrapplehookEntities = new HashMap>(); // server side 13 | 14 | public static void addGrapplehookEntity(int id, GrapplehookEntity hookEntity) { 15 | if (!allGrapplehookEntities.containsKey(id)) { 16 | allGrapplehookEntities.put(id, new HashSet()); 17 | } 18 | allGrapplehookEntities.get(id).add(hookEntity); 19 | } 20 | 21 | public static void removeAllMultiHookGrapplehookEntities(int id) { 22 | if (!allGrapplehookEntities.containsKey(id)) { 23 | allGrapplehookEntities.put(id, new HashSet()); 24 | } 25 | for (GrapplehookEntity hookEntity : allGrapplehookEntities.get(id)) { 26 | if (hookEntity != null && hookEntity.isAlive()) { 27 | hookEntity.removeServer(); 28 | } 29 | } 30 | allGrapplehookEntities.put(id, new HashSet()); 31 | } 32 | 33 | public static void receiveGrappleEnd(int id, Level world, HashSet hookEntityIds) { 34 | if (attached.contains(id)) { 35 | attached.remove(id); 36 | } else { 37 | } 38 | 39 | for (int hookEntityId : hookEntityIds) { 40 | Entity grapple = world.getEntity(hookEntityId); 41 | if (grapple instanceof GrapplehookEntity) { 42 | ((GrapplehookEntity) grapple).removeServer(); 43 | } else { 44 | 45 | } 46 | } 47 | 48 | Entity entity = world.getEntity(id); 49 | if (entity != null) { 50 | entity.fallDistance = 0; 51 | } 52 | 53 | removeAllMultiHookGrapplehookEntities(id); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/utils/GrapplemodUtils.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.utils; 2 | 3 | import com.yyon.grapplinghook.common.CommonSetup; 4 | import net.minecraft.server.level.ServerPlayer; 5 | import net.minecraft.world.entity.Entity; 6 | import net.minecraft.world.level.ClipContext; 7 | import net.minecraft.world.level.Level; 8 | import net.minecraft.world.phys.BlockHitResult; 9 | import net.minecraft.world.phys.HitResult; 10 | import net.minecraftforge.network.PacketDistributor; 11 | 12 | public class GrapplemodUtils { 13 | public static void sendToCorrectClient(Object message, int playerid, Level w) { 14 | Entity entity = w.getEntity(playerid); 15 | if (entity instanceof ServerPlayer) { 16 | CommonSetup.network.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) entity), message); 17 | } else { 18 | System.out.println("ERROR! couldn't find player"); 19 | } 20 | } 21 | 22 | public static BlockHitResult rayTraceBlocks(Level world, Vec from, Vec to) { 23 | HitResult result = world.clip(new ClipContext(from.toVec3d(), to.toVec3d(), ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null)); 24 | if (result != null && result instanceof BlockHitResult) { 25 | BlockHitResult blockhit = (BlockHitResult) result; 26 | if (blockhit.getType() != HitResult.Type.BLOCK) { 27 | return null; 28 | } 29 | return blockhit; 30 | } 31 | return null; 32 | } 33 | 34 | public static long getTime(Level w) { 35 | return w.getGameTime(); 36 | } 37 | 38 | private static int controllerid = 0; 39 | public static int GRAPPLEID = controllerid++; 40 | public static int REPELID = controllerid++; 41 | public static int AIRID = controllerid++; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/yyon/grapplinghook/utils/Vec.java: -------------------------------------------------------------------------------- 1 | package com.yyon.grapplinghook.utils; 2 | 3 | import com.mojang.math.Vector3f; 4 | import com.yyon.grapplinghook.grapplemod; 5 | import net.minecraft.world.entity.Entity; 6 | import net.minecraft.world.phys.Vec3; 7 | 8 | public class Vec { 9 | public double x; 10 | public double y; 11 | public double z; 12 | 13 | public Vec(double x, double y, double z) { 14 | this.x = x; 15 | this.y = y; 16 | this.z = z; 17 | 18 | this.checkNaN(); 19 | } 20 | 21 | public void checkNaN() { 22 | if (Double.isNaN(x) || Double.isNaN(y) || Double.isNaN(z)) { 23 | grapplemod.LOGGER.error("Error: vector contains NaN"); 24 | this.x = 0; this.y = 0; this.z = 0; 25 | // throw new RuntimeException("hello"); 26 | } 27 | } 28 | 29 | public Vec(Vec3 vec3d) { 30 | this.x = vec3d.x; 31 | this.y = vec3d.y; 32 | this.z = vec3d.z; 33 | 34 | this.checkNaN(); 35 | } 36 | 37 | public Vec(Vec vec) { 38 | this.x = vec.x; 39 | this.y = vec.y; 40 | this.z = vec.z; 41 | } 42 | 43 | public Vec(Vector3f vec) { 44 | this.x = vec.x(); 45 | this.y = vec.y(); 46 | this.z = vec.z(); 47 | } 48 | 49 | public Vec3 toVec3d() { 50 | return new Vec3(this.x, this.y, this.z); 51 | } 52 | 53 | public Vector3f toVector3f() { 54 | return new Vector3f((float) this.x, (float) this.y, (float) this.z); 55 | } 56 | 57 | public static Vec positionVec(Entity e) { 58 | return new Vec(e.position()); 59 | } 60 | 61 | public static Vec partialPositionVec(Entity e, double partialTicks) { 62 | return new Vec(lerp(partialTicks, e.xo, e.getX()), lerp(partialTicks, e.yo, e.getY()), lerp(partialTicks, e.zo, e.getZ())); 63 | } 64 | 65 | public static double lerp(double frac, double from, double to) { 66 | return (from * (1-frac)) + (to * frac); 67 | } 68 | 69 | public static Vec motionVec(Entity e) { 70 | return new Vec(e.getDeltaMovement()); 71 | } 72 | 73 | public Vec add(Vec v2) { 74 | return new Vec(this.x + v2.x, this.y + v2.y, this.z + v2.z); 75 | } 76 | 77 | public void add_ip(double x, double y, double z) { 78 | this.x += x; 79 | this.y += y; 80 | this.z += z; 81 | } 82 | 83 | public void add_ip(Vec v2) { 84 | this.x += v2.x; 85 | this.y += v2.y; 86 | this.z += v2.z; 87 | } 88 | 89 | public Vec sub(Vec v2) { 90 | return new Vec(this.x - v2.x, this.y - v2.y, this.z - v2.z); 91 | } 92 | 93 | public void sub_ip(Vec v2) { 94 | this.x -= v2.x; 95 | this.y -= v2.y; 96 | this.z -= v2.z; 97 | } 98 | 99 | public Vec rotateYaw(double a) { 100 | return new Vec(this.x * Math.cos(a) - this.z * Math.sin(a), this.y, this.x * Math.sin(a) + this.z * Math.cos(a)); 101 | } 102 | 103 | public Vec rotatePitch(double pitch) { 104 | return new Vec(this.x, this.y * Math.cos(pitch) + this.z * Math.sin(pitch), this.z * Math.cos(pitch) - this.y * Math.sin(pitch)); 105 | } 106 | 107 | public static Vec fromAngles(double yaw, double pitch) { 108 | return new Vec(Math.tan(-yaw), Math.tan(pitch), 1).normalize(); 109 | } 110 | 111 | public Vec mult(double changefactor) { 112 | return new Vec(this.x * changefactor, this.y * changefactor, this.z * changefactor); 113 | } 114 | 115 | public void mult_ip(double changefactor) { 116 | this.x *= changefactor; 117 | this.y *= changefactor; 118 | this.z *= changefactor; 119 | } 120 | 121 | public double length() { 122 | return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2) + Math.pow(this.z, 2)); 123 | } 124 | 125 | public Vec normalize() { 126 | if (this.length() == 0) { 127 | grapplemod.LOGGER.warn("normalizing vector with no length"); 128 | return new Vec(this); 129 | } 130 | return this.mult(1.0 / this.length()); 131 | } 132 | 133 | public void normalize_ip() { 134 | this.mult_ip(1.0 / this.length()); 135 | } 136 | 137 | public double dot(Vec v2) { 138 | return this.x*v2.x + this.y*v2.y + this.z*v2.z; 139 | } 140 | 141 | public Vec changeLen(double l) { 142 | double oldl = this.length(); 143 | if (oldl != 0) { 144 | double changefactor = l / oldl; 145 | return this.mult(changefactor); 146 | } else { 147 | return this; 148 | } 149 | } 150 | 151 | public void changeLen_ip(double l) { 152 | double oldl = this.length(); 153 | if (oldl != 0) { 154 | double changefactor = l / oldl; 155 | this.mult_ip(changefactor); 156 | } 157 | } 158 | 159 | public Vec proj(Vec v2) { 160 | Vec v3 = v2.normalize(); 161 | double dot = this.dot(v3); 162 | return v3.changeLen(dot); 163 | } 164 | 165 | public double distAlong(Vec v2) { 166 | Vec v3 = v2.normalize(); 167 | return this.dot(v3); 168 | } 169 | 170 | public Vec removeAlong(Vec v2) { 171 | return this.sub(this.proj(v2)); 172 | } 173 | 174 | public void print(){ 175 | System.out.println(this.toString()); 176 | } 177 | 178 | public String toString() { 179 | return "<" + Double.toString(this.x) + "," + Double.toString(this.y) + "," + Double.toString(this.z) + ">"; 180 | } 181 | 182 | public Vec add(double x, double y, double z) { 183 | return new Vec(this.x + x, this.y + y, this.z + z); 184 | } 185 | 186 | public double getYaw() { 187 | Vec norm = this.normalize(); 188 | return Math.toDegrees(-Math.atan2(norm.x, norm.z)); 189 | } 190 | 191 | public double getPitch() { 192 | Vec norm = this.normalize(); 193 | return Math.toDegrees(-Math.asin(norm.y)); 194 | } 195 | 196 | public Vec cross(Vec b) { 197 | return new Vec(this.y * b.z - this.z * b.y, this.z * b.x - this.x * b.z, this.x * b.y - this.y * b.x); 198 | } 199 | 200 | public double angle(Vec b) { 201 | double la = this.length(); 202 | double lb = b.length(); 203 | if (la == 0 || lb == 0) { return 0; } 204 | return Math.acos(this.dot(b) / (la*lb)); 205 | } 206 | 207 | public void setPos(Entity e) { 208 | this.checkNaN(); 209 | 210 | e.setPos(this.x, this.y, this.z); 211 | } 212 | 213 | public void setMotion(Entity e) { 214 | this.checkNaN(); 215 | 216 | e.setDeltaMovement(this.toVec3d()); 217 | } 218 | 219 | public static Vec lookVec(Entity entity) { 220 | return new Vec(entity.getLookAngle()); 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml 2 | modLoader="javafml" #mandatory 3 | # A version range to match for said mod loader - for regular FML @Mod it will be the forge version 4 | loaderVersion="${loader_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. 5 | 6 | license="GPL-3.0" 7 | 8 | [[mods]] #mandatory 9 | # The modid of the mod 10 | modId="${mod_id}" #mandatory 11 | # The version number of the mod 12 | version="${mod_version}" #mandatory 13 | # A display name for the mod 14 | displayName="${mod_name}" #mandatory 15 | 16 | authors="${mod_authors}" #optional 17 | # The description text for the mod (multi line!) (#mandatory) 18 | description='''${mod_description}''' 19 | # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. 20 | [[dependencies.${mod_id}]] #optional 21 | # the modid of the dependency 22 | modId="forge" #mandatory 23 | # Does this dependency have to exist - if not, ordering below must be specified 24 | mandatory=true #mandatory 25 | # The version range of the dependency 26 | versionRange="${forge_version_range}" #mandatory 27 | # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory 28 | ordering="NONE" 29 | # Side this dependency is applied on - BOTH, CLIENT or SERVER 30 | side="BOTH" 31 | # Here's another dependency 32 | [[dependencies.${mod_id}]] 33 | modId="minecraft" 34 | mandatory=true 35 | # This version range declares a minimum of the current minecraft version up to but not including the next major version 36 | versionRange="${minecraft_version_range}" 37 | ordering="NONE" 38 | side="BOTH" 39 | 40 | [[dependencies.${mod_id}]] 41 | modId="cloth_config" 42 | mandatory=true 43 | versionRange="[8, 9)" 44 | ordering="NONE" 45 | side="BOTH" 46 | -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/blockstates/block_grapple_modifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { "model": "grapplemod:block/block_grapple_modifier" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/lang/fr_fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "item.grapplinghook": "Grappin", 3 | "item.motorhook": "Grappin motorisé", 4 | "item.launcheritem": "Bâton de l'Ender", 5 | "item.longfallboots": "Bottes de longue chute", 6 | "item.enderhook": "Grappin de l'Ender", 7 | "item.magnethook": "Grappin magnétique", 8 | "item.repeller": "Champ de force magnétique", 9 | "item.doublemotorhook": "Double grappin motorisé", 10 | "item.smarthook": "Grappin motorisé intelligent", 11 | "item.baseupgradeitem": "Base d'amélioration de grappin", 12 | "item.doubleupgradeitem": "Amélioration double grappin", 13 | "item.forcefieldupgradeitem": "Amélioration grappin champ de force", 14 | "item.motorupgradeitem": "Amélioration grappin motorisé", 15 | "item.magnetupgradeitem": "Amélioration grappin aimanté", 16 | "item.ropeupgradeitem": "Amélioration corde de grappin", 17 | "item.staffupgradeitem": "Amélioration grappin bâton de l'Ender", 18 | "item.swingupgradeitem": "Amélioration balancement de grappin", 19 | "item.throwupgradeitem": "Amélioration lancement de grappin", 20 | "item.limitsupgradeitem": "Amélioration limites de grappin", 21 | "block.block_grapple_modifier": "Modificateur de grappin" 22 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/lang/pt_br.json: -------------------------------------------------------------------------------- 1 | { 2 | "item.grapplinghook": "Gancho de Escalada", 3 | "item.motorhook": "Gancho de Escalada Motorizado", 4 | "item.launcheritem": "Cajado do Fim", 5 | "item.longfallboots": "Botas de Queda Longa", 6 | "item.enderhook": "Gancho de Escalada do Fim", 7 | "item.magnethook": "Gancho de Escalada Magnético", 8 | "item.repeller": "Campo de Força Magnético", 9 | "item.doublemotorhook": "Gancho de Escalada Duplamente Motorizado", 10 | "item.smarthook": "Gancho de Escalada Motorizado Inteligente", 11 | "item.baseupgradeitem": "Melhoria de Gancho de Escalada inicial", 12 | "item.doubleupgradeitem": "Melhoria de Gancho de Escalada dupla", 13 | "item.forcefieldupgradeitem": "Melhoria de Gancho de Escalada de Campo de Força", 14 | "item.motorupgradeitem": "Melhoria de Motor de Gancho de Escalada", 15 | "item.magnetupgradeitem": "Melhoria de Magnetismo de Gancho de Escalada", 16 | "item.ropeupgradeitem": "Melhoria de Corda de Gancho de Escalada", 17 | "item.staffupgradeitem": "Melhoria de Cajado do Fim de Gancho de Escalada", 18 | "item.swingupgradeitem": "Melhoria de Balanço de Gancho de Escalada", 19 | "item.throwupgradeitem": "Melhoria de Lançador de Gancho de Gancho de Escalada", 20 | "item.limitsupgradeitem": "Melhoria de Limite de Gancho de Escalada", 21 | "block.block_grapple_modifier": "Modificador de Gancho de Escalada" 22 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/block/block_grapple_modifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:block/cube_all", 3 | "textures": { 4 | "all": "grapplemod:block/grapplemodifier" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/baseupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/baseupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/block_grapple_modifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "grapplemod:block/block_grapple_modifier" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/doublejumpboots.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "minecraft:items/diamond_boots" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/doublemotorhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/multihook" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/doublemotorhookrope.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/multihookrope" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/doubleupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/doubleupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/enderhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/enderhook" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/forcefieldupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/forcefieldupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/grapplinghook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/grapplinghook" 5 | }, 6 | "overrides": [ 7 | { "predicate": { "attached": 1 }, "model": "grapplemod:item/rope" }, 8 | { "predicate": { "magnet": 1, "attached": 0 }, "model": "grapplemod:item/magnethook" }, 9 | { "predicate": { "magnet": 1, "attached": 1 }, "model": "grapplemod:item/rope" }, 10 | { "predicate": { "enderstaff": 1, "attached": 0 }, "model": "grapplemod:item/enderhook" }, 11 | { "predicate": { "enderstaff": 1, "attached": 1 }, "model": "grapplemod:item/rope" }, 12 | { "predicate": { "motor": 1, "attached": 0 }, "model": "grapplemod:item/motorhook" }, 13 | { "predicate": { "motor": 1, "attached": 1 }, "model": "grapplemod:item/motorhookrope" }, 14 | { "predicate": { "motor": 1, "smart": 1, "attached": 0 }, "model": "grapplemod:item/smarthook" }, 15 | { "predicate": { "motor": 1, "smart": 1, "attached": 1 }, "model": "grapplemod:item/smarthookrope" }, 16 | { "predicate": { "motor": 1, "double": 1, "attached": 0 }, "model": "grapplemod:item/doublemotorhook" }, 17 | { "predicate": { "motor": 1, "double": 1, "attached": 1 }, "model": "grapplemod:item/doublemotorhookrope" }, 18 | { "predicate": { "rocket": 1, "attached": 0 }, "model": "grapplemod:item/rockethook" }, 19 | { "predicate": { "rocket": 1, "attached": 1 }, "model": "grapplemod:item/rockethookrope" }, 20 | { "predicate": { "rocket": 1, "double": 1, "attached": 0 }, "model": "grapplemod:item/rocketdoublemotorhook" }, 21 | { "predicate": { "rocket": 1, "double": 1, "attached": 1 }, "model": "grapplemod:item/rocketdoublemotorhookrope" }, 22 | { "predicate": { "hook": 1 }, "model": "grapplemod:item/hook" } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/hook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:entity/hook" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/launcheritem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/launcheritem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/limitsupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/limitsupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/longfallboots.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/longfallboots" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/magnethook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/magnetbow" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/magnetupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/magnetupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/motorhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/hookshot" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/motorhookrope.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/hookshotrope" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/motorupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/motorupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/repeller.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/repeller" 5 | }, 6 | "overrides": [ 7 | { "predicate": { "attached": 1 }, "model": "grapplemod:item/repelleron" } 8 | ] 9 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/repelleron.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/repelleron" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/rocketdoublemotorhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/odm" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/rocketdoublemotorhookrope.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/odmrope" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/rockethook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/rocket" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/rockethookrope.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/rocketrope" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/rocketupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/rocketupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/rope.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/rope" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/ropeupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/ropeupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/smarthook.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/smarthook" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/smarthookrope.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/smarthookrope" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/staffupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/staffupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/swingupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/swingupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/throwupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "grapplemod:items/throwupgradeitem" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/models/item/wallrunboots.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/handheld", 3 | "textures": { 4 | "layer0": "minecraft:items/diamond_boots" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds.json: -------------------------------------------------------------------------------- 1 | { 2 | "slide": { 3 | "category": "player", 4 | "subtitle": "grapplemod.subtitle.slide", 5 | "sounds": [ "grapplemod:slide1", "grapplemod:slide2", "grapplemod:slide3" ] 6 | }, 7 | "doublejump": { 8 | "category": "player", 9 | "subtitle": "grapplemod.subtitle.doublejump", 10 | "sounds": [ "grapplemod:jump1", "grapplemod:jump2", "grapplemod:jump3", "grapplemod:jump4" ] 11 | }, 12 | "rocket": { 13 | "category": "player", 14 | "subtitle": "grapplemod.subtitle.rocket", 15 | "sounds": [ "grapplemod:rocket"] 16 | }, 17 | "enderstaff": { 18 | "category": "player", 19 | "subtitle": "grapplemod.subtitle.enderstaff", 20 | "sounds": [ "grapplemod:enderstaff"] 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/enderstaff.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/enderstaff.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/jump1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/jump1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/jump2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/jump2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/jump3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/jump3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/jump4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/jump4.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/rocket.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/rocket.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/slide1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/slide1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/slide2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/slide2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/sounds/slide3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/sounds/slide3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/block/grapplemodifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/block/grapplemodifier.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/entity/hook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/entity/hook.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/entity/hook.png.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/entity/hook.png.bak -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/entity/rope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/entity/rope.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/gui/guimodifier_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/gui/guimodifier_bg.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/gui/jei_modifier_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/gui/jei_modifier_bg.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/baseupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/baseupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/doubleupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/doubleupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/enderhook-export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/enderhook-export.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/enderhook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/enderhook.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/forcefieldupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/forcefieldupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/grapplinghook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/grapplinghook.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/hook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/hook.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/hookshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/hookshot.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/hookshotrope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/hookshotrope.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/launcheritem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/launcheritem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/limitsupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/limitsupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/longfallboots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/longfallboots.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/magnetbow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/magnetbow.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/magnetupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/magnetupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/motorupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/motorupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/multihook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/multihook.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/multihookrope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/multihookrope.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/odm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/odm.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/odmrope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/odmrope.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/repeller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/repeller.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/repelleron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/repelleron.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/rocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/rocket.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/rocketrope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/rocketrope.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/rocketupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/rocketupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/rope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/rope.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/ropeupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/ropeupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/smarthook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/smarthook.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/smarthookrope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/smarthookrope.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/staffupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/staffupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/swingupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/swingupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/throwupgradeitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/throwupgradeitem.png -------------------------------------------------------------------------------- /src/main/resources/assets/grapplemod/textures/items/wallrunboots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/assets/grapplemod/textures/items/wallrunboots.png -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/baseupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " 2 ", 5 | "242", 6 | " 4 " 7 | ], 8 | "key": { 9 | "2": { 10 | "item": "minecraft:gold_ingot" 11 | }, 12 | "4": { 13 | "item": "minecraft:string" 14 | } 15 | }, 16 | "result": { 17 | "item": "grapplemod:baseupgradeitem" 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/block_grapple_modifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " 2 ", 5 | "242", 6 | " 2 " 7 | ], 8 | "key": { 9 | "2": { 10 | "item": "grapplemod:baseupgradeitem" 11 | }, 12 | "4": { 13 | "item": "minecraft:anvil", 14 | "data": 0 15 | } 16 | }, 17 | "result": { 18 | "item": "grapplemod:block_grapple_modifier" 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/doublemotorhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:grapplinghook" 6 | }, 7 | { 8 | "item": "grapplemod:grapplinghook" 9 | }, 10 | { 11 | "item": "grapplemod:motorupgradeitem" 12 | } 13 | ], 14 | "result": { 15 | "item": "grapplemod:grapplinghook", 16 | "nbt": { "custom": { 17 | "maxlen": 60, 18 | 19 | "doublehook": true, 20 | "motor": true, 21 | "motormaxspeed": 10, 22 | "sticky": true, 23 | 24 | "hookgravity": 50, 25 | "verticalthrowangle": 30, 26 | "sneakingverticalthrowangle": 25, 27 | "reelin": false, 28 | 29 | "motorwhencrouching": true, 30 | 31 | "smartdoublemotor": true, 32 | 33 | "angle": 25, 34 | "sneakingangle": 0, 35 | 36 | "throwspeed": 20, 37 | 38 | "playermovementmult": 2 39 | }} 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/doubleupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "grapplemod:grapplinghook" 9 | }, 10 | { 11 | "item": "grapplemod:grapplinghook" 12 | } 13 | ], 14 | "result": { 15 | "item": "grapplemod:doubleupgradeitem" 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/enderhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:grapplinghook" 6 | }, 7 | { 8 | "item": "grapplemod:staffupgradeitem" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:grapplinghook", 13 | "nbt": { "custom": { 14 | "throwspeed": 3.5, 15 | "maxlen": 60, 16 | 17 | "enderstaff": true 18 | }} 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/forcefieldupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "grapplemod:repeller" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:forcefieldupgradeitem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/grapplebow.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "minecraft:iron_pickaxe" 6 | }, 7 | { 8 | "item": "minecraft:lead" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:grapplinghook" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/launcher.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "minecraft:ender_pearl" 6 | }, 7 | { 8 | "item": "minecraft:piston" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:launcheritem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/limitsupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "minecraft:nether_star" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:limitsupgradeitem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/magnethook.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:grapplinghook" 6 | }, 7 | { 8 | "item": "grapplemod:forcefieldupgradeitem" 9 | }, 10 | { 11 | "item": "grapplemod:magnetupgradeitem" 12 | } 13 | ], 14 | "result": { 15 | "item": "grapplemod:grapplinghook", 16 | "nbt": { "custom": { 17 | "throwspeed": 3.5, 18 | "maxlen": 60, 19 | 20 | "attract": true, 21 | "repel": true 22 | }} 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/magnetupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "minecraft:compass" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:magnetupgradeitem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/motorhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:grapplinghook" 6 | }, 7 | { 8 | "item": "grapplemod:motorupgradeitem" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:grapplinghook", 13 | "nbt": { "custom": { 14 | "throwspeed": 3.5, 15 | "maxlen": 60, 16 | 17 | "motor": true, 18 | "playermovementmult": 2 19 | }} 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/motorupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "minecraft:piston" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:motorupgradeitem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/repeller.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " 2 ", 5 | "242", 6 | " 2 " 7 | ], 8 | "key": { 9 | "2": { 10 | "item": "minecraft:iron_ingot" 11 | }, 12 | "4": { 13 | "item": "minecraft:compass" 14 | } 15 | }, 16 | "result": { 17 | "item": "grapplemod:repeller" 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/rocketdoublemotorhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:grapplinghook" 6 | }, 7 | { 8 | "item": "grapplemod:grapplinghook" 9 | }, 10 | { 11 | "item": "grapplemod:motorupgradeitem" 12 | }, 13 | { 14 | "item": "grapplemod:rocketupgradeitem" 15 | } 16 | ], 17 | "result": { 18 | "item": "grapplemod:grapplinghook", 19 | "nbt": { "custom": { 20 | "maxlen": 60, 21 | 22 | "doublehook": true, 23 | "motor": true, 24 | "motormaxspeed": 10, 25 | "sticky": true, 26 | 27 | "hookgravity": 50, 28 | "verticalthrowangle": 30, 29 | "sneakingverticalthrowangle": 25, 30 | "reelin": false, 31 | 32 | "motorwhencrouching": true, 33 | 34 | "smartdoublemotor": true, 35 | 36 | "angle": 25, 37 | "sneakingangle": 0, 38 | 39 | "rocket": true, 40 | "rocket_vertical_angle": 30, 41 | 42 | "throwspeed": 20, 43 | 44 | "playermovementmult": 2 45 | }} 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/rockethook.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:grapplinghook" 6 | }, 7 | { 8 | "item": "grapplemod:rocketupgradeitem" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:grapplinghook", 13 | "nbt": { "custom": { 14 | "throwspeed": 3.5, 15 | "maxlen": 60, 16 | 17 | "rocket": true 18 | }} 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/rocketupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "minecraft:firework_rocket" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:rocketupgradeitem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/ropeupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "minecraft:lead" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:ropeupgradeitem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/smarthook.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:grapplinghook" 6 | }, 7 | { 8 | "item": "grapplemod:motorupgradeitem" 9 | }, 10 | { 11 | "item": "minecraft:redstone" 12 | } 13 | ], 14 | "result": { 15 | "item": "grapplemod:grapplinghook", 16 | "nbt": { "custom": { 17 | "throwspeed": 3.5, 18 | "maxlen": 60, 19 | 20 | "motor": true, 21 | "smartmotor": true, 22 | "playermovementmult": 2 23 | }} 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/staffupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "grapplemod:launcheritem" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:staffupgradeitem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/swingupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "minecraft:leather_boots" 9 | }, 10 | { 11 | "item": "minecraft:feather" 12 | } 13 | ], 14 | "result": { 15 | "item": "grapplemod:swingupgradeitem" 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/data/grapplemod/recipes/throwupgradeitem.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "grapplemod:baseupgradeitem" 6 | }, 7 | { 8 | "item": "minecraft:bow" 9 | } 10 | ], 11 | "result": { 12 | "item": "grapplemod:throwupgradeitem" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/grapplemod.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "com.yyon.grapplinghook.mixins", 4 | "compatibilityLevel": "JAVA_17", 5 | "refmap": "${mod_id}.refmap.json", 6 | "mixins": [ 7 | ], 8 | "client": [], 9 | "minVersion": "0.8.4" 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyon/grapplemod/61dd2af68a403dc9f6dbb6e659bfffa4b9bbad5f/src/main/resources/icon.png -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "grapplemod resources", 4 | "pack_format": 6, 5 | "_comment": "A pack_format of 6 requires json lang files and some texture changes from 1.16.2. Note: we require v6 pack meta for all mods." 6 | } 7 | } 8 | --------------------------------------------------------------------------------