├── .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 extends ModifierRecipes> 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 | 
--------------------------------------------------------------------------------