├── .editorconfig ├── .gitattributes ├── .gitignore ├── CREDITS.md ├── LICENSE ├── LICENSE-HEADER.txt ├── README.md ├── build.gradle ├── gradle ├── versions.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lombok.config ├── settings.gradle └── src ├── main ├── java │ └── net │ │ └── awairo │ │ └── minecraft │ │ └── spawnchecker │ │ ├── SpawnChecker.java │ │ ├── SpawnCheckerCommands.java │ │ ├── SpawnCheckerException.java │ │ ├── SpawnCheckerState.java │ │ ├── WrappedProfiler.java │ │ ├── api │ │ ├── Brightness.java │ │ ├── Color.java │ │ ├── HudData.java │ │ ├── HudRenderer.java │ │ ├── Marker.java │ │ ├── MarkerRenderer.java │ │ ├── Mode.java │ │ ├── PlayerPos.java │ │ ├── Renderer.java │ │ ├── ScanRange.java │ │ └── UsingHands.java │ │ ├── config │ │ ├── ConfigHolder.java │ │ ├── HudConfig.java │ │ ├── KeyConfig.java │ │ ├── ModeConfig.java │ │ ├── PresetModeConfig.java │ │ ├── SpawnCheckerConfig.java │ │ ├── UpdateResult.java │ │ └── Updater.java │ │ ├── hud │ │ ├── HudIconResource.java │ │ ├── HudOffset.java │ │ └── HudRendererImpl.java │ │ ├── keybinding │ │ ├── KeyBindingState.java │ │ ├── RepeatDelay.java │ │ ├── RepeatRate.java │ │ ├── SpawnCheckerKeyBinding.java │ │ └── SpawnCheckerKeyConflictContext.java │ │ ├── mode │ │ ├── ConditionalMode.java │ │ ├── EntitySize.java │ │ ├── ModeList.java │ │ ├── ModeState.java │ │ ├── MyMarkerRendererImpl.java │ │ ├── PresetMode.java │ │ ├── RangeConfigHudData.java │ │ ├── ScanArea.java │ │ ├── SelectableMode.java │ │ ├── SlimeCheckMode.java │ │ ├── SpawnCheckMode.java │ │ ├── SpawnEntityType.java │ │ ├── SpawnerVisualizerMode.java │ │ ├── UpdateTimer.java │ │ ├── YOffset.java │ │ └── marker │ │ │ ├── FixedMarker.java │ │ │ ├── MarkerModel.java │ │ │ ├── SpawnPointMarker.java │ │ │ └── model │ │ │ ├── GuidelineModel.java │ │ │ └── SpawnPointModel.java │ │ ├── package-info.java │ │ └── util │ │ └── LazyCachedSupplier.java └── resources │ ├── META-INF │ └── mods.toml │ ├── assets │ └── spawnchecker │ │ ├── lang │ │ ├── en_us.json │ │ └── ja_jp.json │ │ └── textures │ │ ├── hud │ │ ├── brightness.png │ │ ├── horizontal_range.png │ │ ├── slime_chunk_visualizer.png │ │ ├── spawn_checker.png │ │ ├── spawner_visualizer.png │ │ └── vertical_range.png │ │ └── markers │ │ ├── spawn_marker_default.png │ │ ├── spawn_marker_enderman.png │ │ ├── spawn_marker_ghast.png │ │ ├── spawn_marker_slime.png │ │ └── spawn_marker_spider.png │ ├── pack.mcmeta │ └── spawnchecker_logo.png └── test └── java └── net └── awairo └── minecraft └── spawnchecker ├── mode └── ScanRangeTest.java └── util ├── ColorTest.java └── LazyCachedSupplierTest.java /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 2 9 | 10 | [*.java] 11 | indent_size = 4 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Disable autocrlf on generated files, they always generate with LF 2 | # Add any extra files or paths here to make git stop saying they 3 | # are changed when only line endings change. 4 | src/generated/**/.cache/cache text eol=lf 5 | src/generated/**/*.json text eol=lf 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | 4 | # gradle 5 | build 6 | .gradle 7 | gradle.properties 8 | 9 | # eclipse 10 | bin 11 | *.launch 12 | .settings 13 | .metadata 14 | .classpath 15 | .project 16 | 17 | # idea 18 | out 19 | *.ipr 20 | *.iws 21 | *.iml 22 | .idea 23 | 24 | # other 25 | eclipse 26 | run 27 | 28 | /logs 29 | 30 | # Files from Forge MDK 31 | forge*changelog.txt 32 | -------------------------------------------------------------------------------- /CREDITS.md: -------------------------------------------------------------------------------- 1 | CREDITS 2 | ================== 3 | 4 | SpawnChecker という、 [Minecraft](https://www.minecraft.net) の Mod です。 5 | 6 | fillppo氏により作成された、オリジナルの SpawnChecker のアイデア、 7 | 及びそのソースコードを元に、現在の SpawnChecker は開発されています。 8 | 9 | オリジナルの SpawnChecker については、マインクラフト非公式日本ユーザーフォーラムの 10 | 「[[1.1][SpawnChecker110v2]Mobが湧くブロックをチェック](http://forum.minecraftuser.jp/viewtopic.php?t=36)」トピックを参照してください。 11 | 12 | 現在の開発者は、[alalwww](https://github.com/alalwww) です。 13 | 14 | ソースコードは[GitHub](https://github.com/alalwww/SpawnChecker)より取得することが可能です。 15 | 16 | 17 | --------------------------------------- 18 | (以下はfillppo氏の発言の引用です) 19 | > 専用のEntityをスポーンさせ、そのEntityのRendererで描画する方式については、 20 | > WorldEditCUIを参考にさせていただきました。 21 | --------------------------------------- 22 | Minecraft 1.6.x 版の SpawnChecker までは、この手法によりマーカーを描画していました。 23 | 24 | Minecraft 1.7.2 版以降の SpawnChecker では、Minecraft Forge のイベントにより描画タイミングを得るよう変更したため、 25 | Entity のレンダリングとして描画する上記の手法は利用していません。 26 | 27 | [Minecraft Forge](http://minecraftforge.net/) に依存しており、Mdkを利用し作成されています。 28 | 29 | また、マインクラフト非公式日本ユーザーフォーラムや、日本の modder の方々、 30 | 5ちゃんねる(旧名:2ちゃんねる)の Minecraft Texture・MOD総合スレ の住民の方々による、 31 | アイデアやアドバイスを受け、実装されています。 32 | 33 | SpawnChecker のロゴは、サークル「[ニルトニカ](https://twitter.com/nilutonica)」の、[かゑる氏](https://twitter.com/ka_we_ru)に作成して頂きました。 34 | 35 | モードアイコンや範囲、明るさのアイコンは、[あめふらし氏](https://twitter.com/furasanai)に作成を手伝って頂きました。 36 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /LICENSE-HEADER.txt: -------------------------------------------------------------------------------- 1 | SpawnChecker 2 | Copyright (C) ${years} ${name} 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 3 of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, write to the Free Software Foundation, 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SpawnChecker 3 [![Build Status](https://travis-ci.com/alalwww/SpawnChecker.svg?branch=master)](https://travis-ci.com/alalwww/SpawnChecker) 2 | ================== 3 | ![SpawnChecker logo](src/main/resources/spawnchecker_logo.png) 4 | 5 | ## develop 6 | 7 | ### build 8 | ``` 9 | gradlew build 10 | ``` 11 | 12 | ### run/debug client 13 | 14 | #### Create Run/Debug configuration 15 | ``` 16 | gradlew genIntellijRuns 17 | ``` 18 | #### Add program arguments 19 | ``` 20 | --username your_minecraft_account (mail address) 21 | --password password 22 | ``` 23 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenLocal() 4 | maven { url = "https://files.minecraftforge.net/maven" } 5 | jcenter() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath group: "net.minecraftforge.gradle", name: "ForgeGradle", version: "3.+", changing: true 10 | } 11 | } 12 | plugins { 13 | id "net.minecrell.licenser" version "0.4" 14 | } 15 | apply plugin: "net.minecraftforge.gradle" 16 | apply plugin: "eclipse" // Do not delete it, because referred from FG 17 | apply from: "./gradle/versions.gradle" 18 | 19 | import org.apache.tools.ant.filters.FixCrLfFilter 20 | 21 | import static java.time.ZoneOffset.UTC 22 | import static java.time.ZonedDateTime.now 23 | 24 | ext { 25 | modid = "spawnchecker" 26 | javaVersion = JavaVersion.VERSION_1_8 27 | if (System.getenv("TRAVIS_BUILD_NUMBER") != null) { 28 | buildNumber = System.getenv("TRAVIS_BUILD_NUMBER") 29 | snapshot = "" 30 | } else { 31 | buildNumber = "local" 32 | snapshot = "-SNAPSHOT" 33 | } 34 | minecraftVersion = "1.16.4" 35 | minecraftVersionRange = "[1.16.4]" 36 | forgeVersionRange = "[35,)" 37 | forgeVersion = "1.16.4-35.0.1" 38 | mappingsChannel = "snapshot" 39 | mappingsVersion = "20201028-1.16.3" 40 | } 41 | 42 | version = "${versionTag}.${commitCount}${snapshot}" 43 | group = "net.awairo.minecraft.spawnchecker" 44 | archivesBaseName = "spawnchecker-${minecraftVersion}" 45 | 46 | sourceCompatibility = targetCompatibility = javaVersion 47 | tasks.withType(JavaCompile) { 48 | sourceCompatibility = targetCompatibility = javaVersion 49 | options.encoding = "UTF-8" 50 | } 51 | 52 | repositories { 53 | mavenLocal() 54 | jcenter() 55 | mavenCentral() 56 | } 57 | 58 | dependencies { 59 | minecraft "net.minecraftforge:forge:${forgeVersion}" 60 | 61 | implementation "com.google.code.findbugs:jsr305:1.0" 62 | 63 | compileOnly "org.projectlombok:lombok:1.18.+" 64 | annotationProcessor "org.projectlombok:lombok:1.18.+" 65 | testCompileOnly "org.projectlombok:lombok:1.18.+" 66 | testAnnotationProcessor "org.projectlombok:lombok:1.18.+" 67 | 68 | testImplementation "org.mockito:mockito-core:2.+" 69 | testImplementation "org.apiguardian:apiguardian-api:1.0.0" 70 | testImplementation "org.junit.jupiter:junit-jupiter-api:5.+" 71 | testImplementation "org.junit.jupiter:junit-jupiter-engine:5.+" 72 | } 73 | 74 | minecraft { 75 | // the mappings can be changed at any time, and must be in the following format. 76 | // snapshot_YYYYMMDD snapshot are built nightly. 77 | // stable_# stables are built at the discretion of the MCP team. 78 | // Use non-default mappings at your own risk. they may not always work. 79 | // simply re-run your setup task after changing the mappings to update your workspace. 80 | mappings channel: mappingsChannel, version: mappingsVersion 81 | // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. 82 | 83 | // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') 84 | 85 | // Default run configurations. 86 | // These can be tweaked, removed, or duplicated as needed. 87 | runs { 88 | client { 89 | ideaModule "${project.name}.main" 90 | workingDirectory project.file("run/client") 91 | 92 | // Recommended logging data for a userdev environment 93 | property "forge.logging.markers", "SCAN,REGISTRIES,REGISTRYDUMP" 94 | 95 | // Recommended logging level for the console 96 | property "forge.logging.console.level", "debug" 97 | 98 | mods { 99 | spawnchecker { 100 | source sourceSets.main 101 | } 102 | } 103 | } 104 | 105 | server { 106 | ideaModule "${project.name}.main" 107 | workingDirectory project.file("run/server") 108 | 109 | // Recommended logging data for a userdev environment 110 | property "forge.logging.markers", "SCAN,REGISTRIES,REGISTRYDUMP" 111 | 112 | // Recommended logging level for the console 113 | property "forge.logging.console.level", "debug" 114 | 115 | environment "MOD_CLASSES", "" 116 | } 117 | 118 | data { 119 | ideaModule "${project.name}.main" 120 | workingDirectory project.file("run/data") 121 | 122 | // Recommended logging data for a userdev environment 123 | property "forge.logging.markers", "SCAN,REGISTRIES,REGISTRYDUMP" 124 | 125 | // Recommended logging level for the console 126 | property "forge.logging.console.level", "debug" 127 | 128 | args "--mod", "spawnchecker", "--all", "--output", file("src/generated/resources/") 129 | 130 | mods { 131 | spawnchecker { 132 | source sourceSets.main 133 | } 134 | } 135 | } 136 | } 137 | } 138 | 139 | license { 140 | header = project.file("LICENSE-HEADER.txt") 141 | ext { 142 | name = "alalwww" 143 | years = "2019" 144 | } 145 | 146 | exclude "**/*.json" 147 | exclude "**/*.mcmeta" 148 | exclude "**/*.toml" 149 | } 150 | 151 | task processModsTomlResources(type: Copy) { 152 | into(sourceSets.main.output.resourcesDir) 153 | from(sourceSets.main.resources) { 154 | include "META-INF/mods.toml" 155 | } 156 | filter { line -> 157 | switch (line) { 158 | case "version=\"{version}\"": 159 | return "version=\"${project.version}\"" 160 | case "loaderVersion=\"{loaderVersion}\"": 161 | return "loaderVersion=\"${forgeVersionRange}\"" 162 | case " versionRange=\"{forgeVersionRange}\"": 163 | return " versionRange=\"${forgeVersionRange}\"" 164 | case " versionRange=\"{minecraftVersionRange}\"": 165 | return " versionRange=\"${minecraftVersionRange}\"" 166 | default: 167 | return line 168 | } 169 | } 170 | filter(FixCrLfFilter, eol: FixCrLfFilter.CrLf.newInstance("lf")) 171 | } 172 | 173 | processResources { 174 | dependsOn processModsTomlResources 175 | exclude "META-INF/mods.toml" 176 | } 177 | 178 | jar { 179 | into("META-INF") { 180 | from "LICENSE" 181 | from "CREDITS.md" 182 | } 183 | manifest { 184 | attributes "Specification-Title": "SpawnChecker" 185 | attributes "Specification-Vendor": "alalwww" 186 | attributes "Specification-Version": "3.0" 187 | attributes "Implementation-Title": project.group 188 | attributes "Implementation-Vendor": "alalwww" 189 | attributes "Implementation-Version": "${version}" 190 | attributes "Implementation-Timestamp": now(UTC).toString() 191 | attributes "CI-Build-Number": buildNumber 192 | attributes "Git-Commit-Hash": commitHash 193 | } 194 | } 195 | 196 | test { 197 | useJUnitPlatform() 198 | testLogging { 199 | events "passed", "skipped", "failed" 200 | } 201 | } 202 | 203 | task signJar { 204 | dependsOn "reobfJar" 205 | description = "signing jar file" 206 | 207 | def jarFile = jar.archivePath /* jar.archiveFile */ 208 | 209 | inputs.file jarFile 210 | outputs.file jarFile 211 | 212 | if (project.hasProperty('signing_alias') && project.hasProperty('signing_storepass')) { 213 | doLast { 214 | logger.quiet('signJar: ' + jarFile) 215 | ant.signjar( 216 | jar: jarFile, 217 | alias: project.signing_alias, 218 | storepass: project.signing_storepass, 219 | preservelastmodified: true 220 | ) 221 | } 222 | } else { 223 | doLast { 224 | logger.quiet('Skip signJar') 225 | } 226 | } 227 | } 228 | 229 | assemble.dependsOn "signJar" 230 | 231 | logger.quiet("---------------------------------\n mod id: {}\nversion: {}\n commit: {}\n build: {}\n---------------------------------", modid, version, commitHash, buildNumber) 232 | -------------------------------------------------------------------------------- /gradle/versions.gradle: -------------------------------------------------------------------------------- 1 | ant.condition(property: "os", value: "windows") { os(family: "windows") } 2 | ant.condition(property: "os", value: "unix") { os(family: "unix") } 3 | 4 | def out = new ByteArrayOutputStream() 5 | exec { 6 | def releaseTagPattern = "v*.*" 7 | def describeCmd = ["git", "describe", "--match", releaseTagPattern] 8 | switch (ant.properties.os) { 9 | case "windows": 10 | commandLine(["cmd", "/c"] + describeCmd) 11 | break 12 | case "unix": 13 | commandLine(describeCmd) 14 | break 15 | default: 16 | logger.error("unknown os") 17 | throw new RuntimeException("unknown os.(" + ant.properties + ")") 18 | } 19 | standardOutput = out 20 | } 21 | 22 | def (_, tag, count, gitHash) = (out.toString().trim() =~ /^v([^-]+)-(\d+)-(g[0-9a-f]+)$/)[0] 23 | 24 | project.ext.versionTag = tag 25 | project.ext.commitCount = count 26 | project.ext.commitHash = gitHash 27 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /lombok.config: -------------------------------------------------------------------------------- 1 | config.stopBubbling=true 2 | lombok.accessors.chain=false 3 | lombok.accessors.fluent=true 4 | lombok.log.apacheCommons.flagUsage=error 5 | lombok.log.flogger.flagUsage=error 6 | lombok.log.jbosslog.flagUsage=error 7 | lombok.log.javaUtilLogging.flagUsage=error 8 | lombok.log.log4j.flagUsage=error 9 | lombok.log.slf4j.flagUsage=error 10 | lombok.log.xslf4j.flagUsage=error 11 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "SpawnChecker" 2 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/SpawnCheckerCommands.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker; 21 | 22 | import java.util.Collection; 23 | import java.util.Collections; 24 | import java.util.Set; 25 | import java.util.concurrent.CompletableFuture; 26 | import java.util.stream.Stream; 27 | import javax.annotation.Nonnull; 28 | import com.mojang.brigadier.Command; 29 | import com.mojang.brigadier.CommandDispatcher; 30 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 31 | import com.mojang.brigadier.context.CommandContext; 32 | import com.mojang.brigadier.exceptions.CommandSyntaxException; 33 | import com.mojang.brigadier.suggestion.Suggestions; 34 | import com.mojang.brigadier.suggestion.SuggestionsBuilder; 35 | 36 | import net.minecraft.client.Minecraft; 37 | import net.minecraft.client.entity.player.ClientPlayerEntity; 38 | import net.minecraft.client.multiplayer.ClientSuggestionProvider; 39 | import net.minecraft.command.ISuggestionProvider; 40 | import net.minecraft.util.RegistryKey; 41 | import net.minecraft.util.ResourceLocation; 42 | import net.minecraft.util.Util; 43 | import net.minecraft.util.registry.DynamicRegistries; 44 | import net.minecraft.util.text.ITextComponent; 45 | import net.minecraft.util.text.TranslationTextComponent; 46 | import net.minecraft.world.World; 47 | 48 | import net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig; 49 | 50 | import lombok.NonNull; 51 | import lombok.RequiredArgsConstructor; 52 | import lombok.extern.log4j.Log4j2; 53 | import lombok.val; 54 | 55 | @Log4j2 56 | final class SpawnCheckerCommands { 57 | private static final int ALL = 0; 58 | private static final int INTEGRATED_SERVER_OP = 2; 59 | private static final int DEDICATED_SERVER_OP = 4; 60 | 61 | private final SpawnCheckerConfig config; 62 | 63 | private static final ITextComponent TO_ENABLE = 64 | new TranslationTextComponent("spawnchecker.command.message.toEnabled"); 65 | private static final ITextComponent TO_DISABLE = 66 | new TranslationTextComponent("spawnchecker.command.message.toDisabled"); 67 | 68 | private static final ITextComponent GUIDELINE_ON = 69 | new TranslationTextComponent("spawnchecker.command.message.guidelineOn"); 70 | private static final ITextComponent GUIDELINE_OFF = 71 | new TranslationTextComponent("spawnchecker.command.message.guidelineOff"); 72 | 73 | private final CommandDispatcher dispatcher = new CommandDispatcher<>(); 74 | 75 | SpawnCheckerCommands(@NonNull SpawnCheckerConfig config) { 76 | this.config = config; 77 | dispatcher.register(builder()); 78 | } 79 | 80 | private Source commandSource; 81 | 82 | @SuppressWarnings("unchecked") 83 | void registerTo(@NonNull ClientPlayerEntity player) { 84 | this.commandSource = new Source(player.connection.getSuggestionProvider()); 85 | player.connection.getCommandDispatcher() 86 | .register((LiteralArgumentBuilder) (LiteralArgumentBuilder) builder()); 87 | } 88 | 89 | boolean parse(String message) { 90 | val res = dispatcher.parse(message.substring(1), commandSource); 91 | log.debug("res: {}", res.getContext()); 92 | try { 93 | dispatcher.execute(res); 94 | return true; 95 | } catch (CommandSyntaxException e) { 96 | log.debug("Failed execute command.", e); 97 | return false; 98 | } 99 | } 100 | 101 | private LiteralArgumentBuilder builder() { 102 | return literal("spawnchecker") 103 | .then(literal("on").executes(ctx -> success(ctx, config::enable, TO_ENABLE))) 104 | .then(literal("off").executes(ctx -> success(ctx, config::disable, TO_DISABLE))) 105 | .then(literal("guideline") 106 | .then(literal("on").executes(ctx -> success(ctx, config.presetModeConfig()::guidelineOn, GUIDELINE_ON))) 107 | .then(literal("off").executes(ctx -> success(ctx, config.presetModeConfig()::guidelineOff, GUIDELINE_OFF))) 108 | ) 109 | ; 110 | } 111 | 112 | private int success(CommandContext ctx, Runnable runnable, ITextComponent message) { 113 | log.debug("do executes: {}, {}", ctx, message); 114 | runnable.run(); 115 | ctx.getSource().sendFeedback(message); 116 | return Command.SINGLE_SUCCESS; 117 | } 118 | 119 | private LiteralArgumentBuilder literal(String name) { 120 | return LiteralArgumentBuilder.literal(name); 121 | } 122 | 123 | @RequiredArgsConstructor 124 | private static final class Source implements ISuggestionProvider { 125 | private final ClientSuggestionProvider underlying; 126 | 127 | void sendFeedback(ITextComponent message) { 128 | if (Minecraft.getInstance().player != null) { 129 | Minecraft.getInstance().player.sendMessage(message, Util.DUMMY_UUID); 130 | } 131 | } 132 | 133 | @Override 134 | @Nonnull 135 | public Collection getPlayerNames() { 136 | return underlying.getPlayerNames(); 137 | } 138 | 139 | @Override 140 | public Collection getTargetedEntity() { 141 | return underlying.getTargetedEntity(); 142 | } 143 | 144 | @Override 145 | public Collection func_217294_q() { 146 | return underlying.func_217294_q(); 147 | } 148 | 149 | @Override 150 | public Collection func_217293_r() { 151 | return underlying.func_217293_r(); 152 | } 153 | 154 | @Override 155 | public DynamicRegistries func_241861_q() { 156 | return underlying.func_241861_q(); 157 | } 158 | 159 | @Override 160 | @Nonnull 161 | public Collection getTeamNames() { 162 | return underlying.getTeamNames(); 163 | } 164 | 165 | @Override 166 | @Nonnull 167 | public Collection getSoundResourceLocations() { 168 | return underlying.getSoundResourceLocations(); 169 | } 170 | 171 | @Override 172 | @Nonnull 173 | public Stream getRecipeResourceLocations() { 174 | return underlying.getRecipeResourceLocations(); 175 | } 176 | 177 | @Override 178 | @Nonnull 179 | public CompletableFuture getSuggestionsFromServer( 180 | @Nonnull CommandContext context, @Nonnull SuggestionsBuilder suggestionsBuilder) { 181 | return underlying.getSuggestionsFromServer(context, suggestionsBuilder); 182 | } 183 | 184 | @Override 185 | public Set> func_230390_p_() { 186 | return underlying.func_230390_p_(); 187 | } 188 | 189 | @Override 190 | public boolean hasPermissionLevel(int permissionLevel) { 191 | return underlying.hasPermissionLevel(permissionLevel); 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/SpawnCheckerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker; 21 | 22 | import java.util.Objects; 23 | import java.util.function.Supplier; 24 | 25 | import net.awairo.minecraft.spawnchecker.util.LazyCachedSupplier; 26 | 27 | import lombok.NonNull; 28 | 29 | @SuppressWarnings({"WeakerAccess", "unused"}) 30 | public final class SpawnCheckerException extends RuntimeException { 31 | 32 | private final LazyCachedSupplier message; 33 | 34 | public SpawnCheckerException(@NonNull String message) { 35 | this(LazyCachedSupplier.withCached(message)); 36 | } 37 | 38 | public SpawnCheckerException(@NonNull String format, @NonNull Object... args) { 39 | this(() -> String.format(format, (Object[]) args)); 40 | } 41 | 42 | public SpawnCheckerException(Throwable cause, @NonNull String format, @NonNull Object... args) { 43 | this(() -> String.format(format, (Object[]) args), cause); 44 | } 45 | 46 | public SpawnCheckerException(@NonNull Supplier message) { 47 | this(message, null); 48 | } 49 | 50 | public SpawnCheckerException(@NonNull Supplier message, Throwable cause) { 51 | this(LazyCachedSupplier.of(message), cause); 52 | } 53 | 54 | private SpawnCheckerException(LazyCachedSupplier message, Throwable cause) { 55 | this.message = message; 56 | if (Objects.nonNull(cause)) 57 | initCause(cause); 58 | } 59 | 60 | @Override 61 | public String getMessage() { 62 | return message.get(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/SpawnCheckerState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker; 21 | 22 | import java.util.Comparator; 23 | import java.util.Set; 24 | import java.util.concurrent.ConcurrentSkipListSet; 25 | import javax.annotation.Nullable; 26 | 27 | import net.minecraft.client.Minecraft; 28 | import net.minecraft.client.entity.player.ClientPlayerEntity; 29 | import net.minecraft.client.world.ClientWorld; 30 | import net.minecraft.util.Util; 31 | import net.minecraft.world.IWorld; 32 | 33 | import net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig; 34 | import net.awairo.minecraft.spawnchecker.hud.HudRendererImpl; 35 | import net.awairo.minecraft.spawnchecker.keybinding.KeyBindingState; 36 | import net.awairo.minecraft.spawnchecker.mode.ModeState; 37 | 38 | import lombok.AccessLevel; 39 | import lombok.Getter; 40 | import lombok.extern.log4j.Log4j2; 41 | import lombok.val; 42 | 43 | @Log4j2 44 | final class SpawnCheckerState { 45 | 46 | private final Set loadedWorldClient = new ConcurrentSkipListSet<>(Comparator.comparing(Object::toString)); 47 | 48 | private final Minecraft minecraft; 49 | 50 | @Getter 51 | private final SpawnCheckerConfig config; 52 | 53 | @Getter 54 | private final KeyBindingState keyBindingStates; 55 | @Getter 56 | private final ModeState modeState; 57 | 58 | private final HudRendererImpl hudRenderer; 59 | 60 | @Getter(AccessLevel.PACKAGE) 61 | private final SpawnCheckerCommands commands; 62 | 63 | private int tickCount = 0; 64 | 65 | @Nullable 66 | private ClientPlayerEntity player = null; 67 | 68 | SpawnCheckerState(Minecraft minecraft, SpawnCheckerConfig config) { 69 | this.minecraft = minecraft; 70 | this.config = config; 71 | hudRenderer = new HudRendererImpl(minecraft, config); 72 | modeState = new ModeState(minecraft, config, hudRenderer::setData); 73 | keyBindingStates = new KeyBindingState(modeState, config); 74 | commands = new SpawnCheckerCommands(config); 75 | } 76 | 77 | void initialize() { 78 | modeState.initialize(); 79 | } 80 | 81 | void loadWorld(IWorld world) { 82 | if (world instanceof ClientWorld) { 83 | loadedWorldClient.add(world); 84 | modeState.loadWorldClient((ClientWorld) world); 85 | } 86 | } 87 | 88 | void unloadWorld(IWorld world) { 89 | if (world instanceof ClientWorld) { 90 | modeState.unloadWorldClient((ClientWorld) world); 91 | loadedWorldClient.remove(world); 92 | } 93 | } 94 | 95 | void onTickStart() { 96 | if (player != minecraft.player) { 97 | player = minecraft.player; 98 | if (player != null) 99 | commands.registerTo(player); 100 | } 101 | } 102 | 103 | void onTickEnd() { 104 | val nowMilliTime = Util.milliTime(); 105 | tickCount++; 106 | keyBindingStates.onTick(nowMilliTime); 107 | modeState.onTick(tickCount, nowMilliTime); 108 | } 109 | 110 | boolean started() { 111 | return enabled() && !loadedWorldClient.isEmpty(); 112 | } 113 | 114 | private boolean enabled() { 115 | return config.enabled(); 116 | } 117 | 118 | void renderHud(float partialTicks) { 119 | hudRenderer.render(tickCount, partialTicks); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/WrappedProfiler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker; 21 | 22 | import net.minecraft.profiler.IProfiler; 23 | 24 | import lombok.RequiredArgsConstructor; 25 | 26 | @RequiredArgsConstructor 27 | final class WrappedProfiler { 28 | private final IProfiler underlying; 29 | 30 | private void start(final String subSection) { 31 | underlying.startSection(SpawnChecker.MOD_ID); 32 | underlying.startSection(subSection); 33 | } 34 | 35 | private void end() { 36 | underlying.endSection(); 37 | underlying.endSection(); 38 | } 39 | 40 | // FIXME セクションの見直し 41 | 42 | void startClientTick() { 43 | start("clientTick"); 44 | } 45 | 46 | void endClientTick() { 47 | end(); 48 | } 49 | 50 | void startRenderHud() { 51 | start("renderHud"); 52 | } 53 | 54 | void endRenderHud() { 55 | end(); 56 | } 57 | 58 | void startRenderMarker() { 59 | start("renderMarker"); 60 | } 61 | 62 | void endRenderMarker() { 63 | end(); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/Brightness.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import lombok.Getter; 23 | 24 | public enum Brightness { 25 | MINUS_5(-5), 26 | MINUS_4(-4), 27 | MINUS_3(-3), 28 | MINUS_2(-2), 29 | MINUS_1(-1), 30 | ZERO(0), 31 | PLUS_1(1), 32 | PLUS_2(2), 33 | PLUS_3(3), 34 | PLUS_4(4), 35 | PLUS_5(5); 36 | 37 | public static final Brightness DEFAULT = ZERO; 38 | 39 | @Getter 40 | private final int value; 41 | 42 | Brightness(int value) { 43 | this.value = value; 44 | } 45 | 46 | public Brightness next() { 47 | switch (this) { 48 | case MINUS_5: 49 | return MINUS_4; 50 | case MINUS_4: 51 | return MINUS_3; 52 | case MINUS_3: 53 | return MINUS_2; 54 | case MINUS_2: 55 | return MINUS_1; 56 | case MINUS_1: 57 | return ZERO; 58 | case ZERO: 59 | return PLUS_1; 60 | case PLUS_1: 61 | return PLUS_2; 62 | case PLUS_2: 63 | return PLUS_3; 64 | case PLUS_3: 65 | return PLUS_4; 66 | case PLUS_4: 67 | case PLUS_5: 68 | return PLUS_5; 69 | default: 70 | throw new InternalError("Unreachable code"); 71 | } 72 | } 73 | 74 | public Brightness prev() { 75 | switch (this) { 76 | case MINUS_5: 77 | case MINUS_4: 78 | return MINUS_5; 79 | case MINUS_3: 80 | return MINUS_4; 81 | case MINUS_2: 82 | return MINUS_3; 83 | case MINUS_1: 84 | return MINUS_2; 85 | case ZERO: 86 | return MINUS_1; 87 | case PLUS_1: 88 | return ZERO; 89 | case PLUS_2: 90 | return PLUS_1; 91 | case PLUS_3: 92 | return PLUS_2; 93 | case PLUS_4: 94 | return PLUS_3; 95 | case PLUS_5: 96 | return PLUS_4; 97 | default: 98 | throw new InternalError("Unreachable code"); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/HudData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import com.mojang.blaze3d.matrix.MatrixStack; 23 | import com.mojang.blaze3d.platform.GlStateManager.DestFactor; 24 | import com.mojang.blaze3d.platform.GlStateManager.SourceFactor; 25 | import com.mojang.blaze3d.systems.RenderSystem; 26 | 27 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 28 | import net.minecraft.util.ResourceLocation; 29 | import net.minecraft.util.text.ITextComponent; 30 | 31 | import lombok.Getter; 32 | import lombok.NonNull; 33 | import lombok.RequiredArgsConstructor; 34 | import lombok.Value; 35 | import lombok.extern.log4j.Log4j2; 36 | import lombok.val; 37 | 38 | public interface HudData { 39 | 40 | Visibility draw(HudRenderer renderer, long elapsedMillis); 41 | 42 | enum Visibility {SHOW, HIDE} 43 | 44 | @Log4j2 45 | @RequiredArgsConstructor 46 | @Getter 47 | @SuppressWarnings("WeakerAccess") 48 | class Simple implements HudData { 49 | protected static final Color BASE_COLOR = Color.of(255, 255, 255); 50 | protected static final float TEXT_X = 20f; 51 | protected static final float TEXT_Y = 5f; 52 | protected static final double ICON_SIZE = 16d; 53 | 54 | @NonNull 55 | private final ITextComponent text; 56 | @NonNull 57 | private final ResourceLocation icon; 58 | @NonNull 59 | private final ShowDuration showDuration; 60 | @NonNull 61 | private final Color baseColor; 62 | 63 | public Simple(ITextComponent text, ResourceLocation icon, ShowDuration showDuration) { 64 | this(text, icon, showDuration, BASE_COLOR); 65 | } 66 | 67 | @Override 68 | public Visibility draw(@NonNull HudRenderer renderer, long elapsedMillis) { 69 | if (showDuration.isLessThan(elapsedMillis)) { 70 | val stack = new MatrixStack(); 71 | val color = baseColor.withAlpha(computeAlpha(elapsedMillis)); 72 | if (!color.isTransparent()) { 73 | setUpGlState(); 74 | drawIcon(stack, icon, renderer, color); 75 | drawText(stack, text, renderer, color); 76 | } 77 | if (elapsedMillis == 0) { 78 | log.debug( 79 | "Show HudData.(text={}, icon={}, showDuration={}, baseColor={}, elapsedMillis={}, color={})", 80 | text, icon, showDuration, baseColor, elapsedMillis, color 81 | ); 82 | } 83 | return Visibility.SHOW; 84 | } 85 | log.debug( 86 | "Hide HudData.(text={}, icon={}, showDuration={}, baseColor={}, elapsedMillis={})", 87 | text, icon, showDuration, baseColor, elapsedMillis 88 | ); 89 | return Visibility.HIDE; 90 | } 91 | 92 | protected float computeAlpha(long elapsedMillis) { 93 | val rate = showDuration.progressRate(elapsedMillis); 94 | if (rate <= 0.05f) 95 | return Math.min(rate * 20, 1f); 96 | if (rate >= 0.9f) 97 | return Math.min((1 - rate) * 10, 1f); 98 | return 1f; 99 | } 100 | 101 | protected void setUpGlState() { 102 | RenderSystem.enableTexture(); 103 | RenderSystem.enableTexture(); 104 | RenderSystem.enableBlend(); 105 | RenderSystem.blendFuncSeparate( 106 | SourceFactor.SRC_ALPHA.param, DestFactor.ONE_MINUS_SRC_ALPHA.param, 107 | SourceFactor.ONE.param, DestFactor.ZERO.param 108 | ); 109 | } 110 | 111 | @SuppressWarnings("Duplicates") 112 | protected void drawIcon(MatrixStack stack, ResourceLocation icon, HudRenderer renderer, Color color) { 113 | final double xMin, yMin, xMax, yMax, z; 114 | final float uMin, uMax, vMin, vMax; 115 | xMin = yMin = z = 0d; 116 | xMax = yMax = ICON_SIZE; 117 | uMin = vMin = 0f; 118 | uMax = vMax = 1f; 119 | renderer.bindTexture(icon); 120 | renderer.beginQuads(DefaultVertexFormats.POSITION_COLOR_TEX); 121 | renderer.addVertex(xMin, yMin, z, uMin, vMin, color); 122 | renderer.addVertex(xMin, yMax, z, uMin, vMax, color); 123 | renderer.addVertex(xMax, yMax, z, uMax, vMax, color); 124 | renderer.addVertex(xMax, yMin, z, uMax, vMin, color); 125 | renderer.draw(); 126 | } 127 | 128 | protected void drawText(MatrixStack stack, ITextComponent text, HudRenderer renderer, Color color) { 129 | if (isTransparentText(color)) 130 | return; 131 | 132 | renderer.fontRenderer().drawStringWithShadow(stack, text.getString(), Simple.TEXT_X, Simple.TEXT_Y, color.toInt()); 133 | } 134 | 135 | // alpha = 3 以下だと不透明で描画されたためスキップした 136 | protected boolean isTransparentText(Color color) { 137 | return color.intAlpha() < 4; 138 | } 139 | } 140 | 141 | @SuppressWarnings("WeakerAccess") 142 | final class ModeActivated extends Simple { 143 | public ModeActivated(@NonNull Mode mode, @NonNull ShowDuration showDuration) { 144 | super(mode.name().textComponent(), mode.icon(), showDuration); 145 | } 146 | } 147 | 148 | @SuppressWarnings("WeakerAccess") 149 | @Value 150 | final class ShowDuration { 151 | public static final long MIN_VALUE = 0L; 152 | public static final long MAX_VALUE = 10_000L; 153 | public static final ShowDuration DEFAULT = new ShowDuration(5000L); 154 | 155 | public ShowDuration(long milliSeconds) { 156 | if (milliSeconds < MIN_VALUE || milliSeconds > MAX_VALUE) 157 | throw new IllegalArgumentException("Out of range. (" + milliSeconds + ")"); 158 | 159 | this.milliSeconds = milliSeconds; 160 | } 161 | 162 | private final long milliSeconds; 163 | 164 | public boolean isLessThan(long elapsedMillis) { 165 | return elapsedMillis < milliSeconds; 166 | } 167 | 168 | public float progressRate(long elapsedMillis) { 169 | return Math.min((float) elapsedMillis / (float) milliSeconds, 1f); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/HudRenderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import net.minecraft.client.gui.FontRenderer; 23 | 24 | public interface HudRenderer extends Renderer { 25 | int tickCount(); 26 | FontRenderer fontRenderer(); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/Marker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | public interface Marker { 23 | void draw(MarkerRenderer renderer); 24 | 25 | @Override 26 | int hashCode(); 27 | @Override 28 | boolean equals(Object obj); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/MarkerRenderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import net.minecraft.client.renderer.WorldRenderer; 23 | import net.minecraft.client.renderer.entity.EntityRendererManager; 24 | import net.minecraft.util.math.vector.Quaternion; 25 | 26 | public interface MarkerRenderer extends Renderer { 27 | EntityRendererManager renderManager(); 28 | WorldRenderer worldRenderer(); 29 | 30 | void push(); 31 | void pop(); 32 | void translate(double x, double y, double z); 33 | void scale(float m00, float m11, float m22); 34 | void rotate(Quaternion quaternion); 35 | void clear(); 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/Mode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import java.util.Comparator; 23 | import java.util.function.Consumer; 24 | import java.util.stream.Stream; 25 | import javax.annotation.Nonnull; 26 | 27 | import net.minecraft.client.world.ClientWorld; 28 | import net.minecraft.util.ResourceLocation; 29 | import net.minecraft.util.text.ITextComponent; 30 | import net.minecraft.util.text.TranslationTextComponent; 31 | 32 | import lombok.NonNull; 33 | import lombok.Value; 34 | 35 | public interface Mode { 36 | Name name(); 37 | ResourceLocation icon(); 38 | default Priority priority() { return Priority.DEFAULT; } 39 | 40 | boolean isActive(); 41 | default boolean isInactive() { return !isActive(); } 42 | 43 | default void proceedNextOption(State modeState) { } 44 | default void proceedPrevOption(State modeState) { } 45 | 46 | default void activate(State modeState) { 47 | modeState.hudDataRegistry().accept(new HudData.ModeActivated(this, modeState.hudShowDuration())); 48 | } 49 | default void deactivate(State modeState) { } 50 | 51 | Stream update(State modeState, PlayerPos playerPos); 52 | 53 | default boolean isConditional() { return this instanceof Conditional; } 54 | default boolean isSelectable() { return this instanceof Selectable; } 55 | default Conditional asConditional() { return (Conditional) this; } 56 | default Selectable asSelectable() { return (Selectable) this; } 57 | 58 | interface Conditional extends Mode, Comparable { 59 | boolean canActivate(PlayerPos playerPos, Mode.State state); 60 | boolean canContinue(PlayerPos playerPos, Mode.State state); 61 | 62 | @Override 63 | default int compareTo(@Nonnull Conditional o) { 64 | return COMPARATOR.compare(this, o); 65 | } 66 | 67 | Comparator COMPARATOR = Comparator 68 | .comparing(Conditional::priority) 69 | .thenComparing(Conditional::name) 70 | .thenComparingInt(Object::hashCode); 71 | } 72 | 73 | interface Selectable extends Mode, Comparable { 74 | 75 | @Override 76 | default int compareTo(@Nonnull Selectable o) { 77 | return COMPARATOR.compare(this, o); 78 | } 79 | 80 | Comparator COMPARATOR = Comparator 81 | .comparing(Selectable::priority) 82 | .thenComparing(Selectable::name) 83 | .thenComparingInt(Object::hashCode); 84 | } 85 | 86 | interface State { 87 | ClientWorld worldClient(); 88 | int tickCount(); 89 | ScanRange.Horizontal horizontalRange(); 90 | ScanRange.Vertical verticalRange(); 91 | Brightness brightness(); 92 | HudData.ShowDuration hudShowDuration(); 93 | Consumer hudDataRegistry(); 94 | } 95 | 96 | final class Name implements Comparable { 97 | 98 | private final TranslationTextComponent textComponent; 99 | 100 | public ITextComponent textComponent() { 101 | return textComponent; 102 | } 103 | 104 | public String translationKey() { 105 | return textComponent.getKey(); 106 | } 107 | 108 | public Name(@NonNull String translationKey) { 109 | this.textComponent = new TranslationTextComponent(translationKey); 110 | } 111 | 112 | @Override 113 | public int compareTo(@NonNull Name o) { 114 | return textComponent.getKey().compareTo(o.textComponent.getKey()); 115 | } 116 | 117 | @Override 118 | public int hashCode() { 119 | return textComponent.getKey().hashCode(); 120 | } 121 | 122 | @Override 123 | public boolean equals(Object obj) { 124 | return obj == this || 125 | obj instanceof Name && ((Name) obj).textComponent.getKey().equals(textComponent.getKey()); 126 | } 127 | 128 | @Override 129 | public String toString() { 130 | return "Mode.Name(translationKey=" + textComponent.getKey() + ")"; 131 | } 132 | } 133 | 134 | @Value 135 | final class Priority implements Comparable { 136 | public static final int MIN = 0; 137 | public static final Priority DEFAULT = new Priority(0); 138 | 139 | private final int value; 140 | 141 | public Priority(int value) { 142 | if (value < MIN) 143 | throw new IllegalArgumentException("priority must be greater than or equal zero. (" + value + ")"); 144 | this.value = value; 145 | } 146 | 147 | @Override 148 | public int compareTo(@NonNull Priority o) { 149 | // 数値の降順 150 | return Integer.compare(o.value, value); 151 | } 152 | } 153 | } 154 | 155 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/PlayerPos.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import java.util.Optional; 23 | import javax.annotation.Nullable; 24 | import com.google.common.annotations.VisibleForTesting; 25 | import com.google.common.base.MoreObjects; 26 | 27 | import net.minecraft.client.Minecraft; 28 | import net.minecraft.entity.player.PlayerEntity; 29 | import net.minecraft.util.math.BlockPos; 30 | import net.minecraft.util.math.vector.Vector3d; 31 | 32 | import lombok.Getter; 33 | import lombok.NonNull; 34 | 35 | public class PlayerPos { 36 | 37 | public static Optional of(@Nullable Minecraft mayBeMCInstance) { 38 | return Optional.ofNullable(mayBeMCInstance) 39 | .map(mc -> mc.player) 40 | .map(PlayerEntity::getPositionVec) 41 | .map(PlayerPos::new); 42 | } 43 | 44 | @NonNull 45 | private final Vector3d underlying; 46 | 47 | @Getter(lazy = true) 48 | private final BlockPos blockPos = new BlockPos(underlying.x, underlying.y, underlying.z); 49 | 50 | public Vector3d get() { 51 | return underlying; 52 | } 53 | 54 | @VisibleForTesting 55 | PlayerPos(@NonNull Vector3d playerPos) { 56 | this.underlying = playerPos; 57 | } 58 | 59 | private transient int hashCode; 60 | 61 | @Override 62 | public int hashCode() { 63 | int h = hashCode; 64 | if (h == 0) 65 | h = hashCode = underlying.hashCode(); 66 | return h; 67 | } 68 | 69 | @Override 70 | public boolean equals(Object obj) { 71 | return obj == this || obj instanceof PlayerPos && ((PlayerPos) obj).underlying.equals(underlying); 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return MoreObjects.toStringHelper(this) 77 | .add("x", underlying.x) 78 | .add("y", underlying.y) 79 | .add("z", underlying.z) 80 | .toString(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/Renderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import org.lwjgl.opengl.GL11; 23 | 24 | import net.minecraft.client.renderer.BufferBuilder; 25 | import net.minecraft.client.renderer.Tessellator; 26 | import net.minecraft.client.renderer.vertex.VertexFormat; 27 | import net.minecraft.util.ResourceLocation; 28 | 29 | public interface Renderer { 30 | void bindTexture(ResourceLocation texture); 31 | 32 | default Tessellator tessellator() { 33 | return Tessellator.getInstance(); 34 | } 35 | 36 | default BufferBuilder buffer() { 37 | return tessellator().getBuffer(); 38 | } 39 | 40 | default void beginPoints(VertexFormat format) { 41 | begin(GL11.GL_POINT, format); 42 | } 43 | 44 | default void beginLines(VertexFormat format) { 45 | begin(GL11.GL_LINES, format); 46 | } 47 | 48 | default void beginLineLoop(VertexFormat format) { 49 | begin(GL11.GL_LINE_LOOP, format); 50 | } 51 | 52 | default void beginTriangles(VertexFormat format) { 53 | begin(GL11.GL_TRIANGLES, format); 54 | } 55 | 56 | default void beginTriangleStrip(VertexFormat format) { 57 | begin(GL11.GL_TRIANGLE_STRIP, format); 58 | } 59 | 60 | default void beginTriangleFan(VertexFormat format) { 61 | begin(GL11.GL_TRIANGLE_FAN, format); 62 | } 63 | 64 | default void beginQuads(VertexFormat format) { 65 | begin(GL11.GL_QUADS, format); 66 | } 67 | 68 | default void beginQuadStrip(VertexFormat format) { 69 | begin(GL11.GL_QUAD_STRIP, format); 70 | } 71 | 72 | default void beginPolygon(VertexFormat format) { 73 | begin(GL11.GL_POLYGON, format); 74 | } 75 | 76 | default void begin(int glMode, VertexFormat format) { 77 | buffer().begin(glMode, format); 78 | } 79 | 80 | void addVertex(double x, double y, double z); 81 | 82 | void addVertex(double x, double y, double z, float u, float v); 83 | 84 | void addVertex(double x, double y, double z, Color color); 85 | 86 | void addVertex(double x, double y, double z, float u, float v, Color color); 87 | 88 | default void draw() { 89 | tessellator().draw(); 90 | } 91 | 92 | float partialTicks(); 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/ScanRange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import java.util.Comparator; 23 | import java.util.Map; 24 | import java.util.function.IntFunction; 25 | import java.util.function.UnaryOperator; 26 | import java.util.stream.Collectors; 27 | import java.util.stream.IntStream; 28 | import javax.annotation.Nonnull; 29 | 30 | import lombok.Getter; 31 | 32 | public abstract class ScanRange> implements Comparable { 33 | private static final int MIN_VALUE = 3; 34 | private static final int MAX_VALUE = 32; 35 | private static final int DEFAULT_VALUE = 12; 36 | 37 | @Getter 38 | private final int value; 39 | 40 | private ScanRange(int value) { 41 | if (value < MIN_VALUE || value > MAX_VALUE) throw new IllegalArgumentException(Integer.toString(value)); 42 | this.value = value; 43 | } 44 | 45 | public abstract T next(); 46 | 47 | public abstract T prev(); 48 | 49 | @Override 50 | public int compareTo(@Nonnull T o) { 51 | return COMPARATOR.compare(this, o); 52 | } 53 | 54 | @Override 55 | public int hashCode() { 56 | return value; 57 | } 58 | 59 | @Override 60 | public boolean equals(Object obj) { 61 | return obj == this || getClass().isInstance(obj) && ((ScanRange) obj).value == value; 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return "ScanRange." + classSimpleName() + "(" + value + ")"; 67 | } 68 | 69 | int nextValue() { 70 | return Math.min(value + 1, MAX_VALUE); 71 | } 72 | 73 | int prevValue() { 74 | return Math.max(value - 1, MIN_VALUE); 75 | } 76 | 77 | private String classSimpleName() { 78 | return getClass().getSimpleName(); 79 | } 80 | 81 | private static final Comparator> COMPARATOR = 82 | Comparator., String>comparing(ScanRange::classSimpleName) 83 | .thenComparingInt(ScanRange::value); 84 | 85 | private static > Map createValues(IntFunction constructor) { 86 | return IntStream 87 | .iterate(MIN_VALUE, i -> ++i) 88 | .limit(MAX_VALUE - MIN_VALUE + 1) 89 | .mapToObj(constructor) 90 | .collect(Collectors.toMap(ScanRange::value, UnaryOperator.identity())); 91 | } 92 | 93 | public static final class Horizontal extends ScanRange { 94 | public static final int MIN_VALUE = ScanRange.MIN_VALUE; 95 | public static final int MAX_VALUE = ScanRange.MAX_VALUE; 96 | 97 | private static final Map VALUES = createValues(Horizontal::new); 98 | public static final Horizontal DEFAULT = of(DEFAULT_VALUE); 99 | 100 | public static Horizontal of(int value) { 101 | return VALUES.get(value); 102 | } 103 | 104 | private Horizontal(int value) { 105 | super(value); 106 | } 107 | 108 | @Override 109 | public Horizontal next() { 110 | return of(nextValue()); 111 | } 112 | 113 | @Override 114 | public Horizontal prev() { 115 | return of(prevValue()); 116 | } 117 | } 118 | 119 | public static final class Vertical extends ScanRange { 120 | public static final int MIN_VALUE = ScanRange.MIN_VALUE; 121 | public static final int MAX_VALUE = ScanRange.MAX_VALUE; 122 | 123 | private static final Map VALUES = createValues(Vertical::new); 124 | public static final Vertical DEFAULT = of(DEFAULT_VALUE); 125 | 126 | public static Vertical of(int value) { 127 | return VALUES.get(value); 128 | } 129 | 130 | private Vertical(int value) { 131 | super(value); 132 | } 133 | 134 | @Override 135 | public Vertical next() { 136 | return of(nextValue()); 137 | } 138 | 139 | @Override 140 | public Vertical prev() { 141 | return of(prevValue()); 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/api/UsingHands.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.api; 21 | 22 | import lombok.Getter; 23 | import lombok.RequiredArgsConstructor; 24 | 25 | @Getter 26 | @RequiredArgsConstructor 27 | public enum UsingHands { 28 | RIGHT(true, false), 29 | LEFT(false, true), 30 | BOTH(true, true); 31 | 32 | public static final UsingHands DEFAULT = BOTH; 33 | 34 | private final boolean useRightHand; 35 | private final boolean useLeftHand; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/config/ConfigHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.config; 21 | 22 | import net.minecraftforge.fml.config.ModConfig; 23 | 24 | import lombok.RequiredArgsConstructor; 25 | 26 | @RequiredArgsConstructor 27 | public final class ConfigHolder { 28 | 29 | private final SpawnCheckerConfig config; 30 | 31 | public void loadConfig(ModConfig modConfig) { 32 | config.underlying(modConfig.getConfigData()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/config/HudConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.config; 21 | 22 | import net.minecraftforge.common.ForgeConfigSpec; 23 | import net.minecraftforge.common.ForgeConfigSpec.IntValue; 24 | import net.minecraftforge.common.ForgeConfigSpec.LongValue; 25 | 26 | import net.awairo.minecraft.spawnchecker.api.HudData.ShowDuration; 27 | import net.awairo.minecraft.spawnchecker.hud.HudOffset; 28 | 29 | import lombok.NonNull; 30 | import lombok.var; 31 | 32 | import static net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig.*; 33 | 34 | public final class HudConfig { 35 | private static final String PATH = "hud"; 36 | 37 | private final Updater updater; 38 | 39 | HudConfig(@NonNull Updater updater, @NonNull ForgeConfigSpec.Builder builder) { 40 | this.updater = updater; 41 | 42 | builder.comment(" HUD configurations"); 43 | builder.push(PATH); 44 | 45 | showDurationValue = builder 46 | .comment( 47 | " Hud show duration. (ms)", 48 | defaultMinMax(ShowDuration.DEFAULT.milliSeconds(), ShowDuration.MIN_VALUE, ShowDuration.MAX_VALUE) 49 | ) 50 | .translation( 51 | configGuiKey(PATH, "showDuration") 52 | ) 53 | .defineInRange( 54 | "showDuration", 55 | ShowDuration.DEFAULT::milliSeconds, ShowDuration.MIN_VALUE, ShowDuration.MAX_VALUE 56 | ); 57 | 58 | xOffsetValue = builder 59 | .comment( 60 | " HUD position x topOffset.", 61 | defaultMinMax(HudOffset.DEFAULT_VALUE, HudOffset.MIN_VALUE, HudOffset.MAX_VALUE) 62 | ) 63 | .translation( 64 | configGuiKey(PATH, "xOffset") 65 | ) 66 | .defineInRange( 67 | "xOffset", 68 | HudOffset.X.DEFAULT::value, HudOffset.MIN_VALUE, HudOffset.MAX_VALUE 69 | ); 70 | 71 | yOffsetValue = builder 72 | .comment( 73 | " HUD position y topOffset.", 74 | defaultMinMax(HudOffset.Y.DEFAULT.value(), HudOffset.MIN_VALUE, HudOffset.MAX_VALUE) 75 | ) 76 | .translation( 77 | configGuiKey(PATH, "topOffset") 78 | ) 79 | .defineInRange( 80 | "topOffset", 81 | HudOffset.Y.DEFAULT::value, HudOffset.MIN_VALUE, HudOffset.MAX_VALUE 82 | ); 83 | } 84 | 85 | // region [hud] HudShowDuration 86 | 87 | private final LongValue showDurationValue; 88 | private ShowDuration showDurationCache = null; 89 | 90 | public ShowDuration showDuration() { 91 | var cache = showDurationCache; 92 | if (cache == null || cache.milliSeconds() != showDurationValue.get()) 93 | cache = showDurationCache = new ShowDuration(showDurationValue.get()); 94 | return cache; 95 | } 96 | 97 | // endregion 98 | 99 | private final IntValue xOffsetValue; 100 | private HudOffset.X xOffsetCache; 101 | 102 | public HudOffset.X xOffset() { 103 | var cache = xOffsetCache; 104 | if (cache == null || cache.value() != xOffsetValue.get()) 105 | cache = xOffsetCache = HudOffset.xOf(xOffsetValue.get()); 106 | return cache; 107 | } 108 | 109 | private final IntValue yOffsetValue; 110 | private HudOffset.Y yOffsetCache; 111 | 112 | public HudOffset.Y yOffset() { 113 | var cache = yOffsetCache; 114 | if (cache == null || cache.value() != yOffsetValue.get()) 115 | cache = yOffsetCache = HudOffset.yOf(yOffsetValue.get()); 116 | return cache; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/config/KeyConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.config; 21 | 22 | import net.minecraftforge.common.ForgeConfigSpec; 23 | import net.minecraftforge.common.ForgeConfigSpec.IntValue; 24 | 25 | import net.awairo.minecraft.spawnchecker.keybinding.RepeatDelay; 26 | import net.awairo.minecraft.spawnchecker.keybinding.RepeatRate; 27 | 28 | import lombok.NonNull; 29 | import lombok.var; 30 | 31 | import static net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig.*; 32 | 33 | public final class KeyConfig { 34 | private static final String PATH = "key"; 35 | 36 | private final Updater updater; 37 | 38 | KeyConfig(@NonNull Updater updater, @NonNull ForgeConfigSpec.Builder builder) { 39 | this.updater = updater; 40 | 41 | builder.comment(" Key binding configurations."); 42 | builder.push(PATH); 43 | 44 | repeatDelayValue = builder 45 | .comment( 46 | " Key repeat delay. (ms)", 47 | defaultMinMax(RepeatDelay.DEFAULT.milliSeconds(), RepeatDelay.MIN, RepeatDelay.MAX) 48 | ) 49 | .translation( 50 | configGuiKey(PATH, "repeatDelay") 51 | ) 52 | .defineInRange( 53 | "repeatDelay", 54 | RepeatDelay.DEFAULT::milliSeconds, RepeatDelay.MIN, RepeatDelay.MAX 55 | ); 56 | 57 | repeatRateValue = builder 58 | .comment( 59 | " Key repeat rate. (ms)", 60 | defaultMinMax(RepeatRate.DEFAULT.milliSeconds(), RepeatRate.MIN, RepeatRate.MAX) 61 | ) 62 | .translation( 63 | configGuiKey(PATH, "repeatRate") 64 | ) 65 | .defineInRange( 66 | "repeatRate", 67 | RepeatRate.DEFAULT::milliSeconds, RepeatRate.MIN, RepeatRate.MAX 68 | ); 69 | 70 | builder.pop(); 71 | } 72 | 73 | // region [key binding] RepeatDelay 74 | 75 | private final IntValue repeatDelayValue; 76 | private RepeatDelay repeatDelayCache; 77 | 78 | public RepeatDelay repeatDelay() { 79 | var cache = repeatDelayCache; 80 | if (cache == null || cache.milliSeconds() != repeatDelayValue.get()) 81 | repeatDelayCache = cache = RepeatDelay.ofMilliSeconds(repeatDelayValue.get()); 82 | return cache; 83 | } 84 | 85 | // endregion 86 | 87 | // region [key binding] RepeatRate 88 | 89 | private final IntValue repeatRateValue; 90 | private RepeatRate repeatRateCache; 91 | 92 | public RepeatRate repeatRate() { 93 | var cache = repeatRateCache; 94 | if (cache == null || cache.milliSeconds() != repeatRateValue.get()) 95 | repeatRateCache = cache = RepeatRate.ofMilliSeconds(repeatRateValue.get()); 96 | return cache; 97 | } 98 | 99 | // endregion 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/config/ModeConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.config; 21 | 22 | import net.minecraftforge.common.ForgeConfigSpec; 23 | import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; 24 | import net.minecraftforge.common.ForgeConfigSpec.EnumValue; 25 | import net.minecraftforge.common.ForgeConfigSpec.IntValue; 26 | 27 | import net.awairo.minecraft.spawnchecker.api.Brightness; 28 | import net.awairo.minecraft.spawnchecker.api.Mode; 29 | import net.awairo.minecraft.spawnchecker.api.ScanRange.Horizontal; 30 | import net.awairo.minecraft.spawnchecker.api.ScanRange.Vertical; 31 | import net.awairo.minecraft.spawnchecker.mode.SpawnCheckMode; 32 | import net.awairo.minecraft.spawnchecker.mode.UpdateTimer.Interval; 33 | 34 | import lombok.NonNull; 35 | import lombok.var; 36 | 37 | import static net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig.*; 38 | 39 | public final class ModeConfig { 40 | private static final String PATH = "mode"; 41 | 42 | private final Updater updater; 43 | 44 | ModeConfig(@NonNull Updater updater, @NonNull ForgeConfigSpec.Builder builder) { 45 | this.updater = updater; 46 | 47 | builder.push(PATH); 48 | 49 | selectedModeNameValue = builder 50 | .comment( 51 | " Last selected mode id." 52 | ) 53 | .translation( 54 | configGuiKey(PATH, "selectedMode") 55 | ) 56 | .define( 57 | "selectedMode", 58 | SpawnCheckMode.TRANSLATION_KEY 59 | ); 60 | 61 | checkIntervalValue = builder 62 | .comment( 63 | " Minimum scan interval. (ms)", 64 | defaultMinMax(Interval.DEFAULT.milliSeconds(), Interval.MIN_VALUE, Interval.MAX_VALUE) 65 | ) 66 | .translation( 67 | configGuiKey(PATH, "scan.interval") 68 | ) 69 | .defineInRange( 70 | "scan.interval", 71 | Interval.DEFAULT::milliSeconds, Interval.MIN_VALUE, Interval.MAX_VALUE 72 | ); 73 | 74 | horizontalRangeValue = builder 75 | .comment( 76 | " Horizontal range of scan.", 77 | defaultMinMax(Horizontal.DEFAULT.value(), Horizontal.MIN_VALUE, Horizontal.MAX_VALUE) 78 | ) 79 | .translation( 80 | configGuiKey(PATH, "scan.horizontalRange") 81 | ) 82 | .defineInRange( 83 | "scan.horizontalRange", 84 | Horizontal.DEFAULT::value, Horizontal.MIN_VALUE, Horizontal.MAX_VALUE 85 | ); 86 | 87 | verticalRangeValue = builder 88 | .comment( 89 | " Vertical range of scan.", 90 | defaultMinMax(Vertical.DEFAULT.value(), Vertical.MIN_VALUE, Vertical.MAX_VALUE) 91 | ) 92 | .translation( 93 | configGuiKey(PATH, "scan.verticalRange") 94 | ) 95 | .defineInRange( 96 | "scan.verticalRange", 97 | Vertical.DEFAULT::value, Vertical.MIN_VALUE, Vertical.MAX_VALUE 98 | ); 99 | 100 | brightnessValue = builder 101 | .comment( 102 | " Marker brightness.", 103 | defaultValue(Brightness.DEFAULT), 104 | allowValues(Brightness.values()) 105 | ) 106 | .translation( 107 | configGuiKey(PATH, "marker.brightness") 108 | ) 109 | .defineEnum( 110 | "marker.brightness", 111 | Brightness.DEFAULT 112 | ); 113 | 114 | builder.pop(); 115 | } 116 | 117 | // region Selected mode name 118 | 119 | private final ConfigValue selectedModeNameValue; 120 | 121 | public Mode.Name selectedModeName() { 122 | return new Mode.Name(selectedModeNameValue.get()); 123 | } 124 | 125 | public UpdateResult selectedModeName(Mode.Name name) { 126 | return updater.update(selectedModeNameValue, name.translationKey()); 127 | } 128 | 129 | // endregion 130 | 131 | // region Check interval 132 | 133 | private final IntValue checkIntervalValue; 134 | private Interval checkIntervalValueCache; 135 | 136 | public Interval checkInterval() { 137 | var cache = checkIntervalValueCache; 138 | if (cache == null || cache.milliSeconds() != checkIntervalValue.get()) 139 | checkIntervalValueCache = cache = Interval.ofMilliSeconds(checkIntervalValue.get()); 140 | return cache; 141 | } 142 | 143 | // endregion 144 | 145 | // region Horizontal scan ranges 146 | 147 | private final IntValue horizontalRangeValue; 148 | 149 | public Horizontal horizontalRange() { 150 | return Horizontal.of(horizontalRangeValue.get()); 151 | } 152 | 153 | public UpdateResult horizontalRange(Horizontal newValue) { 154 | return updater.update(horizontalRangeValue, newValue.value()); 155 | } 156 | 157 | // endregion 158 | 159 | // region Vertical scan ranges 160 | 161 | private final IntValue verticalRangeValue; 162 | 163 | public Vertical verticalRange() { 164 | return Vertical.of(verticalRangeValue.get()); 165 | } 166 | 167 | public UpdateResult verticalRange(Vertical newValue) { 168 | return updater.update(verticalRangeValue, newValue.value()); 169 | } 170 | 171 | // endregion 172 | 173 | // region Brightness 174 | 175 | private final EnumValue brightnessValue; 176 | 177 | public Brightness brightness() { 178 | return brightnessValue.get(); 179 | } 180 | 181 | public UpdateResult brightness(Brightness newValue) { 182 | return updater.update(brightnessValue, newValue); 183 | } 184 | 185 | // endregion 186 | 187 | } 188 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/config/PresetModeConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.config; 21 | 22 | import net.minecraftforge.common.ForgeConfigSpec; 23 | import net.minecraftforge.common.ForgeConfigSpec.BooleanValue; 24 | 25 | import lombok.NonNull; 26 | 27 | import static net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig.*; 28 | 29 | public final class PresetModeConfig { 30 | private static final String PATH = "preset_mode"; 31 | 32 | private final Updater updater; 33 | 34 | PresetModeConfig(@NonNull Updater updater, @NonNull ForgeConfigSpec.Builder builder) { 35 | this.updater = updater; 36 | 37 | builder.comment(" Preset mode configurations"); 38 | builder.push(PATH); 39 | 40 | drawGuideline = builder 41 | .comment( 42 | " True is drawing spawn check marker guidelines." 43 | ) 44 | .translation( 45 | configGuiKey(PATH, "drawGuideline") 46 | ) 47 | .define( 48 | "drawGuideline", 49 | false 50 | ); 51 | } 52 | 53 | // region [preset_mode] guideline 54 | 55 | private final BooleanValue drawGuideline; 56 | 57 | public boolean drawGuideline() { 58 | return drawGuideline.get(); 59 | } 60 | 61 | public UpdateResult guidelineOn() { 62 | return updater.update(drawGuideline, true); 63 | } 64 | 65 | public UpdateResult guidelineOff() { 66 | return updater.update(drawGuideline, false); 67 | } 68 | 69 | // endregion 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/config/SpawnCheckerConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.config; 21 | 22 | import java.util.Arrays; 23 | import java.util.Objects; 24 | import java.util.stream.Collectors; 25 | import com.electronwill.nightconfig.core.CommentedConfig; 26 | import net.minecraftforge.common.ForgeConfigSpec; 27 | import net.minecraftforge.common.ForgeConfigSpec.BooleanValue; 28 | import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; 29 | import net.minecraftforge.common.ForgeConfigSpec.EnumValue; 30 | 31 | import net.awairo.minecraft.spawnchecker.SpawnChecker; 32 | import net.awairo.minecraft.spawnchecker.api.UsingHands; 33 | 34 | import lombok.AccessLevel; 35 | import lombok.Getter; 36 | import lombok.Setter; 37 | import lombok.extern.log4j.Log4j2; 38 | 39 | @Log4j2 40 | public final class SpawnCheckerConfig { 41 | 42 | @Setter(AccessLevel.PROTECTED) 43 | private CommentedConfig underlying; 44 | 45 | @Getter 46 | private final HudConfig hudConfig; 47 | @Getter 48 | private final KeyConfig keyConfig; 49 | @Getter 50 | private final ModeConfig modeConfig; 51 | 52 | @Getter 53 | private final PresetModeConfig presetModeConfig; 54 | 55 | public SpawnCheckerConfig(ForgeConfigSpec.Builder builder) { 56 | builder.comment( 57 | "", 58 | " SpawnChecker configurations.", 59 | "", 60 | " https://github.com/alalwww/SpawnChecker", 61 | "" 62 | ); 63 | builder.push(SpawnChecker.MOD_ID); 64 | 65 | enabledValue = builder 66 | .comment( 67 | " This value limits the behavior of all the SpawnChecker." 68 | ) 69 | .translation( 70 | configGuiKey("enabled") 71 | ) 72 | .define( 73 | "enabled", 74 | true 75 | ); 76 | 77 | usingHandsValue = builder 78 | .comment( 79 | " Hands to use for item possession condition.", 80 | defaultValue(UsingHands.DEFAULT), 81 | allowValues(UsingHands.values()) 82 | ) 83 | .translation( 84 | configGuiKey("usingHands") 85 | ) 86 | .defineEnum( 87 | "usingHands", 88 | UsingHands.DEFAULT 89 | ); 90 | 91 | hudConfig = new HudConfig(this::update, builder); 92 | keyConfig = new KeyConfig(this::update, builder); 93 | modeConfig = new ModeConfig(this::update, builder); 94 | presetModeConfig = new PresetModeConfig(this::update, builder); 95 | 96 | builder.pop(); 97 | } 98 | 99 | // region [config] Enabled 100 | 101 | private final BooleanValue enabledValue; 102 | 103 | public boolean enabled() { return enabledValue.get(); } 104 | 105 | public UpdateResult enable() { return update(enabledValue, true); } 106 | 107 | public UpdateResult disable() { return update(enabledValue, false); } 108 | 109 | // endregion 110 | 111 | // region [config] usingHands 112 | 113 | private final EnumValue usingHandsValue; 114 | 115 | public UsingHands usingHand() { return usingHandsValue.get(); } 116 | 117 | public UpdateResult usingHand(UsingHands value) { return update(usingHandsValue, value); } 118 | 119 | // endregion 120 | 121 | // region utility methods 122 | 123 | private UpdateResult update(ConfigValue value, T newValue) { 124 | if (underlying != null && !Objects.equals(value.get(), newValue)) { 125 | underlying.update(value.getPath(), newValue); 126 | return UpdateResult.CHANGED; 127 | } 128 | return UpdateResult.NO_CHANGED; 129 | } 130 | 131 | private static String configGuiKey(String key) { 132 | return String.join(".", SpawnChecker.MOD_ID, "config", key); 133 | } 134 | 135 | static String configGuiKey(String path, String key) { 136 | return String.join(".", SpawnChecker.MOD_ID, "config", path, key); 137 | } 138 | 139 | static String defaultMinMax(Object defaultValue, Object min, Object max) { 140 | return String.format(" default: %s, min: %s, max: %s", defaultValue, min, max); 141 | } 142 | 143 | static > String defaultValue(E defaultValue) { 144 | return " default: " + defaultValue.name(); 145 | } 146 | 147 | static > String allowValues(E[] values) { 148 | return Arrays.stream(values) 149 | .map(E::name) 150 | .collect(Collectors.joining(", ", " values: [", "]")); 151 | } 152 | 153 | // endregion 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/config/UpdateResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.config; 21 | 22 | import lombok.AccessLevel; 23 | import lombok.Getter; 24 | import lombok.RequiredArgsConstructor; 25 | 26 | @Getter 27 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE) 28 | public enum UpdateResult { 29 | CHANGED(true), 30 | NO_CHANGED(false); 31 | 32 | private final boolean changed; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/config/Updater.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.config; 21 | 22 | import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; 23 | 24 | @FunctionalInterface 25 | public interface Updater { 26 | UpdateResult update(ConfigValue value, T newValue); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/hud/HudIconResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.hud; 21 | 22 | import net.minecraft.util.ResourceLocation; 23 | 24 | import net.awairo.minecraft.spawnchecker.SpawnChecker; 25 | 26 | import lombok.Getter; 27 | 28 | public enum HudIconResource { 29 | SPAWN_CHECKER("spawn_checker.png"), 30 | SLIME_CHUNK_CHECKER("slime_chunk_visualizer.png"), 31 | SPAWNER_VISUALIZER("spawner_visualizer.png"), 32 | 33 | HORIZONTAL_RANGE("horizontal_range.png"), 34 | VERTICAL_RANGE("vertical_range.png"), 35 | 36 | BRIGHTNESS("brightness.png"), 37 | 38 | ; 39 | 40 | private static final String NAMESPACE = SpawnChecker.MOD_ID; 41 | private static final String DIRECTORY_NAME = "textures/hud"; 42 | 43 | @Getter 44 | private final ResourceLocation location; 45 | 46 | HudIconResource(String name) { 47 | location = new ResourceLocation(NAMESPACE, DIRECTORY_NAME + "/" + name); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/hud/HudOffset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.hud; 21 | 22 | import lombok.Getter; 23 | 24 | public abstract class HudOffset { 25 | public static final int MIN_VALUE = -4_096; 26 | public static final int MAX_VALUE = 4_096; 27 | public static final int DEFAULT_VALUE = 0; 28 | 29 | public static X xOf(int value) { return new X(value);} 30 | 31 | public static Y yOf(int value) { return new Y(value);} 32 | 33 | @Getter 34 | private final int value; 35 | 36 | private HudOffset(int value) { 37 | if (value < MIN_VALUE || value > MAX_VALUE) 38 | throw new IllegalArgumentException("Out of range. (" + value + ")"); 39 | this.value = value; 40 | } 41 | 42 | @Override 43 | public int hashCode() { 44 | return value; 45 | } 46 | 47 | @Override 48 | public boolean equals(Object obj) { 49 | return obj == this || getClass().isInstance(obj) && ((HudOffset) obj).value == value; 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return getClass().getSimpleName() + "(" + value + ")"; 55 | } 56 | 57 | public static final class X extends HudOffset { 58 | public static final X DEFAULT = new X(DEFAULT_VALUE); 59 | 60 | private X(int value) { super(value); } 61 | } 62 | 63 | public static final class Y extends HudOffset { 64 | public static final Y DEFAULT = new Y(DEFAULT_VALUE); 65 | 66 | private Y(int value) { super(value); } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/hud/HudRendererImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.hud; 21 | 22 | import java.util.Objects; 23 | import javax.annotation.Nullable; 24 | import com.mojang.blaze3d.systems.RenderSystem; 25 | 26 | import net.minecraft.client.Minecraft; 27 | import net.minecraft.client.gui.FontRenderer; 28 | import net.minecraft.util.ResourceLocation; 29 | import net.minecraft.util.Util; 30 | 31 | import net.awairo.minecraft.spawnchecker.api.Color; 32 | import net.awairo.minecraft.spawnchecker.api.HudData; 33 | import net.awairo.minecraft.spawnchecker.api.HudData.Visibility; 34 | import net.awairo.minecraft.spawnchecker.api.HudRenderer; 35 | import net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig; 36 | 37 | import lombok.RequiredArgsConstructor; 38 | import lombok.extern.log4j.Log4j2; 39 | import lombok.val; 40 | 41 | // TODO: 位置と表示内容の実装 42 | @Log4j2 43 | @RequiredArgsConstructor 44 | public final class HudRendererImpl implements HudRenderer { 45 | private final Minecraft minecraft; 46 | private final SpawnCheckerConfig config; 47 | 48 | private static final long UNDEFINED = -1; 49 | @Nullable 50 | private HudData hudData = null; 51 | private long showStartTime = UNDEFINED; 52 | private int tickCount; 53 | private float partialTicks; 54 | 55 | @Override 56 | public int tickCount() { 57 | return tickCount; 58 | } 59 | 60 | @Override 61 | public float partialTicks() { 62 | return partialTicks; 63 | } 64 | 65 | @Override 66 | public FontRenderer fontRenderer() { 67 | return minecraft.fontRenderer; 68 | } 69 | 70 | @Override 71 | public void bindTexture(ResourceLocation texture) { 72 | minecraft.textureManager.bindTexture(texture); 73 | } 74 | 75 | @Override 76 | public void addVertex(double x, double y, double z) { 77 | buffer() 78 | .pos(x, y, z) 79 | .endVertex(); 80 | } 81 | 82 | @Override 83 | public void addVertex(double x, double y, double z, float u, float v) { 84 | buffer() 85 | .pos(x, y, z) 86 | .tex(u, v) 87 | .endVertex(); 88 | } 89 | 90 | @Override 91 | public void addVertex(double x, double y, double z, Color color) { 92 | buffer() 93 | .pos(x, y, z) 94 | .color(color.red(), color.green(), color.blue(), color.alpha()) 95 | .endVertex(); 96 | } 97 | 98 | @Override 99 | public void addVertex(double x, double y, double z, float u, float v, Color color) { 100 | buffer() 101 | .pos(x, y, z) 102 | .color(color.red(), color.green(), color.blue(), color.alpha()) 103 | .tex(u, v) 104 | .endVertex(); 105 | } 106 | 107 | public void setData(HudData hudData) { 108 | removeData(); 109 | this.hudData = Objects.requireNonNull(hudData, "hudData"); 110 | } 111 | 112 | private void removeData() { 113 | this.hudData = null; 114 | showStartTime = UNDEFINED; 115 | } 116 | 117 | public void render(int tickCount, float partialTicks) { 118 | if (hudData == null || minecraft.isGamePaused()) 119 | return; 120 | 121 | this.tickCount = tickCount; 122 | this.partialTicks = partialTicks; 123 | val now = Util.milliTime(); 124 | if (showStartTime == UNDEFINED) { 125 | showStartTime = now; 126 | } 127 | val h = minecraft.getMainWindow().getScaledHeight(); 128 | val w = minecraft.getMainWindow().getScaledWidth(); 129 | RenderSystem.pushMatrix(); 130 | RenderSystem.translated( 131 | w / 20 + config.hudConfig().xOffset().value(), 132 | h / 3 + config.hudConfig().yOffset().value(), 133 | 0d 134 | ); 135 | RenderSystem.scalef(1.0f, 1.0f, 1f); 136 | val hudVisibility = hudData.draw(this, now - showStartTime); 137 | RenderSystem.popMatrix(); 138 | 139 | if (hudVisibility == Visibility.HIDE) 140 | removeData(); 141 | } 142 | 143 | // 144 | // public void renderHUD(@SuppressWarnings("unused") float partialTicks) { 145 | // if (!state.enabled()) 146 | // return; 147 | // 148 | // RenderSystem.enableBlend(); 149 | // RenderSystem.blendFuncSeparate(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO); 150 | // RenderSystem.enableTexture2D(); 151 | // 152 | // val x = 0f; 153 | // val y = 50f; 154 | // val r = 0; 155 | // val g = 255; 156 | // val b = 0; 157 | // val a = 127; 158 | // val color = (r << 16) | (g << 8) | b | (a << 24); 159 | // val text = "test"; 160 | // val iconResource = HUDTextures.SPAWN_CHECKER; 161 | // 162 | // drawIcon(minecraft, iconResource, x, y, 255, g, b, a); 163 | // drawTextWithShadow(minecraft, text, x + 30, y, color); 164 | // } 165 | // 166 | // private void drawTextWithShadow(Minecraft game, String text, float x, float y, int color) { 167 | // game.fontRenderer.drawStringWithShadow(text, x, y, color); 168 | // } 169 | // 170 | // private void drawIcon(Minecraft game, HUDTextures resource, float x, float y, int r, int g, int b, int a) { 171 | // final double ltx, rtx, lbx, rbx, lty, rty, lby, rby; 172 | // 173 | // val iconWidth = 16d; 174 | // val iconHeight = 16d; 175 | // val z = 1d; 176 | // val uMin = 0d; 177 | // val uMax = 1d; 178 | // val vMin = 0d; 179 | // val vMax = 1d; 180 | // 181 | // ltx = lbx = x + 0d; 182 | // rtx = rbx = x + iconWidth; 183 | // lty = rty = y + iconHeight; 184 | // lby = rby = y + 0d; 185 | // 186 | // game.textureManager.bindTexture(resource.location); 187 | // 188 | // val tessellator = Tessellator.getInstance(); 189 | // val buffer = tessellator.getBuffer(); 190 | // buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); 191 | // addVertexWithUV(buffer, lbx, lby, z, uMin, vMin, r, g, b, a); 192 | // addVertexWithUV(buffer, ltx, lty, z, uMin, vMax, r, g, b, a); 193 | // addVertexWithUV(buffer, rtx, rty, z, uMax, vMax, r, g, b, a); 194 | // addVertexWithUV(buffer, rbx, rby, z, uMax, vMin, r, g, b, a); 195 | // tessellator.draw(); 196 | // } 197 | // 198 | // private void addVertexWithUV( 199 | // BufferBuilder buffer, double x, double y, double z, double u, double v, int r, int g, int b, int a) { 200 | // buffer 201 | // .pos(x, y, z) 202 | // .tex(u, v) 203 | // .color(r, g, b, a) 204 | // .endVertex(); 205 | // } 206 | } 207 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/keybinding/KeyBindingState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.keybinding; 21 | 22 | import java.util.Collection; 23 | import java.util.Collections; 24 | import java.util.LinkedList; 25 | import net.minecraftforge.client.settings.KeyModifier; 26 | import org.lwjgl.glfw.GLFW; 27 | 28 | import net.minecraft.client.settings.KeyBinding; 29 | 30 | import net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig; 31 | import net.awairo.minecraft.spawnchecker.mode.ModeState; 32 | 33 | import lombok.AccessLevel; 34 | import lombok.Getter; 35 | import lombok.NonNull; 36 | import lombok.extern.log4j.Log4j2; 37 | import lombok.val; 38 | 39 | @Getter 40 | @Log4j2 41 | public final class KeyBindingState { 42 | 43 | @Getter(AccessLevel.NONE) 44 | private final Collection bindings; 45 | @Getter(AccessLevel.NONE) 46 | private final ModeState modeState; 47 | @Getter(AccessLevel.NONE) 48 | private final SpawnCheckerConfig config; 49 | 50 | private final SpawnCheckerKeyBinding prevMode; 51 | private final SpawnCheckerKeyBinding nextMode; 52 | 53 | private final SpawnCheckerKeyBinding prevModeOption; 54 | private final SpawnCheckerKeyBinding nextModeOption; 55 | 56 | private final SpawnCheckerKeyBinding horizontalRangePlus; 57 | private final SpawnCheckerKeyBinding horizontalRangeMinus; 58 | 59 | private final SpawnCheckerKeyBinding verticalRangePlus; 60 | private final SpawnCheckerKeyBinding verticalRangeMinus; 61 | 62 | private final SpawnCheckerKeyBinding brightnessPlus; 63 | private final SpawnCheckerKeyBinding brightnessMinus; 64 | 65 | public KeyBindingState(@NonNull ModeState modeState, @NonNull SpawnCheckerConfig config) { 66 | this.modeState = modeState; 67 | this.config = config; 68 | 69 | val bindings = new LinkedList(); 70 | 71 | // FIXME: キーバインド処理の実装とリストへの登録 72 | 73 | prevMode = new SpawnCheckerKeyBinding.Builder(this) 74 | .descriptionSuffix("prevMode") 75 | .keyModifier(KeyModifier.CONTROL) 76 | .keyCode(GLFW.GLFW_KEY_UP) 77 | .ordinal(0) 78 | .build(); 79 | // bindings.add(prevMode); 80 | 81 | nextMode = new SpawnCheckerKeyBinding.Builder(this) 82 | .descriptionSuffix("nextMode") 83 | .keyModifier(KeyModifier.CONTROL) 84 | .keyCode(GLFW.GLFW_KEY_DOWN) 85 | .ordinal(1) 86 | .build(); 87 | // bindings.add(nextMode); 88 | 89 | prevModeOption = new SpawnCheckerKeyBinding.Builder(this) 90 | .descriptionSuffix("prevModeOption") 91 | .keyModifier(KeyModifier.NONE) 92 | .keyCode(GLFW.GLFW_KEY_UP) 93 | .ordinal(2) 94 | .build(); 95 | // bindings.add(prevModeOption); 96 | 97 | nextModeOption = new SpawnCheckerKeyBinding.Builder(this) 98 | .descriptionSuffix("nextModeOption") 99 | .keyModifier(KeyModifier.NONE) 100 | .keyCode(GLFW.GLFW_KEY_DOWN) 101 | .ordinal(3) 102 | .build(); 103 | // bindings.add(nextModeOption); 104 | 105 | horizontalRangePlus = new SpawnCheckerKeyBinding.Builder(this) 106 | .descriptionSuffix("horizontalRangePlus") 107 | .keyModifier(KeyModifier.NONE) 108 | .keyCode(GLFW.GLFW_KEY_KP_ADD) 109 | .ordinal(4) 110 | .build(); 111 | bindings.add(horizontalRangePlus); 112 | 113 | horizontalRangeMinus = new SpawnCheckerKeyBinding.Builder(this) 114 | .descriptionSuffix("horizontalRangeMinus") 115 | .keyModifier(KeyModifier.NONE) 116 | .keyCode(GLFW.GLFW_KEY_KP_SUBTRACT) 117 | .ordinal(5) 118 | .build(); 119 | bindings.add(horizontalRangeMinus); 120 | 121 | verticalRangePlus = new SpawnCheckerKeyBinding.Builder(this) 122 | .descriptionSuffix("verticalRangePlus") 123 | .keyModifier(KeyModifier.CONTROL) 124 | .keyCode(GLFW.GLFW_KEY_KP_ADD) 125 | .ordinal(6) 126 | .build(); 127 | bindings.add(verticalRangePlus); 128 | 129 | verticalRangeMinus = new SpawnCheckerKeyBinding.Builder(this) 130 | .descriptionSuffix("verticalRangeMinus") 131 | .keyModifier(KeyModifier.CONTROL) 132 | .keyCode(GLFW.GLFW_KEY_KP_SUBTRACT) 133 | .ordinal(7) 134 | .build(); 135 | bindings.add(verticalRangeMinus); 136 | 137 | brightnessPlus = new SpawnCheckerKeyBinding.Builder(this) 138 | .descriptionSuffix("brightnessPlus") 139 | .keyModifier(KeyModifier.ALT) 140 | .keyCode(GLFW.GLFW_KEY_KP_ADD) 141 | .ordinal(8) 142 | .build(); 143 | // bindings.add(brightnessPlus); 144 | 145 | brightnessMinus = new SpawnCheckerKeyBinding.Builder(this) 146 | .descriptionSuffix("brightnessMinus") 147 | .keyModifier(KeyModifier.ALT) 148 | .keyCode(GLFW.GLFW_KEY_KP_SUBTRACT) 149 | .ordinal(9) 150 | .build(); 151 | // bindings.add(brightnessMinus); 152 | 153 | this.bindings = Collections.unmodifiableCollection(bindings); 154 | } 155 | 156 | RepeatDelay repeatDelay() { 157 | return config.keyConfig().repeatDelay(); 158 | } 159 | 160 | RepeatRate repeatRate() { 161 | return config.keyConfig().repeatRate(); 162 | } 163 | 164 | public Collection bindings() { 165 | return Collections.unmodifiableCollection(bindings); 166 | } 167 | 168 | public void onTick(long nowMilliTime) { 169 | bindings.parallelStream().forEach(s -> s.update(nowMilliTime)); 170 | 171 | // mode 172 | while (prevMode().isPressed()) { 173 | modeState.proceedPrevMode(); 174 | } 175 | while (nextMode().isPressed()) { 176 | modeState.proceedNextMode(); 177 | } 178 | 179 | // mode option 180 | while (prevModeOption().isPressed()) { 181 | modeState.proceedPrevModeOption(); 182 | } 183 | while (nextModeOption().isPressed()) { 184 | modeState.proceedNextModeOption(); 185 | } 186 | 187 | // h range 188 | while (horizontalRangePlus().isPressed()) { 189 | modeState.proceedNextHorizontalRange(); 190 | } 191 | while (horizontalRangeMinus().isPressed()) { 192 | modeState.proceedPrevHorizontalRange(); 193 | } 194 | 195 | // v range 196 | while (verticalRangePlus().isPressed()) { 197 | modeState.proceedNextVerticalRange(); 198 | } 199 | while (verticalRangeMinus().isPressed()) { 200 | modeState.proceedPrevVerticalRange(); 201 | } 202 | 203 | // brightness 204 | while (brightnessPlus().isPressed()) { 205 | modeState.proceedNextBrightness(); 206 | } 207 | while (brightnessMinus().isPressed()) { 208 | modeState.proceedPrevBrightness(); 209 | } 210 | } 211 | } 212 | 213 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/keybinding/RepeatDelay.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.keybinding; 21 | 22 | import lombok.Value; 23 | 24 | @Value 25 | public class RepeatDelay { 26 | public static final int MIN = 1; 27 | public static final int MAX = 3_000; 28 | public static final RepeatDelay DEFAULT = new RepeatDelay(500); 29 | 30 | public static RepeatDelay ofMilliSeconds(int milliSeconds) { 31 | return DEFAULT.milliSeconds == milliSeconds ? DEFAULT : new RepeatDelay(milliSeconds); 32 | } 33 | 34 | private final int milliSeconds; 35 | 36 | private RepeatDelay(int milliSeconds) { 37 | if (milliSeconds < MIN || milliSeconds > MAX) 38 | throw new IllegalArgumentException("Out of range. (" + milliSeconds + ")"); 39 | this.milliSeconds = milliSeconds; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/keybinding/RepeatRate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.keybinding; 21 | 22 | import lombok.Value; 23 | 24 | @Value 25 | public class RepeatRate { 26 | public static final int MIN = 1; 27 | public static final int MAX = 3_000; 28 | public static final RepeatRate DEFAULT = new RepeatRate(150); 29 | 30 | public static RepeatRate ofMilliSeconds(int milliSeconds) { 31 | return milliSeconds == DEFAULT.milliSeconds ? DEFAULT : new RepeatRate(milliSeconds); 32 | } 33 | 34 | private final int milliSeconds; 35 | 36 | private RepeatRate(int milliSeconds) { 37 | if (milliSeconds < MIN || milliSeconds > MAX) 38 | throw new IllegalArgumentException("Out of range. (" + milliSeconds + ")"); 39 | this.milliSeconds = milliSeconds; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/keybinding/SpawnCheckerKeyBinding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.keybinding; 21 | 22 | import java.util.Objects; 23 | import java.util.concurrent.atomic.AtomicInteger; 24 | import net.minecraftforge.client.settings.KeyModifier; 25 | 26 | import net.minecraft.client.settings.KeyBinding; 27 | import net.minecraft.client.util.InputMappings.Type; 28 | 29 | import lombok.AccessLevel; 30 | import lombok.NonNull; 31 | import lombok.RequiredArgsConstructor; 32 | import lombok.Setter; 33 | import lombok.experimental.Accessors; 34 | import lombok.extern.log4j.Log4j2; 35 | 36 | @Log4j2 37 | public final class SpawnCheckerKeyBinding extends KeyBinding { 38 | 39 | private static final String CATEGORY = "spawnchecker.key.categoryName"; 40 | private static final String KEY_BINDING_DESCRIPTION_PREFIX = "spawnchecker.key."; 41 | 42 | private final KeyBindingState state; 43 | 44 | private final int ordinal; 45 | private final AtomicInteger pressCount = new AtomicInteger(0); 46 | 47 | private long pressStartMillis = 0L; 48 | private long pressTime = 0L; 49 | private long lastCountedUpTime = 0L; 50 | 51 | private SpawnCheckerKeyBinding( 52 | @NonNull KeyBindingState state, 53 | @NonNull String description, 54 | @NonNull KeyModifier keyModifier, 55 | int keyCode, 56 | int ordinal 57 | ) { 58 | super( 59 | description, 60 | SpawnCheckerKeyConflictContext.INSTANCE, 61 | keyModifier, 62 | Type.KEYSYM, 63 | keyCode, 64 | CATEGORY 65 | ); 66 | this.state = state; 67 | this.ordinal = ordinal; 68 | } 69 | 70 | @Override 71 | public int compareTo(final KeyBinding other) { 72 | if (other instanceof SpawnCheckerKeyBinding) { 73 | return Integer.compare(ordinal, ((SpawnCheckerKeyBinding) other).ordinal); 74 | } 75 | return super.compareTo(other); 76 | } 77 | 78 | @Override 79 | public boolean isPressed() { 80 | return pressCount.getAndUpdate(prev -> Math.max(0, prev - 1)) > 0; 81 | } 82 | 83 | void update(long nowMilliTime) { 84 | 85 | if (isKeyDown()) { 86 | if (isBeforePressed()) { 87 | pressTime = nowMilliTime - pressStartMillis; 88 | if (isRepeated(nowMilliTime)) { 89 | pressCount.getAndIncrement(); 90 | lastCountedUpTime = nowMilliTime; 91 | } 92 | } else { 93 | pressCount.set(1); 94 | lastCountedUpTime = pressStartMillis = nowMilliTime; 95 | pressTime = 0; 96 | } 97 | } else { 98 | pressStartMillis = 0; 99 | pressTime = 0; 100 | } 101 | 102 | // noinspection StatementWithEmptyBody 103 | while (super.isPressed()) { 104 | // consume underlying pressTime 105 | } 106 | } 107 | 108 | private boolean isBeforePressed() { 109 | return pressStartMillis != 0; 110 | } 111 | 112 | private boolean isRepeated(long nowMilliTime) { 113 | return pressTime > state.repeatDelay().milliSeconds() 114 | && nowMilliTime - lastCountedUpTime > state.repeatRate().milliSeconds(); 115 | } 116 | 117 | @Setter 118 | @Accessors(chain = true, fluent = true) 119 | @RequiredArgsConstructor(access = AccessLevel.PACKAGE) 120 | static final class Builder { 121 | @NonNull 122 | private final KeyBindingState state; 123 | private String descriptionSuffix; 124 | private KeyModifier keyModifier; 125 | private int keyCode; 126 | private int ordinal; 127 | 128 | SpawnCheckerKeyBinding build() { 129 | Objects.requireNonNull(descriptionSuffix, "descriptionSuffix"); 130 | Objects.requireNonNull(keyModifier, "keyModifier"); 131 | if (keyCode <= 0) 132 | throw new IllegalStateException("keyCode"); 133 | if (ordinal < 0) 134 | throw new IllegalStateException("ordinal"); 135 | 136 | return new SpawnCheckerKeyBinding( 137 | state, 138 | KEY_BINDING_DESCRIPTION_PREFIX + descriptionSuffix, 139 | keyModifier, 140 | keyCode, 141 | ordinal 142 | ); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/keybinding/SpawnCheckerKeyConflictContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.keybinding; 21 | 22 | import net.minecraftforge.client.settings.IKeyConflictContext; 23 | 24 | public enum SpawnCheckerKeyConflictContext implements IKeyConflictContext { 25 | INSTANCE { 26 | @Override 27 | public boolean isActive() { 28 | return !net.minecraftforge.client.settings.KeyConflictContext.GUI.isActive(); 29 | } 30 | 31 | @Override 32 | public boolean conflicts(IKeyConflictContext other) { 33 | return this == other; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/ConditionalMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import net.awairo.minecraft.spawnchecker.api.Mode; 23 | import net.awairo.minecraft.spawnchecker.hud.HudIconResource; 24 | 25 | abstract class ConditionalMode extends PresetMode implements Mode.Conditional { 26 | ConditionalMode(Name name, HudIconResource icon, Priority priority) { 27 | super(name, icon, priority); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/EntitySize.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import net.minecraft.client.world.ClientWorld; 23 | import net.minecraft.util.math.AxisAlignedBB; 24 | import net.minecraft.util.math.BlockPos; 25 | import net.minecraft.util.math.shapes.VoxelShapes; 26 | 27 | import lombok.AccessLevel; 28 | import lombok.Getter; 29 | import lombok.RequiredArgsConstructor; 30 | import lombok.val; 31 | 32 | @Getter 33 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE) 34 | enum EntitySize { 35 | ENDERMAN(0.6F, 2.9F), 36 | ZOMBIE(0.6F, 1.95F), 37 | SKELETON(0.6F, 1.99F), // zombie より微妙にでかいので判定ではzombieサイズを使うようにした 38 | SPIDER(1.4F, 0.9F), 39 | SLIME(0.51000005F, 0.51000005F), // smallest size 40 | GHAST(4.0F, 4.0F), 41 | 42 | ; 43 | 44 | private final float width; 45 | private final float height; 46 | 47 | // EntityLiving#isNotColliding(IWorldReaderBase) 48 | boolean isNotColliding(ClientWorld worldIn, BlockPos pos) { 49 | val bb = boundingBox(pos); 50 | return !worldIn.containsAnyLiquid(bb) 51 | && worldIn.hasNoCollisions(null, bb) 52 | && worldIn.checkNoEntityCollision(null, VoxelShapes.create(bb)); 53 | } 54 | 55 | boolean isNotCollidingWithoutOtherEntityCollision(ClientWorld worldIn, BlockPos pos) { 56 | val bb = boundingBox(pos); 57 | return !worldIn.containsAnyLiquid(bb) 58 | && worldIn.hasNoCollisions(null, bb); 59 | } 60 | 61 | AxisAlignedBB boundingBox(BlockPos pos) { 62 | return new AxisAlignedBB( 63 | (double) pos.getX(), 64 | (double) pos.getY(), 65 | (double) pos.getZ(), 66 | (double) pos.getX() + width, 67 | (double) pos.getY() + height, 68 | (double) pos.getZ() + width 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/ModeList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import java.util.ArrayList; 23 | import java.util.Collections; 24 | import java.util.List; 25 | import java.util.Optional; 26 | 27 | import net.awairo.minecraft.spawnchecker.api.Mode; 28 | import net.awairo.minecraft.spawnchecker.api.PlayerPos; 29 | 30 | import lombok.AccessLevel; 31 | import lombok.Getter; 32 | import lombok.NoArgsConstructor; 33 | import lombok.RequiredArgsConstructor; 34 | import lombok.extern.log4j.Log4j2; 35 | import lombok.val; 36 | import lombok.var; 37 | 38 | @Log4j2 39 | @NoArgsConstructor(access = AccessLevel.PACKAGE) 40 | final class ModeList { 41 | 42 | private final List selectableModes = new ArrayList<>(); 43 | private final List conditionalModes = new ArrayList<>(); 44 | 45 | private int index = 0; 46 | private int scheduledIndex = 0; 47 | private Mode previous = null; 48 | 49 | @Getter 50 | private Mode current; 51 | 52 | void add(Mode mode) { 53 | 54 | if (mode.isSelectable()) { 55 | selectableModes.add(mode.asSelectable()); 56 | Collections.sort(selectableModes); 57 | return; 58 | } 59 | 60 | if (mode.isConditional()) { 61 | conditionalModes.add(mode.asConditional()); 62 | Collections.sort(conditionalModes); 63 | return; 64 | } 65 | 66 | throw new IllegalArgumentException("unreachable code."); 67 | } 68 | 69 | void scheduleChangeNextMode() { 70 | scheduledIndex++; 71 | } 72 | 73 | void scheduleChangePrevMode() { 74 | scheduledIndex--; 75 | } 76 | 77 | Result updateList(PlayerPos playerPos, Mode.State state) { 78 | if (scheduledIndex != 0) { 79 | log.debug("index={}, scheduledIndex={}", index, scheduledIndex); 80 | var nextIndex = index; 81 | if (current.isConditional()) 82 | popPreviousMode(state); 83 | 84 | // 進む方向に予定されてる回数だけ次に選択するindexを増加させる 85 | while (scheduledIndex > 0) { 86 | scheduledIndex--; 87 | if (nextIndex + 1 < selectableModes.size()) 88 | nextIndex++; 89 | } 90 | // 戻る方向に予定されてる回数だけ次に選択するindexを減少させる 91 | while (scheduledIndex < 0) { 92 | scheduledIndex++; 93 | if (nextIndex > 0) 94 | nextIndex--; 95 | } 96 | // indexが変わる操作だった変更して終了 97 | if (index != nextIndex) { 98 | index = nextIndex; 99 | if (current.isActive()) 100 | current.deactivate(state); 101 | current = currentSelectableMode(); 102 | return Result.CHANGED; 103 | } 104 | } 105 | 106 | if (current.isSelectable()) { 107 | val foundMode = findModeThatCanBeActivated(playerPos, state); 108 | if (foundMode.isPresent()) { 109 | pushConditionalMode(foundMode.get(), state); 110 | return Result.CHANGED; 111 | } 112 | return Result.NOT_CHANGED; 113 | } 114 | 115 | if (current.isConditional()) { 116 | if (((Mode.Conditional) current).canContinue(playerPos, state)) { 117 | return Result.NOT_CHANGED; 118 | } 119 | popPreviousMode(state); 120 | return Result.CHANGED; 121 | } 122 | 123 | return Result.NOT_CHANGED; 124 | } 125 | 126 | void selectBy(Mode.Name name) { 127 | // noinspection OptionalGetWithoutIsPresent 128 | val found = selectableModes.stream() 129 | .filter(mode -> mode.name().equals(name)) 130 | .findFirst() 131 | .orElseGet(() -> selectableModes.stream() 132 | .filter(mode -> mode.name().equals(SpawnCheckMode.NAME)) 133 | .findFirst() 134 | .get() // プリセットモードなのでかならず見つかる想定 135 | ); 136 | 137 | current = found; 138 | index = selectableModes.indexOf(found); 139 | } 140 | 141 | private void pushConditionalMode(Mode.Conditional mode, Mode.State state) { 142 | if (current.isActive()) 143 | current.deactivate(state); 144 | previous = current; 145 | current = mode; 146 | } 147 | 148 | private void popPreviousMode(Mode.State state) { 149 | if (current.isActive()) 150 | current.deactivate(state); 151 | current = previous; 152 | previous = null; 153 | } 154 | 155 | private Mode.Selectable currentSelectableMode() { 156 | return selectableModes.get(index); 157 | } 158 | 159 | private Optional findModeThatCanBeActivated(PlayerPos playerPos, Mode.State state) { 160 | return conditionalModes.stream() 161 | .filter(mode -> mode.canActivate(playerPos, state)) 162 | .findFirst(); 163 | } 164 | 165 | @Getter 166 | @RequiredArgsConstructor 167 | enum Result { 168 | CHANGED(true), 169 | NOT_CHANGED(false); 170 | private final boolean changed; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/MyMarkerRendererImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import com.mojang.blaze3d.matrix.MatrixStack; 23 | 24 | import net.minecraft.client.renderer.WorldRenderer; 25 | import net.minecraft.client.renderer.entity.EntityRendererManager; 26 | import net.minecraft.client.renderer.texture.TextureManager; 27 | import net.minecraft.util.ResourceLocation; 28 | import net.minecraft.util.math.vector.Quaternion; 29 | 30 | import net.awairo.minecraft.spawnchecker.api.Color; 31 | import net.awairo.minecraft.spawnchecker.api.MarkerRenderer; 32 | 33 | import lombok.AccessLevel; 34 | import lombok.Getter; 35 | import lombok.Value; 36 | 37 | @Value 38 | final class MyMarkerRendererImpl implements MarkerRenderer { 39 | private final WorldRenderer worldRenderer; 40 | private final float partialTicks; 41 | @Getter(AccessLevel.PRIVATE) 42 | private final MatrixStack matrixStack; 43 | private final TextureManager textureManager; 44 | private final EntityRendererManager renderManager; 45 | 46 | @Override 47 | public void bindTexture(ResourceLocation texture) { 48 | textureManager.bindTexture(texture); 49 | } 50 | 51 | @Override 52 | public void addVertex(double x, double y, double z) { 53 | buffer() 54 | .pos(matrixStack.getLast().getMatrix(), (float) x, (float) y, (float) z) 55 | .endVertex(); 56 | } 57 | 58 | @Override 59 | public void addVertex(double x, double y, double z, float u, float v) { 60 | buffer() 61 | .pos(matrixStack.getLast().getMatrix(), (float) x, (float) y, (float) z) 62 | .tex(u, v) 63 | .endVertex(); 64 | } 65 | 66 | @Override 67 | public void addVertex(double x, double y, double z, Color color) { 68 | buffer() 69 | .pos(matrixStack.getLast().getMatrix(), (float) x, (float) y, (float) z) 70 | .color(color.red(), color.green(), color.blue(), color.alpha()) 71 | .endVertex(); 72 | } 73 | 74 | @Override 75 | public void addVertex(double x, double y, double z, float u, float v, Color color) { 76 | buffer() 77 | .pos(matrixStack.getLast().getMatrix(), (float) x, (float) y, (float) z) 78 | .tex(u, v) 79 | .color(color.red(), color.green(), color.blue(), color.alpha()) 80 | .endVertex(); 81 | } 82 | 83 | @Override 84 | public void push() { 85 | matrixStack.push(); 86 | } 87 | 88 | @Override 89 | public void pop() { 90 | matrixStack.pop(); 91 | } 92 | 93 | @Override 94 | public void translate(double x, double y, double z) { 95 | matrixStack.translate(x, y, z); 96 | } 97 | 98 | @Override 99 | public void scale(float m00, float m11, float m22) { 100 | matrixStack.scale(m00, m11, m22); 101 | } 102 | 103 | @Override 104 | public void rotate(Quaternion quaternion) { 105 | matrixStack.rotate(quaternion); 106 | } 107 | 108 | @Override 109 | public void clear() { 110 | matrixStack.clear(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/PresetMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import net.minecraft.util.ResourceLocation; 23 | 24 | import net.awairo.minecraft.spawnchecker.api.Mode; 25 | import net.awairo.minecraft.spawnchecker.hud.HudIconResource; 26 | 27 | import lombok.NonNull; 28 | 29 | abstract class PresetMode> implements Mode { 30 | private final Name name; 31 | private final HudIconResource icon; 32 | private final Priority priority; 33 | 34 | private boolean active = false; 35 | 36 | PresetMode(@NonNull Name name, @NonNull HudIconResource icon, @NonNull Priority priority) { 37 | this.name = name; 38 | this.icon = icon; 39 | this.priority = priority; 40 | } 41 | 42 | protected abstract void setUp(); 43 | protected abstract void tearDown(); 44 | 45 | @Override 46 | public final Name name() { 47 | return name; 48 | } 49 | 50 | @Override 51 | public ResourceLocation icon() { 52 | return icon.location(); 53 | } 54 | 55 | @Override 56 | public final Priority priority() { 57 | return priority; 58 | } 59 | 60 | @Override 61 | public final boolean isActive() { 62 | return active; 63 | } 64 | 65 | @Override 66 | public final void activate(State state) { 67 | active = true; 68 | Mode.super.activate(state); 69 | setUp(); 70 | } 71 | 72 | @Override 73 | public final void deactivate(State state) { 74 | tearDown(); 75 | Mode.super.deactivate(state); 76 | active = false; 77 | } 78 | 79 | @Override 80 | public final boolean isInactive() { 81 | return Mode.super.isInactive(); 82 | } 83 | 84 | @Override 85 | public final boolean isSelectable() { 86 | return Mode.super.isSelectable(); 87 | } 88 | 89 | @Override 90 | public final boolean isConditional() { 91 | return Mode.super.isConditional(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/RangeConfigHudData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import com.mojang.blaze3d.matrix.MatrixStack; 23 | 24 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 25 | import net.minecraft.util.ResourceLocation; 26 | import net.minecraft.util.text.ITextComponent; 27 | import net.minecraft.util.text.TranslationTextComponent; 28 | 29 | import net.awairo.minecraft.spawnchecker.api.Color; 30 | import net.awairo.minecraft.spawnchecker.api.HudData; 31 | import net.awairo.minecraft.spawnchecker.api.HudRenderer; 32 | import net.awairo.minecraft.spawnchecker.api.Mode; 33 | import net.awairo.minecraft.spawnchecker.api.ScanRange; 34 | import net.awairo.minecraft.spawnchecker.hud.HudIconResource; 35 | 36 | import lombok.NonNull; 37 | import lombok.val; 38 | 39 | final class RangeConfigHudData extends HudData.Simple { 40 | 41 | private static final String HUD_H_RANGE_KEY = "spawnchecker.hud.horizontalRange"; 42 | private static final String HUD_V_RANGE_KEY = "spawnchecker.hud.verticalRange"; 43 | 44 | private static final float LINE_OFFSET = 7.0f; 45 | 46 | private final ITextComponent hRange; 47 | private final ITextComponent vRange; 48 | 49 | private final double iconMinX; 50 | private final double iconMaxX; 51 | private final float textX; 52 | 53 | RangeConfigHudData( 54 | @NonNull Mode.Name modeName, 55 | @NonNull ResourceLocation icon, 56 | @NonNull ScanRange.Horizontal hRange, 57 | @NonNull ScanRange.Vertical vRange, 58 | @NonNull ShowDuration showDuration) { 59 | super(modeName.textComponent(), icon, showDuration); 60 | 61 | this.hRange = new TranslationTextComponent(HUD_H_RANGE_KEY, hRange.value()); 62 | this.vRange = new TranslationTextComponent(HUD_V_RANGE_KEY, vRange.value()); 63 | 64 | this.iconMinX = TEXT_X; 65 | this.iconMaxX = TEXT_X + ICON_SIZE; 66 | this.textX = TEXT_X * 2; 67 | } 68 | 69 | @Override 70 | @SuppressWarnings("Duplicates") 71 | protected void drawIcon(MatrixStack stack, ResourceLocation icon, HudRenderer renderer, Color color) { 72 | super.drawIcon(stack, icon, renderer, color); 73 | 74 | final double xMin, yMin1, yMin2, xMax, yMax1, yMax2, z; 75 | final float uMin, uMax, vMin, vMax; 76 | xMin = iconMinX; 77 | xMax = iconMaxX; 78 | yMin1 = renderer.fontRenderer().FONT_HEIGHT + LINE_OFFSET; 79 | yMax1 = renderer.fontRenderer().FONT_HEIGHT + LINE_OFFSET + ICON_SIZE; 80 | yMin2 = yMin1 * 2; 81 | yMax2 = yMin1 * 2 + ICON_SIZE; 82 | z = 0d; 83 | uMin = vMin = 0f; 84 | uMax = vMax = 1f; 85 | 86 | renderer.bindTexture(HudIconResource.HORIZONTAL_RANGE.location()); 87 | renderer.beginQuads(DefaultVertexFormats.POSITION_COLOR_TEX); 88 | renderer.addVertex(xMin, yMin1, z, uMin, vMin, color); 89 | renderer.addVertex(xMin, yMax1, z, uMin, vMax, color); 90 | renderer.addVertex(xMax, yMax1, z, uMax, vMax, color); 91 | renderer.addVertex(xMax, yMin1, z, uMax, vMin, color); 92 | renderer.draw(); 93 | 94 | renderer.bindTexture(HudIconResource.VERTICAL_RANGE.location()); 95 | renderer.beginQuads(DefaultVertexFormats.POSITION_COLOR_TEX); 96 | renderer.addVertex(xMin, yMin2, z, uMin, vMin, color); 97 | renderer.addVertex(xMin, yMax2, z, uMin, vMax, color); 98 | renderer.addVertex(xMax, yMax2, z, uMax, vMax, color); 99 | renderer.addVertex(xMax, yMin2, z, uMax, vMin, color); 100 | renderer.draw(); 101 | 102 | } 103 | 104 | @Override 105 | protected void drawText(MatrixStack stack, ITextComponent text, HudRenderer renderer, Color color) { 106 | if (isTransparentText(color)) 107 | return; 108 | 109 | super.drawText(stack, text, renderer, color); 110 | 111 | renderer.fontRenderer() 112 | .drawStringWithShadow( 113 | stack, 114 | hRange.getString(), 115 | textX, 116 | TEXT_Y + renderer.fontRenderer().FONT_HEIGHT + LINE_OFFSET, 117 | color.toInt() 118 | ); 119 | 120 | renderer.fontRenderer() 121 | .drawStringWithShadow( 122 | stack, 123 | vRange.getString(), 124 | textX, 125 | TEXT_Y + (renderer.fontRenderer().FONT_HEIGHT + LINE_OFFSET) * 2, 126 | color.toInt() 127 | ); 128 | } 129 | 130 | @Override 131 | protected float computeAlpha(long elapsedMillis) { 132 | val rate = showDuration().progressRate(elapsedMillis); 133 | if (rate >= 0.9f) 134 | return Math.min((1 - rate) * 10, 1f); 135 | return 1f; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/ScanArea.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import java.util.Iterator; 23 | import java.util.Spliterator; 24 | import java.util.Spliterators; 25 | import java.util.stream.IntStream; 26 | import java.util.stream.Stream; 27 | import java.util.stream.StreamSupport; 28 | 29 | import net.minecraft.util.math.BlockPos; 30 | import net.minecraft.util.math.CubeCoordinateIterator; 31 | 32 | import net.awairo.minecraft.spawnchecker.api.PlayerPos; 33 | import net.awairo.minecraft.spawnchecker.api.ScanRange; 34 | 35 | import lombok.RequiredArgsConstructor; 36 | import lombok.Value; 37 | import lombok.val; 38 | 39 | @Value 40 | final class ScanArea { 41 | private static int CHARACTERISTICS = Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.NONNULL; 42 | private static boolean PARALLEL = true; 43 | 44 | private final PlayerPos playerPos; 45 | private final ScanRange.Horizontal hRange; 46 | private final ScanRange.Vertical vRange; 47 | 48 | Stream xzStream() { 49 | val minX = playerPos.blockPos().getX() - hRange.value(); 50 | val maxX = playerPos.blockPos().getX() + hRange.value(); 51 | val y = playerPos.blockPos().getY(); 52 | val maxZ = playerPos.blockPos().getZ() + hRange.value(); 53 | val minZ = playerPos.blockPos().getZ() - hRange.value(); 54 | val estSize = (hRange.value() * 2 + 1) ^ 2; 55 | val posIter = new BlockPosIterator(new CubeCoordinateIterator(minX, y, minZ, maxX, y, maxZ)); 56 | 57 | return StreamSupport 58 | .stream(Spliterators.spliterator(posIter, estSize, CHARACTERISTICS), PARALLEL) 59 | .map(XZ::new); 60 | } 61 | 62 | @RequiredArgsConstructor 63 | private static final class BlockPosIterator implements Iterator { 64 | private final CubeCoordinateIterator coords; 65 | 66 | @Override 67 | public boolean hasNext() { 68 | return coords.hasNext(); 69 | } 70 | 71 | @Override 72 | public BlockPos next() { 73 | return new BlockPos(coords.getX(), coords.getY(), coords.getZ()); 74 | } 75 | } 76 | 77 | @Value 78 | final class XZ { 79 | // Area内のいずれかのx,z座標でPlayerと同じy座標のpos 80 | final BlockPos playerYPos; 81 | 82 | IntStream yStream() { 83 | return IntStream.range(playerYPos.getY() - vRange.value(), playerYPos.getY() + vRange.value() + 1); 84 | } 85 | 86 | BlockPos withY(int y) { 87 | return new BlockPos(playerYPos.getX(), y, playerYPos.getZ()); 88 | } 89 | 90 | Stream posStream() { 91 | return yStream().mapToObj(this::withY); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/SelectableMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import net.awairo.minecraft.spawnchecker.api.Mode; 23 | import net.awairo.minecraft.spawnchecker.hud.HudIconResource; 24 | 25 | abstract class SelectableMode extends PresetMode implements Mode.Selectable { 26 | SelectableMode(Name name, HudIconResource icon, Priority priority) { 27 | super(name, icon, priority); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/SlimeCheckMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import java.util.stream.Stream; 23 | 24 | import net.awairo.minecraft.spawnchecker.api.Marker; 25 | import net.awairo.minecraft.spawnchecker.api.PlayerPos; 26 | import net.awairo.minecraft.spawnchecker.hud.HudIconResource; 27 | 28 | public class SlimeCheckMode extends SelectableMode { 29 | static final String TRANSLATION_KEY = "spawnchecker.mode.slimeChunkVisualizer"; 30 | static final Name NAME = new Name(TRANSLATION_KEY); 31 | static final Priority PRIORITY = new Priority(50); 32 | 33 | public SlimeCheckMode() { 34 | super(NAME, HudIconResource.SLIME_CHUNK_CHECKER, PRIORITY); 35 | } 36 | 37 | @Override 38 | protected void setUp() { 39 | 40 | } 41 | 42 | @Override 43 | protected void tearDown() { 44 | 45 | } 46 | 47 | @Override 48 | public Stream update(State modeState, PlayerPos playerPos) { 49 | return Stream.empty(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/SpawnCheckMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import java.util.LinkedList; 23 | import java.util.stream.Stream; 24 | 25 | import net.minecraft.block.BlockState; 26 | import net.minecraft.block.Blocks; 27 | import net.minecraft.client.world.ClientWorld; 28 | import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType; 29 | import net.minecraft.entity.EntityType; 30 | import net.minecraft.fluid.FluidState; 31 | import net.minecraft.tags.BlockTags; 32 | import net.minecraft.util.math.BlockPos; 33 | import net.minecraft.world.LightType; 34 | 35 | import net.awairo.minecraft.spawnchecker.api.Color; 36 | import net.awairo.minecraft.spawnchecker.api.Marker; 37 | import net.awairo.minecraft.spawnchecker.api.PlayerPos; 38 | import net.awairo.minecraft.spawnchecker.config.PresetModeConfig; 39 | import net.awairo.minecraft.spawnchecker.hud.HudIconResource; 40 | import net.awairo.minecraft.spawnchecker.mode.marker.SpawnPointMarker; 41 | 42 | import lombok.extern.log4j.Log4j2; 43 | import lombok.val; 44 | 45 | @Log4j2 46 | public class SpawnCheckMode extends SelectableMode { 47 | public static final String TRANSLATION_KEY = "spawnchecker.mode.spawnchecker"; 48 | static final Name NAME = new Name(TRANSLATION_KEY); 49 | private static final Priority PRIORITY = new Priority(100); 50 | 51 | private final PresetModeConfig config; 52 | 53 | public SpawnCheckMode(PresetModeConfig config) { 54 | super(NAME, HudIconResource.SPAWN_CHECKER, PRIORITY); 55 | this.config = config; 56 | } 57 | 58 | @Override 59 | protected void setUp() { 60 | // なんかあるっけ? 61 | } 62 | 63 | @Override 64 | protected void tearDown() { 65 | // なんかあるっけ? 66 | } 67 | 68 | @Override 69 | public Stream update(State modeState, PlayerPos playerPos) { 70 | val world = modeState.worldClient(); 71 | val area = new ScanArea(playerPos, modeState.horizontalRange(), modeState.verticalRange()); 72 | 73 | // TODO: ネザー、エンド対応 74 | // if (world.getDimension().isSurfaceWorld()) { 75 | if (world.func_239132_a_() instanceof net.minecraft.client.world.DimensionRenderInfo.Overworld) { 76 | return updateInSurfaceWorld(world, area); 77 | } 78 | 79 | return Stream.empty(); 80 | } 81 | 82 | private Stream updateInSurfaceWorld(ClientWorld world, ScanArea area) { 83 | 84 | val markerBuilder = SpawnPointMarker.builder() 85 | .endermanMarkerColor(Color.ofColorCode("#40FF0064")) 86 | .zombieSizeMobMarkerColor(Color.ofColorCode("#FFFF6464")) 87 | .spiderMarkerColor(Color.ofColorCode("#4040ff64")) 88 | .slimeMarkerColor(Color.ofColorCode("#50E8C964")) 89 | .ghastMarkerColor(Color.ofColorCode("#4040FF64")) 90 | .drawGuideline(config.drawGuideline()); 91 | 92 | return area.xzStream().parallel().flatMap(xz -> { 93 | val placeType = PlacementType.ON_GROUND; 94 | val posIterator = xz.posStream().iterator(); 95 | 96 | if (!posIterator.hasNext()) 97 | return Stream.empty(); 98 | 99 | val lightLevelThreshold = 7; 100 | BlockPos underLoc = null, loc; 101 | BlockState underBlock = null, locBlock; 102 | FluidState locFluid; 103 | 104 | boolean underIsSpawnableBlock = false; 105 | 106 | val list = new LinkedList(); 107 | 108 | // 現在位置が空気で、下に上面が平らのブロックがある座標を下から上に向かって探索 109 | // TODO: クソ雑ロジック見直す 110 | while (posIterator.hasNext()) { 111 | loc = posIterator.next(); 112 | locBlock = world.getBlockState(loc); 113 | 114 | // region 足元のブロックがスポーン可能であることの判定 115 | // 上面が平らならスポーンできるブロック 116 | if (locBlock.isSolid()) { 117 | // 岩盤とバリアブロックにはスポーンできない 118 | underIsSpawnableBlock = 119 | locBlock.getBlock() != Blocks.BEDROCK && locBlock.getBlock() != Blocks.BARRIER; 120 | underLoc = loc; 121 | underBlock = locBlock; 122 | continue; 123 | } 124 | 125 | // 下がスポーンできるブロックじゃない場合は次のブロックへ 126 | if (!underIsSpawnableBlock) { 127 | underLoc = loc; 128 | underBlock = locBlock; 129 | continue; 130 | } 131 | 132 | // もうこの判定はしないため先にリセット 133 | underIsSpawnableBlock = false; 134 | // endregion 135 | 136 | // region 現在の座標はなにもない空気ブロックであることの判定 137 | // WorldEntitySpawner#func_234968_a_[isValidEmptySpawnBlock](IBlockReader, BlockPos, BlockState, FluidState, EntityType) と同様の判定 138 | 139 | if (locBlock.isOpaqueCube(world, loc) || locBlock.canProvidePower() || locBlock.isIn(BlockTags.RAILS)) { 140 | underLoc = loc; 141 | underBlock = locBlock; 142 | continue; 143 | } 144 | 145 | locFluid = world.getFluidState(loc); 146 | if (!locFluid.isEmpty()) { 147 | underLoc = loc; 148 | underBlock = locBlock; 149 | continue; 150 | } 151 | // endregion 152 | 153 | // region 明るさ判定 154 | // net.minecraft.entity.monster.MonsterEntity#isValidLightLevel() 155 | if (world.getLightFor(LightType.BLOCK, loc) > lightLevelThreshold) { 156 | underLoc = loc; 157 | underBlock = locBlock; 158 | continue; 159 | } 160 | // endregion 161 | 162 | if (EntitySize.ENDERMAN.isNotCollidingWithoutOtherEntityCollision(world, loc) && 163 | underBlock.canCreatureSpawn(world, underLoc, placeType, EntityType.ENDERMAN)) { 164 | list.add(markerBuilder.buildEndermanMarker(loc, YOffset.of(locBlock, underBlock))); 165 | underLoc = loc; 166 | underBlock = locBlock; 167 | continue; 168 | } 169 | 170 | if (EntitySize.ZOMBIE.isNotCollidingWithoutOtherEntityCollision(world, loc) && 171 | underBlock.canCreatureSpawn(world, underLoc, placeType, EntityType.ZOMBIE)) { 172 | // ゾンビOK 173 | list.add(markerBuilder.buildZombieSizeMobMarker(loc, YOffset.of(locBlock, underBlock))); 174 | underLoc = loc; 175 | underBlock = locBlock; 176 | continue; 177 | } 178 | 179 | if (EntitySize.SPIDER.isNotCollidingWithoutOtherEntityCollision(world, loc) && 180 | underBlock.canCreatureSpawn(world, underLoc, placeType, EntityType.SPIDER)) { 181 | // クモOK 182 | list.add(markerBuilder.buildSpiderMarker(loc, YOffset.of(locBlock, underBlock))); 183 | underLoc = loc; 184 | underBlock = locBlock; 185 | continue; 186 | } 187 | 188 | underLoc = loc; 189 | underBlock = locBlock; 190 | } 191 | 192 | return list.stream(); 193 | }); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/SpawnEntityType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | public enum SpawnEntityType { 23 | DEFAULT, 24 | ENDERMAN, 25 | SPIDER 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/SpawnerVisualizerMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import java.util.stream.Stream; 23 | 24 | import net.awairo.minecraft.spawnchecker.api.Marker; 25 | import net.awairo.minecraft.spawnchecker.api.Mode; 26 | import net.awairo.minecraft.spawnchecker.api.PlayerPos; 27 | import net.awairo.minecraft.spawnchecker.hud.HudIconResource; 28 | 29 | public class SpawnerVisualizerMode extends ConditionalMode { 30 | static final String TRANSLATION_KEY = "spawnchecker.mode.spawnerVisualizer"; 31 | static final Name NAME = new Name(TRANSLATION_KEY); 32 | static final Priority PRIORITY = new Priority(100); 33 | 34 | public SpawnerVisualizerMode() { 35 | super(NAME, HudIconResource.SPAWNER_VISUALIZER, PRIORITY); 36 | } 37 | 38 | @Override 39 | public boolean canActivate(PlayerPos playerPos, Mode.State state) { 40 | return false; 41 | } 42 | 43 | @Override 44 | public boolean canContinue(PlayerPos playerPos, Mode.State state) { 45 | return false; 46 | } 47 | 48 | @Override 49 | protected void setUp() { 50 | 51 | } 52 | 53 | @Override 54 | protected void tearDown() { 55 | 56 | } 57 | 58 | @Override 59 | public Stream update(State modeState, PlayerPos playerPos) { 60 | return Stream.empty(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/UpdateTimer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import net.awairo.minecraft.spawnchecker.config.SpawnCheckerConfig; 23 | 24 | import lombok.AccessLevel; 25 | import lombok.RequiredArgsConstructor; 26 | import lombok.Value; 27 | import lombok.val; 28 | 29 | @RequiredArgsConstructor(access = AccessLevel.PACKAGE) 30 | public final class UpdateTimer { 31 | 32 | private final SpawnCheckerConfig config; 33 | 34 | private long lastUpdate; 35 | 36 | boolean canUpdate(long now) { 37 | val ret = now - lastUpdate > config.modeConfig().checkInterval().milliSeconds; 38 | if (ret) 39 | lastUpdate = now; 40 | return ret; 41 | } 42 | 43 | @Value 44 | public static final class Interval { 45 | public static final int MIN_VALUE = 50; 46 | public static final int MAX_VALUE = 5_000; 47 | public static final Interval DEFAULT = new Interval(500); 48 | 49 | public static Interval ofMilliSeconds(int milliSeconds) { 50 | return milliSeconds == DEFAULT.milliSeconds ? DEFAULT : new Interval(milliSeconds); 51 | } 52 | 53 | private final int milliSeconds; 54 | 55 | private Interval(int milliSeconds) { 56 | if (milliSeconds < MIN_VALUE || milliSeconds > MAX_VALUE) 57 | throw new IllegalArgumentException("Out of range. (" + milliSeconds + ")"); 58 | this.milliSeconds = milliSeconds; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/YOffset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import java.util.Objects; 23 | 24 | import net.minecraft.block.BlockState; 25 | import net.minecraft.block.Blocks; 26 | import net.minecraft.block.SlabBlock; 27 | import net.minecraft.state.properties.SlabType; 28 | 29 | import lombok.Getter; 30 | import lombok.RequiredArgsConstructor; 31 | 32 | @RequiredArgsConstructor 33 | @Getter 34 | public enum YOffset { 35 | DEFAULT(0.0d, 0.0d), 36 | SNOW_ON_TOP(0.1d, 0.0d), 37 | SINGLE_TOP_SLAB(0.0d, 0.5d), 38 | SINGLE_TOP_SLAB_SNOW_ON_TOP(SNOW_ON_TOP.topOffset, SINGLE_TOP_SLAB.bottomOffset), 39 | ; 40 | 41 | final double topOffset; 42 | final double bottomOffset; 43 | 44 | static YOffset of(BlockState state, BlockState underState) { 45 | if (snowOnTop(state)) 46 | return singleTopSlab(underState) ? SINGLE_TOP_SLAB_SNOW_ON_TOP : SNOW_ON_TOP; 47 | return singleTopSlab(underState) ? SINGLE_TOP_SLAB : DEFAULT; 48 | } 49 | 50 | private static boolean snowOnTop(BlockState state) { 51 | return Objects.equals(state.getBlock(), Blocks.SNOW); 52 | } 53 | 54 | private static boolean singleTopSlab(BlockState underState) { 55 | return underState.getBlock() instanceof SlabBlock && underState.get(SlabBlock.TYPE) == SlabType.TOP; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "YOffset(top=" + topOffset + ",bottom=" + bottomOffset + ")"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/marker/FixedMarker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode.marker; 21 | 22 | import javax.annotation.Nonnull; 23 | import com.google.common.base.MoreObjects; 24 | 25 | import net.minecraft.util.math.vector.Vector3d; 26 | 27 | import net.awairo.minecraft.spawnchecker.api.Marker; 28 | 29 | import lombok.EqualsAndHashCode; 30 | import lombok.Getter; 31 | import lombok.RequiredArgsConstructor; 32 | 33 | @Getter 34 | @EqualsAndHashCode 35 | @RequiredArgsConstructor 36 | abstract class FixedMarker implements Marker { 37 | 38 | private final Vector3d pos; 39 | 40 | @Nonnull 41 | @Override 42 | public String toString() { 43 | return MoreObjects.toStringHelper(this) 44 | .add("x", pos.x) 45 | .add("y", pos.y) 46 | .add("z", pos.z) 47 | .toString(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/marker/MarkerModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode.marker; 21 | 22 | import net.awairo.minecraft.spawnchecker.api.MarkerRenderer; 23 | 24 | public interface MarkerModel { 25 | void draw(MarkerRenderer renderer); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/marker/SpawnPointMarker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode.marker; 21 | 22 | import javax.annotation.Nullable; 23 | import com.mojang.blaze3d.systems.RenderSystem; 24 | 25 | import net.minecraft.util.ResourceLocation; 26 | import net.minecraft.util.math.BlockPos; 27 | 28 | import net.awairo.minecraft.spawnchecker.SpawnChecker; 29 | import net.awairo.minecraft.spawnchecker.api.Color; 30 | import net.awairo.minecraft.spawnchecker.api.Marker; 31 | import net.awairo.minecraft.spawnchecker.api.MarkerRenderer; 32 | import net.awairo.minecraft.spawnchecker.mode.YOffset; 33 | import net.awairo.minecraft.spawnchecker.mode.marker.model.GuidelineModel; 34 | import net.awairo.minecraft.spawnchecker.mode.marker.model.SpawnPointModel; 35 | 36 | import lombok.AccessLevel; 37 | import lombok.Data; 38 | import lombok.Getter; 39 | import lombok.NoArgsConstructor; 40 | import lombok.RequiredArgsConstructor; 41 | import lombok.experimental.Accessors; 42 | import lombok.val; 43 | 44 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE) 45 | public class SpawnPointMarker implements Marker { 46 | 47 | enum Texture { 48 | DEFAULT, ENDERMAN, GHAST, SLIME, SPIDER; 49 | @Getter 50 | private final ResourceLocation location = 51 | new ResourceLocation(SpawnChecker.MOD_ID, "textures/markers/spawn_marker_" + name().toLowerCase() + ".png"); 52 | } 53 | 54 | public static Builder builder() { return new Builder(); } 55 | 56 | @Data 57 | @Accessors(chain = true, fluent = true) 58 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 59 | public static final class Builder { 60 | private Color endermanMarkerColor; 61 | private Color zombieSizeMobMarkerColor; 62 | private Color spiderMarkerColor; 63 | private Color slimeMarkerColor; 64 | private Color ghastMarkerColor; 65 | private boolean drawGuideline; 66 | private double blockSize = 0.4d; 67 | 68 | public SpawnPointMarker buildEndermanMarker(BlockPos pos, YOffset yOffset) { 69 | return new SpawnPointMarker(Texture.ENDERMAN, blockSize, endermanMarkerColor, pos, yOffset, drawGuideline); 70 | } 71 | 72 | public SpawnPointMarker buildZombieSizeMobMarker(BlockPos pos, YOffset yOffset) { 73 | return new SpawnPointMarker(Texture.DEFAULT, blockSize, zombieSizeMobMarkerColor, pos, yOffset, drawGuideline); 74 | } 75 | 76 | public SpawnPointMarker buildSpiderMarker(BlockPos pos, YOffset yOffset) { 77 | return new SpawnPointMarker(Texture.SPIDER, blockSize, spiderMarkerColor, pos, yOffset, drawGuideline); 78 | } 79 | 80 | public SpawnPointMarker buildSlimeMarker(BlockPos pos, YOffset yOffset) { 81 | return new SpawnPointMarker(Texture.SLIME, blockSize, slimeMarkerColor, pos, yOffset, drawGuideline); 82 | } 83 | 84 | public SpawnPointMarker buildGhastMarker(BlockPos pos, YOffset yOffset) { 85 | return new SpawnPointMarker(Texture.GHAST, blockSize, ghastMarkerColor, pos, yOffset, drawGuideline); 86 | } 87 | } 88 | 89 | private final SpawnPointModel markerModel; 90 | 91 | @Nullable 92 | private final GuidelineModel guidelineModel; 93 | 94 | private final BlockPos pos; 95 | private final Color color; 96 | 97 | private SpawnPointMarker( 98 | Texture texture, 99 | double blockSize, 100 | Color color, 101 | BlockPos pos, 102 | YOffset yOffset, 103 | boolean drawGuideline 104 | ) { 105 | this.markerModel = new SpawnPointModel(texture.location, blockSize, 0.03d, yOffset); 106 | this.guidelineModel = drawGuideline ? new GuidelineModel() : null; 107 | this.pos = pos; 108 | this.color = color; 109 | } 110 | 111 | @Override 112 | public void draw(MarkerRenderer renderer) { 113 | if (renderer.renderManager().info == null) 114 | return; 115 | 116 | val viewerPos = renderer.renderManager().info.getProjectedView(); 117 | renderer.push(); 118 | { 119 | color.setToColor4F(RenderSystem::color4f); 120 | renderer.translate( 121 | ((double) pos.getX()) - viewerPos.x, 122 | ((double) pos.getY()) - viewerPos.y - 1d, // 1ブロック下げる 123 | ((double) pos.getZ()) - viewerPos.z 124 | ); 125 | markerModel.draw(renderer); 126 | 127 | } 128 | renderer.pop(); 129 | 130 | if (guidelineModel == null) 131 | return; 132 | 133 | renderer.push(); 134 | { 135 | color.setToColor4F(RenderSystem::color4f); 136 | renderer.translate( 137 | ((double) pos.getX()) - viewerPos.x, 138 | ((double) pos.getY()) - viewerPos.y, 139 | ((double) pos.getZ()) - viewerPos.z 140 | ); 141 | guidelineModel.draw(renderer); 142 | } 143 | renderer.pop(); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/marker/model/GuidelineModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode.marker.model; 21 | 22 | import com.mojang.blaze3d.platform.GlStateManager.DestFactor; 23 | import com.mojang.blaze3d.platform.GlStateManager.SourceFactor; 24 | import com.mojang.blaze3d.systems.RenderSystem; 25 | import org.lwjgl.opengl.GL11; 26 | 27 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 28 | 29 | import net.awairo.minecraft.spawnchecker.api.MarkerRenderer; 30 | import net.awairo.minecraft.spawnchecker.mode.marker.MarkerModel; 31 | 32 | public class GuidelineModel implements MarkerModel { 33 | 34 | @Override 35 | public void draw(MarkerRenderer renderer) { 36 | RenderSystem.enableBlend(); 37 | RenderSystem.blendFuncSeparate( 38 | SourceFactor.SRC_ALPHA.param, DestFactor.ONE_MINUS_SRC_ALPHA.param, 39 | SourceFactor.ONE.param, DestFactor.ZERO.param 40 | ); 41 | renderer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION); 42 | 43 | renderer.addVertex(0.5d, 0d, 0.5d); 44 | renderer.addVertex(0.5d, 32d, 0.5d); 45 | renderer.draw(); 46 | RenderSystem.disableBlend(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/mode/marker/model/SpawnPointModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode.marker.model; 21 | 22 | import com.google.common.base.MoreObjects; 23 | import com.mojang.blaze3d.platform.GlStateManager.DestFactor; 24 | import com.mojang.blaze3d.platform.GlStateManager.SourceFactor; 25 | import com.mojang.blaze3d.systems.RenderSystem; 26 | import org.lwjgl.opengl.GL11; 27 | 28 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 29 | import net.minecraft.util.ResourceLocation; 30 | 31 | import net.awairo.minecraft.spawnchecker.api.MarkerRenderer; 32 | import net.awairo.minecraft.spawnchecker.mode.YOffset; 33 | import net.awairo.minecraft.spawnchecker.mode.marker.MarkerModel; 34 | 35 | import lombok.NonNull; 36 | import lombok.val; 37 | 38 | public class SpawnPointModel implements MarkerModel { 39 | 40 | private static final double BLOCK_SIZE = 1.0d; 41 | 42 | private final ResourceLocation texture; 43 | private final double markerSize; 44 | private final double offset; 45 | private final YOffset yOffset; 46 | 47 | private final double oMin; 48 | private final double oMax; 49 | private final double oMinY; 50 | private final double oMaxY; 51 | private final double iMin; 52 | private final double iMax; 53 | 54 | public SpawnPointModel(@NonNull ResourceLocation texture, double markerSize, double offset, YOffset yOffset) { 55 | this.texture = texture; 56 | this.markerSize = markerSize; 57 | this.offset = offset; 58 | this.yOffset = yOffset; 59 | 60 | this.oMin = 0d - offset; 61 | this.oMax = BLOCK_SIZE + offset; 62 | this.oMinY = oMin + yOffset.bottomOffset(); 63 | this.oMaxY = oMax + yOffset.topOffset(); 64 | val markerSizeOffset = (oMax - markerSize) / 2; 65 | 66 | this.iMin = oMin + markerSizeOffset; 67 | this.iMax = oMax - markerSizeOffset; 68 | } 69 | 70 | @SuppressWarnings("Duplicates") 71 | @Override 72 | public void draw(MarkerRenderer renderer) { 73 | RenderSystem.enableBlend(); 74 | RenderSystem.blendFuncSeparate( 75 | SourceFactor.SRC_ALPHA.param, DestFactor.ONE_MINUS_SRC_ALPHA.param, 76 | SourceFactor.ONE.param, DestFactor.ZERO.param 77 | ); 78 | RenderSystem.enableTexture(); 79 | 80 | renderer.bindTexture(texture); 81 | 82 | renderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); 83 | 84 | float minU = 0.0f; 85 | float maxU = 0.5f; 86 | float minV = 0.0f; 87 | float maxV = 0.5f; 88 | // top 89 | renderer.addVertex(iMin, oMaxY, iMin, minU, minV); 90 | renderer.addVertex(iMin, oMaxY, iMax, minU, maxV); 91 | renderer.addVertex(iMax, oMaxY, iMax, maxU, maxV); 92 | renderer.addVertex(iMax, oMaxY, iMin, maxU, minV); 93 | // bottom 94 | renderer.addVertex(iMin, oMinY, iMin, minU, minV); 95 | renderer.addVertex(iMax, oMinY, iMin, maxU, minV); 96 | renderer.addVertex(iMax, oMinY, iMax, maxU, maxV); 97 | renderer.addVertex(iMin, oMinY, iMax, minU, maxV); 98 | // east 99 | renderer.addVertex(iMin, iMin, oMin, minU, minV); 100 | renderer.addVertex(iMin, iMax, oMin, minU, maxV); 101 | renderer.addVertex(iMax, iMax, oMin, maxU, maxV); 102 | renderer.addVertex(iMax, iMin, oMin, maxU, minV); 103 | // west 104 | renderer.addVertex(iMin, iMin, oMax, minU, minV); 105 | renderer.addVertex(iMax, iMin, oMax, maxU, minV); 106 | renderer.addVertex(iMax, iMax, oMax, maxU, maxV); 107 | renderer.addVertex(iMin, iMax, oMax, minU, maxV); 108 | // north 109 | renderer.addVertex(oMin, iMin, iMin, minU, minV); 110 | renderer.addVertex(oMin, iMin, iMax, minU, maxV); 111 | renderer.addVertex(oMin, iMax, iMax, maxU, maxV); 112 | renderer.addVertex(oMin, iMax, iMin, maxU, minV); 113 | // south 114 | renderer.addVertex(oMax, iMin, iMin, minU, minV); 115 | renderer.addVertex(oMax, iMax, iMin, maxU, minV); 116 | renderer.addVertex(oMax, iMax, iMax, maxU, maxV); 117 | renderer.addVertex(oMax, iMin, iMax, minU, maxV); 118 | 119 | renderer.draw(); 120 | RenderSystem.disableBlend(); 121 | } 122 | 123 | @Override 124 | public String toString() { 125 | return MoreObjects.toStringHelper(this) 126 | .add("markerSize", markerSize) 127 | .add("topOffset", offset) 128 | .add("yOffset", yOffset) 129 | .add("oMin", oMin) 130 | .add("oMax", oMax) 131 | .add("oMaxY", oMaxY) 132 | .add("iMin", iMin) 133 | .add("iMax", iMax) 134 | .toString(); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | /** 21 | * SpawnChecker. 22 | */ 23 | package net.awairo.minecraft.spawnchecker; 24 | -------------------------------------------------------------------------------- /src/main/java/net/awairo/minecraft/spawnchecker/util/LazyCachedSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.util; 21 | 22 | import java.util.function.Supplier; 23 | 24 | import lombok.NonNull; 25 | import lombok.val; 26 | 27 | public class LazyCachedSupplier implements Supplier { 28 | 29 | public static LazyCachedSupplier of(@NonNull Supplier supplier) { 30 | if (!(supplier instanceof LazyCachedSupplier)) 31 | return new LazyCachedSupplier<>(supplier); 32 | 33 | @SuppressWarnings("unchecked") 34 | val ret = (LazyCachedSupplier) supplier; 35 | return ret; 36 | } 37 | 38 | public static LazyCachedSupplier withCached(@NonNull T value) { 39 | return new LazyCachedSupplier<>(dummySupplier(), value); 40 | } 41 | 42 | private final Supplier underlying; 43 | private volatile Object cache; 44 | 45 | private LazyCachedSupplier(Supplier supplier) { 46 | this(supplier, unset()); 47 | } 48 | 49 | private LazyCachedSupplier(Supplier supplier, T value) { 50 | this.underlying = supplier; 51 | this.cache = value; 52 | } 53 | 54 | @Override 55 | public T get() { 56 | if (cache == UNSET) 57 | synchronized (this) { 58 | if (cache == UNSET) 59 | cache = underlying.get(); 60 | } 61 | 62 | @SuppressWarnings("unchecked") 63 | T ret = (T) cache; 64 | return ret; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return String.format( 70 | "LazyCachedSupplier(cache=%s, underlying=%s)", 71 | (cache == UNSET ? "none" : "'" + cache + "'"), underlying 72 | ); 73 | } 74 | 75 | private static final Object UNSET = new Object(); 76 | private static final Supplier DUMMY_SUPPLIER = () -> { 77 | throw new UnsupportedOperationException("DUMMY_SUPPLIER"); 78 | }; 79 | 80 | @SuppressWarnings("unchecked") 81 | private static T unset() { 82 | return (T) UNSET; 83 | } 84 | 85 | @SuppressWarnings("unchecked") 86 | private static Supplier dummySupplier() { 87 | return (Supplier) DUMMY_SUPPLIER; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | # 2 | # SpawnChecker. 3 | # 4 | modLoader="javafml" 5 | loaderVersion="{loaderVersion}" 6 | license="GNU LGPLv3" 7 | issueTrackerURL="https://github.com/alalwww/SpawnChecker/issues" 8 | 9 | [[mods]] 10 | modId="spawnchecker" 11 | version="{version}" 12 | logoFile="spawnchecker_logo.png" 13 | displayName="SpawnChecker" 14 | displayURL="https://awairo.net/minecraft/" 15 | authors="alalwww" 16 | credits="By alalwww, original mod idea by fillppo." 17 | description=''' 18 | The SpawnChecker draw information of mob spawn points, slime chunks and the monster spawner on in-game. 19 | ''' 20 | #updateJSONURL="https://awairo.net/minecraft/SpawnChecker-update.json" 21 | 22 | [[dependencies.spawnchecker]] 23 | modId="forge" 24 | mandatory=true 25 | versionRange="{forgeVersionRange}" 26 | ordering="NONE" 27 | side="CLIENT" 28 | 29 | [[dependencies.spawnchecker]] 30 | modId="minecraft" 31 | mandatory=true 32 | versionRange="{minecraftVersionRange}" 33 | ordering="NONE" 34 | side="CLIENT" 35 | -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "spawnchecker.name" : "SpawnChecker", 3 | "spawnchecker.key.categoryName" : "Spawn Checker Control", 4 | "spawnchecker.key.prevMode" : "Select prev mode", 5 | "spawnchecker.key.nextMode" : "Select next mode", 6 | "spawnchecker.key.prevModeOption" : "Select prev mode option", 7 | "spawnchecker.key.nextModeOption" : "Select next mode option", 8 | "spawnchecker.key.horizontalRangePlus" : "Increment horizontal range", 9 | "spawnchecker.key.horizontalRangeMinus" : "Decrement horizontal range", 10 | "spawnchecker.key.verticalRangePlus" : "Increment Vertical range", 11 | "spawnchecker.key.verticalRangeMinus" : "Decrement Vertical range", 12 | "spawnchecker.key.brightnessPlus" : "Increment marker brightness", 13 | "spawnchecker.key.brightnessMinus" : "Decrement marker brightness", 14 | "spawnchecker.config.enabled" : "", 15 | "spawnchecker.config.usingHands" : "", 16 | "spawnchecker.config.hud.showDuration" : "", 17 | "spawnchecker.config.key.repeatDelay" : "", 18 | "spawnchecker.config.key.repeatRate" : "", 19 | "spawnchecker.config.mode.selectedMode" : "", 20 | "spawnchecker.config.mode.scan.interval" : "", 21 | "spawnchecker.config.mode.scan.horizontalRange" : "", 22 | "spawnchecker.config.mode.scan.verticalRange" : "", 23 | "spawnchecker.config.mode.marker.brightness" : "", 24 | "spawnchecker.hud.brightness" : "Brightness: %+d", 25 | "spawnchecker.hud.horizontalRange" : "H Range: %2d", 26 | "spawnchecker.hud.verticalRange" : "V Range: %2d", 27 | "spawnchecker.mode.spawnchecker" : "Spawn checker mode", 28 | "spawnchecker.mode.slimeChunkVisualizer" : "Slime chunk visualizer mode", 29 | "spawnchecker.mode.spawnerVisualizer" : "Spawner visualizer mode", 30 | "spawnchecker.mode.option.disable" : " - Disabled", 31 | "spawnchecker.mode.option.marker" : " - Marker", 32 | "spawnchecker.mode.option.guideline" : " - Guideline", 33 | "spawnchecker.mode.option.slime" : " - Slime marker", 34 | "spawnchecker.mode.option.ghast" : " - Ghast marker", 35 | "spawnchecker.mode.option.force" : " - Force", 36 | "spawnchecker.mode.option.forceMarker" : " - Marker(Force)", 37 | "spawnchecker.mode.option.forceGuideline" : " - Guideline(Force)", 38 | "spawnchecker.mode.option.forceSlime" : " - Slime marker(Force)", 39 | "spawnchecker.mode.option.slimeChunk" : " - Slime chunk", 40 | "spawnchecker.mode.option.spawnerHidden" : " - Hidden", 41 | "spawnchecker.mode.option.spawnerSpawnArea" : " - Spawn area", 42 | "spawnchecker.mode.option.spawnerSpawnLimitArea" : " - Spawn limit area", 43 | "spawnchecker.mode.option.spawnerSpawnablePoint" : " - Spawn-able point", 44 | "spawnchecker.mode.option.spawnerUnspawnablePoint": " - Un-spawn-able point", 45 | "spawnchecker.mode.option.spawnerActivateArea" : " - Activate area", 46 | "spawnchecker.fingerprintViolation" : "fingerprint violation: This mod may have been hacked. (modid: %s)", 47 | "spawnchecker.command.message.toEnabled" : "Enabled SpawnChecker.", 48 | "spawnchecker.command.message.toDisabled" : "Disabled SpawnChecker.", 49 | "spawnchecker.command.message.guidelineOn" : "Enabled marker guidelines.", 50 | "spawnchecker.command.message.guidelineOff" : "Disabled marker guidelines." 51 | } 52 | -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/lang/ja_jp.json: -------------------------------------------------------------------------------- 1 | { 2 | "spawnchecker.name" : "SpawnChecker", 3 | "spawnchecker.key.categoryName" : "スポーンチェッカー操作", 4 | "spawnchecker.key.prevMode" : "前のモード選択", 5 | "spawnchecker.key.nextMode" : "次のモード選択", 6 | "spawnchecker.key.prevModeOption" : "前のモードオプション選択", 7 | "spawnchecker.key.nextModeOption" : "次のモードオプション選択", 8 | "spawnchecker.key.horizontalRangePlus" : "水平スキャン範囲を広げる", 9 | "spawnchecker.key.horizontalRangeMinus" : "水平スキャン範囲を狭める", 10 | "spawnchecker.key.verticalRangePlus" : "垂直スキャン範囲を広げる", 11 | "spawnchecker.key.verticalRangeMinus" : "垂直スキャン範囲を狭める", 12 | "spawnchecker.key.brightnessPlus" : "マーカーの明るさを上げる", 13 | "spawnchecker.key.brightnessMinus" : "マーカーの明るさを下げる", 14 | "spawnchecker.config.enabled" : "", 15 | "spawnchecker.config.usingHands" : "", 16 | "spawnchecker.config.hud.showDuration" : "", 17 | "spawnchecker.config.key.repeatDelay" : "", 18 | "spawnchecker.config.key.repeatRate" : "", 19 | "spawnchecker.config.mode.selectedMode" : "", 20 | "spawnchecker.config.mode.scan.interval" : "", 21 | "spawnchecker.config.mode.scan.horizontalRange" : "", 22 | "spawnchecker.config.mode.scan.verticalRange" : "", 23 | "spawnchecker.config.mode.marker.brightness" : "", 24 | "spawnchecker.hud.brightness" : "マーカー明るさ: %+d", 25 | "spawnchecker.hud.horizontalRange" : "水平範囲: %2d", 26 | "spawnchecker.hud.verticalRange" : "垂直範囲: %2d", 27 | "spawnchecker.mode.spawnchecker" : "スポーンチェッカー", 28 | "spawnchecker.mode.slimeChunkVisualizer" : "スライムチャンク可視化", 29 | "spawnchecker.mode.spawnerVisualizer" : "スポーンブロック可視化", 30 | "spawnchecker.mode.option.disable" : " - 無効", 31 | "spawnchecker.mode.option.marker" : " - マーカー", 32 | "spawnchecker.mode.option.guideline" : " - ガイドライン", 33 | "spawnchecker.mode.option.slime" : " - スライムマーカー", 34 | "spawnchecker.mode.option.ghast" : " - ガストマーカー", 35 | "spawnchecker.mode.option.force" : " - 常に表示", 36 | "spawnchecker.mode.option.forceMarker" : " - マーカー(常に表示)", 37 | "spawnchecker.mode.option.forceGuideline" : " - ガイドライン(常に表示)", 38 | "spawnchecker.mode.option.forceSlime" : " - スライムマーカー(常に表示)", 39 | "spawnchecker.mode.option.slimeChunk" : " - スライムチャンク", 40 | "spawnchecker.mode.option.spawnerHidden" : " - 非表示", 41 | "spawnchecker.mode.option.spawnerSpawnArea" : " - スポーン範囲", 42 | "spawnchecker.mode.option.spawnerSpawnLimitArea" : " - スポーン数制限範囲", 43 | "spawnchecker.mode.option.spawnerSpawnablePoint" : " - スポーン可能ポイント", 44 | "spawnchecker.mode.option.spawnerUnspawnablePoint": " - スポーン不可能ポイント", 45 | "spawnchecker.mode.option.spawnerActivateArea" : " - スポーナー活性化範囲", 46 | "spawnchecker.fingerprintViolation" : "fingerprint violation: このModはハックされている可能性があります。 (modid: %s)", 47 | "spawnchecker.command.message.toEnabled" : "スポーンチェッカーを有効にしました。", 48 | "spawnchecker.command.message.toDisabled" : "スポーンチェッカーを無効にしました。", 49 | "spawnchecker.command.message.guidelineOn" : "マーカーガイドラインを有効にしました。", 50 | "spawnchecker.command.message.guidelineOff" : "マーカーガイドラインを無効にしました。" 51 | } 52 | -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/hud/brightness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/hud/brightness.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/hud/horizontal_range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/hud/horizontal_range.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/hud/slime_chunk_visualizer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/hud/slime_chunk_visualizer.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/hud/spawn_checker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/hud/spawn_checker.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/hud/spawner_visualizer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/hud/spawner_visualizer.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/hud/vertical_range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/hud/vertical_range.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_default.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_enderman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_enderman.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_ghast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_ghast.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_slime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_slime.png -------------------------------------------------------------------------------- /src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_spider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/assets/spawnchecker/textures/markers/spawn_marker_spider.png -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "SpawnChecker Resources", 4 | "pack_format": 4 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/spawnchecker_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alalwww/SpawnChecker/a480d3649c96af7cc989fe616dca0b7368017043/src/main/resources/spawnchecker_logo.png -------------------------------------------------------------------------------- /src/test/java/net/awairo/minecraft/spawnchecker/mode/ScanRangeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.mode; 21 | 22 | import java.util.concurrent.ThreadLocalRandom; 23 | 24 | import net.awairo.minecraft.spawnchecker.api.ScanRange; 25 | import net.awairo.minecraft.spawnchecker.api.ScanRange.Vertical; 26 | 27 | import lombok.val; 28 | import org.junit.jupiter.api.Test; 29 | 30 | import static org.junit.jupiter.api.Assertions.*; 31 | 32 | class ScanRangeTest { 33 | 34 | @Test 35 | void testNext() { 36 | val value = ThreadLocalRandom.current().nextInt(ScanRange.Vertical.MIN_VALUE, ScanRange.Vertical.MAX_VALUE); 37 | assertEquals(Vertical.of(value).next(), Vertical.of(value + 1)); 38 | } 39 | 40 | @Test 41 | void testPrev() { 42 | val value = ThreadLocalRandom.current().nextInt(ScanRange.Vertical.MIN_VALUE, ScanRange.Vertical.MAX_VALUE) + 1; 43 | assertEquals(Vertical.of(value).prev(), Vertical.of(value - 1)); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/net/awairo/minecraft/spawnchecker/util/LazyCachedSupplierTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SpawnChecker 3 | * Copyright (C) 2019 alalwww 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3 of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | package net.awairo.minecraft.spawnchecker.util; 21 | 22 | import java.util.function.Supplier; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static org.junit.jupiter.api.Assertions.*; 27 | 28 | class LazyCachedSupplierTest { 29 | private static final class TestObject { 30 | static boolean initialized = false; 31 | 32 | TestObject() { 33 | if (initialized) 34 | fail("already initialized"); 35 | initialized = true; 36 | } 37 | } 38 | 39 | @Test 40 | void cachedTest() { 41 | Supplier sup = LazyCachedSupplier.of(TestObject::new); 42 | 43 | assertSame(sup.get(), sup.get()); 44 | } 45 | } 46 | --------------------------------------------------------------------------------