├── .editorconfig
├── .github
├── FUNDING.yml
└── workflows
│ └── gradle.yml
├── .gitignore
├── LICENSE
├── README.md
├── build.gradle.kts
├── changelogs
├── 1.6.0.md
├── 1.6.1.md
├── 1.6.2.md
├── 1.7.0.md
├── 1.7.1.md
├── 2.0.0.md
├── 2.0.1.md
├── 2.0.2.md
├── 2.0.3.md
├── 2.10.0.md
├── 2.11.0.md
├── 2.11.1.md
├── 2.11.2.md
├── 2.12.0.md
├── 2.13.1.md
├── 2.13.2.md
├── 2.13.3.md
├── 2.13.4.md
├── 2.13.5.md
├── 2.14.0.md
├── 2.2.0.md
├── 2.3.0.md
├── 2.4.0.md
├── 2.4.1.md
├── 2.4.2.md
├── 2.5.0.md
├── 2.6.0.md
├── 2.7.0.md
├── 2.8.0.md
├── 2.9.0.md
├── 2.9.1.md
├── 2.9.2.md
├── 2.9.3.md
└── 2.9.4.md
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── screenshots
├── affect-hand-fov-disabled-example.gif
├── cinematic-cam-example.gif
├── individual-transition.png
├── keybind-conflict-detection.png
├── relative-sensitivity-example.gif
├── relative-view-bobbing-example.gif
├── scroll-zoom-example.gif
├── secondary-zoom.gif
├── spyglass-integration-example.gif
├── zoom-example.gif
├── zoom-hand.webp
└── zoom-world.webp
├── settings.gradle.kts
├── src
└── main
│ ├── java
│ └── dev
│ │ └── isxander
│ │ └── zoomify
│ │ └── mixins
│ │ ├── hooks
│ │ └── MinecraftClientMixin.java
│ │ ├── spyglass
│ │ ├── AbstractClientPlayerEntityMixin.java
│ │ ├── InGameHudMixin.java
│ │ └── SpyglassItemMixin.java
│ │ └── zoom
│ │ ├── GameRendererMixin.java
│ │ ├── MouseMixin.java
│ │ └── secondary
│ │ └── GameRendererMixin.java
│ ├── kotlin
│ └── dev
│ │ └── isxander
│ │ └── zoomify
│ │ ├── Zoomify.kt
│ │ ├── config
│ │ ├── Presets.kt
│ │ ├── SettingsGuiFactory.kt
│ │ ├── SpyglassBehaviour.kt
│ │ ├── ZoomKeyBehaviour.kt
│ │ ├── ZoomifySettings.kt
│ │ ├── demo
│ │ │ ├── ControlEmulation.kt
│ │ │ └── ZoomDemoImageRenderer.kt
│ │ └── migrator
│ │ │ ├── Migration.kt
│ │ │ ├── MigrationAvailableScreen.kt
│ │ │ ├── MigrationResultScreen.kt
│ │ │ ├── Migrator.kt
│ │ │ └── impl
│ │ │ └── OkZoomerMigrator.kt
│ │ ├── integrations
│ │ ├── ControlifyIntegration.kt
│ │ ├── IntegrationHelper.kt
│ │ └── ModMenuIntegration.kt
│ │ ├── utils
│ │ ├── KeySource.kt
│ │ ├── MinecraftExt.kt
│ │ ├── NameableEnumKt.kt
│ │ └── TransitionType.kt
│ │ └── zoom
│ │ ├── DefaultZoomHelpers.kt
│ │ ├── Interpolator.kt
│ │ └── ZoomHelper.kt
│ └── resources
│ ├── assets
│ └── zoomify
│ │ ├── lang
│ │ ├── de_de.json
│ │ ├── en_gb.json
│ │ ├── en_us.json
│ │ ├── es_es.json
│ │ ├── es_mx.json
│ │ ├── et_ee.json
│ │ ├── fr_fr.json
│ │ ├── ja_jp.json
│ │ ├── pt_br.json
│ │ ├── ru_ru.json
│ │ ├── sv_se.json
│ │ ├── tr_tr.json
│ │ ├── vi_vn.json
│ │ ├── zh_cn.json
│ │ └── zh_tw.json
│ │ ├── textures
│ │ └── demo
│ │ │ ├── third-person-hud.webp
│ │ │ ├── third-person-view.webp
│ │ │ ├── zoom-hand.webp
│ │ │ └── zoom-world.webp
│ │ └── zoomify.png
│ ├── fabric.mod.json
│ └── zoomify.mixins.json
├── stonecutter.gradle.kts
└── versions
├── 1.20.1
└── gradle.properties
├── 1.20.4
└── gradle.properties
├── 1.20.6
└── gradle.properties
├── 1.21.1
└── gradle.properties
└── 1.21.3
└── gradle.properties
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: isxander
2 |
--------------------------------------------------------------------------------
/.github/workflows/gradle.yml:
--------------------------------------------------------------------------------
1 | name: Gradle CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - '**'
7 | paths-ignore:
8 | - 'README.md'
9 | - 'LICENSE'
10 | - '.gitignore'
11 | - '.editorconfig'
12 | - 'changelogs/**'
13 | pull_request:
14 | branches:
15 | - '**'
16 | paths-ignore:
17 | - 'README.md'
18 | - 'LICENSE'
19 | - '.gitignore'
20 | - '.editorconfig'
21 | - 'changelogs/**'
22 | - 'src/*/resources/lang/*'
23 | workflow_dispatch:
24 | jobs:
25 | build:
26 | runs-on: ubuntu-latest
27 | name: Build with gradle
28 |
29 | steps:
30 | - uses: actions/checkout@v4
31 | - name: Set up JDK
32 | uses: actions/setup-java@v4
33 | with:
34 | java-version: 21
35 | distribution: temurin
36 | - name: Grant execute permission for gradlew
37 | run: chmod +x gradlew
38 | - name: Build with Gradle
39 | uses: Wandalen/wretry.action@master
40 | with:
41 | command: ./gradlew buildAllVersions --stacktrace
42 | - uses: actions/upload-artifact@v4
43 | with:
44 | path: versions/**/build/libs/*.jar
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | run
2 | build
3 | /.idea
4 | .gradle
5 | !.gitkeep
6 | .kotlin
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | # Zoomify
6 |
7 | [](https://fabricmc.net)
8 | 
9 | [](https://short.isxander.dev/discord)
10 |
11 | [](https://modrinth.com/mod/zoomify)
12 | [](https://curseforge.com/minecraft/mc-mods/zoomify)
13 |
14 | [](https://ko-fi.com/isxander)
15 |
16 | *A zoom mod with infinite customizability.*
17 |
18 | Zoomify aims to provide the easiest, most configurable and most sexy looking zoom mod you will ever find.
19 |
20 | 
21 |
22 | [](https://bisecthosting.com/xander)
23 |
24 |
25 |
26 | ## How to use
27 | ### Keybind
28 | Initially, Minecraft has a keybind that overrides Zoomify by default.
29 | Go to the controls menu and make sure the Zoomify keybind (default `C`)
30 | isn't conflicting (goes red).
31 |
32 | ### Open settings menu
33 | You can access the settings menu with two ways.
34 |
35 | - The client command `/zoomify`
36 | - [Mod Menu](https://modrinth.com/mod/modmenu) settings button
37 |
38 | ## Features
39 | ### Scroll Zoom
40 | You can zoom in further using your scroll wheel.
41 |
42 | 
43 |
44 | ### Spyglass Integration
45 | You can configure Zoomify to only be able to zoom in when you are holding or carrying a spyglass.
46 | Or even just override the spyglass zoom with Zoomify!
47 |
48 | Show the spyglass overlay and play spyglass sound effects when using Zoomify.
49 |
50 | 
51 |
52 | ### Transitions
53 | **14 different** transitions to choose from!
54 |
55 | - Instant
56 | - Linear
57 | - [Ease in Sine](https://easings.net/#easeInSine)
58 | - [Ease out Sine](https://easings.net/#easeOutSine)
59 | - [Ease in/out Sine](https://easings.net/#easeInOutSine)
60 | - [Ease in Quad](https://easings.net/#easeInQuad)
61 | - [Ease out Quad](https://easings.net/#easeOutQuad)
62 | - [Ease in/out Quad](https://easings.net/#easeInOutQuad)
63 | - [Ease in Cubic](https://easings.net/#easeInCubic)
64 | - [Ease out Cubic](https://easings.net/#easeOutCubic)
65 | - [Ease in/out Cubic](https://easings.net/#easeInOutCubic)
66 | - [Ease in Exponential](https://easings.net/#easeInExp)
67 | - [Ease out Exponential](https://easings.net/#easeOutExp)
68 | - [Ease in/out Exponential](https://easings.net/#easeInOutExp)
69 |
70 | You can even pick what transition you would like for zooming in and out individually!
71 |
72 | 
73 |
74 | ### Relative Sensitivity
75 | Reduce your mouse sensitivity based on the amount of zoom,
76 | so you have fine control over your player.
77 |
78 | 
79 |
80 | ### Relative View Bobbing
81 | Reduce the view bobbing effect based on the amount of zoom,
82 | so you can walk and zoom at the same time!
83 |
84 | 
85 |
86 | ### Cinematic Camera
87 | Make the mouse/camera smooth, like the zoom in [OptiFine](https://www.optifine.net).
88 |
89 | 
90 |
91 | ### Affect Hand FOV
92 | Turn off this setting to prevent your hand from also being zoomed in!
93 |
94 | 
95 |
96 | ### Secondary Zoom
97 |
98 | Completely separate zoom from normal Zoomify.
99 | Aimed for content creators, features `Hide HUD While Zooming` option and longer zoom in times.
100 |
101 | 
102 |
103 | ### Presets
104 |
105 | You can reset to default, make Zoomify behave like OptiFine and others!
106 |
107 | ### Smart Keybinding Detection
108 |
109 | On first launch, if a keybinding is conflicting with Zoomify's zoom, a notification will appear notifying them of this.
110 |
111 | 
112 |
113 | ### Highly configurable
114 | Absolutely **NO** hard-coded values. Everything about your zoom is configurable!
115 |
116 | ### Control the zoom speed with seconds
117 | Instead of some stupid arbitrary value such as zoom speed, you can pick
118 | the exact amount of seconds it will take to zoom in, with a separate setting for zooming out.
119 |
120 | ### Credits
121 | - [Xander](https://github.com/isXander) - Developer
122 | - [MoonTidez](https://github.com/MoonTidez) - Logo designer
123 |
124 | #### Translators
125 | Languages in alphabetical order
126 |
127 | - [神枪968](https://github.com/GodGun968) - 简体中文 / Chinese (Simplified)
128 | - [Xander](https://github.com/isXander) - English (United Kingdom)
129 | - [Madis0](https://github.com/Madis0) - eesti keel / Estonian
130 | - [co-91](https://github.com/co-91) - 日本語 / Japanese
131 | - [Rodrigo Appelt](https://github.com/Agentew04) - Português / Portuguese
132 | - [SyberiaK](https://github.com/SyberiaK) - Русский / Russian
133 | - [Felix14-v2](https://github.com/Felix14-v2) - Русский / Russian
134 | - [Zetsphiron](https://github.com/Zetsphiron) - Español (mexicano) / Spanish (Mexico)
135 | - [Zetsphiron](https://github.com/Zetsphiron) - Español (españa) / Spanish (Spain)
136 | - [localfossa](https://github.com/localfossa) - Türkçe / Turkish
137 | - [Im Vietnam](https://github.com/ImVietnam) - Tiếng Việt / Vietnamese
138 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | `java-library`
3 |
4 | val kotlinVersion = "2.1.10"
5 | kotlin("jvm") version kotlinVersion
6 | kotlin("plugin.serialization") version kotlinVersion
7 |
8 | id("fabric-loom") version "1.10.+"
9 |
10 | id("me.modmuss50.mod-publish-plugin") version "0.8.4"
11 | `maven-publish`
12 |
13 | id("org.ajoberstar.grgit") version "5.0.+"
14 | }
15 |
16 | val mcVersion = property("mcVersion")!!.toString()
17 | val mcSemverVersion = stonecutter.current.version
18 | val mcDep = property("fmj.mcDep").toString()
19 |
20 | group = "dev.isxander"
21 | val versionWithoutMC = "2.14.3"
22 | version = "$versionWithoutMC+${stonecutter.current.project}"
23 |
24 | val isAlpha = "alpha" in version.toString()
25 | val isBeta = "beta" in version.toString()
26 |
27 | base {
28 | archivesName.set(property("modName").toString())
29 | }
30 |
31 | loom {
32 | if (stonecutter.current.isActive) {
33 | runConfigs.all {
34 | ideConfigGenerated(true)
35 | runDir("../../run")
36 | }
37 | }
38 |
39 | mixin {
40 | useLegacyMixinAp.set(false)
41 | }
42 | }
43 |
44 | stonecutter {
45 | swap(
46 | "fov-precision",
47 | if (stonecutter.eval(stonecutter.current.version, ">=1.21.2"))
48 | "float" else "double"
49 | )
50 | }
51 |
52 | repositories {
53 | mavenCentral()
54 | maven("https://maven.terraformersmc.com")
55 | maven("https://maven.isxander.dev/releases")
56 | maven("https://maven.isxander.dev/snapshots")
57 | maven("https://maven.parchmentmc.org")
58 | maven("https://maven.quiltmc.org/repository/release")
59 | exclusiveContent {
60 | forRepository { maven("https://api.modrinth.com/maven") }
61 | filter { includeGroup("maven.modrinth") }
62 | }
63 | exclusiveContent {
64 | forRepository { maven("https://cursemaven.com") }
65 | filter { includeGroup("curse.maven") }
66 | }
67 | maven("https://jitpack.io")
68 | maven("https://maven.flashyreese.me/snapshots")
69 | maven("https://oss.sonatype.org/content/repositories/snapshots")
70 | }
71 |
72 | dependencies {
73 | minecraft("com.mojang:minecraft:$mcVersion")
74 | mappings(loom.layered {
75 | // quilt does not support pre-releases so it is necessary to only layer if they exist
76 | optionalProp("deps.parchment") {
77 | parchment("org.parchmentmc.data:parchment-$it@zip")
78 | }
79 |
80 | officialMojangMappings()
81 | })
82 | modImplementation("net.fabricmc:fabric-loader:${property("deps.fabricLoader")}")
83 |
84 | val fapiVersion = property("deps.fabricApi").toString()
85 | listOf(
86 | "fabric-resource-loader-v0",
87 | "fabric-lifecycle-events-v1",
88 | "fabric-key-binding-api-v1",
89 | "fabric-command-api-v2",
90 | ).forEach {
91 | modImplementation(fabricApi.module(it, fapiVersion))
92 | }
93 | modRuntimeOnly("net.fabricmc.fabric-api:fabric-api:$fapiVersion") // so you can do `depends: fabric-api` in FMJ
94 | modImplementation("net.fabricmc:fabric-language-kotlin:${property("deps.flk")}")
95 |
96 | modApi("dev.isxander:yet-another-config-lib:${property("deps.yacl")}") {
97 | // was including old fapi version that broke things at runtime
98 | exclude(group = "net.fabricmc.fabric-api", module = "fabric-api")
99 | }
100 |
101 | // mod menu compat
102 | optionalProp("deps.modMenu") {
103 | modImplementation("com.terraformersmc:modmenu:$it")
104 | }
105 |
106 | optionalProp("deps.controlify") {
107 | modImplementation("dev.isxander:controlify:$it")
108 | }
109 |
110 | modImplementation(include("com.akuleshov7:ktoml-core-jvm:${property("deps.ktoml")}")!!)
111 | }
112 |
113 | tasks {
114 | processResources {
115 | val modId: String by project
116 | val modName: String by project
117 | val modDescription: String by project
118 | val githubProject: String by project
119 |
120 | val props = mapOf(
121 | "id" to modId,
122 | "group" to project.group,
123 | "name" to modName,
124 | "description" to modDescription,
125 | "version" to project.version,
126 | "github" to githubProject,
127 | "mc" to mcDep
128 | )
129 |
130 | props.forEach(inputs::property)
131 |
132 | filesMatching("fabric.mod.json") {
133 | expand(props)
134 | }
135 |
136 | eachFile {
137 | // don't include photoshop files for the textures for development
138 | if (name.endsWith(".psd")) {
139 | exclude()
140 | }
141 | }
142 | }
143 |
144 | register("releaseMod") {
145 | group = "mod"
146 |
147 | dependsOn("publishMods")
148 | dependsOn("publish")
149 | }
150 | }
151 |
152 | val javaMajorVersion = property("java.version").toString().toInt()
153 | java {
154 | withSourcesJar()
155 |
156 | javaMajorVersion
157 | .let { JavaVersion.values()[it - 1] }
158 | .let {
159 | sourceCompatibility = it
160 | targetCompatibility = it
161 | }
162 | }
163 |
164 | tasks.withType {
165 | options.release = javaMajorVersion
166 | }
167 | kotlin {
168 | jvmToolchain(javaMajorVersion)
169 | }
170 |
171 | publishMods {
172 | displayName.set("Zoomify $versionWithoutMC for MC $mcVersion")
173 | file.set(tasks.remapJar.get().archiveFile)
174 | changelog.set(
175 | rootProject.file("changelogs/${versionWithoutMC}.md")
176 | .takeIf { it.exists() }
177 | ?.readText()
178 | ?: "No changelog provided."
179 | )
180 | type.set(when {
181 | isAlpha -> ALPHA
182 | isBeta -> BETA
183 | else -> STABLE
184 | })
185 | modLoaders.add("fabric")
186 |
187 | fun versionList(prop: String) = findProperty(prop)?.toString()
188 | ?.split(',')
189 | ?.map { it.trim() }
190 | ?: emptyList()
191 |
192 | // modrinth and curseforge use different formats for snapshots. this can be expressed globally
193 | val stableMCVersions = versionList("pub.stableMC")
194 |
195 | val modrinthId: String by project
196 | if (modrinthId.isNotBlank() && hasProperty("modrinth.token")) {
197 | modrinth {
198 | projectId.set(modrinthId)
199 | accessToken.set(findProperty("modrinth.token")?.toString())
200 | minecraftVersions.addAll(stableMCVersions)
201 | minecraftVersions.addAll(versionList("pub.modrinthMC"))
202 |
203 | requires { slug.set("fabric-api") }
204 | requires { slug.set("yacl") }
205 | optional { slug.set("modmenu") }
206 | }
207 | }
208 |
209 | val curseforgeId: String by project
210 | if (curseforgeId.isNotBlank() && hasProperty("curseforge.token")) {
211 | curseforge {
212 | projectId.set(curseforgeId)
213 | accessToken.set(findProperty("curseforge.token")?.toString())
214 | minecraftVersions.addAll(stableMCVersions)
215 | minecraftVersions.addAll(versionList("pub.curseMC"))
216 |
217 | requires { slug.set("fabric-api") }
218 | requires { slug.set("yacl") }
219 | optional { slug.set("modmenu") }
220 | }
221 | }
222 |
223 | val githubProject: String by project
224 | if (githubProject.isNotBlank() && hasProperty("github.token")) {
225 | github {
226 | repository.set(githubProject)
227 | accessToken.set(findProperty("github.token")?.toString())
228 | commitish.set(grgit.branch.current().name)
229 | }
230 | }
231 | }
232 |
233 | publishing {
234 | publications {
235 | create("mod") {
236 | groupId = "dev.isxander"
237 | artifactId = "zoomify"
238 |
239 | from(components["java"])
240 | }
241 | }
242 |
243 | repositories {
244 | val username = "XANDER_MAVEN_USER".let { System.getenv(it) ?: findProperty(it) }?.toString()
245 | val password = "XANDER_MAVEN_PASS".let { System.getenv(it) ?: findProperty(it) }?.toString()
246 | if (username != null && password != null) {
247 | maven(url = "https://maven.isxander.dev/releases") {
248 | name = "XanderReleases"
249 | credentials {
250 | this.username = username
251 | this.password = password
252 | }
253 | }
254 | } else {
255 | println("Xander Maven credentials not satisfied.")
256 | }
257 | }
258 | }
259 |
260 | fun optionalProp(property: String, block: (String) -> T?) {
261 | findProperty(property)?.toString()?.takeUnless { it.isBlank() }?.let(block)
262 | }
263 |
264 | fun isPropDefined(property: String): Boolean {
265 | return findProperty(property)?.toString()?.isNotBlank() ?: false
266 | }
267 |
--------------------------------------------------------------------------------
/changelogs/1.6.0.md:
--------------------------------------------------------------------------------
1 | - Fix zoom speed being FPS dependent
2 | - Remove telemetry and update checking
3 | - Allow up to 150% zoom speed
4 |
--------------------------------------------------------------------------------
/changelogs/1.6.1.md:
--------------------------------------------------------------------------------
1 | - 1.19 release
2 | - Fix animation being jumpy when you stop zooming before the animation is completed
3 | - Increase max scroll zoom
4 | - Add more scroll zoom steps
5 | - Internally switch to Settxi enums to now the multi-choice options are toggles rather than dropdowns
6 |
--------------------------------------------------------------------------------
/changelogs/1.6.2.md:
--------------------------------------------------------------------------------
1 | - Fix crash
2 |
--------------------------------------------------------------------------------
/changelogs/1.7.0.md:
--------------------------------------------------------------------------------
1 | - Relative Sensitivity Gradient - Controls the gradient of the sensitivity based on the zoom level.
2 |
--------------------------------------------------------------------------------
/changelogs/1.7.1.md:
--------------------------------------------------------------------------------
1 | - Removed scroll zoom transitions in favour of "Smooth Transition" on/off option.
2 | - Doubled amount of scroll steps from 10 to 20
3 |
--------------------------------------------------------------------------------
/changelogs/2.0.0.md:
--------------------------------------------------------------------------------
1 | ## Highlights
2 |
3 | ### Spyglass Integration
4 |
5 | - `Zoom Behaviour` option. Controls if Zoomify can only be used
6 | with a spyglass or override the vanilla spyglass zoom.
7 | - `Overlay Visibility` option controls when to render the
8 | spyglass overlay when zooming with Zoomify.
9 | - `Sound Behaviour` option controls when to play the
10 | zoom in and out sounds of the spyglass.
11 |
12 | ### Relative View Bobbing
13 |
14 | - Added `Relative View Bobbing` option which reduced the amount of bobbing
15 | depending on the zoom level to make walking less jarring.
16 |
17 | ### Zoom Speed Changes
18 |
19 | - Remove `Zoom Speed` option in favour of `Zoom In Time` and `Zoom Out Time`
20 | which dictates amount of seconds it takes to do said action.
21 | - Remove `Scroll Zoom Speed` option in favour of `Scroll Zoom Smoothness`.
22 | The higher the smoothness the longer and smoother the scrolling is.
23 |
24 | ## Full Patch Notes
25 |
26 | - `Zoom Behaviour` option. Controls if Zoomify can only be used
27 | with a spyglass or override the vanilla spyglass zoom.
28 | - `Overlay Visibility` option controls when to render the
29 | spyglass overlay when zooming with Zoomify.
30 | - `Sound Behaviour` option controls when to play the
31 | zoom in and out sounds of the spyglass.
32 | - Remove `Zoom Speed` option in favour of `Zoom In Time` and `Zoom Out Time`
33 | which dictates amount of seconds it takes to do said action.
34 | - Added `Relative View Bobbing` option which reduced the amount of bobbing
35 | depending on the zoom level to make walking less jarring.
36 | - Remove `Scroll Zoom Speed` option in favour of `Scroll Zoom Smoothness`.
37 | The higher the smoothness the longer and smoother the scrolling is.
38 | - Remove `Relative Sensitivity Gradient` to reduce down to just the one
39 | `Relative Sensitivity` setting which can be disabled by setting the slider to 0.
40 | - When letting go of the zoom key or toggling zoom off whilst scrolled in,
41 | the normal zoom out transition is used with the same amount of time as if you weren't scrolled.
42 | - Increased number of scroll steps to 30.
43 | - Apply function to scroll zoom steps to make the first few steps smaller
44 | and the last steps larger to create a more linear effect.
45 |
--------------------------------------------------------------------------------
/changelogs/2.0.1.md:
--------------------------------------------------------------------------------
1 | - Fix zoom in/out time being halved in-game
2 | - Add Russian translation
3 | - Update Estonian translation
4 | - Fix typo in English (US & GB)
5 |
--------------------------------------------------------------------------------
/changelogs/2.0.2.md:
--------------------------------------------------------------------------------
1 | - Remove settings keybind.
2 | - Add `/zoomify` client command.
3 |
--------------------------------------------------------------------------------
/changelogs/2.0.3.md:
--------------------------------------------------------------------------------
1 | - Fix Ease Out Cubic transition
2 |
--------------------------------------------------------------------------------
/changelogs/2.10.0.md:
--------------------------------------------------------------------------------
1 | - Updated to 1.20 (still supports 1.19.4)
2 | - Updated to YACL 3.x
3 |
--------------------------------------------------------------------------------
/changelogs/2.11.0.md:
--------------------------------------------------------------------------------
1 | # Zoomify 2.11.0
2 |
3 | ## New Features
4 |
5 | Added a live zoom preview to most of the Zoomify settings.
6 |
7 | This now allows you to see the effect of your changes without saving,
8 | leaving the menu and entering a world. This should make it easier to configure
9 | all the settings to your liking.
10 |
11 | ## Language Updates
12 |
13 | - Added Vietnamese by [Im Vietnam](https://github.com/ImVietnam) ([#160](https://github.com/isXander/Zoomify/pull/160)).
14 | - Added Japanese by [co-91](https://github.com/co-91) ([#167](https://github.com/isXander/Zoomify/pull/167)).
15 |
--------------------------------------------------------------------------------
/changelogs/2.11.1.md:
--------------------------------------------------------------------------------
1 | - Update for YACL 3.1.1+1.20
2 |
--------------------------------------------------------------------------------
/changelogs/2.11.2.md:
--------------------------------------------------------------------------------
1 | - Fix broken Controlify compatibility
2 |
--------------------------------------------------------------------------------
/changelogs/2.12.0.md:
--------------------------------------------------------------------------------
1 | # Zoomify 2.12.0 for 1.20.2
2 |
3 | - Update to 1.20.2
4 |
--------------------------------------------------------------------------------
/changelogs/2.13.1.md:
--------------------------------------------------------------------------------
1 | - Update to support Controlify 2.0
2 |
--------------------------------------------------------------------------------
/changelogs/2.13.2.md:
--------------------------------------------------------------------------------
1 | - *Actually* fix Controlify on 2.x.x
2 |
--------------------------------------------------------------------------------
/changelogs/2.13.3.md:
--------------------------------------------------------------------------------
1 | - Update to 1.20.5
2 |
--------------------------------------------------------------------------------
/changelogs/2.13.4.md:
--------------------------------------------------------------------------------
1 | # Zoomify 2.13.4
2 |
3 | Implemented the Stonecutter build system to target multiple versions,
4 | like Controlify and YACL!
5 |
6 | This comes with the benefit that Zoomify will now receive updates for the older versions,
7 | so the Controlify 2.0 incompatibility is now solved on 1.20.1
8 |
9 | ## Targets
10 |
11 | Zoomify now targets the following Minecraft versions:
12 | - 1.20.1
13 | - 1.20.4 (also supports 1.20.3)
14 | - 1.20.6 (also supports 1.20.5)
15 | Make sure you download the correct version for your Minecraft version!
16 |
17 | ## Translations
18 |
19 | - Updated Mexican Spanish translation (thanks to @TheLegendofSaram)
20 |
--------------------------------------------------------------------------------
/changelogs/2.13.5.md:
--------------------------------------------------------------------------------
1 | # Zoomify 2.13.5
2 |
3 | Zoomify now targets the following Minecraft versions:
4 |
5 | - 1.20.1
6 | - 1.20.4 (also supports 1.20.3)
7 | - 1.20.6 (also supports 1.20.5)
8 |
9 | Make sure you download the correct version for your Minecraft version!
10 |
11 | ## Changes
12 |
13 | - Fix Controlify compatibility
14 | - Remove zoom key behaviour option and instead have two separate keybinds
15 |
--------------------------------------------------------------------------------
/changelogs/2.14.0.md:
--------------------------------------------------------------------------------
1 | # Zoomify 2.14.0
2 |
3 | Zoomify now targets the following Minecraft versions:
4 |
5 | - 1.20.1
6 | - 1.20.4 (also supports 1.20.3)
7 | - 1.20.6 (also supports 1.20.5)
8 | - 1.21
9 |
10 | Make sure you download the correct version for your Minecraft version!
11 |
12 | ## Changes
13 |
14 | - Presets now have demo animations in their descriptions
15 | - 1.21 support
16 | - Internally rewrite settings with new experimental YetAnotherConfigLib API
17 |
--------------------------------------------------------------------------------
/changelogs/2.2.0.md:
--------------------------------------------------------------------------------
1 | ## Features
2 |
3 | - You can now independently change the zoom in and out transitions.
4 |
5 | 
6 |
7 | ## Translation Updates
8 |
9 | - Add Spanish (Spain) Translation - [Zetsphiron](https://github.com/isXander/Zoomify/pull/73)
10 | - Add Spanish (Mexico) Translation - [Zetsphiron](https://github.com/isXander/Zoomify/pull/73)
11 | - Update Chinese (Simplified) Translation - [神枪968](https://github.com/isXander/Zoomify/pull/67)
12 | - Update Portuguese Translation - [Rodrigo Appelt](https://github.com/isXander/Zoomify/pull/69)
13 |
--------------------------------------------------------------------------------
/changelogs/2.3.0.md:
--------------------------------------------------------------------------------
1 | ## Features
2 |
3 | - You can now apply presets! As of now there are 3 to choose from:
4 | + Default - Resets all settings to default
5 | + OptiFine - Makes Zoomify behave like OptiFine zoom
6 | + OK Zoomer - Makes Zoomify behave like OK Zoomer defaults (useful for migrating)
7 |
8 | 
9 |
10 | - Retain scroll steps setting: remember the amount of times you scrolled in since last zoom
11 | - Affect hand fov: on by default, turning off doesn't make your hand zoom in
12 | - Linear-like zoom setting: make scroll zoom increments appear more linear
13 | + This was already in Zoomify, but it wasn't able to be turned off.
14 |
15 |
16 |
--------------------------------------------------------------------------------
/changelogs/2.4.0.md:
--------------------------------------------------------------------------------
1 | ## Keybinding Conflict Detection
2 | - Upon first launch of Zoomify (detected when config file doesn't exist), a toast appears explaining that Zoomify
3 | won't work, and you need to go to settings and unbind conflicting keybindings.
4 |
5 | 
6 |
7 | - New button in settings: Unbind conflicting keys does just that, with a toast for each key that was modified.
8 |
9 | 
10 |
11 | - `Presets` category renamed to `Misc` and presets moved into subcategory
12 |
13 | 
14 |
--------------------------------------------------------------------------------
/changelogs/2.4.1.md:
--------------------------------------------------------------------------------
1 | - Fix conflict detection
2 |
--------------------------------------------------------------------------------
/changelogs/2.4.2.md:
--------------------------------------------------------------------------------
1 | - Add `Support me!` button to config
2 | - Update Estonian translations
3 |
--------------------------------------------------------------------------------
/changelogs/2.5.0.md:
--------------------------------------------------------------------------------
1 | - Converted Cinematic Camera to a slider, 0% for off, 100% for normal etc
2 | - Add suffixes to some sliders, for example:
3 | * Initial Zoom: 4x
4 | * Relative Sensitivity: 100%
5 | * Cinematic Camera: 0%
6 | - Update default zoom times:
7 | * Zoom In: 1.0 secs
8 | * Zoom Out: 0.5 secs
9 |
--------------------------------------------------------------------------------
/changelogs/2.6.0.md:
--------------------------------------------------------------------------------
1 | - Switched to [YetAnotherConfigLib](https://curseforge.com/minecraft/mc-mods/yacl) (you need to download it) library rather than Cloth Config
2 | - Decrease maximum zoom in and out time to 5 seconds for better slider usability.
3 | - Update translations.
4 |
--------------------------------------------------------------------------------
/changelogs/2.7.0.md:
--------------------------------------------------------------------------------
1 | - Keybind Scrolling: Instead of using scroll wheel, use keybinds! (Configurable)
2 | - Fix funky behaviour with Spyglass integration
3 |
--------------------------------------------------------------------------------
/changelogs/2.8.0.md:
--------------------------------------------------------------------------------
1 | ## Secondary Zoom
2 | This new feature is a completely separate zoom to normal Zoomify.
3 | Its primary goal is to compete with a similar feature in
4 | [Camera Utils](https://curseforge.com/minecraft/mc-mods/camera-utils) (with more settings of course)
5 | that I have seen many content creators love.
6 |
7 | All you need to do is press another keybinding found in options! (F6 by default)
8 |
9 | This secondary zoom has a few exclusive features but misses advanced ones present in
10 | regular zoom that aren't really needed for the intended use case. These include:
11 |
12 | - Option to hide HUD whilst zooming
13 | - Cinematic camera is always on
14 | - An increased maximum zoom in time (5secs -> 30secs)
15 | - Toggleable only
16 | - No transitions - linear only
17 | - No additional mouse settings
18 |
19 | This feature came with a semi-major rewrite to the internals of Zoomify,
20 | though you shouldn't notice a difference. If you do, make sure to report it on the
21 | [issue tracker](https://github.com/isXander/Zoomify/issues).
22 |
--------------------------------------------------------------------------------
/changelogs/2.9.0.md:
--------------------------------------------------------------------------------
1 | - Build on 1.19.3 (though 1.19.2 is still supported)
2 | - Add automatic migration from OK Zoomer to Zoomify
3 |
--------------------------------------------------------------------------------
/changelogs/2.9.1.md:
--------------------------------------------------------------------------------
1 | - Re-compile with latest version of YetAnotherConfigLib as new version JAR isn't backwards compatible
2 |
--------------------------------------------------------------------------------
/changelogs/2.9.2.md:
--------------------------------------------------------------------------------
1 | - Fix crash when checking migrations
2 |
--------------------------------------------------------------------------------
/changelogs/2.9.3.md:
--------------------------------------------------------------------------------
1 | - Fix instant transition not being instant
2 |
--------------------------------------------------------------------------------
/changelogs/2.9.4.md:
--------------------------------------------------------------------------------
1 | - Updated chinese translation
2 | - New german translation
3 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx2G
2 |
3 | kotlin.code.style=official
4 | systemProp.kotlinVersion=2.1.10
5 |
6 | modId=zoomify
7 | modName=Zoomify
8 | modDescription=A zoom mod with infinite customizability.
9 |
10 | modrinthId=w7ThoJFB
11 | curseforgeId=574741
12 | githubProject=isXander/Zoomify
13 |
14 | deps.fabricLoader=0.16.10
15 | deps.ktoml=0.5.2
16 | deps.flk=1.13.1+kotlin.2.1.10
17 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-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 | # Stop when "xargs" is not available.
209 | if ! command -v xargs >/dev/null 2>&1
210 | then
211 | die "xargs is not available"
212 | fi
213 |
214 | # Use "xargs" to parse quoted args.
215 | #
216 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
217 | #
218 | # In Bash we could simply go:
219 | #
220 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
221 | # set -- "${ARGS[@]}" "$@"
222 | #
223 | # but POSIX shell has neither arrays nor command substitution, so instead we
224 | # post-process each arg (as a line of input to sed) to backslash-escape any
225 | # character that might be a shell metacharacter, then use eval to reverse
226 | # that process (while maintaining the separation between arguments), and wrap
227 | # the whole thing up as a single "set" statement.
228 | #
229 | # This will of course break if any of these variables contains a newline or
230 | # an unmatched quote.
231 | #
232 |
233 | eval "set -- $(
234 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
235 | xargs -n1 |
236 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
237 | tr '\n' ' '
238 | )" '"$@"'
239 |
240 | exec "$JAVACMD" "$@"
241 |
--------------------------------------------------------------------------------
/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% equ 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% equ 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 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------
/screenshots/affect-hand-fov-disabled-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/affect-hand-fov-disabled-example.gif
--------------------------------------------------------------------------------
/screenshots/cinematic-cam-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/cinematic-cam-example.gif
--------------------------------------------------------------------------------
/screenshots/individual-transition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/individual-transition.png
--------------------------------------------------------------------------------
/screenshots/keybind-conflict-detection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/keybind-conflict-detection.png
--------------------------------------------------------------------------------
/screenshots/relative-sensitivity-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/relative-sensitivity-example.gif
--------------------------------------------------------------------------------
/screenshots/relative-view-bobbing-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/relative-view-bobbing-example.gif
--------------------------------------------------------------------------------
/screenshots/scroll-zoom-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/scroll-zoom-example.gif
--------------------------------------------------------------------------------
/screenshots/secondary-zoom.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/secondary-zoom.gif
--------------------------------------------------------------------------------
/screenshots/spyglass-integration-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/spyglass-integration-example.gif
--------------------------------------------------------------------------------
/screenshots/zoom-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/zoom-example.gif
--------------------------------------------------------------------------------
/screenshots/zoom-hand.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/zoom-hand.webp
--------------------------------------------------------------------------------
/screenshots/zoom-world.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/screenshots/zoom-world.webp
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.kikugie.stonecutter.StonecutterSettings
2 |
3 | pluginManagement {
4 | repositories {
5 | mavenCentral()
6 | gradlePluginPortal()
7 | maven("https://maven.fabricmc.net")
8 | maven("https://maven.quiltmc.org/repository/release")
9 | maven("https://maven.kikugie.dev/releases")
10 | }
11 | }
12 |
13 | plugins {
14 | id("dev.kikugie.stonecutter") version "0.4.5"
15 | }
16 |
17 | extensions.configure {
18 | kotlinController = true
19 | centralScript = "build.gradle.kts"
20 | shared {
21 | versions("1.20.1", "1.20.4", "1.20.6", "1.21.1", "1.21.3")
22 | }
23 | create(rootProject)
24 | }
25 |
26 | rootProject.name = "Zoomify"
27 |
28 |
--------------------------------------------------------------------------------
/src/main/java/dev/isxander/zoomify/mixins/hooks/MinecraftClientMixin.java:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.mixins.hooks;
2 |
3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4 | import dev.isxander.zoomify.Zoomify;
5 | import net.minecraft.client.Minecraft;
6 | import net.minecraft.server.packs.resources.ReloadInstance;
7 | import org.spongepowered.asm.mixin.Mixin;
8 | import org.spongepowered.asm.mixin.injection.At;
9 |
10 | @Mixin(Minecraft.class)
11 | public class MinecraftClientMixin {
12 | @ModifyExpressionValue(
13 | method = "",
14 | at = @At(
15 | value = "INVOKE",
16 | target = "Lnet/minecraft/server/packs/resources/ReloadableResourceManager;createReload(Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;Ljava/util/concurrent/CompletableFuture;Ljava/util/List;)Lnet/minecraft/server/packs/resources/ReloadInstance;"
17 | )
18 | )
19 | private ReloadInstance onReloadResources(ReloadInstance resourceReload) {
20 | resourceReload.done().thenRun(Zoomify.INSTANCE::onGameFinishedLoading);
21 | return resourceReload;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/dev/isxander/zoomify/mixins/spyglass/AbstractClientPlayerEntityMixin.java:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.mixins.spyglass;
2 |
3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4 | import dev.isxander.zoomify.config.SpyglassBehaviour;
5 | import dev.isxander.zoomify.config.ZoomifySettings;
6 | import net.minecraft.client.player.AbstractClientPlayer;
7 | import org.spongepowered.asm.mixin.Mixin;
8 | import org.spongepowered.asm.mixin.injection.At;
9 |
10 | @Mixin(AbstractClientPlayer.class)
11 | public class AbstractClientPlayerEntityMixin {
12 | @ModifyExpressionValue(
13 | method = "getFieldOfViewModifier",
14 | at = @At(value = "CONSTANT", args = "floatValue=0.1f")
15 | )
16 | private float modifySpyglassFovMultiplier(float multiplier) {
17 | if (ZoomifySettings.Companion.getSpyglassBehaviour().get() != SpyglassBehaviour.COMBINE)
18 | return 1f;
19 | return multiplier;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/dev/isxander/zoomify/mixins/spyglass/InGameHudMixin.java:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.mixins.spyglass;
2 |
3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4 | import dev.isxander.zoomify.Zoomify;
5 | import net.minecraft.client.Minecraft;
6 | import net.minecraft.client.gui.Gui;
7 | import org.spongepowered.asm.mixin.Final;
8 | import org.spongepowered.asm.mixin.Mixin;
9 | import org.spongepowered.asm.mixin.Shadow;
10 | import org.spongepowered.asm.mixin.injection.At;
11 |
12 | @Mixin(Gui.class)
13 | public class InGameHudMixin {
14 | @Shadow @Final private Minecraft minecraft;
15 |
16 | @ModifyExpressionValue(
17 | /*? if >1.20.4 {*/
18 | method = "renderCameraOverlays",
19 | /*?} else {*/
20 | /*method = "render",
21 | *//*?}*/
22 | at = @At(
23 | value = "INVOKE",
24 | target = "Lnet/minecraft/client/player/LocalPlayer;isScoping()Z"
25 | )
26 | )
27 | private boolean shouldRenderSpyglassOverlay(boolean isUsingSpyglass) {
28 | return Zoomify.shouldRenderOverlay(minecraft.player, isUsingSpyglass);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/dev/isxander/zoomify/mixins/spyglass/SpyglassItemMixin.java:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.mixins.spyglass;
2 |
3 | import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
4 | import dev.isxander.zoomify.config.OverlayVisibility;
5 | import dev.isxander.zoomify.config.SoundBehaviour;
6 | import dev.isxander.zoomify.config.ZoomifySettings;
7 | import net.minecraft.sounds.SoundEvent;
8 | import net.minecraft.world.entity.player.Player;
9 | import net.minecraft.world.item.SpyglassItem;
10 | import org.spongepowered.asm.mixin.Mixin;
11 | import org.spongepowered.asm.mixin.injection.At;
12 |
13 | @Mixin(SpyglassItem.class)
14 | public class SpyglassItemMixin {
15 | @WrapWithCondition(
16 | method = {"use", "stopUsing"},
17 | at = @At(
18 | value = "INVOKE",
19 | target = "Lnet/minecraft/world/entity/player/Player;playSound(Lnet/minecraft/sounds/SoundEvent;FF)V"
20 | )
21 | )
22 | private boolean shouldPlaySpyglassSound(Player instance, SoundEvent event, float volume, float pitch) {
23 | if (ZoomifySettings.Companion.getSpyglassSoundBehaviour().get() == SoundBehaviour.NEVER)
24 | return false;
25 |
26 | if (ZoomifySettings.Companion.getSpyglassSoundBehaviour().get() == SoundBehaviour.WITH_OVERLAY
27 | && ZoomifySettings.Companion.getSpyglassOverlayVisibility().get() == OverlayVisibility.NEVER) {
28 | return false;
29 | }
30 |
31 | return true;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/dev/isxander/zoomify/mixins/zoom/GameRendererMixin.java:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.mixins.zoom;
2 |
3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4 | import com.llamalad7.mixinextras.injector.ModifyReturnValue;
5 | import com.llamalad7.mixinextras.sugar.Local;
6 | import dev.isxander.zoomify.Zoomify;
7 | import dev.isxander.zoomify.config.ZoomifySettings;
8 | import net.minecraft.client.Camera;
9 | import net.minecraft.client.renderer.GameRenderer;
10 | import net.minecraft.util.Mth;
11 | import org.objectweb.asm.Opcodes;
12 | import org.spongepowered.asm.mixin.Mixin;
13 | import org.spongepowered.asm.mixin.injection.At;
14 |
15 | @Mixin(GameRenderer.class)
16 | public class GameRendererMixin {
17 | @ModifyReturnValue(
18 | method = "getFov",
19 | at = @At("RETURN")
20 | )
21 | private /*$ fov-precision >>*/ float modifyFovWithZoom(
22 | /*$ fov-precision >>*/ float fov,
23 | @Local(argsOnly = true) float tickDelta
24 | ) {
25 | return fov / Zoomify.getZoomDivisor(tickDelta);
26 | }
27 |
28 | @ModifyExpressionValue(
29 | method = "bobView",
30 | at = {
31 | @At(
32 | value = "FIELD",
33 | //? if >=1.21.2 {
34 | target = "Lnet/minecraft/client/player/AbstractClientPlayer;oBob:F",
35 | //?} else {
36 | /*target = "Lnet/minecraft/world/entity/player/Player;oBob:F",
37 | *///?}
38 | opcode = Opcodes.GETFIELD
39 | ),
40 | @At(
41 | value = "FIELD",
42 | //? if >=1.21.2 {
43 | target = "Lnet/minecraft/client/player/AbstractClientPlayer;bob:F",
44 | //?} else {
45 | /*target = "Lnet/minecraft/world/entity/player/Player;bob:F",
46 | *///?}
47 | opcode = Opcodes.GETFIELD
48 | ),
49 | }
50 | )
51 | private float modifyBobbingIntensity(float p) {
52 | if (!ZoomifySettings.Companion.getRelativeViewBobbing().get())
53 | return p;
54 |
55 | return (float) (p / Mth.lerp(0.2, 1.0, Zoomify.INSTANCE.getPreviousZoomDivisor()));
56 | }
57 |
58 | @ModifyExpressionValue(
59 | method = "renderItemInHand",
60 | at = @At(
61 | value = "INVOKE",
62 | //? if >=1.21.2 {
63 | target = "Lnet/minecraft/client/renderer/GameRenderer;getFov(Lnet/minecraft/client/Camera;FZ)F"
64 | //?} else {
65 | /*target = "Lnet/minecraft/client/renderer/GameRenderer;getFov(Lnet/minecraft/client/Camera;FZ)D"
66 | *///?}
67 | )
68 | )
69 | private /*$ fov-precision >>*/ float keepHandFov(
70 | /*$ fov-precision >>*/ float fov,
71 | @Local(argsOnly=true) float tickDelta
72 | ) {
73 | if (!ZoomifySettings.Companion.getAffectHandFov().get())
74 | return fov * Zoomify.getZoomDivisor(tickDelta);
75 | return fov;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/dev/isxander/zoomify/mixins/zoom/MouseMixin.java:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.mixins.zoom;
2 |
3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4 | import com.llamalad7.mixinextras.sugar.Local;
5 | import dev.isxander.zoomify.Zoomify;
6 | import dev.isxander.zoomify.config.SpyglassBehaviour;
7 | import dev.isxander.zoomify.config.ZoomifySettings;
8 | import net.minecraft.client.MouseHandler;
9 | import net.minecraft.util.Mth;
10 | import org.joml.Vector2i;
11 | import org.spongepowered.asm.mixin.Mixin;
12 | import org.spongepowered.asm.mixin.Shadow;
13 | import org.spongepowered.asm.mixin.injection.At;
14 | import org.spongepowered.asm.mixin.injection.Inject;
15 | import org.spongepowered.asm.mixin.injection.ModifyArg;
16 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
17 |
18 | @Mixin(MouseHandler.class)
19 | public class MouseMixin {
20 |
21 | /*? if <=1.20.1 {*/
22 | /*@Shadow
23 | private double accumulatedScroll;
24 | *//*?}*/
25 |
26 | @Inject(
27 | method = "onScroll",
28 | /*? if >1.20.1 {*/
29 | at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isSpectator()Z"),
30 | /*?} else {*/
31 | /*at = @At(value = "FIELD", target = "Lnet/minecraft/client/MouseHandler;accumulatedScroll:D", ordinal = 7),
32 | *//*?}*/
33 | cancellable = true
34 | )
35 | private void scrollStepCounter(
36 | CallbackInfo ci
37 | //? if >=1.21.2 {
38 | , @Local Vector2i scroll
39 | //?} elif >1.20.1 {
40 | /*, @Local(ordinal = 1) int scrollY
41 | *///?}
42 | ) {
43 | //? if >=1.21.2 {
44 | int scrollY = scroll.y;
45 | /*?} elif <=1.20.1 {*/
46 | /*double scrollY = accumulatedScroll;
47 | *//*?}*/
48 |
49 | if (ZoomifySettings.Companion.getScrollZoom().get()
50 | && Zoomify.INSTANCE.getZooming() && scrollY != 0
51 | && !ZoomifySettings.Companion.getKeybindScrolling()) {
52 | Zoomify.mouseZoom(scrollY);
53 | ci.cancel();
54 | }
55 | }
56 |
57 | @ModifyExpressionValue(
58 | method = "turnPlayer",
59 | at = @At(value = "FIELD", target = "Lnet/minecraft/client/Options;smoothCamera:Z")
60 | )
61 | private boolean smoothCameraIfZoom(boolean original) {
62 | return original
63 | || Zoomify.INSTANCE.getSecondaryZooming()
64 | || (Zoomify.INSTANCE.getZooming() && ZoomifySettings.Companion.getCinematicCamera().get() > 0);
65 | }
66 |
67 | @ModifyExpressionValue(
68 | method = "turnPlayer",
69 | at = @At(
70 | value = "INVOKE",
71 | target = "Lnet/minecraft/client/OptionInstance;get()Ljava/lang/Object;",
72 | ordinal = 0
73 | )
74 | )
75 | private Object applyRelativeSensitivity(Object genericValue) {
76 | double value = (Double) genericValue;
77 | return value / Mth.lerp(
78 | ZoomifySettings.Companion.getRelativeSensitivity().get() / 100.0,
79 | 1.0,
80 | Zoomify.INSTANCE.getPreviousZoomDivisor()
81 | );
82 | }
83 |
84 | @ModifyExpressionValue(
85 | method = "turnPlayer",
86 | at = @At(
87 | value = "INVOKE",
88 | target = "Lnet/minecraft/client/player/LocalPlayer;isScoping()Z"
89 | )
90 | )
91 | private boolean shouldApplySpyglassSensitivity(boolean isUsingSpyglass) {
92 | if (ZoomifySettings.Companion.getSpyglassBehaviour().get() != SpyglassBehaviour.COMBINE)
93 | return false;
94 | return isUsingSpyglass;
95 | }
96 |
97 | @ModifyArg(
98 | method = "turnPlayer",
99 | at = @At(
100 | value = "INVOKE",
101 | target = "Lnet/minecraft/util/SmoothDouble;getNewDeltaValue(DD)D"
102 | ),
103 | index = 1
104 | )
105 | private double modifyCinematicSmoothness(double smoother) {
106 | if (Zoomify.INSTANCE.getZooming() && ZoomifySettings.Companion.getCinematicCamera().get() > 0)
107 | return smoother / (ZoomifySettings.Companion.getCinematicCamera().get() / 100.0);
108 |
109 | return smoother;
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/dev/isxander/zoomify/mixins/zoom/secondary/GameRendererMixin.java:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.mixins.zoom.secondary;
2 |
3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4 | import dev.isxander.zoomify.Zoomify;
5 | import dev.isxander.zoomify.config.ZoomifySettings;
6 | import net.minecraft.client.renderer.GameRenderer;
7 | import org.objectweb.asm.Opcodes;
8 | import org.spongepowered.asm.mixin.Mixin;
9 | import org.spongepowered.asm.mixin.injection.At;
10 |
11 | @Mixin(GameRenderer.class)
12 | public class GameRendererMixin {
13 | @ModifyExpressionValue(
14 | method = "render",
15 | at = @At(
16 | value = "FIELD",
17 | target = "Lnet/minecraft/client/Options;hideGui:Z",
18 | opcode = Opcodes.GETFIELD
19 | )
20 | )
21 | private boolean shouldHideHUD(boolean hideHUD) {
22 | return hideHUD || (Zoomify.INSTANCE.getSecondaryZooming() && ZoomifySettings.Companion.getSecondaryHideHUDOnZoom().get());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/Zoomify.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify
2 |
3 | import com.mojang.blaze3d.platform.InputConstants
4 | import dev.isxander.yacl3.config.v3.value
5 | import dev.isxander.zoomify.config.*
6 | import dev.isxander.zoomify.config.migrator.Migrator
7 | import dev.isxander.zoomify.integrations.constrainModVersionIfLoaded
8 | import dev.isxander.zoomify.utils.toast
9 | import dev.isxander.zoomify.zoom.*
10 | import net.fabricmc.api.ClientModInitializer
11 | import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal
12 | import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback
13 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
14 | import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper
15 | import net.minecraft.client.KeyMapping
16 | import net.minecraft.client.Minecraft
17 | import net.minecraft.client.player.AbstractClientPlayer
18 | import net.minecraft.network.chat.Component
19 | import net.minecraft.sounds.SoundEvents
20 | import net.minecraft.util.Mth
21 | import net.minecraft.world.item.ItemStack
22 | import net.minecraft.world.item.Items
23 | import org.slf4j.LoggerFactory
24 |
25 | object Zoomify : ClientModInitializer {
26 | val LOGGER = LoggerFactory.getLogger("Zoomify")!!
27 |
28 | private val zoomKey = KeyMapping("zoomify.key.zoom", InputConstants.Type.KEYSYM, InputConstants.KEY_C, "zoomify.key.category")
29 | private val secondaryZoomKey = KeyMapping("zoomify.key.zoom.secondary", InputConstants.Type.KEYSYM, InputConstants.KEY_F6, "zoomify.key.category")
30 | private val scrollZoomIn = KeyMapping("zoomify.key.zoom.in", -1, "zoomify.key.category")
31 | private val scrollZoomOut = KeyMapping("zoomify.key.zoom.out", -1, "zoomify.key.category")
32 |
33 | var zooming = false
34 | private set
35 | private val zoomHelper = RegularZoomHelper(ZoomifySettings)
36 |
37 | var secondaryZooming = false
38 | private set
39 | private val secondaryZoomHelper = SecondaryZoomHelper(ZoomifySettings)
40 |
41 | var previousZoomDivisor = 1.0
42 | private set
43 |
44 | const val maxScrollTiers = 30
45 | private var scrollSteps = 0
46 |
47 | private var shouldPlaySound = false
48 |
49 | private var displayGui = false
50 |
51 | override fun onInitializeClient() {
52 | // controlify compat only works on 2.x
53 | constrainModVersionIfLoaded("controlify", "2.x.x")
54 |
55 | // imports on
56 | ZoomifySettings
57 |
58 | KeyBindingHelper.registerKeyBinding(zoomKey)
59 | KeyBindingHelper.registerKeyBinding(secondaryZoomKey)
60 | if (ZoomifySettings.keybindScrolling) {
61 | KeyBindingHelper.registerKeyBinding(scrollZoomIn)
62 | KeyBindingHelper.registerKeyBinding(scrollZoomOut)
63 | }
64 |
65 | ClientCommandRegistrationCallback.EVENT.register { dispatcher, _ ->
66 | dispatcher.register(
67 | literal("zoomify").executes {
68 | displayGui = true
69 | 0
70 | }
71 | )
72 | }
73 |
74 | ClientTickEvents.END_CLIENT_TICK.register(this::tick)
75 | }
76 |
77 | private fun tick(minecraft: Minecraft) {
78 | val prevZooming = zooming
79 |
80 | when (ZoomifySettings.zoomKeyBehaviour.value) {
81 | ZoomKeyBehaviour.HOLD -> zooming = zoomKey.isDown
82 | ZoomKeyBehaviour.TOGGLE -> {
83 | while (zoomKey.consumeClick()) {
84 | zooming = !zooming
85 | }
86 | }
87 | }
88 |
89 | while (secondaryZoomKey.consumeClick()) {
90 | secondaryZooming = !secondaryZooming
91 | }
92 |
93 | if (ZoomifySettings.keybindScrolling) {
94 | while (scrollZoomIn.consumeClick()) {
95 | scrollSteps++
96 | }
97 | while (scrollZoomOut.consumeClick()) {
98 | scrollSteps--
99 | }
100 |
101 | scrollSteps = scrollSteps.coerceIn(0..maxScrollTiers)
102 | }
103 |
104 | handleSpyglass(minecraft, prevZooming)
105 |
106 | zoomHelper.tick(zooming, scrollSteps)
107 | secondaryZoomHelper.tick(secondaryZooming, scrollSteps)
108 |
109 | if (displayGui) {
110 | displayGui = false
111 | minecraft.setScreen(createSettingsGui(minecraft.screen))
112 | }
113 | }
114 |
115 | @JvmStatic
116 | fun getZoomDivisor(tickDelta: Float): Float {
117 | if (!zooming) {
118 | if (!ZoomifySettings.retainZoomSteps.value)
119 | scrollSteps = 0
120 |
121 | zoomHelper.reset()
122 | }
123 |
124 | return (zoomHelper.getZoomDivisor(tickDelta).also { previousZoomDivisor = it } * secondaryZoomHelper.getZoomDivisor(tickDelta)).toFloat()
125 | }
126 |
127 | @JvmStatic
128 | fun mouseZoom(mouseDelta: Double) {
129 | if (mouseDelta > 0) {
130 | scrollSteps++
131 | } else if (mouseDelta < 0) {
132 | scrollSteps--
133 | }
134 | scrollSteps = scrollSteps.coerceIn(0..maxScrollTiers)
135 | }
136 |
137 | private fun handleSpyglass(minecraft: Minecraft, prevZooming: Boolean) {
138 | val cameraEntity = minecraft.cameraEntity
139 |
140 | if (cameraEntity is AbstractClientPlayer) {
141 | when (ZoomifySettings.spyglassBehaviour.value) {
142 | SpyglassBehaviour.ONLY_ZOOM_WHILE_HOLDING -> {
143 | if (!cameraEntity.isHolding(Items.SPYGLASS))
144 | zooming = false
145 | }
146 | SpyglassBehaviour.ONLY_ZOOM_WHILE_CARRYING ->
147 | if (!cameraEntity.inventory.hasAnyMatching { it.`is`(Items.SPYGLASS) })
148 | zooming = false
149 | SpyglassBehaviour.OVERRIDE ->
150 | if (cameraEntity.isScoping)
151 | zooming = zooming && minecraft.options.cameraType.isFirstPerson
152 | else -> {}
153 | }
154 |
155 | val requiresSpyglass = ZoomifySettings.spyglassBehaviour.value != SpyglassBehaviour.COMBINE
156 | if (requiresSpyglass && cameraEntity.isScoping) {
157 | zooming = true
158 | }
159 |
160 | if (shouldPlaySound) {
161 | if (!zooming && prevZooming) {
162 | cameraEntity.playSound(SoundEvents.SPYGLASS_STOP_USING, 1f, 1f)
163 | }
164 | }
165 |
166 | shouldPlaySound = when (ZoomifySettings.spyglassSoundBehaviour.value) {
167 | SoundBehaviour.NEVER -> false
168 | SoundBehaviour.ALWAYS -> true
169 | SoundBehaviour.ONLY_SPYGLASS -> cameraEntity.isScoping || (requiresSpyglass && zooming && cameraEntity.isHolding(Items.SPYGLASS))
170 | SoundBehaviour.WITH_OVERLAY -> shouldRenderOverlay(
171 | cameraEntity,
172 | minecraft.options.cameraType.isFirstPerson && cameraEntity.isScoping
173 | ) && requiresSpyglass
174 | }
175 |
176 | if (shouldPlaySound) {
177 | if (zooming && !prevZooming) {
178 | cameraEntity.playSound(SoundEvents.SPYGLASS_USE, 1f, 1f)
179 | }
180 | }
181 | }
182 | }
183 |
184 | @JvmStatic
185 | fun shouldRenderOverlay(player: AbstractClientPlayer, isUsingSpyglass: Boolean) =
186 | when (ZoomifySettings.spyglassOverlayVisibility.value) {
187 | OverlayVisibility.NEVER -> false
188 | OverlayVisibility.ALWAYS -> zooming
189 | OverlayVisibility.HOLDING -> isUsingSpyglass
190 | || (zooming && player.isHolding(Items.SPYGLASS))
191 | && ZoomifySettings.spyglassBehaviour.value != SpyglassBehaviour.COMBINE
192 | OverlayVisibility.CARRYING -> zooming
193 | && player.inventory.hasAnyMatching { stack: ItemStack -> stack.`is`(Items.SPYGLASS) }
194 | }
195 |
196 | fun onGameFinishedLoading() {
197 | if (ZoomifySettings.firstLaunch) {
198 | LOGGER.info("Zoomify detected first launch!")
199 | detectConflictingToast()
200 |
201 | Migrator.checkMigrations()
202 | }
203 | }
204 |
205 | fun unbindConflicting(): Boolean {
206 | val minecraft = Minecraft.getInstance()
207 | if (!zoomKey.isUnbound) {
208 | for (key in minecraft.options.keyMappings) {
209 | if (key != zoomKey && key.equals(zoomKey)) {
210 | key.setKey(InputConstants.UNKNOWN)
211 | minecraft.options.save()
212 |
213 | toast(
214 | Component.translatable("zoomify.toast.unbindConflicting.name"),
215 | Component.translatable("zoomify.toast.unbindConflicting.description",
216 | Component.translatable(key.name)
217 | ),
218 | longer = false
219 | )
220 |
221 | return true
222 | }
223 | }
224 | }
225 |
226 | return false
227 | }
228 |
229 | private fun detectConflictingToast() {
230 | val minecraft = Minecraft.getInstance()
231 |
232 | if (zoomKey.isUnbound)
233 | return
234 |
235 | if (minecraft.options.keyMappings.any { it != zoomKey && it.equals(zoomKey) }) {
236 | toast(
237 | Component.translatable("zoomify.toast.conflictingKeybind.title"),
238 | Component.translatable("zoomify.toast.conflictingKeybind.description",
239 | Component.translatable("yacl3.config.zoomify.category.misc")
240 | ),
241 | longer = true
242 | )
243 | }
244 | }
245 | }
246 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/Presets.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config
2 |
3 | import dev.isxander.yacl3.config.v3.ConfigEntry
4 | import dev.isxander.yacl3.config.v3.default
5 | import dev.isxander.yacl3.config.v3.value
6 | import dev.isxander.zoomify.utils.TransitionType
7 | import net.minecraft.network.chat.Component
8 |
9 | enum class Presets(val displayName: Component, val apply: ZoomifySettings.() -> Unit) {
10 | Default("zoomify.gui.preset.default", {
11 | this.allSettings.forEach { it.setToDefault() }
12 | }),
13 | Optifine("zoomify.gui.preset.optifine", {
14 | Default.apply(this)
15 |
16 | this.zoomInTransition.value = TransitionType.INSTANT
17 | this.zoomOutTransition.value = TransitionType.INSTANT
18 | this.scrollZoom.value = false
19 | this.relativeSensitivity.value = 0
20 | this.relativeViewBobbing.value = false
21 | this.cinematicCamera.value = 100
22 | }),
23 | OkZoomer("zoomify.gui.preset.ok_zoomer", {
24 | Default.apply(this)
25 |
26 | this.zoomInTime.value = 0.25
27 | this.zoomOutTime.value = 0.25
28 | this.relativeSensitivity.value = 50
29 | this.relativeViewBobbing.value = false
30 | this.scrollZoomSmoothness.value = 25
31 | this.linearLikeSteps.value = false
32 | });
33 |
34 | constructor(displayName: String, apply: ZoomifySettings.() -> Unit)
35 | : this(Component.translatable(displayName), apply)
36 | }
37 |
38 | private fun ConfigEntry.setToDefault() = set(default)
39 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/SpyglassBehaviour.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config
2 |
3 | import dev.isxander.zoomify.utils.NameableEnumKt
4 | import net.minecraft.network.chat.Component
5 | import net.minecraft.util.StringRepresentable
6 |
7 | enum class SpyglassBehaviour(override val localisedName: Component) : NameableEnumKt, StringRepresentable {
8 | COMBINE("zoomify.spyglass_behaviour.combine"),
9 | OVERRIDE("zoomify.spyglass_behaviour.override"),
10 | ONLY_ZOOM_WHILE_HOLDING("zoomify.spyglass_behaviour.only_zoom_while_holding"),
11 | ONLY_ZOOM_WHILE_CARRYING("zoomify.spyglass_behaviour.only_zoom_while_carrying");
12 |
13 | override fun getSerializedName(): String = name.lowercase()
14 |
15 | constructor(localisedName: String) : this(Component.translatable(localisedName))
16 |
17 | companion object {
18 | val CODEC = StringRepresentable.fromEnum(::values)
19 | }
20 | }
21 |
22 | enum class OverlayVisibility(override val localisedName: Component) : NameableEnumKt, StringRepresentable {
23 | NEVER("zoomify.overlay_visibility.never"),
24 | HOLDING("zoomify.overlay_visibility.holding"),
25 | CARRYING("zoomify.overlay_visibility.carrying"),
26 | ALWAYS("zoomify.overlay_visibility.always");
27 |
28 | override fun getSerializedName(): String = name.lowercase()
29 |
30 | constructor(localisedName: String) : this(Component.translatable(localisedName))
31 |
32 | companion object {
33 | val CODEC = StringRepresentable.fromEnum(::values)
34 | }
35 | }
36 |
37 | enum class SoundBehaviour(override val localisedName: Component) : NameableEnumKt, StringRepresentable {
38 | NEVER("zoomify.sound_behaviour.never"),
39 | ALWAYS("zoomify.sound_behaviour.always"),
40 | ONLY_SPYGLASS("zoomify.sound_behaviour.only_spyglass"),
41 | WITH_OVERLAY("zoomify.sound_behaviour.with_overlay");
42 |
43 | override fun getSerializedName(): String = name.lowercase()
44 |
45 | constructor(localisedName: String) : this(Component.translatable(localisedName))
46 |
47 | companion object {
48 | val CODEC = StringRepresentable.fromEnum(::values)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/ZoomKeyBehaviour.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config
2 |
3 | import dev.isxander.zoomify.utils.NameableEnumKt
4 | import net.minecraft.network.chat.Component
5 | import net.minecraft.util.StringRepresentable
6 |
7 | enum class ZoomKeyBehaviour(override val localisedName: Component) : NameableEnumKt, StringRepresentable {
8 | HOLD("zoomify.zoom_key_behaviour.hold"),
9 | TOGGLE("zoomify.zoom_key_behaviour.toggle");
10 |
11 | override fun getSerializedName(): String = name.lowercase()
12 |
13 | constructor(localisedName: String) : this(Component.translatable(localisedName))
14 |
15 | companion object {
16 | val CODEC = StringRepresentable.fromEnum(::values)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/ZoomifySettings.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config
2 |
3 | import com.mojang.serialization.Codec
4 | import dev.isxander.yacl3.config.v3.JsonFileCodecConfig
5 | import dev.isxander.yacl3.config.v3.register
6 | import dev.isxander.yacl3.config.v3.value
7 | import dev.isxander.zoomify.utils.TransitionType
8 | import net.fabricmc.loader.api.FabricLoader
9 |
10 | open class ZoomifySettings() : JsonFileCodecConfig(
11 | FabricLoader.getInstance().configDir.resolve("zoomify.json")
12 | ) {
13 | val initialZoom by register(default = 4, Codec.INT)
14 |
15 | val zoomInTime by register(default = 1.0, Codec.DOUBLE)
16 | val zoomOutTime by register(default = 0.5, Codec.DOUBLE)
17 |
18 | val zoomInTransition by register(default = TransitionType.EASE_OUT_EXP, TransitionType.CODEC)
19 | val zoomOutTransition by register(default = TransitionType.EASE_OUT_EXP, TransitionType.CODEC)
20 |
21 | val affectHandFov by register(default = true, Codec.BOOL)
22 |
23 | val retainZoomSteps by register(default = false, Codec.BOOL)
24 | val linearLikeSteps by register(default = true, Codec.BOOL)
25 |
26 | val scrollZoom by register(default = true, Codec.BOOL)
27 | val scrollZoomAmount by register(default = 3, Codec.INT)
28 | val scrollZoomSmoothness by register(default = 70, Codec.INT)
29 |
30 | val zoomKeyBehaviour by register(default = ZoomKeyBehaviour.HOLD, ZoomKeyBehaviour.CODEC)
31 |
32 | var keybindScrolling = false
33 | val _keybindScrolling by register(default = keybindScrolling, codec = Codec.BOOL)
34 |
35 | val relativeSensitivity by register(default = 100, Codec.INT)
36 | val relativeViewBobbing by register(default = true, Codec.BOOL)
37 |
38 | val cinematicCamera by register(default = 0, Codec.INT)
39 |
40 | val spyglassBehaviour by register(default = SpyglassBehaviour.COMBINE, SpyglassBehaviour.CODEC)
41 | val spyglassOverlayVisibility by register(default = OverlayVisibility.HOLDING, OverlayVisibility.CODEC)
42 | val spyglassSoundBehaviour by register(default = SoundBehaviour.WITH_OVERLAY, SoundBehaviour.CODEC)
43 |
44 | val secondaryZoomAmount by register(default = 4, Codec.INT)
45 | val secondaryZoomInTime by register(default = 10.0, Codec.DOUBLE)
46 | val secondaryZoomOutTime by register(default = 1.0, Codec.DOUBLE)
47 | val secondaryHideHUDOnZoom by register(default = true, Codec.BOOL)
48 |
49 | var firstLaunch = false
50 | val _firstLaunch by register(default = true, Codec.BOOL)
51 |
52 | final val allSettings = arrayOf(
53 | initialZoom,
54 | zoomInTime,
55 | zoomOutTime,
56 | zoomInTransition,
57 | zoomOutTransition,
58 | affectHandFov,
59 | retainZoomSteps,
60 | linearLikeSteps,
61 | scrollZoom,
62 | scrollZoomAmount,
63 | scrollZoomSmoothness,
64 | zoomKeyBehaviour,
65 | _keybindScrolling,
66 | relativeSensitivity,
67 | relativeViewBobbing,
68 | cinematicCamera,
69 | spyglassBehaviour,
70 | spyglassOverlayVisibility,
71 | spyglassSoundBehaviour,
72 | secondaryZoomAmount,
73 | secondaryZoomInTime,
74 | secondaryZoomOutTime,
75 | secondaryHideHUDOnZoom,
76 | _firstLaunch,
77 | )
78 |
79 | constructor(settings: ZoomifySettings) : this() {
80 | this.initialZoom.value = settings.initialZoom.value
81 | this.zoomInTime.value = settings.zoomInTime.value
82 | this.zoomOutTime.value = settings.zoomOutTime.value
83 | this.zoomInTransition.value = settings.zoomInTransition.value
84 | this.zoomOutTransition.value = settings.zoomOutTransition.value
85 | this.affectHandFov.value = settings.affectHandFov.value
86 | this.retainZoomSteps.value = settings.retainZoomSteps.value
87 | this.linearLikeSteps.value = settings.linearLikeSteps.value
88 | this.scrollZoom.value = settings.scrollZoom.value
89 | this.scrollZoomAmount.value = settings.scrollZoomAmount.value
90 | this.scrollZoomSmoothness.value = settings.scrollZoomSmoothness.value
91 | this.zoomKeyBehaviour.value = settings.zoomKeyBehaviour.value
92 | this.keybindScrolling = settings.keybindScrolling
93 | this._keybindScrolling.value = settings._keybindScrolling.value
94 | this.relativeSensitivity.value = settings.relativeSensitivity.value
95 | this.relativeViewBobbing.value = settings.relativeViewBobbing.value
96 | this.cinematicCamera.value = settings.cinematicCamera.value
97 | this.spyglassBehaviour.value = settings.spyglassBehaviour.value
98 | this.spyglassOverlayVisibility.value = settings.spyglassOverlayVisibility.value
99 | this.spyglassSoundBehaviour.value = settings.spyglassSoundBehaviour.value
100 | this.secondaryZoomAmount.value = settings.secondaryZoomAmount.value
101 | this.secondaryZoomInTime.value = settings.secondaryZoomInTime.value
102 | this.secondaryZoomOutTime.value = settings.secondaryZoomOutTime.value
103 | this.secondaryHideHUDOnZoom.value = settings.secondaryHideHUDOnZoom.value
104 | this.firstLaunch = settings.firstLaunch
105 | this._firstLaunch.value = settings._firstLaunch.value
106 | }
107 |
108 | companion object : ZoomifySettings() {
109 | init {
110 | if (!loadFromFile()) {
111 | saveToFile()
112 | }
113 |
114 | if (_firstLaunch.value) {
115 | firstLaunch = true
116 | _firstLaunch.value = false
117 | saveToFile()
118 | }
119 |
120 | _keybindScrolling.value = keybindScrolling
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/demo/ControlEmulation.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config.demo
2 |
3 | fun interface ControlEmulation {
4 | fun tick(imageRenderer: ZoomDemoImageRenderer)
5 |
6 | fun pause(imageRenderer: ZoomDemoImageRenderer) {}
7 |
8 | fun setup(imageRenderer: ZoomDemoImageRenderer) {}
9 |
10 | object InitialOnly : ControlEmulation {
11 | private var switchPauseTicks = 0
12 |
13 | override fun tick(imageRenderer: ZoomDemoImageRenderer) {
14 | // if the previous state is identical to the current state, pause for a bit, then inverse what we just did
15 | if (switchPauseTicks > 0) {
16 | switchPauseTicks--
17 | if (switchPauseTicks == 0) {
18 | imageRenderer.keyDown = !imageRenderer.keyDown
19 | }
20 | } else if (imageRenderer.zoomHelper.getZoomDivisor(1f) == imageRenderer.zoomHelper.getZoomDivisor(0f)) {
21 | switchPauseTicks = 20
22 | }
23 | }
24 |
25 | override fun pause(imageRenderer: ZoomDemoImageRenderer) {
26 | imageRenderer.keyDown = false
27 | switchPauseTicks = 20
28 | }
29 |
30 | override fun setup(imageRenderer: ZoomDemoImageRenderer) {
31 | imageRenderer.keyDown = true
32 | }
33 | }
34 |
35 | object ScrollOnly : ControlEmulation {
36 | private var scrollPauseTicks = 0
37 | private var reverse = false
38 |
39 | override fun tick(imageRenderer: ZoomDemoImageRenderer) {
40 | if (imageRenderer.zoomHelper.maxScrollTiers() == 0) {
41 | imageRenderer.zoomHelper.setToZero(initial = false, scroll = true)
42 | imageRenderer.scrollTiers = 0
43 | return
44 | }
45 |
46 | if (scrollPauseTicks > 0) {
47 | scrollPauseTicks--
48 | } else {
49 | scrollPauseTicks = 3
50 |
51 | if (!reverse) {
52 | imageRenderer.scrollTiers++
53 | if (imageRenderer.scrollTiers >= imageRenderer.zoomHelper.maxScrollTiers()) {
54 | reverse = true
55 | scrollPauseTicks = 20
56 | }
57 | } else {
58 | imageRenderer.scrollTiers--
59 | if (imageRenderer.scrollTiers <= 0) {
60 | reverse = false
61 | scrollPauseTicks = 20
62 | }
63 | }
64 | }
65 | }
66 |
67 |
68 | override fun setup(imageRenderer: ZoomDemoImageRenderer) {
69 | imageRenderer.keyDown = true
70 | imageRenderer.zoomHelper.skipInitial()
71 | }
72 |
73 | override fun pause(imageRenderer: ZoomDemoImageRenderer) {
74 | scrollPauseTicks = 20
75 | reverse = false
76 | imageRenderer.scrollTiers = 0
77 | imageRenderer.zoomHelper.skipInitial()
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/demo/ZoomDemoImageRenderer.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config.demo
2 |
3 | import dev.isxander.yacl3.gui.image.ImageRenderer
4 | import dev.isxander.yacl3.gui.image.ImageRendererManager
5 | import dev.isxander.yacl3.gui.image.impl.AnimatedDynamicTextureImage
6 | import dev.isxander.zoomify.utils.*
7 | import dev.isxander.zoomify.zoom.ZoomHelper
8 | import net.minecraft.client.gui.GuiGraphics
9 | import net.minecraft.resources.ResourceLocation
10 | import java.util.Optional
11 | import java.util.concurrent.CompletableFuture
12 |
13 | abstract class ZoomDemoImageRenderer(val zoomHelper: ZoomHelper, private val zoomControl: ControlEmulation) : ImageRenderer {
14 | var keyDown = false
15 | var scrollTiers = 0
16 |
17 | init {
18 | zoomControl.setup(this)
19 | }
20 |
21 | abstract override fun render(graphics: GuiGraphics, x: Int, y: Int, renderWidth: Int, deltaTime: Float): Int
22 |
23 | override fun tick() {
24 | zoomHelper.tick(keyDown, scrollTiers)
25 | zoomControl.tick(this)
26 | }
27 |
28 | fun pause() {
29 | zoomHelper.setToZero()
30 | zoomControl.pause(this)
31 | }
32 |
33 | companion object {
34 | @JvmStatic
35 | protected fun makeWebp(id: ResourceLocation): CompletableFuture {
36 | return ImageRendererManager.registerOrGetImage(id) { AnimatedDynamicTextureImage.createWEBPFromTexture(id) }
37 | }
38 | }
39 |
40 | }
41 |
42 | class FirstPersonDemo(zoomHelper: ZoomHelper, zoomControl: ControlEmulation) : ZoomDemoImageRenderer(zoomHelper, zoomControl) {
43 | var keepHandFov = false
44 |
45 | private val handRenderer = makeWebp(HAND_TEXTURE)
46 | private val worldRenderer = makeWebp(WORLD_TEXTURE)
47 |
48 | override fun render(graphics: GuiGraphics, x: Int, y: Int, renderWidth: Int, deltaTime: Float): Int {
49 | val ratio = renderWidth / TEX_WIDTH.toDouble()
50 | val renderHeight = (TEX_HEIGHT * ratio).toInt()
51 | if (!handRenderer.isDone || !worldRenderer.isDone) {
52 | return renderHeight
53 | }
54 |
55 | graphics.enableScissor(x, y, x + renderWidth, y + renderHeight)
56 |
57 | graphics.pushPose()
58 | graphics.translate(x.toDouble(), y.toDouble(), 0.0)
59 | graphics.scale(ratio.toFloat(), ratio.toFloat(), 1f)
60 |
61 | val zoomScale = zoomHelper.getZoomDivisor(deltaTime).toFloat()
62 | graphics.pushPose()
63 | graphics.translate(TEX_WIDTH / 2f, TEX_HEIGHT / 2f, 0.0F)
64 | graphics.scale(zoomScale, zoomScale, 1.0F)
65 | graphics.translate(-TEX_WIDTH / 2f, -TEX_HEIGHT / 2f, 0.0F)
66 |
67 | worldRenderer.get().render(graphics, 0, 0, TEX_WIDTH, deltaTime)
68 |
69 | if (keepHandFov) graphics.popPose()
70 | handRenderer.get().render(graphics, 0, 0, TEX_WIDTH, deltaTime)
71 | if (!keepHandFov) graphics.popPose()
72 |
73 | graphics.popPose()
74 |
75 | graphics.disableScissor()
76 |
77 | return renderHeight
78 | }
79 |
80 | override fun close() {
81 | Optional.ofNullable(worldRenderer.getNow(null)).map { it.close() }
82 | Optional.ofNullable(handRenderer.getNow(null)).map { it.close() }
83 | }
84 |
85 | companion object {
86 | const val TEX_WIDTH = 1916
87 | const val TEX_HEIGHT = 910
88 |
89 | val WORLD_TEXTURE = zoomifyRl("textures/demo/zoom-world.webp")
90 | val HAND_TEXTURE = zoomifyRl("textures/demo/zoom-hand.webp")
91 |
92 | }
93 | }
94 |
95 | class ThirdPersonDemo(zoomHelper: ZoomHelper, zoomControl: ControlEmulation) : ZoomDemoImageRenderer(zoomHelper, zoomControl) {
96 | private val thirdPersonViewRenderer = makeWebp(PLAYER_VIEW)
97 | private val hudRenderer = makeWebp(HUD_TEXTURE)
98 |
99 | var renderHud = true
100 |
101 | override fun render(graphics: GuiGraphics, x: Int, y: Int, renderWidth: Int, deltaTime: Float): Int {
102 | val ratio = renderWidth / TEX_WIDTH.toDouble()
103 | val renderHeight = (TEX_HEIGHT * ratio).toInt()
104 | if (!thirdPersonViewRenderer.isDone || !hudRenderer.isDone) {
105 | return renderHeight
106 | }
107 |
108 | graphics.enableScissor(x, y, x + renderWidth, y + renderHeight)
109 |
110 | graphics.pushPose()
111 | graphics.translate(x.toDouble(), y.toDouble(), 0.0)
112 | graphics.scale(ratio.toFloat(), ratio.toFloat(), 1f)
113 |
114 | val zoomScale = zoomHelper.getZoomDivisor(deltaTime).toFloat()
115 | graphics.pushPose()
116 | graphics.translate(FirstPersonDemo.TEX_WIDTH / 2f, FirstPersonDemo.TEX_HEIGHT / 2f, 0.0F)
117 | graphics.scale(zoomScale, zoomScale, 1.0F)
118 | graphics.translate(-FirstPersonDemo.TEX_WIDTH / 2f, -FirstPersonDemo.TEX_HEIGHT / 2f, 0.0F)
119 |
120 | thirdPersonViewRenderer.get().render(graphics, 0, 0, TEX_WIDTH, deltaTime)
121 |
122 | graphics.popPose()
123 |
124 | if (renderHud)
125 | hudRenderer.get().render(graphics, 0, 0, TEX_WIDTH, deltaTime)
126 |
127 | graphics.popPose()
128 | graphics.disableScissor()
129 |
130 | return renderHeight
131 | }
132 |
133 | override fun close() {
134 | Optional.ofNullable(thirdPersonViewRenderer.getNow(null)).map { it.close() }
135 | Optional.ofNullable(hudRenderer.getNow(null)).map { it.close() }
136 | }
137 |
138 | companion object {
139 | const val TEX_WIDTH = 1915
140 | const val TEX_HEIGHT = 910
141 |
142 | val PLAYER_VIEW = zoomifyRl("textures/demo/third-person-view.webp")
143 | val HUD_TEXTURE = zoomifyRl("textures/demo/third-person-hud.webp")
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/migrator/Migration.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config.migrator
2 |
3 | import net.minecraft.ChatFormatting
4 | import net.minecraft.network.chat.Component
5 |
6 | class Migration {
7 | private val warnings = mutableListOf()
8 | private val errors = mutableListOf()
9 | var requireRestart = false
10 | private set
11 |
12 | fun error(text: Component) = errors.add(text)
13 | fun warn(text: Component) = warnings.add(text)
14 |
15 | fun requireRestart() {
16 | requireRestart = true
17 | }
18 |
19 | fun generateReport(): Component {
20 | val text = Component.empty()
21 |
22 | val errors = this.errors
23 | if (requireRestart) {
24 | errors.add(0, Component.translatable("zoomify.migrate.restart"))
25 | }
26 |
27 | for (error in errors) {
28 | val line = Component.empty()
29 | .append("\u25C6 ")
30 | .append(error)
31 | .append("\n")
32 | .withStyle(ChatFormatting.RED)
33 | text.append(line)
34 | }
35 |
36 | for (warning in warnings) {
37 | val line = Component.empty()
38 | .append("\u25C6 ")
39 | .append(warning)
40 | .append("\n")
41 | .withStyle(ChatFormatting.YELLOW)
42 | text.append(line)
43 | }
44 |
45 | return text
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/migrator/MigrationAvailableScreen.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config.migrator
2 |
3 | import dev.isxander.zoomify.config.ZoomifySettings
4 | import net.minecraft.ChatFormatting
5 | import net.minecraft.client.Minecraft
6 | import net.minecraft.client.gui.screens.ConfirmScreen
7 | import net.minecraft.client.gui.screens.Screen
8 | import net.minecraft.network.chat.Component
9 |
10 | class MigrationAvailableScreen(migrator: Migrator, parent: Screen?) : ConfirmScreen(
11 | { yes ->
12 | if (yes) {
13 | val migration = Migration()
14 | migrator.migrate(migration)
15 | ZoomifySettings.saveToFile()
16 | Minecraft.getInstance().setScreen(MigrationResultScreen(migration, parent))
17 | } else {
18 | Minecraft.getInstance().setScreen(parent)
19 | }
20 | },
21 | Component.translatable("zoomify.migrate.available.title", migrator.name.copy().withStyle(ChatFormatting.BOLD)),
22 | Component.translatable("zoomify.migrate.available.message", migrator.name)
23 | )
24 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/migrator/MigrationResultScreen.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config.migrator
2 |
3 | import net.minecraft.client.Minecraft
4 | import net.minecraft.client.gui.screens.AlertScreen
5 | import net.minecraft.client.gui.screens.Screen
6 | import net.minecraft.network.chat.CommonComponents
7 | import net.minecraft.network.chat.Component
8 |
9 |
10 | class MigrationResultScreen(
11 | migration: Migration,
12 | parent: Screen?,
13 | ) : AlertScreen(
14 | {
15 | if (migration.requireRestart)
16 | Minecraft.getInstance().stop()
17 | else
18 | Minecraft.getInstance().setScreen(parent)
19 | },
20 | Component.translatable("zoomify.migrate.result.title"),
21 | migration.generateReport(),
22 | if (migration.requireRestart)
23 | Component.translatable("zoomify.migrate.result.restart_game")
24 | else
25 | CommonComponents.GUI_DONE,
26 | true
27 | )
28 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/migrator/Migrator.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config.migrator
2 |
3 | import dev.isxander.zoomify.config.migrator.impl.OkZoomerMigrator
4 | import net.minecraft.client.Minecraft
5 | import net.minecraft.network.chat.Component
6 |
7 | interface Migrator {
8 | val name: Component
9 |
10 | fun isMigrationAvailable(): Boolean
11 |
12 | fun migrate(migration: Migration)
13 |
14 | companion object {
15 | val MIGRATORS = listOf(OkZoomerMigrator)
16 |
17 | fun checkMigrations(): Boolean {
18 | val available = MIGRATORS.filter { it.isMigrationAvailable() }
19 |
20 | if (available.isEmpty())
21 | return false
22 |
23 | var lastScreen = Minecraft.getInstance().screen
24 |
25 | for (migrator in available) {
26 | lastScreen = MigrationAvailableScreen(migrator, lastScreen)
27 | }
28 |
29 | Minecraft.getInstance().setScreen(lastScreen)
30 | return true
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/config/migrator/impl/OkZoomerMigrator.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.config.migrator.impl
2 |
3 | import com.akuleshov7.ktoml.Toml
4 | import com.akuleshov7.ktoml.TomlInputConfig
5 | import dev.isxander.yacl3.config.v3.value
6 | import dev.isxander.zoomify.Zoomify
7 | import dev.isxander.zoomify.config.*
8 | import dev.isxander.zoomify.config.migrator.Migration
9 | import dev.isxander.zoomify.config.migrator.Migrator
10 | import kotlinx.serialization.SerialName
11 | import kotlinx.serialization.Serializable
12 | import kotlinx.serialization.decodeFromString
13 | import net.fabricmc.loader.api.FabricLoader
14 | import java.nio.file.Files
15 | import dev.isxander.zoomify.config.migrator.impl.OkZoomerMigrator.OkZoomerConfig.Features.CinematicCameraState
16 | import dev.isxander.zoomify.config.migrator.impl.OkZoomerMigrator.OkZoomerConfig.Features.ZoomMode
17 | import dev.isxander.zoomify.config.migrator.impl.OkZoomerMigrator.OkZoomerConfig.Features.Overlay
18 | import dev.isxander.zoomify.config.migrator.impl.OkZoomerMigrator.OkZoomerConfig.Features.SpyglassDependency
19 | import dev.isxander.zoomify.utils.TransitionType
20 | import net.minecraft.network.chat.Component
21 | import kotlin.math.roundToInt
22 |
23 | object OkZoomerMigrator : Migrator {
24 | private val file = FabricLoader.getInstance().configDir.resolve("ok_zoomer/config.toml")
25 | private val toml = Toml(
26 | inputConfig = TomlInputConfig(
27 | ignoreUnknownNames = true
28 | )
29 | )
30 |
31 | override val name: Component = Component.translatable("zoomify.migrate.okz")
32 |
33 | override fun isMigrationAvailable(): Boolean =
34 | Files.exists(file)
35 |
36 | override fun migrate(migration: Migration) {
37 | val okz = toml.decodeFromString(Files.readString(file))
38 |
39 | when (okz.features.cinematicCamera) {
40 | CinematicCameraState.VANILLA ->
41 | ZoomifySettings.cinematicCamera.value = 100
42 | CinematicCameraState.MULTIPLIED ->
43 | ZoomifySettings.cinematicCamera.value = (1 / okz.values.cinematicMultiplier * 100).toInt()
44 | CinematicCameraState.OFF ->
45 | ZoomifySettings.cinematicCamera.value = 0
46 | }
47 |
48 | if (okz.features.reduceSensitivity) {
49 | ZoomifySettings.relativeSensitivity.value = 100
50 | } else {
51 | ZoomifySettings.relativeSensitivity.value = 0
52 | }
53 |
54 | when (okz.features.zoomMode) {
55 | ZoomMode.HOLD ->
56 | ZoomifySettings.zoomKeyBehaviour.value = ZoomKeyBehaviour.HOLD
57 | ZoomMode.TOGGLE ->
58 | ZoomifySettings.zoomKeyBehaviour.value = ZoomKeyBehaviour.TOGGLE
59 | ZoomMode.PERSISTENT -> {
60 | migration.error(Component.translatable("zoomify.migrate.okz.persistent"))
61 | }
62 | }
63 |
64 | ZoomifySettings._keybindScrolling.value = okz.features.extraKeyBinds
65 | migration.requireRestart()
66 |
67 | when (okz.features.zoomOverlay) {
68 | Overlay.OFF ->
69 | ZoomifySettings.spyglassOverlayVisibility.value = OverlayVisibility.NEVER
70 | Overlay.SPYGLASS ->
71 | ZoomifySettings.spyglassOverlayVisibility.value = when (okz.features.spyglassDependency) {
72 | SpyglassDependency.REPLACE_ZOOM -> OverlayVisibility.ALWAYS
73 | SpyglassDependency.REQUIRE_ITEM, SpyglassDependency.BOTH -> OverlayVisibility.HOLDING
74 | SpyglassDependency.OFF -> OverlayVisibility.ALWAYS
75 | }
76 | Overlay.VIGNETTE -> {
77 | migration.error(Component.translatable("zoomify.migrate.okz.vignette"))
78 | }
79 | }
80 |
81 | when (okz.features.spyglassDependency) {
82 | SpyglassDependency.OFF ->
83 | ZoomifySettings.spyglassBehaviour.value = SpyglassBehaviour.COMBINE
84 | SpyglassDependency.REPLACE_ZOOM ->
85 | ZoomifySettings.spyglassBehaviour.value = SpyglassBehaviour.OVERRIDE
86 | SpyglassDependency.REQUIRE_ITEM ->
87 | ZoomifySettings.spyglassBehaviour.value = SpyglassBehaviour.ONLY_ZOOM_WHILE_HOLDING
88 | SpyglassDependency.BOTH ->
89 | ZoomifySettings.spyglassBehaviour.value = SpyglassBehaviour.ONLY_ZOOM_WHILE_CARRYING // FIXME: idk what this does
90 | }
91 |
92 | ZoomifySettings.spyglassSoundBehaviour.value =
93 | if (okz.tweaks.useSpyglassSounds)
94 | SoundBehaviour.ALWAYS
95 | else
96 | SoundBehaviour.NEVER
97 |
98 | ZoomifySettings.initialZoom.value = okz.values.zoomDivisor.roundToInt()
99 | migration.warn(Component.translatable("zoomify.migrate.okz.minZoomDiv"))
100 | ZoomifySettings.scrollZoomAmount.value = ((okz.values.maxZoomDivisor - ZoomifySettings.initialZoom.value) / Zoomify.maxScrollTiers).roundToInt()
101 |
102 | migration.warn(Component.translatable("zoomify.migrate.okz.stepAmt"))
103 |
104 | when (okz.features.zoomTransition) {
105 | OkZoomerConfig.Features.TransitionMode.LINEAR -> {
106 | migration.error(Component.translatable("zoomify.migrate.okz.linearNotSupported"))
107 | ZoomifySettings.zoomInTransition.value = TransitionType.LINEAR
108 | ZoomifySettings.zoomOutTransition.value = TransitionType.LINEAR
109 | }
110 | OkZoomerConfig.Features.TransitionMode.SMOOTH -> {
111 | val targetMultiplier = 1f / ZoomifySettings.initialZoom.value
112 | var multiplier = 1f
113 | var ticks = 0
114 | while (multiplier != targetMultiplier) {
115 | multiplier += (targetMultiplier - multiplier) * okz.values.smoothMultiplier.toFloat()
116 | ticks++
117 | }
118 | val zoomTime = (ticks * 0.05 / 0.1).roundToInt() * 0.1
119 | ZoomifySettings.zoomInTime.value = zoomTime
120 | ZoomifySettings.zoomOutTime.value = zoomTime
121 | ZoomifySettings.zoomInTransition.value = TransitionType.EASE_IN_EXP
122 | ZoomifySettings.zoomOutTransition.value = TransitionType.EASE_IN_EXP
123 | }
124 | OkZoomerConfig.Features.TransitionMode.OFF -> {
125 | ZoomifySettings.zoomInTime.value = 0.0
126 | ZoomifySettings.zoomOutTime.value = 0.0
127 | ZoomifySettings.zoomInTransition.value = TransitionType.INSTANT
128 | ZoomifySettings.zoomOutTransition.value = TransitionType.INSTANT
129 | }
130 | }
131 |
132 |
133 | ZoomifySettings.retainZoomSteps.value = !okz.tweaks.forgetZoomDivisor
134 |
135 | if (okz.tweaks.unbindConflictingKey) {
136 | Zoomify.unbindConflicting()
137 | }
138 | }
139 |
140 | @Serializable
141 | data class OkZoomerConfig(
142 | val features: Features,
143 | val values: Values,
144 | val tweaks: Tweaks,
145 | ) {
146 | @Serializable
147 | data class Features(
148 | @SerialName("cinematic_camera") val cinematicCamera: CinematicCameraState,
149 | @SerialName("reduce_sensitivity") val reduceSensitivity: Boolean,
150 | @SerialName("zoom_transition") val zoomTransition: TransitionMode,
151 | @SerialName("zoom_mode") val zoomMode: ZoomMode,
152 | @SerialName("zoom_scrolling") val zoomScrolling: Boolean,
153 | @SerialName("extra_key_binds") val extraKeyBinds: Boolean,
154 | @SerialName("zoom_overlay") val zoomOverlay: Overlay,
155 | @SerialName("spyglass_dependency") val spyglassDependency: SpyglassDependency
156 | ) {
157 | @Serializable
158 | enum class CinematicCameraState {
159 | OFF, VANILLA, MULTIPLIED
160 | }
161 |
162 | @Serializable
163 | enum class TransitionMode {
164 | OFF, SMOOTH, LINEAR
165 | }
166 |
167 | @Serializable
168 | enum class ZoomMode {
169 | HOLD, TOGGLE, PERSISTENT
170 | }
171 |
172 | @Serializable
173 | enum class Overlay {
174 | OFF, VIGNETTE, SPYGLASS
175 | }
176 |
177 | @Serializable
178 | enum class SpyglassDependency {
179 | OFF, REQUIRE_ITEM, REPLACE_ZOOM, BOTH
180 | }
181 | }
182 |
183 | @Serializable
184 | data class Values(
185 | @SerialName("zoom_divisor") val zoomDivisor: Double,
186 | @SerialName("minimum_zoom_divisor") val minZoomDivisor: Double,
187 | @SerialName("maximum_zoom_divisor") val maxZoomDivisor: Double,
188 | @SerialName("upper_scroll_steps") val upperScrollSteps: Long,
189 | @SerialName("lower_scroll_steps") val lowerScrollSteps: Long,
190 | @SerialName("smooth_multiplier") val smoothMultiplier: Double,
191 | @SerialName("cinematic_multiplier") val cinematicMultiplier: Double,
192 | @SerialName("minimum_linear_step") val minLinearStep: Double,
193 | @SerialName("maximum_linear_step") val maxLinearSteps: Double,
194 | )
195 |
196 | @Serializable
197 | data class Tweaks(
198 | @SerialName("reset_zoom_with_mouse") val resetZoomWithMouse: Boolean,
199 | @SerialName("forget_zoom_divisor") val forgetZoomDivisor: Boolean,
200 | @SerialName("unbind_conflicting_key") val unbindConflictingKey: Boolean,
201 | @SerialName("use_spyglass_texture") val useSpyglassTexture: Boolean,
202 | @SerialName("use_spyglass_sounds") val useSpyglassSounds: Boolean,
203 | )
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/integrations/ControlifyIntegration.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.integrations
2 |
3 | import dev.isxander.controlify.api.ControlifyApi
4 | import dev.isxander.controlify.api.entrypoint.ControlifyEntrypoint
5 | import dev.isxander.controlify.api.event.ControlifyEvents
6 | import dev.isxander.yacl3.config.v3.value
7 | import dev.isxander.zoomify.Zoomify
8 | import dev.isxander.zoomify.config.ZoomifySettings
9 | import net.minecraft.util.Mth
10 |
11 | object ControlifyIntegration : ControlifyEntrypoint {
12 | override fun onControlifyInit(controlify: ControlifyApi) {
13 | ControlifyEvents.LOOK_INPUT_MODIFIER.register {
14 | it.lookInput.x /= Mth.lerp(ZoomifySettings.relativeSensitivity.value / 100.0, 1.0, Zoomify.previousZoomDivisor).toFloat()
15 | it.lookInput.y /= Mth.lerp(ZoomifySettings.relativeSensitivity.value / 100.0, 1.0, Zoomify.previousZoomDivisor).toFloat()
16 | }
17 | }
18 |
19 | override fun onControllersDiscovered(controlify: ControlifyApi) {
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/integrations/IntegrationHelper.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.integrations
2 |
3 | import net.fabricmc.loader.api.FabricLoader
4 | import net.fabricmc.loader.api.metadata.version.VersionPredicate
5 |
6 | fun constrainModVersionIfLoaded(modId: String, constraint: String) {
7 | val predicate = VersionPredicate.parse(constraint)
8 |
9 | val modContainer = FabricLoader.getInstance().getModContainer(modId)
10 | if (modContainer.isPresent) {
11 | val version = modContainer.get().metadata.version
12 | if (!predicate.test(version)) {
13 | throw IllegalStateException("Mod $modId is not constrained to version $constraint")
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/integrations/ModMenuIntegration.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.integrations
2 |
3 | import com.terraformersmc.modmenu.api.ConfigScreenFactory
4 | import com.terraformersmc.modmenu.api.ModMenuApi
5 | import dev.isxander.zoomify.config.createSettingsGui
6 |
7 | object ModMenuIntegration : ModMenuApi {
8 | override fun getModConfigScreenFactory(): ConfigScreenFactory<*> = ConfigScreenFactory { parent ->
9 | createSettingsGui(parent)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/utils/KeySource.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.utils
2 |
3 | import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper
4 | import net.minecraft.client.KeyMapping
5 |
6 | interface KeySource {
7 | val justPressed: Boolean
8 |
9 | val isDown: Boolean
10 | }
11 |
12 | class MultiKeySource(sources: List) : KeySource {
13 | private val sources = sources.toMutableList()
14 |
15 | constructor(vararg sources: KeySource) : this(sources.toList())
16 | constructor() : this(emptyList())
17 |
18 | override val justPressed: Boolean
19 | get() = sources.any { it.justPressed }
20 |
21 | override val isDown: Boolean
22 | get() = sources.any { it.isDown }
23 |
24 | fun addSource(source: KeySource) {
25 | sources.add(source)
26 | }
27 | }
28 |
29 | fun KeyMapping.toKeySource(register: Boolean = false) = object : KeySource {
30 | override val justPressed: Boolean
31 | get() = this@toKeySource.consumeClick()
32 |
33 | override val isDown: Boolean
34 | get() = this@toKeySource.isDown
35 | }.also { if (register) KeyBindingHelper.registerKeyBinding(this) }
36 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/utils/MinecraftExt.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.utils
2 |
3 | import net.minecraft.client.Minecraft
4 | import net.minecraft.client.gui.GuiGraphics
5 | import net.minecraft.client.gui.components.toasts.SystemToast
6 | import net.minecraft.network.chat.Component
7 | import net.minecraft.resources.ResourceLocation
8 |
9 | val minecraft: Minecraft = Minecraft.getInstance()
10 |
11 | fun GuiGraphics.pushPose() = pose().pushPose()
12 | fun GuiGraphics.popPose() = pose().popPose()
13 | fun GuiGraphics.translate(x: Double, y: Double, z: Double) = pose().translate(x, y, z)
14 | fun GuiGraphics.translate(x: Float, y: Float, z: Float) = pose().translate(x, y, z)
15 | fun GuiGraphics.scale(x: Float, y: Float, z: Float) = pose().scale(x, y, z)
16 |
17 | // i love kotlin
18 | typealias ToastTypes =
19 | //? if >1.20.1 {
20 | SystemToast.SystemToastId
21 | //?} else {
22 | /*SystemToast.SystemToastIds
23 | *///?}
24 |
25 | fun toast(
26 | title: Component,
27 | description: Component,
28 | longer: Boolean = false
29 | ): SystemToast = SystemToast.multiline(
30 | minecraft,
31 | if (longer) ToastTypes.UNSECURE_SERVER_WARNING else ToastTypes.PERIODIC_NOTIFICATION,
32 | title,
33 | description
34 | ).also {
35 | val toastManager = /*? if >=1.21.2 {*/ minecraft.toastManager /*?} else {*/ /*minecraft.toasts *//*?}*/
36 | toastManager.addToast(it)
37 | }
38 |
39 | fun zoomifyRl(path: String) =
40 | //? if >=1.21 {
41 | ResourceLocation.fromNamespaceAndPath("zoomify", path)
42 | //?} else {
43 | /*ResourceLocation("zoomify", path)
44 | *///?}
45 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/utils/NameableEnumKt.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.utils
2 |
3 | import dev.isxander.yacl3.api.NameableEnum
4 | import net.minecraft.network.chat.Component
5 |
6 | interface NameableEnumKt : NameableEnum {
7 | val localisedName: Component
8 |
9 | override fun getDisplayName(): Component = localisedName
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/utils/TransitionType.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.utils
2 |
3 | import dev.isxander.yacl3.api.NameableEnum
4 | import net.minecraft.network.chat.Component
5 | import net.minecraft.util.StringRepresentable
6 | import kotlin.math.*
7 |
8 | enum class TransitionType(val localisedName: Component) : Transition, NameableEnum, StringRepresentable {
9 | INSTANT("zoomify.transition.instant") {
10 | override fun apply(t: Double) =
11 | t
12 | },
13 | LINEAR("zoomify.transition.linear") {
14 | override fun apply(t: Double) =
15 | t
16 | },
17 | EASE_IN_SINE("zoomify.transition.ease_in_sine") {
18 | override fun apply(t: Double): Double =
19 | 1 - cos((t * PI) / 2)
20 |
21 | override fun inverse(x: Double) =
22 | acos(-(x - 1)) * 2 / PI
23 | },
24 | EASE_OUT_SINE("zoomify.transition.ease_out_sine") {
25 | override fun apply(t: Double): Double =
26 | sin((t * PI) / 2)
27 |
28 | override fun inverse(x: Double) =
29 | asin(x) * 2 / PI
30 | },
31 | EASE_IN_OUT_SINE("zoomify.transition.ease_in_out_sine") {
32 | override fun apply(t: Double): Double =
33 | -(cos(PI * t) - 1) / 2
34 | },
35 | EASE_IN_QUAD("zoomify.transition.ease_in_quad") {
36 | override fun apply(t: Double): Double =
37 | t * t
38 |
39 | override fun inverse(x: Double) =
40 | sqrt(x)
41 | },
42 | EASE_OUT_QUAD("zoomify.transition.ease_out_quad") {
43 | override fun apply(t: Double): Double =
44 | 1 - (1 - t) * (1 - t)
45 |
46 | override fun inverse(x: Double) =
47 | -(sqrt(-(x - 1)) - 1)
48 |
49 | },
50 | EASE_IN_OUT_QUAD("zoomify.transition.ease_in_out_quad") {
51 | override fun apply(t: Double): Double =
52 | if (t < 0.5)
53 | 2 * t * t
54 | else
55 | 1 - (-2 * t + 2).pow(2) / 2
56 | },
57 | EASE_IN_CUBIC("zoomify.transition.ease_in_cubic") {
58 | override fun apply(t: Double): Double =
59 | t.pow(3)
60 |
61 | override fun inverse(x: Double) =
62 | x.pow(1 / 3.0)
63 | },
64 | EASE_OUT_CUBIC("zoomify.transition.ease_out_cubic") {
65 | override fun apply(t: Double): Double =
66 | 1 - (1 - t).pow(3)
67 |
68 | override fun inverse(x: Double) =
69 | -((-x + 1).pow(1.0 / 3.0)) + 1
70 | },
71 | EASE_IN_OUT_CUBIC("zoomify.transition.ease_in_out_cubic") {
72 | override fun apply(t: Double): Double =
73 | if (t < 0.5)
74 | 4 * t * t * t
75 | else
76 | 1 - (-2 * t + 2).pow(3) / 2
77 | },
78 | EASE_IN_EXP("zoomify.transition.ease_in_exp") {
79 | private val c_log2_1023 = log(1023.0, base=2.0)
80 |
81 | override fun apply(t: Double): Double =
82 | when (t) {
83 | 0.0 -> 0.0
84 | 1.0 -> 1.0
85 | else -> 2.0.pow(10.0 * t - c_log2_1023) - 1/1023
86 | }
87 |
88 | override fun inverse(x: Double) =
89 | when (x) {
90 | 0.0 -> 0.0
91 | 1.0 -> 1.0
92 | else -> ln(1023 * x + 1) / (10 * ln(2.0))
93 | }
94 | },
95 | EASE_OUT_EXP("zoomify.transition.ease_out_exp") {
96 | private val c_log2_1023 = log(1023.0, base=2.0)
97 | private val c_10_ln2 = 10.0 * ln(2.0)
98 | private val c_ln_1203 = ln(1023.0)
99 |
100 | override fun apply(t: Double): Double =
101 | when (t) {
102 | 0.0 -> 0.0
103 | 1.0 -> 1.0
104 | else -> 1.0 - 2.0.pow(10.0 - c_log2_1023 - 10.0 * t) + 1/1023
105 | }
106 |
107 | override fun inverse(x: Double) =
108 | when (x) {
109 | 0.0 -> 0.0
110 | 1.0 -> 1.0
111 | else -> -((ln(-((1023 * x - 1024) / 1023)) - c_10_ln2 + c_ln_1203) / c_10_ln2)
112 | }
113 | },
114 | EASE_IN_OUT_EXP("zoomify.transition.ease_in_out_exp") {
115 | private val c_log2_1023 = log(1023.0, base=2.0)
116 |
117 | override fun apply(t: Double): Double =
118 | when {
119 | t == 0.0 -> 0.0
120 | t == 1.0 -> 1.0
121 | t < 0.5 -> 2.0.pow(20.0 * t - c_log2_1023) - 1/1023
122 | else -> 1.0 - 2.0.pow(10.0 - c_log2_1023 - 10.0 * t) + 1/1023
123 | }
124 | };
125 |
126 | constructor(name: String) : this(Component.translatable(name))
127 |
128 | override fun getSerializedName(): String = name.lowercase()
129 | override fun getDisplayName(): Component = localisedName
130 |
131 | fun opposite(): TransitionType = when (this) {
132 | INSTANT -> INSTANT
133 | LINEAR -> LINEAR
134 | EASE_IN_SINE -> EASE_OUT_SINE
135 | EASE_OUT_SINE -> EASE_IN_SINE
136 | EASE_IN_OUT_SINE -> EASE_IN_OUT_SINE
137 | EASE_IN_QUAD -> EASE_OUT_QUAD
138 | EASE_OUT_QUAD -> EASE_IN_QUAD
139 | EASE_IN_OUT_QUAD -> EASE_IN_OUT_QUAD
140 | EASE_IN_CUBIC -> EASE_OUT_CUBIC
141 | EASE_OUT_CUBIC -> EASE_IN_CUBIC
142 | EASE_IN_OUT_CUBIC -> EASE_IN_OUT_CUBIC
143 | EASE_IN_EXP -> EASE_OUT_EXP
144 | EASE_OUT_EXP -> EASE_IN_EXP
145 | EASE_IN_OUT_EXP -> EASE_IN_OUT_EXP
146 | }
147 |
148 | companion object {
149 | val CODEC = StringRepresentable.fromEnum(::values)
150 | }
151 | }
152 |
153 | fun interface Transition {
154 | fun apply(t: Double): Double
155 |
156 | fun inverse(x: Double): Double {
157 | throw UnsupportedOperationException()
158 | }
159 |
160 | fun hasInverse() = try {
161 | inverse(0.0)
162 | true
163 | } catch (_: UnsupportedOperationException) {
164 | false
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/zoom/DefaultZoomHelpers.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.zoom
2 |
3 | import dev.isxander.yacl3.config.v3.value
4 | import dev.isxander.zoomify.Zoomify
5 | import dev.isxander.zoomify.config.ZoomifySettings
6 | import net.minecraft.util.Mth
7 |
8 | fun RegularZoomHelper(settings: ZoomifySettings) = ZoomHelper(
9 | TransitionInterpolator(
10 | settings.zoomInTransition::value,
11 | settings.zoomOutTransition::value,
12 | settings.zoomInTime::value,
13 | settings.zoomOutTime::value
14 | ),
15 | SmoothInterpolator {
16 | Mth.lerp(
17 | settings.scrollZoomSmoothness.value / 100.0,
18 | 1.0,
19 | 0.1
20 | )
21 | },
22 | initialZoom = settings.initialZoom::value,
23 | scrollZoomAmount = settings.scrollZoomAmount::value,
24 | maxScrollTiers = Zoomify::maxScrollTiers,
25 | linearLikeSteps = settings.linearLikeSteps::value,
26 | )
27 |
28 | fun SecondaryZoomHelper(settings: ZoomifySettings) = ZoomHelper(
29 | TimedInterpolator(settings.secondaryZoomInTime::value, settings.secondaryZoomOutTime::value),
30 | InstantInterpolator,
31 | initialZoom = settings.secondaryZoomAmount::value,
32 | scrollZoomAmount = { 0 },
33 | maxScrollTiers = { 0 },
34 | linearLikeSteps = { false },
35 | )
36 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/zoom/Interpolator.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.zoom
2 |
3 | import dev.isxander.zoomify.utils.TransitionType
4 | import kotlin.math.max
5 | import kotlin.math.min
6 |
7 | interface Interpolator {
8 | fun tickInterpolation(targetInterpolation: Double, currentInterpolation: Double, tickDelta: Double): Double
9 |
10 | fun modifyInterpolation(interpolation: Double): Double = interpolation
11 |
12 | fun modifyPrevInterpolation(interpolation: Double): Double = interpolation
13 | val isSmooth: Boolean
14 | }
15 |
16 | object InstantInterpolator : Interpolator {
17 | override fun tickInterpolation(targetInterpolation: Double, currentInterpolation: Double, tickDelta: Double): Double {
18 | return targetInterpolation
19 | }
20 |
21 | override val isSmooth: Boolean = false
22 | }
23 |
24 | sealed class LinearInterpolator : Interpolator {
25 | protected var goingIn = true
26 | private set
27 |
28 | override fun tickInterpolation(targetInterpolation: Double, currentInterpolation: Double, tickDelta: Double): Double {
29 | if (targetInterpolation > currentInterpolation) {
30 | goingIn = true
31 | return min(currentInterpolation + getTimeIncrement(false, tickDelta, targetInterpolation, currentInterpolation), targetInterpolation)
32 | } else if (targetInterpolation < currentInterpolation) {
33 | goingIn = false
34 | return max(currentInterpolation - getTimeIncrement(true, tickDelta, targetInterpolation, currentInterpolation), targetInterpolation)
35 | }
36 | goingIn = true
37 | return targetInterpolation
38 | }
39 |
40 | override val isSmooth: Boolean = true
41 |
42 | abstract fun getTimeIncrement(
43 | zoomingOut: Boolean,
44 | tickDelta: Double,
45 | targetInterpolation: Double,
46 | currentInterpolation: Double
47 | ): Double
48 | }
49 |
50 | open class TimedInterpolator(val timeIn: () -> Double, val timeOut: () -> Double) : LinearInterpolator() {
51 | override fun getTimeIncrement(
52 | zoomingOut: Boolean,
53 | tickDelta: Double,
54 | targetInterpolation: Double,
55 | currentInterpolation: Double
56 | ): Double {
57 | return tickDelta / if (zoomingOut) timeOut() else timeIn()
58 | }
59 |
60 | override val isSmooth: Boolean
61 | get() = (goingIn && timeIn() > 0.0) || (!goingIn && timeOut() > 0.0)
62 | }
63 |
64 | class TransitionInterpolator(val transitionIn: () -> TransitionType, transitionOut: () -> TransitionType, timeIn: () -> Double, timeOut: () -> Double) : TimedInterpolator(timeIn, timeOut) {
65 | val transitionOut = { transitionOut().opposite() }
66 | private var activeTransition: TransitionType = transitionIn()
67 | private var inactiveTransition: TransitionType = transitionOut()
68 | private var prevTargetInterpolation: Double = 0.0
69 | private var justSwappedTransition = false
70 |
71 | override fun tickInterpolation(
72 | targetInterpolation: Double,
73 | currentInterpolation: Double,
74 | tickDelta: Double
75 | ): Double {
76 | var currentInterpolationMod = currentInterpolation
77 |
78 | if (targetInterpolation > currentInterpolation) {
79 | activeTransition = transitionIn()
80 | inactiveTransition = transitionOut()
81 |
82 | if (prevTargetInterpolation < targetInterpolation && activeTransition.hasInverse()) {
83 | justSwappedTransition = true
84 | currentInterpolationMod = activeTransition.inverse(inactiveTransition.apply(currentInterpolationMod))
85 | }
86 | } else if (targetInterpolation < currentInterpolation) {
87 | activeTransition = transitionOut()
88 | inactiveTransition = transitionIn()
89 |
90 | if (prevTargetInterpolation > targetInterpolation && activeTransition.hasInverse()) {
91 | justSwappedTransition = true
92 | currentInterpolationMod = activeTransition.inverse(inactiveTransition.apply(currentInterpolationMod))
93 | }
94 | }
95 |
96 | prevTargetInterpolation = targetInterpolation
97 |
98 | if (activeTransition == TransitionType.INSTANT)
99 | return targetInterpolation
100 |
101 | return super.tickInterpolation(targetInterpolation, currentInterpolationMod, tickDelta)
102 | }
103 |
104 | override fun modifyInterpolation(interpolation: Double): Double {
105 | return activeTransition.apply(interpolation)
106 | }
107 |
108 | override fun modifyPrevInterpolation(interpolation: Double): Double {
109 | if (justSwappedTransition) {
110 | justSwappedTransition = false
111 | return activeTransition.inverse(inactiveTransition.apply(interpolation))
112 | }
113 | return interpolation
114 | }
115 |
116 | override val isSmooth: Boolean
117 | get() = !justSwappedTransition && super.isSmooth && activeTransition != TransitionType.INSTANT
118 | }
119 |
120 | class SmoothInterpolator(val smoothness: () -> Double) : LinearInterpolator() {
121 | override fun getTimeIncrement(
122 | zoomingOut: Boolean,
123 | tickDelta: Double,
124 | targetInterpolation: Double,
125 | currentInterpolation: Double
126 | ): Double {
127 | val diff = if (!zoomingOut) targetInterpolation - currentInterpolation else currentInterpolation - targetInterpolation
128 | return diff * smoothness() / 0.05 * tickDelta
129 | }
130 |
131 | override fun tickInterpolation(
132 | targetInterpolation: Double,
133 | currentInterpolation: Double,
134 | tickDelta: Double
135 | ): Double {
136 | if (!isSmooth)
137 | return targetInterpolation
138 |
139 | return super.tickInterpolation(targetInterpolation, currentInterpolation, tickDelta)
140 | }
141 |
142 | override val isSmooth: Boolean
143 | get() = smoothness() != 1.0
144 | }
145 |
--------------------------------------------------------------------------------
/src/main/kotlin/dev/isxander/zoomify/zoom/ZoomHelper.kt:
--------------------------------------------------------------------------------
1 | package dev.isxander.zoomify.zoom
2 |
3 | import dev.isxander.zoomify.Zoomify
4 | import net.minecraft.util.Mth
5 | import kotlin.math.pow
6 |
7 | class ZoomHelper(
8 | private val initialInterpolator: Interpolator,
9 | private val scrollInterpolator: Interpolator,
10 |
11 | private val initialZoom: () -> Int,
12 | private val scrollZoomAmount: () -> Int,
13 | val maxScrollTiers: () -> Int,
14 | private val linearLikeSteps: () -> Boolean,
15 | ) {
16 | private var prevInitialInterpolation = 0.0
17 | private var initialInterpolation = 0.0
18 |
19 | private var zoomingLastTick = false
20 |
21 | private var prevScrollInterpolation = 0.0
22 | private var scrollInterpolation = 0.0
23 | private var lastScrollTier = 0
24 |
25 | private var resetting = false
26 | private var resetMultiplier = 0.0
27 |
28 | fun tick(zooming: Boolean, scrollTiers: Int, lastFrameDuration: Double = 0.05) {
29 | tickInitial(zooming, lastFrameDuration)
30 | tickScroll(scrollTiers, lastFrameDuration)
31 | }
32 |
33 | private fun tickInitial(zooming: Boolean, lastFrameDuration: Double) {
34 | if (zooming && !zoomingLastTick)
35 | resetting = false
36 |
37 | val targetZoom = if (zooming) 1.0 else 0.0
38 | prevInitialInterpolation = initialInterpolation
39 | initialInterpolation =
40 | initialInterpolator.tickInterpolation(targetZoom, initialInterpolation, lastFrameDuration)
41 | prevInitialInterpolation = initialInterpolator.modifyPrevInterpolation(prevInitialInterpolation)
42 | if (!initialInterpolator.isSmooth)
43 | prevInitialInterpolation = initialInterpolation
44 | zoomingLastTick = zooming
45 | }
46 |
47 | private fun tickScroll(scrollTiers: Int, lastFrameDuration: Double) {
48 | if (scrollTiers > lastScrollTier)
49 | resetting = false
50 |
51 | var targetZoom =
52 | if (maxScrollTiers() > 0)
53 | scrollTiers.toDouble() / Zoomify.maxScrollTiers
54 | else 0.0
55 | if (linearLikeSteps()) {
56 | val curvature = 0.3
57 | val exp = 1 / (1 - curvature)
58 | targetZoom = 2 * (targetZoom.pow(exp) / (targetZoom.pow(exp) + (2 - targetZoom).pow(exp)))
59 | }
60 |
61 | prevScrollInterpolation = scrollInterpolation
62 | scrollInterpolation = scrollInterpolator.tickInterpolation(targetZoom, scrollInterpolation, lastFrameDuration)
63 | prevScrollInterpolation = scrollInterpolator.modifyPrevInterpolation(prevScrollInterpolation)
64 | if (!initialInterpolator.isSmooth)
65 | prevInitialInterpolation = initialInterpolation
66 | lastScrollTier = scrollTiers
67 | }
68 |
69 | fun getZoomDivisor(tickDelta: Float = 1f): Double {
70 | val initialMultiplier = getInitialZoomMultiplier(tickDelta)
71 | val scrollDivisor = getScrollZoomDivisor(tickDelta)
72 |
73 | return (1 / initialMultiplier + scrollDivisor).also {
74 | if (initialInterpolation == 0.0 && scrollInterpolation == 0.0) resetting = false
75 | if (!resetting) resetMultiplier = 1 / it
76 | }
77 | }
78 |
79 | private fun getInitialZoomMultiplier(tickDelta: Float): Double {
80 | return Mth.lerp(
81 | if (initialInterpolator.isSmooth) initialInterpolator.modifyInterpolation(
82 | Mth.lerp(
83 | tickDelta.toDouble(),
84 | prevInitialInterpolation,
85 | initialInterpolation
86 | )
87 | ) else initialInterpolation,
88 | 1.0,
89 | if (!resetting) 1 / initialZoom().toDouble() else resetMultiplier
90 | )
91 | }
92 |
93 | private fun getScrollZoomDivisor(tickDelta: Float): Double {
94 | return Mth.lerp(
95 | if (scrollInterpolator.isSmooth) scrollInterpolator.modifyInterpolation(
96 | Mth.lerp(
97 | tickDelta.toDouble(),
98 | prevScrollInterpolation,
99 | scrollInterpolation
100 | )
101 | )
102 | else scrollInterpolation,
103 | 0.0,
104 | Zoomify.maxScrollTiers * (scrollZoomAmount() * 3.0)
105 | ).let { if (resetting) 0.0 else it }
106 | }
107 |
108 | fun reset() {
109 | if (!resetting && scrollInterpolation > 0.0) {
110 | resetting = true
111 | scrollInterpolation = 0.0
112 | prevScrollInterpolation = 0.0
113 | }
114 | }
115 |
116 | fun setToZero(initial: Boolean = true, scroll: Boolean = true) {
117 | if (initial) {
118 | initialInterpolation = 0.0
119 | prevInitialInterpolation = 0.0
120 | zoomingLastTick = false
121 | }
122 | if (scroll) {
123 | scrollInterpolation = 0.0
124 | prevScrollInterpolation = 0.0
125 | lastScrollTier = 0
126 | }
127 | resetting = false
128 | }
129 |
130 | fun skipInitial() {
131 | initialInterpolation = 1.0
132 | prevInitialInterpolation = 1.0
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/lang/en_gb.json:
--------------------------------------------------------------------------------
1 | {
2 | "zoomify.key.zoom": "Zoom",
3 | "zoomify.key.zoom.in": "Scroll Zoom In",
4 | "zoomify.key.zoom.out": "Scroll Zoom Out",
5 | "zoomify.key.category": "Zoomify",
6 |
7 |
8 | "zoomify.gui.title": "Zoomify",
9 |
10 | "yacl3.config.zoomify.category.behaviour": "Behaviour",
11 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom": "Initial Zoom",
12 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom.description.1": "The zoom level when you first press the keybind.",
13 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime": "Zoom In Time",
14 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime.description.1": "How many seconds to complete zooming in.",
15 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime": "Zoom Out Time",
16 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime.description.1": "How many seconds to complete zooming out.",
17 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition": "Zoom In Transition",
18 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition.description.1": "The transition type used when zooming in.",
19 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition": "Zoom Out Transition",
20 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition.description.1": "The transition type used when zooming out.",
21 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov": "Affect Hand FOV",
22 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov.description.1": "When zooming, keep the FOV of the hand normal while the world view zooms in.",
23 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps": "Remember Zoom Steps",
24 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps.description.1": "Keep scroll zoom amount between zooming in and out.",
25 |
26 | "yacl3.config.zoomify.category.behaviour.group.scrolling": "Scrolling",
27 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom": "Enable Scroll Zoom",
28 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom.description.1": "Allow you to zoom in and out more with scroll wheel.",
29 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount": "Scroll Zoom Amount",
30 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount.description.1": "The additional divisor of the FOV per scroll step.",
31 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness": "Scroll Zoom Smoothness",
32 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness.description.1": "How smooth/how long it takes to scroll-zoom.",
33 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom": "Smooth Transition",
34 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom.description.1": "Makes scrolling in and out smooth.",
35 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps": "Linear-like Steps",
36 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps.description.1": "Applies a curve to the increments to make them feel more linear.",
37 |
38 | "yacl3.config.zoomify.category.controls": "Controls",
39 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour": "Zoom Key Behaviour",
40 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour.description.1": "The behaviour of the zoom key.",
41 | "yacl3.config.zoomify.category.controls.root.option._keybindScrolling": "Keybind Scrolling",
42 | "yacl3.config.zoomify.category.controls.root.option._keybindScrolling.description.1": "Use Minecraft keybinds to control scroll zoom instead of the scroll wheel.",
43 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity": "Relative Sensitivity",
44 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity.description.1": "Controls the sensitivity based on the zoom level.",
45 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing": "Relative View Bobbing",
46 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing.description.1": "Make view-bobbing less jarring when zoomed in.",
47 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera": "Cinematic Camera",
48 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera.description.1": "How much the camera glides once moved.",
49 |
50 | "yacl3.config.zoomify.category.behaviour.group.spyglass": "Spyglass",
51 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour": "Zoom Behaviour",
52 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour.description.1": "How Zoomify interacts with spyglass zoom.",
53 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility": "Overlay Visibility",
54 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility.description.1": "When to show the spyglass overlay.",
55 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour": "Sound Behaviour",
56 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour.description.1": "When to play the zoom in and out sounds from the spyglass.",
57 |
58 | "yacl3.config.zoomify.category.secondary": "Secondary Zoom",
59 | "yacl3.config.zoomify.category.secondary.root.label.infoLabel": "Completely separate from all other settings of Zoomify. Secondary zoom is toggle-only with a separate keybinding in controls.",
60 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomAmount": "Zoom Amount",
61 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomAmount.description.1": "How many times to divide the current FOV once transition completes.",
62 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomInTime": "Zoom In Time",
63 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomInTime.description.1": "How many seconds to complete zooming in.",
64 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomOutTime": "Zoom Out Time",
65 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomOutTime.description.1": "How many seconds to complete zooming out.",
66 | "yacl3.config.zoomify.category.secondary.root.option.secondaryHideHUDOnZoom": "Hide HUD On Zoom",
67 | "yacl3.config.zoomify.category.secondary.root.option.secondaryHideHUDOnZoom.description.1": "Stops rendering the HUD whilst zooming in, much like pressing F1.",
68 |
69 |
70 | "yacl3.config.zoomify.category.misc": "Misc",
71 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting": "Unbind Conflicting Keybind",
72 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.button": "Unbind",
73 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.description.1": "Removes the keybind that has the same key as Zoomify zoom key.",
74 | "yacl3.config.zoomify.category.misc.group.presets": "Presets",
75 | "zoomify.gui.preset.default": "Default",
76 | "zoomify.gui.preset.optifine": "OptiFine",
77 | "zoomify.gui.preset.ok_zoomer": "OK Zoomer",
78 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.button": "Apply Preset",
79 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.description": "Makes Zoomify behave like %s.",
80 | "yacl3.config.zoomify.category.misc.group.presets.label.applyWarning": "Pressing the button will immediately apply changes!",
81 |
82 | "zoomify.gui.formatter.instant": "Instant",
83 | "zoomify.gui.formatter.seconds": "%s secs",
84 |
85 | "zoomify.transition.instant": "Instant",
86 | "zoomify.transition.linear": "Linear",
87 | "zoomify.transition.ease_in_sine": "Ease In Sine",
88 | "zoomify.transition.ease_out_sine": "Ease Out Sine",
89 | "zoomify.transition.ease_in_out_sine": "Ease In Out Sine",
90 | "zoomify.transition.ease_in_quad": "Ease In Quad",
91 | "zoomify.transition.ease_out_quad": "Ease Out Quad",
92 | "zoomify.transition.ease_in_out_quad": "Ease In Out Quad",
93 | "zoomify.transition.ease_in_cubic": "Ease In Cubic",
94 | "zoomify.transition.ease_out_cubic": "Ease Out Cubic",
95 | "zoomify.transition.ease_in_out_cubic": "Ease In Out Cubic",
96 | "zoomify.transition.ease_in_exp": "Ease In Exponential",
97 | "zoomify.transition.ease_out_exp": "Ease Out Exponential",
98 | "zoomify.transition.ease_in_out_exp": "Ease In Out Exponential",
99 |
100 |
101 | "zoomify.zoom_key_behaviour.hold": "Hold",
102 | "zoomify.zoom_key_behaviour.toggle": "Toggle",
103 |
104 |
105 | "zoomify.spyglass_behaviour.combine": "Combine",
106 | "zoomify.spyglass_behaviour.override": "Override",
107 | "zoomify.spyglass_behaviour.only_zoom_while_holding": "Allow While Holding",
108 | "zoomify.spyglass_behaviour.only_zoom_while_carrying": "Allow While Carrying",
109 |
110 | "zoomify.overlay_visibility.never": "Never",
111 | "zoomify.overlay_visibility.holding": "Holding",
112 | "zoomify.overlay_visibility.carrying": "Carrying",
113 | "zoomify.overlay_visibility.always": "Always",
114 |
115 | "zoomify.sound_behaviour.never": "Never",
116 | "zoomify.sound_behaviour.always": "Always",
117 | "zoomify.sound_behaviour.only_spyglass": "Only Holding Spyglass",
118 | "zoomify.sound_behaviour.with_overlay": "Match Overlay",
119 |
120 | "zoomify.toast.conflictingKeybind.title": "Zoomify won't work!",
121 | "zoomify.toast.conflictingKeybind.description": "There is a conflicting keybind preventing the usage of the zoom key. You can unbind it in the %s category of Zoomify settings.",
122 | "zoomify.toast.unbindConflicting.name": "Unbound %s",
123 | "zoomify.toast.unbindConflicting.description": "Zoomify unbound key because it was conflicting with the zoom key.",
124 |
125 | "zoomify.gui.donate": "Support me!"
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/lang/es_es.json:
--------------------------------------------------------------------------------
1 | {
2 | "zoomify.key.zoom": "Zoom",
3 | "zoomify.key.gui": "Abrir interfaz",
4 | "zoomify.key.category": "Zoomify",
5 |
6 |
7 | "yacl3.config.zoomify.title": "Zoomify",
8 |
9 | "yacl3.config.zoomify.category.behaviour": "Comportamiento",
10 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom": "Zoom inicial",
11 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom.description.1": "El nivel de acercamiento cuando recién presionas la tecla de zoom.",
12 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime": "Tiempo de entrada",
13 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime.description.1": "Cuántos segundos para que la animación inicial se complete.",
14 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime": "Tiempo de salida",
15 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime.description.1": "Cuántos segundos para que la animación final se complete.",
16 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition": "Transición de acercamiento",
17 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition.description.1": "El tipo de transición usada al acercarse.",
18 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition": "Transición de alejamiento",
19 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition.description.1": "El tipo de transición usada al alejarse.",
20 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov": "Afectar campo de visión de la mano",
21 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov.description.1": "Cuando se haga zoom, que la mano no se acerque junto con el mundo.",
22 |
23 | "yacl3.config.zoomify.category.behaviour.group.scrolling": "Rueda de scroll",
24 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom": "Habilitar zoom con scroll",
25 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom.description.1": "Te deja acercarte y alejarte más con la rueda de scroll.",
26 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount": "Nivel de zoom por cada scroll",
27 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount.description.1": "El divisor adicional del campo de visión por cada paso de la rueda de scroll.",
28 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness": "Fluidez del zoom con scroll",
29 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness.description.1": "Qué tan fluido y qué tanto tarda el zoom por scroll.",
30 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom": "Transición fluida",
31 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom.description.1": "Hace que el acercamiento y alejamiento por scroll sea fluido.",
32 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps": "Incrementos pseudo-lineares",
33 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps.description.1": "Aplica una curva a los incrementos para hacerlos sentir mas lineares.",
34 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps": "Recordar nivel de zoom",
35 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps.description.1": "Mantener el nivel de acercamiento entre zooms.",
36 |
37 | "yacl3.config.zoomify.category.behaviour.group.spyglass": "Catalejo",
38 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour": "Comportamiento del zoom",
39 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour.description.1": "Cómo Zoomify interactúa con el zoom del catalejo.",
40 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility": "Visibilidad del overlay",
41 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility.description.1": "Cuándo mostrar el overlay del catalejo.",
42 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour": "Comportamiento de los FX",
43 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour.description.1": "Cuándo reproducir los sonidos de acercamiento y alejamiento del catalejo.",
44 |
45 | "yacl3.config.zoomify.category.controls": "Controles",
46 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour": "Comportamiento de la tecla zoom",
47 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour.description.1": "El comportamiento de la tecla zoom.",
48 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity": "Sensibilidad relativa",
49 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity.description.1": "Controla la sensibilidad de la cámara basada en el nivel de zoom.",
50 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing": "Balanceo relativo de la cámara",
51 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing.description.1": "Hace que el balanceo de la cámara sea menos incómodo cuando esta está acercada.",
52 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera": "Cámara cinemática",
53 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera.description.1": "Hacer que la cámara se deslice suavemente al hacer zoom.",
54 |
55 | "yacl3.config.zoomify.category.misc": "Misceláneo",
56 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting": "Desvincular tecla en conflicto",
57 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.button": "Desvincular",
58 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.description.1": "Desvincula la(s) tecla(s) que está(n) asignada(s) igual que la tecla de zoom de Zoomify.",
59 | "yacl3.config.zoomify.category.misc.group.presets": "Preajustes",
60 | "zoomify.gui.preset.default": "Default",
61 | "zoomify.gui.preset.optifine": "OptiFine",
62 | "zoomify.gui.preset.ok_zoomer": "OK Zoomer",
63 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.button": "Aplicar preajuste",
64 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.description": "Hace que Zoomify actúe como %s.",
65 | "yacl3.config.zoomify.category.misc.group.presets.label.applyWarning": "Presionar este botón aplicará los cambios de inmediato!",
66 |
67 |
68 | "zoomify.transition.instant": "Instantánea",
69 | "zoomify.transition.linear": "Linear",
70 | "zoomify.transition.ease_in_sine": "Ease In (Seno)",
71 | "zoomify.transition.ease_out_sine": "Ease Out (Seno)",
72 | "zoomify.transition.ease_in_out_sine": "Ease In Out (Seno)",
73 | "zoomify.transition.ease_in_quad": "Ease In (Quad)",
74 | "zoomify.transition.ease_out_quad": "Ease Out (Quad)",
75 | "zoomify.transition.ease_in_out_quad": "Ease In Out (Quad)",
76 | "zoomify.transition.ease_in_cubic": "Ease In (Cúbico)",
77 | "zoomify.transition.ease_out_cubic": "Ease Out (Cúbico)",
78 | "zoomify.transition.ease_in_out_cubic": "Ease In Out (Cúbico)",
79 | "zoomify.transition.ease_in_exp": "Ease In (Exponencial)",
80 | "zoomify.transition.ease_out_exp": "Ease Out (Exponencial)",
81 | "zoomify.transition.ease_in_out_exp": "Ease In Out (Exponencial)",
82 |
83 |
84 | "zoomify.zoom_key_behaviour.hold": "Mantener",
85 | "zoomify.zoom_key_behaviour.toggle": "Alternar",
86 |
87 |
88 | "zoomify.spyglass_behaviour.combine": "Combinar",
89 | "zoomify.spyglass_behaviour.override": "Sobreescribir",
90 | "zoomify.spyglass_behaviour.only_zoom_while_holding": "Estando en una mano",
91 | "zoomify.spyglass_behaviour.only_zoom_while_carrying": "Estando en el inv.",
92 |
93 | "zoomify.overlay_visibility.never": "Nunca",
94 | "zoomify.overlay_visibility.holding": "Estando en una mano",
95 | "zoomify.overlay_visibility.carrying": "Estando en el inv.",
96 | "zoomify.overlay_visibility.always": "Siempre",
97 |
98 | "zoomify.sound_behaviour.never": "Nunca",
99 | "zoomify.sound_behaviour.always": "Siempre",
100 | "zoomify.sound_behaviour.only_spyglass": "Con el catalejo en mano",
101 | "zoomify.sound_behaviour.with_overlay": "Coincidir con el overlay",
102 |
103 | "zoomify.toast.conflictingKeybind.title": "Zoomify no funcionará!",
104 | "zoomify.toast.conflictingKeybind.description": "Hay una tecla en conflicto previniendo el uso de la tecla de zoom. Puedes desvincularla en la categoría de %s en los ajustes de Zoomify.",
105 | "zoomify.toast.unbindConflicting.name": "La tecla en conflicto ha sido desvinculada",
106 | "zoomify.toast.unbindConflicting.description": "Zoomify desvinculó la tecla llamada '%s' porque estaba en conflicto con la tecla de zoom.",
107 |
108 | "zoomify.gui.donate": "Apóyame!"
109 | }
110 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/lang/et_ee.json:
--------------------------------------------------------------------------------
1 | {
2 | "zoomify.key.zoom": "Suum",
3 | "zoomify.key.gui": "Ava liides",
4 | "zoomify.key.category": "Zoomify",
5 |
6 |
7 | "zoomify.gui.title": "Zoomify",
8 |
9 | "yacl3.config.zoomify.category.behaviour": "Käitumine",
10 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom": "Esialgne suum",
11 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom.description.1": "Suumitase esialgsel klahvivajutusel.",
12 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime": "Sissesuumimise aeg",
13 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime.description.1": "Mitu sekundit kulub sissesuumimiseks.",
14 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime": "Väljasuumimise aeg",
15 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime.description.1": "Mitu sekundit kulub väljasuumimiseks.",
16 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition": "Sisse suumimise üleminek",
17 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition.description.1": "Sisse suumimisel kasutatav üleminekutüüp.",
18 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition": "Välja suumimise üleminek",
19 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition.description.1": "Välja suumimisel kasutatav üleminekutüüp.",
20 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov": "Mõjuta käe vaatevälja",
21 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov.description.1": "Hoia suumimisel käe vaateväli normaalsena, kuni maailmavaade sisse suumib.",
22 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps": "Jäta suumitasemed meelde",
23 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps.description.1": "Jäta suumitasemete arv enne välja suumimist meelde, et seda arvu järgmisel suumimisel kasutada.",
24 |
25 | "yacl3.config.zoomify.category.behaviour.group.scrolling": "Kerimine",
26 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom": "Luba kerimissuum",
27 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom.description.1": "Võimaldab kerimisrattaga rohkem sisse ja välja suumida.",
28 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount": "Kerimissuumi kogus",
29 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount.description.1": "Täiendav vaatevälja jagaja kerimisammu kohta.",
30 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness": "Kerimissuumi sujuvus",
31 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness.description.1": "Kui sujuv/kui kaua kulub aega kerimissuumiks.",
32 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom": "Sujuv üleminek",
33 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom.description.1": "Muudab sisse-välja kerimise sujuvaks.",
34 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps": "Lineaarse-sarnased sammud",
35 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps.description.1": "Lisab juurdekasvudele kõveruse, et need tunduksid lineaarsemad.",
36 |
37 | "yacl3.config.zoomify.category.controls": "Juhtnupud",
38 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour": "Suumiklahvi käitumine",
39 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour.description.1": "Suumiklahvi käitumise valik.",
40 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity": "Suhteline tundlikkus",
41 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity.description.1": "Juhib suumitasemest sõltuvat tundlikkuse üleminekut.",
42 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing": "Suhteline vaate hüplemine",
43 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing.description.1": "Muudab vaate hüplemise sissesuumimisel vähem \"teravaks\".",
44 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera": "Kinemaatiline kaamera",
45 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera.description.1": "Muuda kaamera suumimise ajal sujuvalt liikuma.",
46 |
47 | "yacl3.config.zoomify.category.behaviour.group.spyglass": "Pikksilm",
48 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour": "Suumi käitumine",
49 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour.description.1": "Kuidas Zoomify käitub pikksilma suumiga.",
50 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility": "Ülekatte nähtavus",
51 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility.description.1": "Millal kuvada pikksilma ülekatet.",
52 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour": "Helikäitumine",
53 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour.description.1": "Millal esitada pikksilma sisse-välja suumimise helisid.",
54 |
55 | "yacl3.config.zoomify.category.misc": "Varia",
56 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting": "Tühjenda konfliktse kiirklahvi määrang",
57 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.button": "Tühjenda",
58 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.description.1": "Eemaldab kiirklahvi määrangu, millel on Zoomify suumiklahviga sama klahv.",
59 | "yacl3.config.zoomify.category.misc.group.presets": "Eelseadistused",
60 | "zoomify.gui.preset.default": "Vaikimisi",
61 |
62 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.button": "Rakenda eelseadistus",
63 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.description": "Määrab Zoomify käituma nagu %s.",
64 | "yacl3.config.zoomify.category.misc.group.presets.label.applyWarning": "Nupu vajutamine rakendab muudatused koheselt!",
65 |
66 |
67 | "zoomify.transition.instant": "Kohene",
68 | "zoomify.transition.linear": "Lineaarne",
69 | "zoomify.transition.ease_in_sine": "Sujuvalt sisse siinus",
70 | "zoomify.transition.ease_out_sine": "Sujuvalt välja siinus",
71 | "zoomify.transition.ease_in_out_sine": "Sujuvalt sisse-välja siinus",
72 | "zoomify.transition.ease_in_quad": "Sujuvalt sisse nelinurk",
73 | "zoomify.transition.ease_out_quad": "Sujuvalt välja nelinurk",
74 | "zoomify.transition.ease_in_out_quad": "Sujuvalt sisse-välja nelinurk",
75 | "zoomify.transition.ease_in_cubic": "Sujuvalt sisse kuubik",
76 | "zoomify.transition.ease_out_cubic": "Sujuvalt välja kuubik",
77 | "zoomify.transition.ease_in_out_cubic": "Sujuvalt sisse-välja kuubik",
78 | "zoomify.transition.ease_in_exp": "Sujuvalt eksponentsiaalselt",
79 | "zoomify.transition.ease_out_exp": "Sujuvalt eksponentsiaalne",
80 | "zoomify.transition.ease_in_out_exp": "Sujuvalt sisse-välja eksponentsiaalselt",
81 |
82 |
83 | "zoomify.zoom_key_behaviour.hold": "Hoia",
84 | "zoomify.zoom_key_behaviour.toggle": "Lülita",
85 |
86 | "zoomify.spyglass_behaviour.combine": "Kombineeri",
87 | "zoomify.spyglass_behaviour.override": "Kirjuta üle",
88 | "zoomify.spyglass_behaviour.only_zoom_while_holding": "Luba käes hoides",
89 | "zoomify.spyglass_behaviour.only_zoom_while_carrying": "Luba kaasas kandes",
90 |
91 | "zoomify.overlay_visibility.never": "Mitte kunagi",
92 | "zoomify.overlay_visibility.holding": "Hoides",
93 | "zoomify.overlay_visibility.carrying": "Kaasas kandes",
94 | "zoomify.overlay_visibility.always": "Alati",
95 |
96 | "zoomify.sound_behaviour.never": "Mitte kunagi",
97 | "zoomify.sound_behaviour.always": "Alati",
98 | "zoomify.sound_behaviour.only_spyglass": "Ainult pikksilma hoidmisel",
99 | "zoomify.sound_behaviour.with_overlay": "Sama, mis ülekatte valik",
100 |
101 | "zoomify.toast.conflictingKeybind.title": "Zoomify ei tööta!",
102 | "zoomify.toast.conflictingKeybind.description": "Konfliktne kiirklahvi määrang ei võimalda suumiklahvi kasutada. Sa saad selle tühjendada Zoomify seadete kategoorias %s.",
103 | "zoomify.toast.unbindConflicting.name": "Konfliktne kiirklahv tühjendatud",
104 | "zoomify.toast.unbindConflicting.description": "Zoomify tühjendas klahvi \"%s\" määrangu, kuna see oli suumiklahviga konfliktis."
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/lang/ja_jp.json:
--------------------------------------------------------------------------------
1 | {
2 | "zoomify.key.zoom":"ズーム",
3 | "zoomify.key.zoom.secondary":"第二ズーム",
4 | "zoomify.key.zoom.in":"スクロールズームイン",
5 | "zoomify.key.zoom.out":"スクロールズームアウト",
6 | "zoomify.key.category":"Zoomify",
7 |
8 | "zoomify.gui.title":"Zoomify",
9 |
10 | "yacl3.config.zoomify.category.behaviour":"挙動",
11 | "yacl3.config.zoomify.category.controls":"操作",
12 | "yacl3.config.zoomify.category.secondary":"第二ズーム",
13 | "yacl3.config.zoomify.category.misc":"その他",
14 |
15 | "yacl3.config.zoomify.category.behaviour.group.basic":"基本",
16 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom":"初期ズーム倍率",
17 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom.description.1":"最初にキーバインドを押したときのズーム倍率.",
18 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime":"ズームイン時間",
19 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime.description.1":"ズームインが完了するまでの秒数.",
20 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime":"ズームアウト時間",
21 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime.description.1":"ズームアウトが完了するまでの秒数.",
22 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition":"ズームインの倍率推移",
23 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition.description.1":"ズームイン時に使用する倍率推移パターン.",
24 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition":"ズームアウトの倍率推移",
25 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition.description.1":"ズームアウト時に使用する倍率推移パターン.",
26 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov":"手の見え方への影響",
27 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov.description.1":"無効にした場合,ズーム中も手の見え方を通常のままにする.",
28 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps":"倍率を保持",
29 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps.description.1":"スクロールズームの倍率を保持する.",
30 |
31 | "yacl3.config.zoomify.category.behaviour.group.scrolling":"スクロール",
32 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom":"スクロールズーム",
33 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom.description.1":"スクロールホイールでズーム倍率を変えられるようにする.",
34 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount":"スクロールズーム量",
35 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount.description.1":"スクロール毎の追加視野除数(乗数).",
36 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness":"スクロールズームの滑らかさ",
37 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness.description.1":"スクロールズームの滑らかさ/かかる時間.",
38 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps":"直線的な倍率変更",
39 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps.description.1":"増分に曲線を適用することで見かけの変化をより直線的にする.",
40 |
41 | "yacl3.config.zoomify.category.behaviour.group.spyglass":"望遠鏡",
42 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour":"ズームの挙動",
43 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour.description.1":"Zoomifyと望遠鏡のズームがどのように相互作用するか.",
44 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility":"オーバーレイ表示",
45 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility.description.1":"望遠鏡のオーバーレイを表示する状況.",
46 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour":"音の再生",
47 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour.description.1":"望遠鏡の音を再生する状況.",
48 |
49 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour":"ズームキーの挙動",
50 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour.description.1":"ズームキーの挙動.",
51 | "yacl3.config.zoomify.category.controls.root.option._keybindScrolling":"スクロールのキー割り当て",
52 | "yacl3.config.zoomify.category.controls.root.option._keybindScrolling.description.1":"Minecraftのキー割り当てを使用してスクロールホイール以外でスクロールズームを操作する.",
53 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity":"相対的な感度",
54 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity.description.1":"ズーム倍率に応じてマウス感度を調節する.",
55 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing":"相対的な画面の揺れ",
56 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing.description.1":"ズーム中に画面の揺れを小さくする.",
57 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera":"映画的なカメラ",
58 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera.description.1":"カメラの動きをどの程度滑らせるか.",
59 |
60 | "yacl3.config.zoomify.category.secondary.root.label.infoLabel":"Zoomifyの他の設定とは完全に独立した設定です.\n第二ズームは切り替えのみのオプションであり,操作設定に個別のキー割り当てがあります.",
61 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomAmount":"ズーム量",
62 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomAmount.description.1":"ズーム完了時に現在の視野を何分割するか.",
63 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomInTime":"ズームイン時間",
64 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomInTime.description.1":"ズームイン完了までにかかる時間.",
65 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomOutTime":"ズームアウト時間",
66 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomOutTime.description.1":"ズームアウト完了までにかかる時間.",
67 | "yacl3.config.zoomify.category.secondary.root.option.secondaryHideHUDOnZoom":"ズーム中にHUDを隠す",
68 | "yacl3.config.zoomify.category.secondary.root.option.secondaryHideHUDOnZoom.description.1":"ズーム中はF1を押したときのようにHUDを非表示にする.",
69 |
70 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting":"競合しているキー割り当てを解除する",
71 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.button":"解除",
72 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.description.1":"Zoomifyのズームキーと同じキーを使用しているキー割り当てを削除する.",
73 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations":"移行を確認",
74 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations.button":"確認",
75 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations.description.1":"利用可能な自動移行を確認する.",
76 | "yacl3.config.zoomify.category.misc.group.presets":"プリセット",
77 | "zoomify.gui.preset.default":"デフォルト",
78 | "zoomify.gui.preset.optifine":"OptiFine",
79 | "zoomify.gui.preset.ok_zoomer":"OK Zoomer",
80 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.button":"プリセットを適用",
81 | "zoomify.gui.preset.toast.title":"プリセット適用",
82 | "zoomify.gui.preset.toast.description":"Zoomifyに%sのプリセットを適用しました.",
83 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.description":"Zoomifyで%sの挙動を再現する.",
84 | "yacl3.config.zoomify.category.misc.group.presets.label.applyWarning":"プリセット適用は即座に行われ,保存していない変更はすべて取り消されます.",
85 | "zoomify.gui.formatter.instant":"即時",
86 | "zoomify.gui.formatter.seconds":"%s 秒",
87 |
88 | "zoomify.transition.instant":"即時",
89 | "zoomify.transition.linear":"線形",
90 | "zoomify.transition.ease_in_sine":"イーズイン(正弦)",
91 | "zoomify.transition.ease_out_sine":"イーズアウト(正弦)",
92 | "zoomify.transition.ease_in_out_sine":"イーズインアウト(正弦)",
93 | "zoomify.transition.ease_in_quad":"イーズイン(二乗)",
94 | "zoomify.transition.ease_out_quad":"イーズアウト(二乗)",
95 | "zoomify.transition.ease_in_out_quad":"イーズインアウト(二乗)",
96 | "zoomify.transition.ease_in_cubic":"イーズイン(三乗)",
97 | "zoomify.transition.ease_out_cubic":"イーズアウト(三乗)",
98 | "zoomify.transition.ease_in_out_cubic":"イーズインアウト(三乗)",
99 | "zoomify.transition.ease_in_exp":"イーズイン(指数)",
100 | "zoomify.transition.ease_out_exp":"イーズアウト(指数)",
101 | "zoomify.transition.ease_in_out_exp":"イーズインアウト(指数)",
102 |
103 | "zoomify.spyglass_behaviour.combine":"組み合わせ",
104 | "zoomify.spyglass_behaviour.override":"上書き",
105 | "zoomify.spyglass_behaviour.only_zoom_while_holding":"手に持っているときのみ許可",
106 | "zoomify.spyglass_behaviour.only_zoom_while_carrying":"所持しているときのみ許可",
107 |
108 | "zoomify.overlay_visibility.never":"しない",
109 | "zoomify.overlay_visibility.holding":"手に持っているとき",
110 | "zoomify.overlay_visibility.carrying":"所持しているとき",
111 | "zoomify.overlay_visibility.always":"常に",
112 |
113 | "zoomify.sound_behaviour.never":"しない",
114 | "zoomify.sound_behaviour.always":"常に",
115 | "zoomify.sound_behaviour.only_spyglass":"望遠鏡を手に持っているとき",
116 | "zoomify.sound_behaviour.with_overlay":"オーバーレイ表示に合わせる",
117 |
118 | "zoomify.zoom_key_behaviour.hold":"固定",
119 | "zoomify.zoom_key_behaviour.toggle":"切り替え",
120 |
121 | "zoomify.toast.conflictingKeybind.title":"Zoomifyは機能しません!",
122 | "zoomify.toast.conflictingKeybind.description":"ズームキーと競合しているキー割り当てがあります.Zoomifyの設定の%sカテゴリで割り当てを解除できます.",
123 | "zoomify.toast.unbindConflicting.name":"競合キー割り当て解除",
124 | "zoomify.toast.unbindConflicting.description":"ズームキーと競合していたキー割り当て「%s」を解除しました.",
125 |
126 | "zoomify.migrate.no_migrations":"利用可能な移行はありません.",
127 | "zoomify.migrate.result.title":"移行完了",
128 | "zoomify.migrate.restart":"再起動が必要です",
129 | "zoomify.migrate.result.restart_game":"再起動",
130 | "zoomify.migrate.available.title":"%sの自動移行が利用可能",
131 | "zoomify.migrate.available.message":"%sの設定を自動的にZoomifyに移行しますか?",
132 |
133 | "zoomify.migrate.okz":"OK Zoomer",
134 | "zoomify.migrate.okz.persistent":"persistent zoom modeには対応していません.",
135 | "zoomify.migrate.okz.vignette":"vignette overlayには対応していません.",
136 | "zoomify.migrate.okz.minZoomDiv":"minimum zoom divisorの設定には対応していません.",
137 | "zoomify.migrate.okz.stepAmt":"scroll step amountの設定には対応していません.",
138 | "zoomify.migrate.okz.linearNotSupported":"linear timingsは自動的に計算されません.",
139 |
140 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom":"滑らかな倍率変更",
141 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom.description.1":"スクロールズームを滑らかにする."
142 | }
143 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/lang/pt_br.json:
--------------------------------------------------------------------------------
1 | {
2 | "zoomify.key.zoom": "Zoom",
3 | "zoomify.key.gui": "Abrir GUI",
4 | "zoomify.key.category": "Zoomify",
5 |
6 |
7 | "zoomify.gui.title": "Zoomify",
8 |
9 | "yacl3.config.zoomify.category.behaviour": "Comportamento",
10 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom": "Zoom Inicial",
11 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom.description.1": "O nível de zoom quando você aperta a tecla primeiro.",
12 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime": "Tempo para aumentar o Zoom",
13 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime.description.1": "Quantos segundos leva para aumentar o Zoom.",
14 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime": "Tempo para diminuir o Zoom",
15 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime.description.1": "Quantos segundos leva para diminuir o Zoom.",
16 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition": "Transição de entrada do zoom",
17 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition.description.1": "O tipo de transição usado na entrada do zoom.",
18 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition": "Transição de saída do zoom",
19 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition.description.1": "O tipo de transição usado na saída do zoom.",
20 |
21 | "yacl3.config.zoomify.category.behaviour.group.scrolling": "Rolagem",
22 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom": "Habilitar Zoom de Rolagem",
23 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom.description.1": "Permitir você dar zoom com a roda do mouse.",
24 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount": "Quantidade de Zoom de Rolagem",
25 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount.description.1": "O divisor adicional do FOV por etapa de rolagem.",
26 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness": "Suavidade do Zoom de Rolagem",
27 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness.description.1": "Quão suave/quanto tempo leva para usar o Zoom de Rolagem.",
28 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom": "Transição suave",
29 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom.description.1": "Faz o zoom aumentar e diminuir suavemente.",
30 |
31 | "yacl3.config.zoomify.category.controls": "Controles",
32 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour": "Comportamento da telca de Zoom",
33 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour.description.1": "O comportamento da tecla de zoom.",
34 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity": "Sensibilidade relativa",
35 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity.description.1": "Controla o gradiente da sensibilidade baseado no nível de zoom.",
36 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing": "Balançado Relativo da Visão",
37 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing.description.1": "Faz o balançar da tela menos duro com o Zoom ativo.",
38 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera": "Câmera cinemática",
39 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera.description.1": "Faz a câmera se mover suavemente no zoom.",
40 |
41 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov": "Afetar o Campo de Visão da Mão",
42 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov.description.1": "Com zoom, mantém o campo de visão da mão normal, enquanto o mundo aumenta.",
43 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps": "Lembrar Etapas de Zoom",
44 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps.description.1": "Mantém a quantia de zoom entre entrada e saída de zoom.",
45 |
46 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps": "Etapas Quase Lineares",
47 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps.description.1": "Aplica uma curva aos incrementos para eles parecerem lineares.",
48 |
49 | "yacl3.config.zoomify.category.misc.group.presets": "Padronizações",
50 | "zoomify.gui.preset.default": "Padrão",
51 | "zoomify.gui.preset.optifine": "OptiFine",
52 | "zoomify.gui.preset.ok_zoomer": "OK Zoomer",
53 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.button": "Aplicar Padronização",
54 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.description": "Faz o Zoomify se comportar como %s.",
55 | "yacl3.config.zoomify.category.misc.group.presets.label.applyWarning": "Pressionar o botão vai aplicar as mudanças instantaneamente!",
56 |
57 | "zoomify.transition.instant": "Instantâneo",
58 | "zoomify.transition.linear": "Linear",
59 | "zoomify.transition.ease_in_sine": "Entrada Suave Seno",
60 | "zoomify.transition.ease_out_sine": "Saída Suave Seno",
61 | "zoomify.transition.ease_in_out_sine": "Entrada Saída Suave Seno",
62 | "zoomify.transition.ease_in_quad": "Entrada Suave Quadrática",
63 | "zoomify.transition.ease_out_quad": "Saída Suave Quadrática",
64 | "zoomify.transition.ease_in_out_quad": "Entrada Saída Suave Quadrática",
65 | "zoomify.transition.ease_in_cubic": "Entrada Suave Cúbica",
66 | "zoomify.transition.ease_out_cubic": "Saída Suave Cúbica",
67 | "zoomify.transition.ease_in_out_cubic": "Entrada Saída Suave Cúbica",
68 | "zoomify.transition.ease_in_exp": "Entrada Suave Exponencial",
69 | "zoomify.transition.ease_out_exp": "Saída Suave Exponencial",
70 | "zoomify.transition.ease_in_out_exp": "Entrada Saída Suave Exponencial",
71 |
72 |
73 | "zoomify.zoom_key_behaviour.hold": "Segurar",
74 | "zoomify.zoom_key_behaviour.toggle": "Alternar",
75 |
76 |
77 | "zoomify.spyglass_behaviour.combine": "Combinar",
78 | "zoomify.spyglass_behaviour.override": "Substituir",
79 | "zoomify.spyglass_behaviour.only_zoom_while_holding": "Permitir Enquanto Segurando",
80 | "zoomify.spyglass_behaviour.only_zoom_while_carrying": "Permitir Enquanto Carregando",
81 |
82 | "zoomify.overlay_visibility.never": "Nunca",
83 | "zoomify.overlay_visibility.holding": "Segurando",
84 | "zoomify.overlay_visibility.carrying": "Carregando",
85 | "zoomify.overlay_visibility.always": "Sempre",
86 |
87 | "zoomify.sound_behaviour.never": "Nunca",
88 | "zoomify.sound_behaviour.always": "Sempre",
89 | "zoomify.sound_behaviour.only_spyglass": "Apenas Segurando Luneta",
90 | "zoomify.sound_behaviour.with_overlay": "Corresponder Sobreposição"
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/lang/tr_tr.json:
--------------------------------------------------------------------------------
1 | {
2 | "zoomify.key.zoom": "Yakınlaştır",
3 | "zoomify.key.gui": "Menüyü Aç",
4 | "zoomify.key.category": "Zoomify",
5 |
6 |
7 | "zoomify.gui.title": "Zoomify",
8 |
9 | "yacl3.config.zoomify.category.behaviour": "Davranış",
10 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom": "İlk Yakınlaştırma",
11 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom.description.1": "Tuş takımına ilk bastığınızda yakınlaştırma düzeyi",
12 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime": "Yakınlaştırma Süresi",
13 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime.description.1": "Yakınlaştırmayı tamamlamak için ne kadar sürenin var olduğu",
14 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime": "Uzaklaştırma Süresi",
15 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime.description.1": "Uzaklaştırmayı tamamlamak için ne kadar sürenin var olduğu",
16 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition": "Yakınlaştırma Geçişi",
17 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition.description.1": "Yakınlaştırırken kullanılan geçiş türü",
18 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition": "Uzaklaştırma Geçişi",
19 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition.description.1": "Uzaklaştırırken kullanılan geçiş türü",
20 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov": "El FOV'unu Etkile",
21 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov.description.1": "Yakınlaştırırken, görüş yaklaşırken elin FOV'unu normal tutun.",
22 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps": "Yakınlaştırma Adımlarını Hatırla",
23 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps.description.1": "Yakınlaştırma ve uzaklaştırma arasındaki kaydırarak yakınlaştırma miktarını koruyun.",
24 |
25 | "yacl3.config.zoomify.category.behaviour.group.scrolling": "Kaydırma",
26 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom": "Kaydırma Yakınlaştırmasını Etkinleştir",
27 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom.description.1": "Kaydırma tekerleği ile daha fazla yakınlaştırma ve uzaklaştırma yapmanızı sağlar.",
28 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount": "Kaydırma Yakınlaştırma Miktarı",
29 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount.description.1": "Kaydırma adımı başına FOV'un ek böleni",
30 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness": "Kaydırma Yakınlaştırma Pürüzsüzlüğü",
31 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness.description.1": "Kaydırmanın-Yakınlaştırmanın ne kadar yumuşak olduğu/ne kadar sürdüğü",
32 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom": "Yumuşak Geçiş",
33 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom.description.1": "İçeri ve dışarı kaydırmayı pürüzsüz yapar.",
34 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps": "Doğrusal Benzeri Adımlar",
35 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps.description.1": "Daha doğrusal hissettirmek için artışlara bir eğri uygular.",
36 |
37 | "yacl3.config.zoomify.category.controls": "Kontroller",
38 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour": "Yakınlaştırma Tuşu Davranışı",
39 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour.description.1": "Yakınlaştırma tuşunun davranışı",
40 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity": "Bağıl Hassaslık",
41 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity.description.1": "Yakınlaştırma düzeyine göre hassasiyeti kontrol eder.",
42 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing": "Bağıl Sallanan Görüntü",
43 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing.description.1": "Yakınlaştırıldığında görüntü sallanmasını daha az sarsıcı hale getir.",
44 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera": "Sinematik Kamera",
45 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera.description.1": "Yakınlaştırıldığında kameranın düzgünce hareket etmesini sağla.",
46 |
47 | "yacl3.config.zoomify.category.behaviour.group.spyglass": "Dürbün",
48 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour": "Yakınlaştırma Davranışı",
49 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour.description.1": "Zoomify'ın dürbün yakınlaştırma ile nasıl etkileşime geçeceği",
50 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility": "Kaplama Görünürlüğü",
51 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility.description.1": "Dürbün kaplamasının ne zaman gösterileceği",
52 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour": "Ses Davranışı",
53 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour.description.1": "Dürbünden gelen yakınlaştırma ve uzaklaştırma seslerinin ne zaman oynatılacağı",
54 |
55 | "yacl3.config.zoomify.category.misc.group.presets": "Ön Ayarlar",
56 | "zoomify.gui.preset.default": "Varsayılan",
57 | "zoomify.gui.preset.optifine": "OptiFine",
58 | "zoomify.gui.preset.ok_zoomer": "OK Zoomer",
59 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.button": "Ön Ayarı Uygula",
60 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.description": "Zoomify'ın %s gibi davranmasını sağlar.",
61 | "yacl3.config.zoomify.category.misc.group.presets.label.applyWarning": "Düğmeye basmak, değişiklikleri hemen uygulayacaktır!",
62 |
63 |
64 | "zoomify.transition.instant": "Anında",
65 | "zoomify.transition.linear": "Doğrusal",
66 | "zoomify.transition.ease_in_sine": "Kademeli Sinüs Girişi",
67 | "zoomify.transition.ease_out_sine": "Kademeli Sinüs Çıkışı",
68 | "zoomify.transition.ease_in_out_sine": "Kademeli Sinüs Giriş Çıkışı",
69 | "zoomify.transition.ease_in_quad": "Kademeli Dörtlü Giriş",
70 | "zoomify.transition.ease_out_quad": "Kademeli Dörtlü Çıkış",
71 | "zoomify.transition.ease_in_out_quad": "Kademeli Dörtlü Giriş Çıkışı",
72 | "zoomify.transition.ease_in_cubic": "Kademeli Kübik Girişi",
73 | "zoomify.transition.ease_out_cubic": "Kademeli Kübik Çıkışı",
74 | "zoomify.transition.ease_in_out_cubic": "Kademeli Kübik Giriş Çıkışı",
75 | "zoomify.transition.ease_in_exp": "Kademeli Üstel Giriş",
76 | "zoomify.transition.ease_out_exp": "Kademeli Üstel Çıkış",
77 | "zoomify.transition.ease_in_out_exp": "Kademeli Üstel Giriş Çıkışı",
78 |
79 |
80 | "zoomify.zoom_key_behaviour.hold": "Basılı Tut",
81 | "zoomify.zoom_key_behaviour.toggle": "Aç/Kapa",
82 |
83 |
84 | "zoomify.spyglass_behaviour.combine": "Birleştir",
85 | "zoomify.spyglass_behaviour.override": "Geçersiz Kıl",
86 | "zoomify.spyglass_behaviour.only_zoom_while_holding": "Basılı Tutarken İzin Ver",
87 | "zoomify.spyglass_behaviour.only_zoom_while_carrying": "Taşırken İzin Ver",
88 |
89 | "zoomify.overlay_visibility.never": "Asla",
90 | "zoomify.overlay_visibility.holding": "Basılı Tutma",
91 | "zoomify.overlay_visibility.carrying": "Taşıma",
92 | "zoomify.overlay_visibility.always": "Her Zaman",
93 |
94 | "zoomify.sound_behaviour.never": "Asla",
95 | "zoomify.sound_behaviour.always": "Her Zaman",
96 | "zoomify.sound_behaviour.only_spyglass": "Sadece Dürbün Tutarken",
97 | "zoomify.sound_behaviour.with_overlay": "Kaplamaya Uy"
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/lang/zh_cn.json:
--------------------------------------------------------------------------------
1 | {
2 | "zoomify.key.zoom": "放大(按住)",
3 | "zoomify.key.zoom_toggle": "放大(切换)",
4 | "zoomify.key.zoom.secondary": "二次缩放",
5 | "zoomify.key.zoom.in": "滚动放大",
6 | "zoomify.key.zoom.out": "滚动缩小",
7 | "zoomify.key.category": "缩放(Zoomify)",
8 |
9 |
10 | "yacl3.config.zoomify.title": "缩放(Zoomify)",
11 |
12 | "yacl3.config.zoomify.category.behaviour": "行为",
13 | "yacl3.config.zoomify.category.behaviour.group.basic": "基本",
14 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom": "初始缩放",
15 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom.description.1": "首次按下绑定键时的缩放级别。",
16 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime": "放大时间",
17 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime.description.1": "多少秒完成放大。",
18 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime": "缩小时间",
19 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime.description.1": "多少秒完成缩小。",
20 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition": "放大过渡",
21 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition.description.1": "放大时使用的过渡类型。",
22 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition": "缩小过度",
23 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition.description.1": "缩小时使用的过渡类型。",
24 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov": "影响手部FOV值",
25 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov.description.1": "缩放时,世界视图放大且保持手部的FOV值正常。",
26 |
27 | "yacl3.config.zoomify.category.behaviour.group.scrolling": "滚动",
28 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom": "启用滚动缩放",
29 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom.description.1": "允许您使用滚轮放大或缩小一些。",
30 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount": "滚动缩放量",
31 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount.description.1": "每个滚动步骤FOV的附加除数。",
32 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness": "滚动缩放平滑度",
33 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness.description.1": "滚动缩放的平滑度/需要多长时间。",
34 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom": "平滑过渡",
35 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom.description.1": "使滚入和滚出更平滑。",
36 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps": "类似线性步骤",
37 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps.description.1": "将曲线应用于增量以让他们感觉起来更像线性。",
38 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps": "记住缩放步骤",
39 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps.description.1": "在放大和缩小之间保持滚动缩放量。",
40 |
41 | "yacl3.config.zoomify.category.behaviour.group.spyglass": "望远镜",
42 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour": "缩放行为",
43 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour.description.1": "Zoomify如何与望远镜缩放相互影响。",
44 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility": "覆盖可视",
45 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility.description.1": "什么时候显示望远镜覆盖层。",
46 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour": "声音行为",
47 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour.description.1": "什么时候播放望远镜放大和缩小时的声音。",
48 |
49 | "yacl3.config.zoomify.category.controls": "控制",
50 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour": "缩放键行为",
51 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour.description.1": "按下缩放键时的行为。",
52 | "yacl3.config.zoomify.category.controls.root.option._keybindScrolling": "滚动缩放键绑定",
53 | "yacl3.config.zoomify.category.controls.root.option._keybindScrolling.description.1": "使用Minecraft键绑定来控制滚动缩放缩放而不是鼠标滚轮。",
54 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity": "相对灵敏度",
55 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity.description.1": "根据缩放级别控制灵敏度的梯度。",
56 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing": "相对视线晃动",
57 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing.description.1": "在放大时使视线晃动较为协调。",
58 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera": "电影摄像机",
59 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera.description.1": "使相机在缩放时平滑移动。",
60 |
61 | "yacl3.config.zoomify.category.secondary": "二次缩放",
62 | "yacl3.config.zoomify.category.secondary.root.label.infoLabel": "与Zoomify的其他所有设置完全分开。二次缩放仅在控制中使用单独的键绑定进行切换。",
63 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomAmount": "缩放量",
64 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomAmount.description.1": "一旦过渡完成,将当前的FOV划分多少倍。",
65 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomInTime": "放大时间",
66 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomInTime.description.1": "多少秒完成放大。",
67 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomOutTime": "缩小时间",
68 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomOutTime.description.1": "多少秒完成缩小",
69 | "yacl3.config.zoomify.category.secondary.root.option.secondaryHideHUDOnZoom": "在缩放时隐藏HUD",
70 | "yacl3.config.zoomify.category.secondary.root.option.secondaryHideHUDOnZoom.description.1": "放大时停止渲染HUD,就像按F1。",
71 |
72 | "yacl3.config.zoomify.category.misc": "杂项",
73 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting": "解除冲突键位",
74 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.button": "解除",
75 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.description.1": "移除与Zoomify缩放键具有相同键位的键绑定。",
76 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations": "检查迁移",
77 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations.button": "检查",
78 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations.description.1": "检查可用的自动迁移。",
79 | "yacl3.config.zoomify.category.misc.group.presets": "预设",
80 | "yacl3.config.zoomify.category.misc.group.presets.label.applyWarning": "应用预设将立即应用更改并撤消任何未做出决定的更改。",
81 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.button": "应用预设",
82 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.description": "使Zoomify的行为像%s。",
83 |
84 | "zoomify.gui.preset.default": "默认",
85 | "zoomify.gui.preset.optifine": "OptiFine",
86 | "zoomify.gui.preset.ok_zoomer": "OK Zoomer",
87 | "zoomify.gui.preset.toast.title": "应用预设",
88 | "zoomify.gui.preset.toast.description": "Zoomify应用了%s预设。",
89 |
90 | "zoomify.gui.formatter.instant": "立即",
91 | "zoomify.gui.formatter.seconds": "%s秒",
92 |
93 | "zoomify.transition.instant": "立即",
94 | "zoomify.transition.linear": "直线",
95 | "zoomify.transition.ease_in_sine": "正弦缓入",
96 | "zoomify.transition.ease_out_sine": "正弦缓出",
97 | "zoomify.transition.ease_in_out_sine": "正弦缓出入",
98 | "zoomify.transition.ease_in_quad": "四方缓入",
99 | "zoomify.transition.ease_out_quad": "四方缓出",
100 | "zoomify.transition.ease_in_out_quad": "四方缓出入",
101 | "zoomify.transition.ease_in_cubic": "立方缓入",
102 | "zoomify.transition.ease_out_cubic": "立方缓出",
103 | "zoomify.transition.ease_in_out_cubic": "立方缓出入",
104 | "zoomify.transition.ease_in_exp": "指数缓入",
105 | "zoomify.transition.ease_out_exp": "指数缓出",
106 | "zoomify.transition.ease_in_out_exp": "指数缓出入",
107 |
108 |
109 | "zoomify.zoom_key_behaviour.hold": "开始放大",
110 | "zoomify.zoom_key_behaviour.toggle": "切换放大缩小",
111 |
112 |
113 | "zoomify.spyglass_behaviour.combine": "合并",
114 | "zoomify.spyglass_behaviour.override": "覆盖",
115 | "zoomify.spyglass_behaviour.only_zoom_while_holding": "开镜时启用",
116 | "zoomify.spyglass_behaviour.only_zoom_while_carrying": "携带时启用",
117 |
118 | "zoomify.overlay_visibility.never": "从不",
119 | "zoomify.overlay_visibility.holding": "按住时",
120 | "zoomify.overlay_visibility.carrying": "携带时",
121 | "zoomify.overlay_visibility.always": "总是",
122 |
123 | "zoomify.sound_behaviour.never": "从不",
124 | "zoomify.sound_behaviour.always": "总是",
125 | "zoomify.sound_behaviour.only_spyglass": "只有望远镜开镜时",
126 | "zoomify.sound_behaviour.with_overlay": "匹配覆盖(只有按望远镜时)",
127 |
128 | "zoomify.toast.conflictingKeybind.title": "Zoomify不起作用!",
129 | "zoomify.toast.conflictingKeybind.description": "存在冲突的按键绑定,阻止了缩放键起作用。你可以在Zoomify设置的%s类别中取消绑定。",
130 | "zoomify.toast.unbindConflicting.name": "解除冲突键位",
131 | "zoomify.toast.unbindConflicting.description": "Zoomify解除绑定键‘%s’因为它与缩放键冲突。",
132 |
133 |
134 | "zoomify.migrate.no_migrations": "没有可用的迁移。",
135 | "zoomify.migrate.result.title": "迁移完成",
136 | "zoomify.migrate.restart": "需要重启",
137 | "zoomify.migrate.result.restart_game": "重启游戏",
138 | "zoomify.migrate.available.title": "%s的自动迁移可用",
139 | "zoomify.migrate.available.message": "你想要自动将你的%s配置迁移到Zoomify吗?",
140 |
141 | "zoomify.migrate.okz": "OK Zoomer",
142 | "zoomify.migrate.okz.persistent": "不支持持续缩放模式。",
143 | "zoomify.migrate.okz.vignette": "不支持Vignette overlay。",
144 | "zoomify.migrate.okz.minZoomDiv": "不支持设置最小放大倍数。",
145 | "zoomify.migrate.okz.stepAmt": "不支持设置scroll step amount。",
146 | "zoomify.migrate.okz.linearNotSupported": "无法自动计算线性时序。"
147 | }
148 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/lang/zh_tw.json:
--------------------------------------------------------------------------------
1 | {
2 | "zoomify.key.zoom": "縮放",
3 | "zoomify.key.zoom.secondary": "次要縮放",
4 | "zoomify.key.zoom.in": "向上滾動放大",
5 | "zoomify.key.zoom.out": "向下滾動縮小",
6 | "zoomify.key.category": "Zoomify",
7 |
8 |
9 | "zoomify.gui.title": "Zoomify",
10 |
11 | "yacl3.config.zoomify.category.behaviour": "行為",
12 | "yacl3.config.zoomify.category.behaviour.group.basic": "基本",
13 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom": "初始化縮放大小",
14 | "yacl3.config.zoomify.category.behaviour.group.basic.option.initialZoom.description.1": "按下快捷鍵時的縮放等級。",
15 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime": "放大時間",
16 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTime.description.1": "要多少秒完成放大。",
17 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime": "縮小時間",
18 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTime.description.1": "要多少秒完成縮小。",
19 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition": "放大過渡效果",
20 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomInTransition.description.1": "當放大時使用的過渡效果類型。",
21 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition": "縮小過渡效果",
22 | "yacl3.config.zoomify.category.behaviour.group.basic.option.zoomOutTransition.description.1": "當縮小時使用的過渡效果類型。",
23 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov": "影響手部視角",
24 | "yacl3.config.zoomify.category.behaviour.group.basic.option.affectHandFov.description.1": "當縮放時,在世界視角被縮放時保持手部視角正常。",
25 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps": "記住縮放步驟量",
26 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.retainZoomSteps.description.1": "在放大縮小時保持滾動縮放量。",
27 |
28 | "yacl3.config.zoomify.category.behaviour.group.scrolling": "滾動",
29 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom": "啟用滾動縮放",
30 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoom.description.1": "允許使用滾輪進行更多縮放動作。",
31 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount": "滾動縮放量",
32 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomAmount.description.1": "每次滾動時的視角額外除數。",
33 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness": "滾動縮放平滑度",
34 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.scrollZoomSmoothness.description.1": "滾動縮放時所需要的時間與平滑度。",
35 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom": "平滑過渡效果",
36 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.smoothScrollZoom.description.1": "讓滾動縮放更加的平滑。",
37 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps": "類線性步驟",
38 | "yacl3.config.zoomify.category.behaviour.group.scrolling.option.linearLikeSteps.description.1": "對增量套用曲線,使其感覺更加線性。",
39 |
40 | "yacl3.config.zoomify.category.controls": "控制",
41 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour": "縮放鍵行為",
42 | "yacl3.config.zoomify.category.controls.root.option.zoomKeyBehaviour.description.1": "按下縮放鍵時的行為。",
43 | "yacl3.config.zoomify.category.controls.root.option._keybindScrolling": "綁定鍵滾動",
44 | "yacl3.config.zoomify.category.controls.root.option._keybindScrolling.description.1": "使用 Minecraft 綁定鍵來控制滾動縮放而不是用滾輪。",
45 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity": "相對敏感度",
46 | "yacl3.config.zoomify.category.controls.root.option.relativeSensitivity.description.1": "根據縮放等級控制敏感度。",
47 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing": "相對視角晃動",
48 | "yacl3.config.zoomify.category.controls.root.option.relativeViewBobbing.description.1": "使放大時視角晃動更少。",
49 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera": "劇院鏡頭",
50 | "yacl3.config.zoomify.category.controls.root.option.cinematicCamera.description.1": "鏡頭滑動的速度。",
51 |
52 | "yacl3.config.zoomify.category.behaviour.group.spyglass": "望遠鏡",
53 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour": "縮放行為",
54 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassBehaviour.description.1": "Zoomify 的縮放效果,要如何與望遠鏡互動。",
55 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility": "重疊可見度",
56 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassOverlayVisibility.description.1": "何時顯示望遠鏡的重疊。",
57 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour": "音效行為",
58 | "yacl3.config.zoomify.category.behaviour.group.spyglass.option.spyglassSoundBehaviour.description.1": "何時播放來自望遠鏡的放大縮小聲音。",
59 |
60 | "yacl3.config.zoomify.category.secondary": "次要縮放",
61 | "yacl3.config.zoomify.category.secondary.root.label.infoLabel": "完全與 Zoomify 的所有其他設定分離。次要縮放僅具有切換功能,使用單獨的綁定鍵來控制。",
62 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomAmount": "縮放量",
63 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomAmount.description.1": "完成過渡後的視角除數次數。",
64 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomInTime": "放大時間",
65 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomInTime.description.1": "要多少秒完成放大。",
66 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomOutTime": "縮小時間",
67 | "yacl3.config.zoomify.category.secondary.root.option.secondaryZoomOutTime.description.1": "要多少秒完成縮小。",
68 | "yacl3.config.zoomify.category.secondary.root.option.secondaryHideHUDOnZoom": "縮放時隱藏 HUD",
69 | "yacl3.config.zoomify.category.secondary.root.option.secondaryHideHUDOnZoom.description.1": "在縮放時停止繪製 HUD,就像是按下 F1 鍵時一樣。",
70 |
71 | "yacl3.config.zoomify.category.misc": "其他",
72 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting": "解除有衝突的按鍵綁定",
73 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.button": "解除綁定",
74 | "yacl3.config.zoomify.category.misc.root.option.unbindConflicting.description.1": "移除和 Zoomify 縮放鍵相同的按鍵綁定。",
75 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations": "檢查轉移",
76 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations.button": "檢查",
77 | "yacl3.config.zoomify.category.misc.root.option.checkMigrations.description.1": "檢查是否有可用的自動轉移。",
78 | "yacl3.config.zoomify.category.misc.group.presets": "預設值",
79 | "zoomify.gui.preset.default": "預設",
80 | "zoomify.gui.preset.optifine": "OptiFine",
81 | "zoomify.gui.preset.ok_zoomer": "OK Zoomer",
82 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.button": "套用預設值",
83 | "zoomify.gui.preset.toast.title": "已套用預設值",
84 | "zoomify.gui.preset.toast.description": "Zoomify 已套用 %s 預設值。",
85 | "yacl3.config.zoomify.category.misc.group.presets.presetBtn.description": "讓 Zoomify 行為類似於 %s。",
86 | "yacl3.config.zoomify.category.misc.group.presets.label.applyWarning": "套用預設值將會立即套用變更並撤銷任何擱置中的變更。",
87 |
88 | "zoomify.gui.formatter.instant": "即時",
89 | "zoomify.gui.formatter.seconds": "%s 秒",
90 |
91 | "zoomify.transition.instant": "即時",
92 | "zoomify.transition.linear": "線性",
93 | "zoomify.transition.ease_in_sine": "正弦緩入",
94 | "zoomify.transition.ease_out_sine": "正弦緩出",
95 | "zoomify.transition.ease_in_out_sine": "正弦緩入緩出",
96 | "zoomify.transition.ease_in_quad": "二次方緩入",
97 | "zoomify.transition.ease_out_quad": "二次方緩出",
98 | "zoomify.transition.ease_in_out_quad": "二次方緩入緩出",
99 | "zoomify.transition.ease_in_cubic": "三次方緩入",
100 | "zoomify.transition.ease_out_cubic": "三次方緩出",
101 | "zoomify.transition.ease_in_out_cubic": "三次方緩入緩出",
102 | "zoomify.transition.ease_in_exp": "指數緩入",
103 | "zoomify.transition.ease_out_exp": "指數緩出",
104 | "zoomify.transition.ease_in_out_exp": "指數緩入緩出",
105 |
106 |
107 | "zoomify.zoom_key_behaviour.hold": "按住",
108 | "zoomify.zoom_key_behaviour.toggle": "切換",
109 |
110 |
111 | "zoomify.spyglass_behaviour.combine": "組合",
112 | "zoomify.spyglass_behaviour.override": "覆蓋",
113 | "zoomify.spyglass_behaviour.only_zoom_while_holding": "當按住時",
114 | "zoomify.spyglass_behaviour.only_zoom_while_carrying": "當手持時",
115 |
116 | "zoomify.overlay_visibility.never": "永不",
117 | "zoomify.overlay_visibility.holding": "按住時",
118 | "zoomify.overlay_visibility.carrying": "手持時",
119 | "zoomify.overlay_visibility.always": "總是",
120 |
121 | "zoomify.sound_behaviour.never": "永不",
122 | "zoomify.sound_behaviour.always": "總是",
123 | "zoomify.sound_behaviour.only_spyglass": "僅在持握望遠鏡時",
124 | "zoomify.sound_behaviour.with_overlay": "相符重疊",
125 |
126 | "zoomify.toast.conflictingKeybind.title": "Zoomify 無法運作!",
127 | "zoomify.toast.conflictingKeybind.description": "有按鍵衝突阻止使用縮放按鍵。你可以在 Zoomify 設定中的 %s 類別將衝突的按鍵解除綁定。",
128 | "zoomify.toast.unbindConflicting.name": "解除有衝突的按鍵綁定",
129 | "zoomify.toast.unbindConflicting.description": "Zoomify 解除了名為「%s」的按鍵,因為它與縮放鍵衝突。",
130 |
131 |
132 | "zoomify.migrate.no_migrations": "沒有可用的轉移。",
133 | "zoomify.migrate.result.title": "轉移完成",
134 | "zoomify.migrate.restart": "需要重啟",
135 | "zoomify.migrate.result.restart_game": "重啟遊戲",
136 | "zoomify.migrate.available.title": "自動轉移「%s」的設定可用",
137 | "zoomify.migrate.available.message": "你想要自動轉移你的 %s 設定到 Zoomify?",
138 |
139 | "zoomify.migrate.okz": "OK Zoomer",
140 | "zoomify.migrate.okz.persistent": "不支援永續性縮放模式。",
141 | "zoomify.migrate.okz.vignette": "不支援暈影重疊。",
142 | "zoomify.migrate.okz.minZoomDiv": "不支援設定最小縮放除數。",
143 | "zoomify.migrate.okz.stepAmt": "不支援設定滾輪步驟量。",
144 | "zoomify.migrate.okz.linearNotSupported": "線性時間無法被自動計算。"
145 | }
146 |
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/textures/demo/third-person-hud.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/src/main/resources/assets/zoomify/textures/demo/third-person-hud.webp
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/textures/demo/third-person-view.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/src/main/resources/assets/zoomify/textures/demo/third-person-view.webp
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/textures/demo/zoom-hand.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/src/main/resources/assets/zoomify/textures/demo/zoom-hand.webp
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/textures/demo/zoom-world.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/src/main/resources/assets/zoomify/textures/demo/zoom-world.webp
--------------------------------------------------------------------------------
/src/main/resources/assets/zoomify/zoomify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/isXander/Zoomify/80337e5b6690d47b10a635acd4db140e49eddc19/src/main/resources/assets/zoomify/zoomify.png
--------------------------------------------------------------------------------
/src/main/resources/fabric.mod.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": 1,
3 | "id": "${id}",
4 | "version": "${version}",
5 | "name": "${name}",
6 | "description": "${description}",
7 | "authors": [
8 | "isXander"
9 | ],
10 | "contact": {
11 | "homepage": "https://isxander.dev",
12 | "issues": "https://github.com/isXander/Zoomify/issues",
13 | "sources": "https://github.com/isXander/Zoomify"
14 | },
15 | "icon": "assets/zoomify/zoomify.png",
16 | "license": "LGPLv3",
17 | "environment": "client",
18 | "entrypoints": {
19 | "client": [
20 | {
21 | "adapter": "kotlin",
22 | "value": "dev.isxander.zoomify.Zoomify"
23 | }
24 | ],
25 | "preLaunch": [
26 | "com.llamalad7.mixinextras.MixinExtrasBootstrap::init"
27 | ],
28 | "modmenu": [
29 | {
30 | "adapter": "kotlin",
31 | "value": "dev.isxander.zoomify.integrations.ModMenuIntegration"
32 | }
33 | ],
34 | "controlify": [
35 | {
36 | "adapter": "kotlin",
37 | "value": "dev.isxander.zoomify.integrations.ControlifyIntegration"
38 | }
39 | ]
40 | },
41 | "mixins": [
42 | "zoomify.mixins.json"
43 | ],
44 | "depends": {
45 | "fabric-api": "*",
46 | "fabricloader": ">=0.14.22",
47 | "fabric-language-kotlin": ">=1.11.0+kotlin.2.0.0",
48 | "minecraft": "${mc}",
49 | "java": ">=17",
50 | "yet_another_config_lib_v3": ">=3.5.0"
51 | },
52 | "suggests": {
53 | "modmenu": "*"
54 | },
55 | "breaks": {
56 | "optifabric": "*",
57 | "controlify": "<2.0.0-beta.9"
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/resources/zoomify.mixins.json:
--------------------------------------------------------------------------------
1 | {
2 | "required": true,
3 | "package": "dev.isxander.zoomify.mixins",
4 | "compatibilityLevel": "JAVA_17",
5 | "injectors": {
6 | "defaultRequire": 1
7 | },
8 | "client": [
9 | "hooks.MinecraftClientMixin",
10 | "spyglass.AbstractClientPlayerEntityMixin",
11 | "spyglass.InGameHudMixin",
12 | "spyglass.SpyglassItemMixin",
13 | "zoom.GameRendererMixin",
14 | "zoom.MouseMixin",
15 | "zoom.secondary.GameRendererMixin"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/stonecutter.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("dev.kikugie.stonecutter")
3 | }
4 | stonecutter active "1.21.3" /* [SC] DO NOT EDIT */
5 |
6 | stonecutter.configureEach {
7 | fun String.propDefined() = project.findProperty(this)?.toString()?.isNotBlank() ?: false
8 |
9 | consts(listOf(
10 | "mod-menu" to "deps.modMenu".propDefined()
11 | ))
12 | }
13 |
14 | stonecutter registerChiseled tasks.register("buildAllVersions", stonecutter.chiseled) {
15 | group = "mod"
16 | ofTask("build")
17 | }
18 |
19 | stonecutter registerChiseled tasks.register("releaseAllVersions", stonecutter.chiseled) {
20 | group = "mod"
21 | ofTask("releaseMod")
22 | }
23 |
--------------------------------------------------------------------------------
/versions/1.20.1/gradle.properties:
--------------------------------------------------------------------------------
1 | mcVersion=1.20.1
2 |
3 | deps.parchment=1.20.1:2023.09.03
4 | deps.fabricApi=0.92.0+1.20.1
5 | deps.yacl=3.5.0+1.20.1-fabric
6 | deps.modMenu=7.2.2
7 | deps.controlify=2.0.0-beta.12+1.20.1-fabric
8 |
9 | java.version=17
10 |
11 | fmj.mcDep=>=1.20 <=1.20.1
12 |
13 | pub.stableMC=1.20, 1.20.1
14 |
--------------------------------------------------------------------------------
/versions/1.20.4/gradle.properties:
--------------------------------------------------------------------------------
1 | mcVersion=1.20.4
2 |
3 | deps.parchment=1.20.4:2024.04.14
4 | deps.fabricApi=0.96.11+1.20.4
5 | deps.yacl=3.5.0+1.20.4-fabric
6 | deps.modMenu=9.0.0
7 | deps.controlify=2.0.0-beta.12+1.20.4-fabric
8 |
9 | java.version=17
10 |
11 | fmj.mcDep=>=1.20.3 <=1.20.4
12 |
13 | pub.stableMC=1.20.3,1.20.4
14 |
--------------------------------------------------------------------------------
/versions/1.20.6/gradle.properties:
--------------------------------------------------------------------------------
1 | mcVersion=1.20.6
2 |
3 | deps.parchment=1.20.6:2024.05.01
4 | deps.fabricApi=0.100.0+1.20.6
5 | deps.yacl=3.5.0+1.20.6-fabric
6 | deps.modMenu=10.0.0-beta.1
7 | deps.controlify=2.0.0-beta.12+1.20.6-fabric
8 |
9 | java.version=21
10 |
11 | fmj.mcDep=~1.20.5
12 |
13 | pub.modrinthMC=1.20.5,1.20.6
14 | pub.curseMC=1.20.5,1.20.6
15 |
--------------------------------------------------------------------------------
/versions/1.21.1/gradle.properties:
--------------------------------------------------------------------------------
1 | mcVersion=1.21.1
2 |
3 | deps.parchment=1.21:2024.07.28
4 | deps.fabricApi=0.104.0+1.21.1
5 | deps.yacl=3.5.0+1.21-fabric
6 | deps.modMenu=11.0.2
7 | deps.controlify=2.0.0-beta.12+1.21-fabric
8 |
9 | java.version=21
10 |
11 | fmj.mcDep=~1.21 <1.21.2
12 |
13 | pub.modrinthMC=1.21,1.21.1
14 | pub.curseMC=1.21,1.21.1
15 |
--------------------------------------------------------------------------------
/versions/1.21.3/gradle.properties:
--------------------------------------------------------------------------------
1 | mcVersion=1.21.3
2 |
3 | #deps.parchment=1.21:2024.07.28
4 | deps.fabricApi=0.106.1+1.21.3
5 | deps.yacl=3.6.1+1.21.2-fabric
6 | deps.modMenu=12.0.0-beta.1
7 | deps.controlify=2.0.0-beta.18+1.21.2-fabric
8 |
9 | java.version=21
10 |
11 | fmj.mcDep=~1.21.2
12 |
13 | pub.modrinthMC=1.21.2,1.21.3
14 | pub.curseMC=1.21.2,1.21.3
15 |
--------------------------------------------------------------------------------