├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── conf ├── astyle.cfg └── settings.json ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── patch_mergetool.py ├── patches └── net │ └── minecraft │ ├── client │ ├── ClientBrandRetriever.java.patch │ ├── MainWindow.java.patch │ └── gui │ │ └── GuiCreateWorld.java.patch │ ├── server │ ├── MinecraftServer.java.patch │ └── dedicated │ │ └── DedicatedServer.java.patch │ ├── util │ └── SharedSeedRandom.java.patch │ └── world │ ├── WorldServer.java.patch │ ├── biome │ ├── DeepWarmOceanBiome.java.patch │ ├── MushroomFieldShoreBiome.java.patch │ ├── SnowyTaigaBiome.java.patch │ ├── SnowyTaigaHillsBiome.java.patch │ ├── SnowyTundraBiome.java.patch │ ├── StoneShoreBiome.java.patch │ ├── SunflowerPlainsBiome.java.patch │ ├── SwampHillsBiome.java.patch │ └── TaigaHillsBiome.java.patch │ └── gen │ ├── ChunkGenSettings.java.patch │ ├── feature │ ├── Feature.java.patch │ └── structure │ │ ├── BuriedTreasureStructure.java.patch │ │ ├── DesertPyramidStructure.java.patch │ │ ├── FortressStructure.java.patch │ │ ├── IglooStructure.java.patch │ │ ├── JunglePyramidStructure.java.patch │ │ ├── MineshaftStructure.java.patch │ │ ├── OceanMonumentStructure.java.patch │ │ ├── OceanRuinStructure.java.patch │ │ ├── ScatteredStructure.java.patch │ │ ├── ShipwreckStructure.java.patch │ │ ├── StrongholdStructure.java.patch │ │ ├── SwampHutStructure.java.patch │ │ ├── VillageStructure.java.patch │ │ └── WoodlandMansionStructure.java.patch │ └── layer │ ├── GenLayerBiome.java.patch │ ├── GenLayerMixOceans.java.patch │ └── LayerUtil.java.patch ├── settings.gradle └── src └── main └── java └── net └── earthcomputer └── bedrockified ├── BedrockAddOceanEdgeLayer.java ├── BedrockAddOceanTemperatureLayer.java ├── BedrockRandom.java ├── BedrockSeed.java ├── BedrockShipwreckStructure.java ├── BedrockSpawnPoint.java ├── BedrockStrongholdStructure.java └── package-info.java /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | /projects/ 3 | .project 4 | /build/ 5 | /out/ 6 | /.idea/ 7 | *.iml 8 | /run/ 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Joseph Burton (Earthcomputer) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bedrockified 2 | The Bedrockified project aims to implement Bedrock Edition mechanics into Java edition to ensure we understand these mechanics properly. 3 | 4 | ## Features 5 | The following should have parity between Bedrockified and real Bedrock edition: 6 | - Biome generation (only the biomes, not every tree will be the same) 7 | - Overworld and Nether structure locations 8 | - Slime chunks 9 | - Spawn point 10 | 11 | ## Installation instructions 12 | There are two easy ways to install Bedrockified, one using [MultiMC](https://multimc.org) and one using the server JAR. 13 | It is also possible to install the client version of Bedrockified on the vanilla launcher, but this is complicated so there are no instructions here. 14 | 15 | ### MultiMC 16 | 1. Download the client version of the Bedrockified zip from the releases page. 17 | 1. Download and install MultiMC from [https://multimc.org](https://multimc.org) if you don't have it already. 18 | 1. Create a new instance for Minecraft version 1.13.1 (note this is not the latest version!). 19 | 1. Click "edit instance", and on the right, "add to Minecraft.jar". 20 | 1. Navigate to and select the Bedrockified zip. 21 | 1. Start the game. 22 | 23 | ### Dedicated server 24 | 1. Download the server version of the Bedrockified zip from the releases page. 25 | 1. Download the 1.13.1 Minecraft server from [Mojang](https://launcher.mojang.com/v1/objects/fe123682e9cb30031eae351764f653500b7396c9/server.jar). 26 | 1. Move the server JAR into a separate folder, and execute it once from the command line using `java -jar server.jar`. 27 | 1. Open `eula.txt`, read the EULA it links to, then change the value to true. 28 | 1. Copy the contents of the Bedrockified zip into the server jar (which is just a zip with a different file extension), overwriting existing entries. How you do this is up to you, but I recommend 7zip. 29 | 1. Launch the server again, it should be running Bedrockified. Connect to it with a vanilla 1.13.1 client. 30 | 31 | ## Installation from source + contribution 32 | Bedrockified uses jarmod-buildsystem-2 by Earthcomputer, built on top of ForgeGradle 3.0 for making JAR mods in Minecraft: Java Edition 1.13+ 33 | 34 | ### Requirements 35 | - You need to have at least JDK8 update 92 for recompilation to work, due to a bug in earlier versions of `javac`. You also cannot use JDK9 or JDK10 yet. 36 | - You need to have `git` installed. 37 | - Eclipse Oxygen.3 or later, due to [this Eclipse bug](https://bugs.eclipse.org/bugs/show_bug.cgi?id=526911). 38 | - Or Intellij 39 | 40 | ### First-time setup 41 | - Copy all the files in this repository into your new project folder. 42 | - Delete the example mod from inside `patches` (do not delete the `patches` directory itself) and from inside`src/main/java`. 43 | - Edit `conf/settings.json` for your project. Each setting is described in more detail below. 44 | - Run `gradlew setup` to decompile and deobfuscate the code. 45 | - Run `gradlew eclipse` to setup the appropriate Eclipse projects. Do this even if you are planning on using Intellij IDEA. 46 | - If you use Eclipse, open Eclipse, and navigate to `File -> Import -> General -> Existing Projects into Workspace`. Navigate to and select the `projects` subdirectory, and check your mod project, and optionally the clean (unmodified) project too. 47 | - Otherwise, open Intellij IDEA and import the Eclipse project. 48 | 49 | ### Project layout + management 50 | Once you have setup the project, you should see a file structure in Eclipse which looks something like this: 51 | ``` 52 | - src/main/java This is where all of the MINECRAFT classes go, i.e. classes which you may or may not have modified, but no classes you have added. 53 | - src/main/resources Similar to src/main/java except for non-java files. 54 | - main-java This is where all of the MOD classes go, i.e. the classes which you have added. 55 | - main-resources Similar to main-java except for non-java files. 56 | ``` 57 | From outside Eclipse, the file structure looks a little different. However, you should avoid editing these files from outside Eclipse: 58 | ``` 59 | - src/main/java The MOD classes 60 | - src/main/resources The MOD resources 61 | - patches Patches your mod has made to the MINECRAFT classes, which can be pushed to public repositories 62 | - projects//src/main/java * The MINECRAFT classes 63 | - projects//src/main/resources * The MINECRAFT resources 64 | - projects/clean/src/main/java * The unmodified MINECRAFT classes 65 | - projects/clean/src/main/resources * The unmodified MINECRAFT resources 66 | * = ignored by git 67 | ``` 68 | 69 | - You should be able to run Minecraft directly from within the IDE. 70 | - Every time you checkout a branch which has changed files in the `patches` directory, you need to run `gradlew setup` again to update the code in `src/main/java` inside Eclipse. This will not try to decompile again like it did the first time, so won't take long. 71 | - Every time you make changes to MINECRAFT classes and want to push to the public repo, you need to run `gradlew genPatches` to update the patch files in the `patches` directory. This takes a few seconds. 72 | - When you are ready to create a release, run `gradlew createRelease`. This may take longer than the other tasks because it is recompiling the code. Once it is done, your releases can be found in the `build/distributions` directory. 73 | 74 | ### Settings you can change 75 | - `modname` the name of your mod. 76 | - `modversion` the version your mod is on. 77 | - `mcpconfig` the MCPConfig version you are using. 78 | - `mappings` the MCP mappings you are using. 79 | - `mcversion` the Minecraft version. 80 | - `pipeline`, either `joined`, `client` or `server` - whether your mod is to be a client-side-only or server-side-only mod, or to be both and share the same codebase. 81 | - `clientmain` the main class on the client. 82 | - `servermain` the main class on the server. 83 | - `reformat` whether to run Artistic Style on the code to reformat it. Makes the build process a little slower but does mean you can change the formatting options with `conf/astyle.cfg`. 84 | - `customsrg` The custom tsrg file inside the `conf/` folder, to override the one in the MCPConfig distribution, used to deobfuscate even newer Minecraft versions. 85 | 86 | ### A word of warning 87 | 1.13 modding is still in its infancy, and there are already known bugs that occur in the decompiled code which do not occur in vanilla. If you care about maintaining vanilla behaviour, then whenever making a change which may modify a certain vanilla class, make sure to weigh up the benefit of modifying said class against the risk that there might be a decompile bug in the class. This situation is constantly improving as 1.13 modding matures, but for now you can at least minimize the effect by distributing as few modified classes as possible. 88 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenLocal() 4 | maven { url = 'http://files.minecraftforge.net/maven' } 5 | jcenter() 6 | mavenCentral() 7 | //maven {url 'http://plugins.gradle.org/m2/'} // For debug purposes 8 | } 9 | dependencies { 10 | classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.23' 11 | classpath 'com.github.abrarsyed.jastyle:jAstyle:1.3' 12 | classpath 'com.google.code.gson:gson:2.8.0' // because groovy JsonGenerator doesn't exist wtf 13 | classpath 'commons-io:commons-io:2.6' 14 | classpath 'org.ow2.asm:asm-debug-all:5.2' 15 | //classpath "gradle.plugin.com.dorongold.plugins:task-tree:1.3" // For debug purposes 16 | } 17 | } 18 | 19 | import com.github.abrarsyed.jastyle.ASFormatter; 20 | import com.github.abrarsyed.jastyle.OptParser; 21 | import com.google.gson.GsonBuilder 22 | import groovy.json.JsonSlurper 23 | import java.util.zip.* 24 | import net.minecraftforge.gradle.patcher.task.TaskExtractMCPData 25 | import org.apache.commons.io.IOUtils 26 | import org.apache.commons.io.input.NullInputStream 27 | import org.objectweb.asm.* 28 | import org.objectweb.asm.tree.* 29 | 30 | // ===== MAIN BUILDSCRIPT ===== // 31 | 32 | // configuration 33 | def settings = new JsonSlurper().parseText(file('conf/settings.json').text) 34 | 35 | apply plugin: 'eclipse' 36 | //apply plugin: "com.dorongold.task-tree" // For debug purposes 37 | 38 | group = 'com.example' 39 | version = settings.modversion 40 | 41 | 42 | // subprojects 43 | 44 | project(':mcp') { 45 | apply plugin: 'net.minecraftforge.gradle.forgedev.mcp' 46 | mcp { 47 | config = 'de.oceanlabs.mcp:mcp_config:' + settings.mcpconfig + '@zip' 48 | pipeline = settings.pipeline 49 | } 50 | } 51 | 52 | 53 | project(':clean') { 54 | evaluationDependsOn(':mcp') 55 | apply plugin: 'eclipse' 56 | apply plugin: 'net.minecraftforge.gradle.forgedev.patcher' 57 | repositories { 58 | mavenCentral() 59 | } 60 | patcher { 61 | parent = project(':mcp') 62 | patchedSrc = file('src/main/java') 63 | mappings channel: 'snapshot', version: settings.mappings 64 | mcVersion = settings.mcversion 65 | } 66 | task runclient(type: JavaExec) { 67 | doFirst { 68 | mkdir 'runclient' 69 | } 70 | classpath sourceSets.main.runtimeClasspath 71 | args = ['--accessToken', '0', '--version', '1.13'] 72 | main 'net.minecraft.client.main.Main' 73 | workingDir 'runclient' 74 | } 75 | } 76 | 77 | 78 | project(':' + settings.modname) { 79 | evaluationDependsOn(':clean') 80 | apply plugin: 'eclipse' 81 | apply plugin: 'net.minecraftforge.gradle.forgedev.patcher' 82 | sourceSets { 83 | main { 84 | java { 85 | srcDir "$rootDir/src/main/java" 86 | } 87 | resources { 88 | srcDir "$rootDir/src/main/resources" 89 | } 90 | } 91 | } 92 | repositories { 93 | mavenLocal() 94 | mavenCentral() 95 | } 96 | patcher { 97 | parent = project(':clean') 98 | patches = file("$rootDir/patches") 99 | patchedSrc = file('src/main/java') 100 | srgPatches = false 101 | clientRun { 102 | main = settings.clientmain 103 | properties = [ 104 | assetDirectory: downloadAssets.output 105 | ] 106 | } 107 | serverRun { 108 | main = settings.servermain 109 | } 110 | } 111 | applyPatches { 112 | canonicalizeAccess true 113 | canonicalizeWhitespace true 114 | maxFuzz 3 115 | } 116 | dependencies { 117 | // Add extra dependencies here 118 | } 119 | 120 | task runclient(type: JavaExec, dependsOn: [":" + settings.modname + ":downloadAssets", ":" + settings.modname + ":extractNatives"]) { 121 | doFirst { 122 | mkdir 'runclient' 123 | } 124 | doFirst { 125 | copy { 126 | from sourceSets.main.resources 127 | into "$buildDir/classes/java/main" 128 | } 129 | } 130 | classpath sourceSets.main.runtimeClasspath 131 | main settings.clientmain 132 | systemProperties = [ 133 | "org.lwjgl.util.Debug": "true", 134 | "org.lwjgl.util.DebugLoader": "true" 135 | ] 136 | environment += [ 137 | assetDirectory: file("${gradle.getGradleUserHomeDir()}/caches/forge_gradle/assets/"), 138 | nativesDirectory: extractNatives.output 139 | ] 140 | workingDir 'runclient' 141 | } 142 | 143 | task runserver(type: JavaExec) { 144 | doFirst { 145 | mkdir 'runserver' 146 | } 147 | classpath sourceSets.main.runtimeClasspath 148 | main settings.servermain 149 | args 'nogui' 150 | workingDir 'runserver' 151 | } 152 | } 153 | 154 | 155 | // Main setup task 156 | task setup() { 157 | dependsOn ':clean:extractMapped' 158 | dependsOn ':' + settings.modname + ':extractMapped' //These must be strings so that we can do lazy resolution. Else we need evaluationDependsOnChildren above 159 | } 160 | 161 | // ===== UTILITY ===== // 162 | class JarFilter { 163 | String filename 164 | final InputStream istream 165 | final boolean newFile 166 | JarFilter(String filename, InputStream istream, boolean newFile) { 167 | this.filename = filename 168 | this.istream = istream 169 | this.newFile = newFile 170 | } 171 | static def filterJar(File jarIn, File jarOut, Closure transformer, Map additionalDirs = [:]) { 172 | def existing = [] as HashSet 173 | def zipOut = new ZipOutputStream(new FileOutputStream(jarOut)) 174 | additionalDirs.each { additionalDir, prefix -> 175 | additionalDir.eachFileRecurse { file -> 176 | def filter = new JarFilter(prefix + additionalDir.toPath().relativize(file.toPath()).toString().replace(File.separator, '/'), file.isDirectory() ? new NullInputStream(0) : file.newInputStream(), true) 177 | transformer.delegate = filter 178 | def content = transformer.call() 179 | if (content != null && !existing.contains(filter.filename)) { 180 | def entryOut = new ZipEntry(filter.filename) 181 | existing << filter.filename 182 | zipOut.putNextEntry(entryOut) 183 | zipOut << content 184 | zipOut.closeEntry() 185 | } 186 | } 187 | } 188 | def zipIn = new ZipFile(jarIn) 189 | zipIn.entries().each { entryIn -> 190 | def filter = new JarFilter(entryIn.getName(), zipIn.getInputStream(entryIn), false) 191 | transformer.delegate = filter 192 | def content = transformer.call() 193 | if (content != null && !existing.contains(filter.filename)) { 194 | def entryOut = new ZipEntry(filter.filename) 195 | existing << filter.filename 196 | zipOut.putNextEntry(entryOut) 197 | zipOut << content 198 | zipOut.closeEntry() 199 | } 200 | } 201 | zipIn.close() 202 | zipOut.close() 203 | } 204 | } 205 | 206 | // ===== FIXES ===== // 207 | 208 | // Fix recompilation requiring extractSrg output 209 | setup.dependsOn ':clean:extractSrg' 210 | 211 | // Generic fixMcpConfig task for anything that needs to modify the mcpconfig 212 | class FixMcpConfigTask extends DefaultTask { 213 | List configActions = [] 214 | List filterActions = [] 215 | Map additionalDirs = [:] 216 | void configAction(Closure action) { 217 | configActions.add(action) 218 | } 219 | void filterAction(Closure action) { 220 | filterActions.add(action) 221 | } 222 | void additionalDir(Object dir, String prefix) { 223 | additionalDirs.put(project.file(dir), prefix) 224 | } 225 | @TaskAction 226 | void filterMcpConfig() { 227 | JarFilter.filterJar(project.file(project.downloadConfig.output), project.file('build/mcp_config.zip'), { 228 | if (filename == 'config.json') { 229 | def cfg = new JsonSlurper().parse(istream) 230 | for (def action : configActions) { 231 | action.call(cfg) 232 | } 233 | return new GsonBuilder().setPrettyPrinting().create().toJson(cfg) 234 | } else { 235 | for (def action : filterActions) { 236 | action.delegate = delegate 237 | def newistream = action.call() 238 | if (!istream.is(newistream)) 239 | return newistream 240 | } 241 | return istream 242 | } 243 | }, additionalDirs) 244 | } 245 | 246 | static def register(def proj) { 247 | if (!proj.ext.properties.containsKey('registered')) { 248 | proj.ext.registered = true 249 | proj.downloadConfig.output = proj.file('build/mcp_config_broken.zip') 250 | proj.task('fixMcpConfig', type: FixMcpConfigTask) { 251 | dependsOn proj.downloadConfig 252 | inputs.file proj.downloadConfig.output 253 | outputs.file 'build/mcp_config.zip' 254 | } 255 | proj.loadConfig.dependsOn proj.fixMcpConfig 256 | } 257 | } 258 | } 259 | 260 | // Fix https://github.com/MinecraftForge/ForgeGradle/issues/517 - FG3 server pipeline missing download version JSON 261 | // Also fix recompile error on server due to mcp.client.Start being present 262 | if (settings.pipeline == 'server') { 263 | project(':mcp') { 264 | FixMcpConfigTask.register(project) 265 | fixMcpConfig.configAction {cfg -> cfg.steps.server.add(1, [type: 'downloadJson'])} 266 | fixMcpConfig.filterAction {return filename.startsWith('config/inject/mcp/client/') ? null : istream} 267 | } 268 | } 269 | 270 | // Custom SRG 271 | if (settings.customsrg != null) { 272 | project(':mcp') { 273 | FixMcpConfigTask.register(project) 274 | fixMcpConfig.configAction { cfg -> 275 | cfg.version = settings.mcversion 276 | cfg.data.mappings = 'config/' + settings.customsrg 277 | } 278 | fixMcpConfig.filterAction { 279 | if (filename == 'config/joined.tsrg') { 280 | filename = 'config/' + settings.customsrg 281 | return new FileInputStream(rootProject.file('conf/' + settings.customsrg)) 282 | } else if (filename.startsWith('patches/') && !newFile) { 283 | return null 284 | } else { 285 | return istream 286 | } 287 | } 288 | } 289 | } 290 | 291 | // Custom patches 292 | if (rootProject.file('conf/patches/').exists()) { 293 | project(':mcp') { 294 | FixMcpConfigTask.register(project) 295 | fixMcpConfig.additionalDir(rootProject.file('conf/patches/'), 'patches/' + settings.pipeline + '/') 296 | } 297 | } 298 | 299 | // Fix formatting, optionally 300 | if (settings.reformat) { 301 | project(':mcp') { 302 | task reformat { 303 | dependsOn setupMCP 304 | inputs.file setupMCP.output 305 | outputs.file 'build/reformat/output.zip' 306 | doLast { 307 | def formatter = new ASFormatter() 308 | formatter.setUseProperInnerClassIndenting(false) 309 | def parser = new OptParser(formatter) 310 | parser.parseOptionFile(rootProject.file('conf/astyle.cfg')) 311 | 312 | JarFilter.filterJar(file(setupMCP.output), file('build/reformat/output.zip')) { 313 | if (filename.endsWith('.java') && !filename.endsWith('package-info.java')) { 314 | def sw = new StringWriter() 315 | try { 316 | formatter.format(new InputStreamReader(istream), sw) 317 | return sw.toString() 318 | } catch (RuntimeException e) { 319 | println('Failed to reformat ' + filename) 320 | return istream 321 | } 322 | } else { 323 | return istream 324 | } 325 | } 326 | } 327 | } 328 | } 329 | project(':clean') { 330 | applyPatches.dependsOn project(':mcp').reformat 331 | applyPatches.setClean(project(':mcp').file('build/reformat/output.zip')) 332 | } 333 | } 334 | 335 | // Fix reobf error due to local variable signatures (with lambdas?). Apply to both clean and modded to keep the classes the same 336 | for (def projname : [':clean', ':' + settings.modname]) { 337 | project(projname) { 338 | def reobfArgs = [] 339 | reobfJar.args.each {reobfArgs << it} 340 | reobfArgs << '--kill-lvt' 341 | reobfJar.args = reobfArgs.toArray([] as String[]) 342 | } 343 | } 344 | 345 | // ===== RELEASE TASKS ===== // 346 | 347 | // Utility class for dealing with @OnlyIn(Dist.XXX) using ASM 348 | class DistUtils { 349 | static def containsUnwanted(List anns, String unwanted) { 350 | if (anns == null) 351 | return false 352 | def annItr = anns.iterator() 353 | while (annItr.hasNext()) { 354 | def ann = annItr.next() 355 | if (ann.desc == 'Lnet/minecraftforge/api/distmarker/OnlyIn;') { 356 | annItr.remove() 357 | def value = ann.values[1] 358 | value = value[1] 359 | return value == unwanted 360 | } 361 | } 362 | return false 363 | } 364 | 365 | static def classUnwanted(InputStream istream, String unwanted) { 366 | ClassReader reader = new ClassReader(istream) 367 | ClassNode clazz = new ClassNode() 368 | reader.accept(clazz, ClassReader.SKIP_CODE) 369 | return containsUnwanted(clazz.visibleAnnotations, unwanted) 370 | } 371 | 372 | static def stripDist(InputStream istream, String unwanted, Closure classProvider) { 373 | ClassReader reader = new ClassReader(istream) 374 | ClassNode clazz = new ClassNode() 375 | reader.accept(clazz, 0) 376 | 377 | if (containsUnwanted(clazz.visibleAnnotations, unwanted)) 378 | return null 379 | 380 | if (clazz.interfaces != null) { 381 | def itfItr = clazz.interfaces.iterator() 382 | while (itfItr.hasNext()) { 383 | def itf = classProvider.call(itfItr.next()) 384 | if (itf != null && classUnwanted(itf, unwanted)) 385 | itfItr.remove() 386 | } 387 | } 388 | 389 | if (clazz.fields != null) { 390 | def fieldItr = clazz.fields.iterator() 391 | while (fieldItr.hasNext()) 392 | if (containsUnwanted(fieldItr.next().visibleAnnotations, unwanted)) 393 | fieldItr.remove() 394 | } 395 | 396 | if (clazz.methods != null) { 397 | def methodItr = clazz.methods.iterator() 398 | while (methodItr.hasNext()) 399 | if (containsUnwanted(methodItr.next().visibleAnnotations, unwanted)) 400 | methodItr.remove() 401 | } 402 | 403 | if (clazz.innerClasses != null) { 404 | def innerClassItr = clazz.innerClasses.iterator() 405 | while (innerClassItr.hasNext()) { 406 | def innerClass = innerClassItr.next() 407 | if (innerClass.outerName == clazz.name && classUnwanted(classProvider.call(innerClass.name), unwanted)) 408 | innerClassItr.remove() 409 | } 410 | } 411 | 412 | ClassWriter writer = new ClassWriter(0) 413 | clazz.accept(writer) 414 | return writer.toByteArray() 415 | } 416 | } 417 | 418 | // Tasks to split joined jars into client and server jars 419 | if (settings.pipeline == 'joined') { 420 | for (def projname : [':clean', ':' + settings.modname]) { 421 | project(projname) { 422 | def dists = ['Client', 'Server'] 423 | def unwantedDists = ['DEDICATED_SERVER', 'CLIENT'] 424 | for (def i = 0; i < 2; i++) { 425 | def idx = i 426 | task('filterDist' + dists[idx]) { 427 | dependsOn reobfJar 428 | inputs.file reobfJar.output 429 | outputs.file 'build/filterDist' + dists[idx] + '/output.zip' 430 | doLast { 431 | JarFilter.filterJar(file(reobfJar.output), file('build/filterDist' + dists[idx] + '/output.zip')) { 432 | if (filename.endsWith('.class')) { 433 | return DistUtils.stripDist(istream, unwantedDists[idx]) { classname -> 434 | def zip = new ZipFile(file(reobfJar.output)) 435 | def entry = zip.getEntry(classname + '.class') 436 | if (entry == null) 437 | return null 438 | return zip.getInputStream(entry) 439 | } 440 | } else { 441 | return istream 442 | } 443 | } 444 | } 445 | } 446 | } 447 | } 448 | } 449 | } 450 | 451 | // Tasks to produce zip files containing only the changed classes, making the final release zip 452 | for (def dist : ['Client', 'Server']) { 453 | task('createRelease' + dist, type: Zip) { 454 | def inputTaskName = settings.pipeline == 'joined' ? 'filterDist' + dist : 'reobfJar' 455 | def inputArchiveName = settings.pipeline == 'joined' ? 'output.zip' : 'output.jar' 456 | from(zipTree('projects/' + settings.modname + '/build/' + inputTaskName + '/' + inputArchiveName)) { 457 | eachFile { moddedFile -> 458 | def entryName = moddedFile.getRelativePath().toString() 459 | def vanillaJar = new ZipFile(file('projects/clean/build/' + inputTaskName + '/' + inputArchiveName)) 460 | def vanillaEntry = vanillaJar.getEntry entryName 461 | if (vanillaEntry != null) { 462 | def moddedJar = new ZipFile(file('projects/' + settings.modname + '/build/' + inputTaskName + '/' + inputArchiveName)) 463 | def moddedEntry = moddedJar.getEntry entryName 464 | if (IOUtils.contentEquals(vanillaJar.getInputStream(vanillaEntry), moddedJar.getInputStream(moddedEntry))) 465 | moddedFile.exclude() 466 | } 467 | } 468 | } 469 | 470 | archiveName = "${settings.modname}_${project.version}_${dist}.zip" 471 | destinationDir = file('build/distributions') 472 | includeEmptyDirs = false 473 | 474 | dependsOn ':clean:' + inputTaskName, ':' + settings.modname + ':' + inputTaskName 475 | } 476 | } 477 | 478 | // Master task to invoke all createRelease tasks 479 | task createRelease { 480 | if (settings.pipeline != 'server') 481 | dependsOn createReleaseClient 482 | if (settings.pipeline != 'client') 483 | dependsOn createReleaseServer 484 | } 485 | -------------------------------------------------------------------------------- /conf/astyle.cfg: -------------------------------------------------------------------------------- 1 | # Artistic Style format configuration 2 | # see http://astyle.sourceforge.net/astyle.html 3 | 4 | style=allman 5 | 6 | add-brackets 7 | break-closing-brackets 8 | 9 | indent-switches 10 | 11 | max-instatement-indent=40 12 | 13 | pad-oper 14 | pad-header 15 | unpad-paren 16 | 17 | break-blocks 18 | 19 | delete-empty-lines 20 | -------------------------------------------------------------------------------- /conf/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "modname": "bedrockified", 3 | "modversion": "1.0", 4 | "mcpconfig": "1.13.1-20180929.143449", 5 | "mappings": "20181128-1.13.1", 6 | "mcversion": "1.13.1", 7 | "pipeline": "joined", 8 | "clientmain": "mcp.client.Start", 9 | "servermain": "net.minecraft.server.MinecraftServer", 10 | "reformat": false, 11 | "customsrg": null 12 | } 13 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Earthcomputer/bedrockified/044483147b7137e2c88b1a91b2de9378f82b297c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 12 13:05:41 BST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 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 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /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 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /patch_mergetool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # This interactive script resolves merge conflicts in the patch files 4 | # patch_mergetool.py 5 | 6 | import os 7 | import re 8 | import sys 9 | 10 | # Classes 11 | 12 | # Fields: 13 | # header 14 | # hunks 15 | class PatchFile: 16 | pass 17 | 18 | # Fields: 19 | # start_a 20 | # len_a 21 | # start_b 22 | # len_b 23 | # suffix 24 | # lines 25 | # is_duplicate (set later) 26 | class Hunk: 27 | pass 28 | 29 | # Fields: 30 | # content 31 | # added 32 | class Line: 33 | def __init__(self, content, added): 34 | self.content = content 35 | self.added = added 36 | def __eq__(self, other): 37 | return self.content == other.content and self.added == other.added 38 | 39 | # Matches the @@ hunk headers @@ 40 | hunk_header_pattern = re.compile(r"^@@ -(\d+),(\d+) \+(\d+),(\d+) @@(.*)$", flags = re.DOTALL) 41 | 42 | # Separates a file with conflict markers into the two files that are trying to be merged 43 | def get_each_content(content): 44 | content_a = [] 45 | content_b = [] 46 | in_a = False 47 | in_b = False 48 | for line in content.splitlines(keepends = True): 49 | if in_a: 50 | if line.startswith("======="): 51 | in_a = False 52 | in_b = True 53 | else: 54 | content_a.append(Line(line, True)) 55 | elif in_b: 56 | if line.startswith(">>>>>>>"): 57 | in_b = False 58 | else: 59 | content_b.append(Line(line, True)) 60 | else: 61 | if line.startswith("<<<<<<<"): 62 | in_a = True 63 | else: 64 | content_a.append(Line(line, False)) 65 | content_b.append(Line(line, False)) 66 | return (content_a, content_b) 67 | 68 | # Parses the lines of a patch file into a patch file object 69 | def parse_file(lines): 70 | patch = PatchFile() 71 | patch.hunks = [] 72 | current_hunk = None 73 | current_lines = [] 74 | for line in lines: 75 | match = hunk_header_pattern.match(line.content) 76 | if match != None: 77 | if current_hunk == None: 78 | patch.header = current_lines 79 | current_hunk = Hunk() 80 | current_hunk.start_a = int(match.group(1)) 81 | current_hunk.len_a = int(match.group(2)) 82 | current_hunk.start_b = int(match.group(3)) 83 | current_hunk.len_b = int(match.group(4)) 84 | current_hunk.suffix = match.group(5) 85 | current_lines = [] 86 | current_hunk.lines = current_lines 87 | patch.hunks.append(current_hunk) 88 | else: 89 | current_lines.append(line) 90 | return patch 91 | 92 | # Takes old file content, returns new content, unless merging failed, then it returns None 93 | def process_file(content): 94 | # Split Content 95 | lines_a, lines_b = get_each_content(content) 96 | 97 | # Parse files 98 | file_a = parse_file(lines_a) 99 | file_b = parse_file(lines_b) 100 | 101 | # Header conflicts unresolvable 102 | if file_a.header != file_b.header: 103 | return None 104 | 105 | # Get list of all hunks, sorted in order of where the patches are applied in the original file 106 | sorted_hunks = file_a.hunks + file_b.hunks 107 | sorted_hunks.sort(key = lambda hunk: hunk.start_a) 108 | 109 | # Resolve conflicts (hunks applied in the same place which differ) and automatically resolve duplicates (hunks applied in the same place which don't differ) 110 | last_hunk = None 111 | conflict_count = 0 112 | for hunk in sorted_hunks: 113 | hunk.is_duplicate = False 114 | if last_hunk != None: 115 | if hunk.start_a < last_hunk.start_a + last_hunk.len_a: # if hunks overlap 116 | if hunk.start_a != last_hunk.start_a or hunk.len_a != last_hunk.len_a or hunk.len_b != last_hunk.len_b or hunk.lines != last_hunk.lines: # if hunks conflict 117 | conflict_count += 1 118 | print("Conflict #" + str(conflict_count) + ":") 119 | print(" Hunk A:") 120 | for line in last_hunk.lines: 121 | print(" " + line.content) 122 | print(" Hunk B:") 123 | for line in hunk.lines: 124 | print(" " + line.content) 125 | answer = input(" Which hunk should be preferred (A/B)? Or press enter to abort the merge: ").lower() 126 | if answer.startswith("a"): 127 | hunk.is_duplicate = True 128 | elif answer.startswith("b"): 129 | last_hunk.is_duplicate = True 130 | else: 131 | return None 132 | else: # if hunks are non-conflicting duplicates 133 | hunk.is_duplicate = True 134 | last_hunk = hunk 135 | # Remove hunks marked to be removed 136 | sorted_hunks = [hunk for hunk in sorted_hunks if not hunk.is_duplicate] 137 | 138 | # Fix the new offsets 139 | offset = 0 140 | for hunk in sorted_hunks: 141 | hunk.start_b = hunk.start_a + offset 142 | offset += hunk.len_b - hunk.len_a 143 | 144 | # Build output 145 | output = "" 146 | for line in file_a.header: 147 | output += line.content 148 | for hunk in sorted_hunks: 149 | output += "@@ -" + str(hunk.start_a) + "," + str(hunk.len_a) + " +" + str(hunk.start_b) + "," + str(hunk.len_b) + " @@" + hunk.suffix 150 | for line in hunk.lines: 151 | output += line.content 152 | 153 | return output 154 | 155 | def main(files): 156 | for filename in files: 157 | with open(filename) as f: 158 | content = f.read() 159 | print("Resolving conflicts in file " + filename) 160 | content = process_file(content) 161 | if content == None: 162 | print("Could not resolve conflicts in file " + filename) 163 | else: 164 | with open(filename, "w") as f: 165 | f.write(content) 166 | os.system("git add " + filename) 167 | print("Resolved conflicts in file " + filename) 168 | 169 | if len(sys.argv) < 2: 170 | print("patch_mergetool.py ") 171 | else: 172 | main(sys.argv[1:]) 173 | -------------------------------------------------------------------------------- /patches/net/minecraft/client/ClientBrandRetriever.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/client/ClientBrandRetriever.java 2 | +++ b/net/minecraft/client/ClientBrandRetriever.java 3 | @@ -6,6 +6,6 @@ 4 | @OnlyIn(Dist.CLIENT) 5 | public class ClientBrandRetriever { 6 | public static String getClientModName() { 7 | - return "vanilla"; 8 | + return "bedrockified"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /patches/net/minecraft/client/MainWindow.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/client/MainWindow.java 2 | +++ b/net/minecraft/client/MainWindow.java 3 | @@ -83,7 +83,7 @@ 4 | this.prevWindowX = this.windowX = this.monitor.getVirtualPosX() + videomode.getWidth() / 2 - this.width / 2; 5 | this.prevWindowY = this.windowY = this.monitor.getVirtualPosY() + videomode.getHeight() / 2 - this.height / 2; 6 | GLFW.glfwDefaultWindowHints(); 7 | - this.handle = GLFW.glfwCreateWindow(this.width, this.height, "Minecraft 1.13.1", this.fullscreen ? this.monitor.getMonitorPointer() : 0L, 0L); 8 | + this.handle = GLFW.glfwCreateWindow(this.width, this.height, "Minecraft Bedrockified 1.13.1", this.fullscreen ? this.monitor.getMonitorPointer() : 0L, 0L); 9 | mcIn.isWindowFocused = true; 10 | this.setMonitorFromVirtualScreen(); 11 | GLFW.glfwMakeContextCurrent(this.handle); 12 | -------------------------------------------------------------------------------- /patches/net/minecraft/client/gui/GuiCreateWorld.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/client/gui/GuiCreateWorld.java 2 | +++ b/net/minecraft/client/gui/GuiCreateWorld.java 3 | @@ -4,6 +4,8 @@ 4 | import com.mojang.datafixers.Dynamic; 5 | import com.mojang.datafixers.types.JsonOps; 6 | import java.util.Random; 7 | + 8 | +import net.earthcomputer.bedrockified.BedrockSeed; 9 | import net.minecraft.client.resources.I18n; 10 | import net.minecraft.nbt.NBTDynamicOps; 11 | import net.minecraft.nbt.NBTTagCompound; 12 | @@ -248,6 +250,9 @@ 13 | this.alreadyGenerated = true; 14 | long i = (new Random()).nextLong(); 15 | String s = this.worldSeedField.getText(); 16 | + // BEDROCK: seed conversion 17 | + i = BedrockSeed.getBedrockSeed(s, i); 18 | + /* 19 | if (!StringUtils.isEmpty(s)) { 20 | try { 21 | long j = Long.parseLong(s); 22 | @@ -258,6 +263,7 @@ 23 | i = (long)s.hashCode(); 24 | } 25 | } 26 | + */ 27 | 28 | WorldSettings worldsettings = new WorldSettings(i, GameType.getByName(this.gameMode), this.generateStructuresEnabled, this.hardCoreMode, WorldType.WORLD_TYPES[this.selectedIndex]); 29 | worldsettings.setGeneratorOptions((JsonElement)Dynamic.convert(NBTDynamicOps.INSTANCE, JsonOps.INSTANCE, this.chunkProviderSettingsJson)); 30 | -------------------------------------------------------------------------------- /patches/net/minecraft/server/MinecraftServer.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/server/MinecraftServer.java 2 | +++ b/net/minecraft/server/MinecraftServer.java 3 | @@ -935,7 +935,7 @@ 4 | } 5 | 6 | public String getServerModName() { 7 | - return "vanilla"; 8 | + return "bedrockified"; 9 | } 10 | 11 | public CrashReport addServerInfoToCrashReport(CrashReport report) { 12 | -------------------------------------------------------------------------------- /patches/net/minecraft/server/dedicated/DedicatedServer.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/server/dedicated/DedicatedServer.java 2 | +++ b/net/minecraft/server/dedicated/DedicatedServer.java 3 | @@ -20,6 +20,8 @@ 4 | import java.util.concurrent.TimeUnit; 5 | import java.util.function.BooleanSupplier; 6 | import java.util.regex.Pattern; 7 | + 8 | +import net.earthcomputer.bedrockified.BedrockSeed; 9 | import net.minecraft.command.CommandSource; 10 | import net.minecraft.command.Commands; 11 | import net.minecraft.crash.CrashReport; 12 | @@ -193,6 +195,9 @@ 13 | String s1 = this.settings.getStringProperty("level-type", "DEFAULT"); 14 | String s2 = this.settings.getStringProperty("generator-settings", ""); 15 | long k = (new Random()).nextLong(); 16 | + // BEDROCK: seed conversion 17 | + k = BedrockSeed.getBedrockSeed(s, k); 18 | + /* 19 | if (!s.isEmpty()) { 20 | try { 21 | long l = Long.parseLong(s); 22 | @@ -203,6 +208,7 @@ 23 | k = (long)s.hashCode(); 24 | } 25 | } 26 | + */ 27 | 28 | WorldType worldtype = WorldType.byName(s1); 29 | if (worldtype == null) { 30 | -------------------------------------------------------------------------------- /patches/net/minecraft/util/SharedSeedRandom.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/util/SharedSeedRandom.java 2 | +++ b/net/minecraft/util/SharedSeedRandom.java 3 | @@ -1,15 +1,17 @@ 4 | package net.minecraft.util; 5 | 6 | +import net.earthcomputer.bedrockified.BedrockRandom; 7 | + 8 | import java.util.Random; 9 | 10 | -public class SharedSeedRandom extends Random { 11 | +public class SharedSeedRandom extends BedrockRandom { // BEDROCK: changed RNG 12 | private int usageCount; 13 | 14 | public SharedSeedRandom() { 15 | } 16 | 17 | public SharedSeedRandom(long seed) { 18 | - super(seed); 19 | + super((int) seed); // BEDROCK: 32-bit seeds 20 | } 21 | 22 | public void skip(int bits) { 23 | @@ -47,8 +49,9 @@ 24 | 25 | public long setLargeFeatureSeed(long seed, int x, int z) { 26 | this.setSeed(seed); 27 | - long i = this.nextLong(); 28 | - long j = this.nextLong(); 29 | + // BEDROCK: replace nextLongs with nextInts 30 | + long i = this.nextInt(); 31 | + long j = this.nextInt(); 32 | long k = (long)x * i ^ (long)z * j ^ seed; 33 | this.setSeed(k); 34 | return k; 35 | @@ -61,6 +64,6 @@ 36 | } 37 | 38 | public static Random seedSlimeChunk(int p_205190_0_, int p_205190_1_, long p_205190_2_, long p_205190_4_) { 39 | - return new Random(p_205190_2_ + (long)(p_205190_0_ * p_205190_0_ * 4987142) + (long)(p_205190_0_ * 5947611) + (long)(p_205190_1_ * p_205190_1_) * 4392871L + (long)(p_205190_1_ * 389711) ^ p_205190_4_); 40 | + return new BedrockRandom((p_205190_0_ * 522133279) ^ p_205190_1_); // BEDROCK 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/WorldServer.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/WorldServer.java 2 | +++ b/net/minecraft/world/WorldServer.java 3 | @@ -14,6 +14,8 @@ 4 | import java.util.stream.Stream; 5 | import javax.annotation.Nonnull; 6 | import javax.annotation.Nullable; 7 | + 8 | +import net.earthcomputer.bedrockified.BedrockSpawnPoint; 9 | import net.minecraft.block.Block; 10 | import net.minecraft.block.BlockEventData; 11 | import net.minecraft.block.state.IBlockState; 12 | @@ -596,6 +598,9 @@ 13 | this.worldInfo.setSpawn(BlockPos.ORIGIN.up()); 14 | } else { 15 | BiomeProvider biomeprovider = this.chunkProvider.getChunkGenerator().getBiomeProvider(); 16 | + // BEDROCK: replace spawn point algorithm 17 | + this.worldInfo.setSpawn(BedrockSpawnPoint.findSpawnPosition(settings, biomeprovider)); 18 | + /* 19 | List list = biomeprovider.getBiomesToSpawnIn(); 20 | Random random = new Random(this.getSeed()); 21 | BlockPos blockpos = biomeprovider.findBiomePosition(0, 0, 256, list, random); 22 | @@ -642,6 +647,7 @@ 23 | if (settings.isBonusChestEnabled()) { 24 | this.createBonusChest(); 25 | } 26 | + */ 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/DeepWarmOceanBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/DeepWarmOceanBiome.java 2 | +++ b/net/minecraft/world/biome/DeepWarmOceanBiome.java 3 | @@ -42,7 +42,7 @@ 4 | this.addStructure(Feature.OCEAN_RUIN, new OceanRuinConfig(OceanRuinStructure.Type.WARM, 0.3F, 0.9F)); 5 | this.addStructure(Feature.OCEAN_MONUMENT, new OceanMonumentConfig()); 6 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 7 | - this.addStructure(Feature.SHIPWRECK, new ShipwreckConfig(false)); 8 | + //this.addStructure(Feature.SHIPWRECK, new ShipwreckConfig(false)); // BEDROCK 9 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CAVE_WORLD_CARVER, new ProbabilityConfig(0.06666667F))); 10 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CANYON_WORLD_CARVER, new ProbabilityConfig(0.02F))); 11 | this.addCarver(GenerationStage.Carving.LIQUID, createWorldCarverWrapper(UNDERWATER_CANYON_WORLD_CARVER, new ProbabilityConfig(0.02F))); 12 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/MushroomFieldShoreBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/MushroomFieldShoreBiome.java 2 | +++ b/net/minecraft/world/biome/MushroomFieldShoreBiome.java 3 | @@ -17,6 +17,7 @@ 4 | import net.minecraft.world.gen.feature.TwoFeatureChoiceConfig; 5 | import net.minecraft.world.gen.feature.structure.MineshaftConfig; 6 | import net.minecraft.world.gen.feature.structure.MineshaftStructure; 7 | +import net.minecraft.world.gen.feature.structure.ShipwreckConfig; 8 | import net.minecraft.world.gen.feature.structure.StrongholdConfig; 9 | import net.minecraft.world.gen.placement.ChanceConfig; 10 | import net.minecraft.world.gen.placement.CountRangeConfig; 11 | @@ -33,6 +34,7 @@ 12 | super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder(DEFAULT_SURFACE_BUILDER, MYCELIUM_DIRT_GRAVEL_SURFACE)).precipitation(Biome.RainType.RAIN).category(Biome.Category.MUSHROOM).depth(0.0F).scale(0.025F).temperature(0.9F).downfall(1.0F).waterColor(4159204).waterFogColor(329011).parent((String)null)); 13 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 14 | this.addStructure(Feature.STRONGHOLD, new StrongholdConfig()); 15 | + this.addStructure(Feature.SHIPWRECK, new ShipwreckConfig(true)); // BEDROCK 16 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CAVE_WORLD_CARVER, new ProbabilityConfig(0.14285715F))); 17 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CANYON_WORLD_CARVER, new ProbabilityConfig(0.02F))); 18 | this.addStructureFeatures(); 19 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/SnowyTaigaBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/SnowyTaigaBiome.java 2 | +++ b/net/minecraft/world/biome/SnowyTaigaBiome.java 3 | @@ -16,10 +16,7 @@ 4 | import net.minecraft.world.gen.feature.ProbabilityConfig; 5 | import net.minecraft.world.gen.feature.RandomDefaultFeatureListConfig; 6 | import net.minecraft.world.gen.feature.SphereReplaceConfig; 7 | -import net.minecraft.world.gen.feature.structure.IglooConfig; 8 | -import net.minecraft.world.gen.feature.structure.MineshaftConfig; 9 | -import net.minecraft.world.gen.feature.structure.MineshaftStructure; 10 | -import net.minecraft.world.gen.feature.structure.StrongholdConfig; 11 | +import net.minecraft.world.gen.feature.structure.*; 12 | import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig; 13 | import net.minecraft.world.gen.placement.ChanceConfig; 14 | import net.minecraft.world.gen.placement.CountRangeConfig; 15 | @@ -34,6 +31,7 @@ 16 | public final class SnowyTaigaBiome extends Biome { 17 | public SnowyTaigaBiome() { 18 | super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder(DEFAULT_SURFACE_BUILDER, GRASS_DIRT_GRAVEL_SURFACE)).precipitation(Biome.RainType.SNOW).category(Biome.Category.TAIGA).depth(0.2F).scale(0.2F).temperature(-0.5F).downfall(0.4F).waterColor(4020182).waterFogColor(329011).parent((String)null)); 19 | + this.addStructure(Feature.VILLAGE, new VillageConfig(0, VillagePieces.Type.SPRUCE)); // BEDROCK 20 | this.addStructure(Feature.IGLOO, new IglooConfig()); 21 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 22 | this.addStructure(Feature.STRONGHOLD, new StrongholdConfig()); 23 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/SnowyTaigaHillsBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/SnowyTaigaHillsBiome.java 2 | +++ b/net/minecraft/world/biome/SnowyTaigaHillsBiome.java 3 | @@ -16,9 +16,7 @@ 4 | import net.minecraft.world.gen.feature.ProbabilityConfig; 5 | import net.minecraft.world.gen.feature.RandomDefaultFeatureListConfig; 6 | import net.minecraft.world.gen.feature.SphereReplaceConfig; 7 | -import net.minecraft.world.gen.feature.structure.MineshaftConfig; 8 | -import net.minecraft.world.gen.feature.structure.MineshaftStructure; 9 | -import net.minecraft.world.gen.feature.structure.StrongholdConfig; 10 | +import net.minecraft.world.gen.feature.structure.*; 11 | import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig; 12 | import net.minecraft.world.gen.placement.ChanceConfig; 13 | import net.minecraft.world.gen.placement.CountRangeConfig; 14 | @@ -33,6 +31,7 @@ 15 | public final class SnowyTaigaHillsBiome extends Biome { 16 | public SnowyTaigaHillsBiome() { 17 | super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder(DEFAULT_SURFACE_BUILDER, GRASS_DIRT_GRAVEL_SURFACE)).precipitation(Biome.RainType.SNOW).category(Biome.Category.TAIGA).depth(0.45F).scale(0.3F).temperature(-0.5F).downfall(0.4F).waterColor(4020182).waterFogColor(329011).parent((String)null)); 18 | + this.addStructure(Feature.VILLAGE, new VillageConfig(0, VillagePieces.Type.SPRUCE)); // BEDROCK 19 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 20 | this.addStructure(Feature.STRONGHOLD, new StrongholdConfig()); 21 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CAVE_WORLD_CARVER, new ProbabilityConfig(0.14285715F))); 22 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/SnowyTundraBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/SnowyTundraBiome.java 2 | +++ b/net/minecraft/world/biome/SnowyTundraBiome.java 3 | @@ -15,10 +15,7 @@ 4 | import net.minecraft.world.gen.feature.ProbabilityConfig; 5 | import net.minecraft.world.gen.feature.SphereReplaceConfig; 6 | import net.minecraft.world.gen.feature.TallGrassConfig; 7 | -import net.minecraft.world.gen.feature.structure.IglooConfig; 8 | -import net.minecraft.world.gen.feature.structure.MineshaftConfig; 9 | -import net.minecraft.world.gen.feature.structure.MineshaftStructure; 10 | -import net.minecraft.world.gen.feature.structure.StrongholdConfig; 11 | +import net.minecraft.world.gen.feature.structure.*; 12 | import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig; 13 | import net.minecraft.world.gen.placement.ChanceConfig; 14 | import net.minecraft.world.gen.placement.CountRangeConfig; 15 | @@ -32,6 +29,7 @@ 16 | public final class SnowyTundraBiome extends Biome { 17 | public SnowyTundraBiome() { 18 | super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder(DEFAULT_SURFACE_BUILDER, GRASS_DIRT_GRAVEL_SURFACE)).precipitation(Biome.RainType.SNOW).category(Biome.Category.ICY).depth(0.125F).scale(0.05F).temperature(0.0F).downfall(0.5F).waterColor(4159204).waterFogColor(329011).parent((String)null)); 19 | + this.addStructure(Feature.VILLAGE, new VillageConfig(0, VillagePieces.Type.OAK)); // BEDROCK: ice plains villages 20 | this.addStructure(Feature.IGLOO, new IglooConfig()); 21 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 22 | this.addStructure(Feature.STRONGHOLD, new StrongholdConfig()); 23 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/StoneShoreBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/StoneShoreBiome.java 2 | +++ b/net/minecraft/world/biome/StoneShoreBiome.java 3 | @@ -15,9 +15,7 @@ 4 | import net.minecraft.world.gen.feature.ProbabilityConfig; 5 | import net.minecraft.world.gen.feature.SphereReplaceConfig; 6 | import net.minecraft.world.gen.feature.TallGrassConfig; 7 | -import net.minecraft.world.gen.feature.structure.MineshaftConfig; 8 | -import net.minecraft.world.gen.feature.structure.MineshaftStructure; 9 | -import net.minecraft.world.gen.feature.structure.StrongholdConfig; 10 | +import net.minecraft.world.gen.feature.structure.*; 11 | import net.minecraft.world.gen.placement.ChanceConfig; 12 | import net.minecraft.world.gen.placement.CountRangeConfig; 13 | import net.minecraft.world.gen.placement.DepthAverageConfig; 14 | @@ -32,6 +30,7 @@ 15 | super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder(DEFAULT_SURFACE_BUILDER, STONE_STONE_GRAVEL_SURFACE)).precipitation(Biome.RainType.RAIN).category(Biome.Category.NONE).depth(0.1F).scale(0.8F).temperature(0.2F).downfall(0.3F).waterColor(4159204).waterFogColor(329011).parent((String)null)); 16 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 17 | this.addStructure(Feature.STRONGHOLD, new StrongholdConfig()); 18 | + this.addStructure(Feature.BURIED_TREASURE, new BuriedTreasureConfig(1f)); // BEDROCK 19 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CAVE_WORLD_CARVER, new ProbabilityConfig(0.14285715F))); 20 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CANYON_WORLD_CARVER, new ProbabilityConfig(0.02F))); 21 | this.addStructureFeatures(); 22 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/SunflowerPlainsBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/SunflowerPlainsBiome.java 2 | +++ b/net/minecraft/world/biome/SunflowerPlainsBiome.java 3 | @@ -17,9 +17,7 @@ 4 | import net.minecraft.world.gen.feature.RandomDefaultFeatureListConfig; 5 | import net.minecraft.world.gen.feature.SphereReplaceConfig; 6 | import net.minecraft.world.gen.feature.TallGrassConfig; 7 | -import net.minecraft.world.gen.feature.structure.MineshaftConfig; 8 | -import net.minecraft.world.gen.feature.structure.MineshaftStructure; 9 | -import net.minecraft.world.gen.feature.structure.StrongholdConfig; 10 | +import net.minecraft.world.gen.feature.structure.*; 11 | import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig; 12 | import net.minecraft.world.gen.placement.ChanceConfig; 13 | import net.minecraft.world.gen.placement.CountRangeConfig; 14 | @@ -34,6 +32,7 @@ 15 | public final class SunflowerPlainsBiome extends Biome { 16 | protected SunflowerPlainsBiome() { 17 | super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder(DEFAULT_SURFACE_BUILDER, GRASS_DIRT_GRAVEL_SURFACE)).precipitation(Biome.RainType.RAIN).category(Biome.Category.PLAINS).depth(0.125F).scale(0.05F).temperature(0.8F).downfall(0.4F).waterColor(4159204).waterFogColor(329011).parent("plains")); 18 | + this.addStructure(Feature.VILLAGE, new VillageConfig(0, VillagePieces.Type.OAK)); // BEDROCK 19 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 20 | this.addStructure(Feature.STRONGHOLD, new StrongholdConfig()); 21 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CAVE_WORLD_CARVER, new ProbabilityConfig(0.14285715F))); 22 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/SwampHillsBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/SwampHillsBiome.java 2 | +++ b/net/minecraft/world/biome/SwampHillsBiome.java 3 | @@ -18,6 +18,7 @@ 4 | import net.minecraft.world.gen.feature.TallGrassConfig; 5 | import net.minecraft.world.gen.feature.structure.MineshaftConfig; 6 | import net.minecraft.world.gen.feature.structure.MineshaftStructure; 7 | +import net.minecraft.world.gen.feature.structure.SwampHutConfig; 8 | import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig; 9 | import net.minecraft.world.gen.placement.ChanceConfig; 10 | import net.minecraft.world.gen.placement.CountRangeConfig; 11 | @@ -34,6 +35,7 @@ 12 | public final class SwampHillsBiome extends Biome { 13 | protected SwampHillsBiome() { 14 | super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder(SWAMP_SURFACE_BUILDER, GRASS_DIRT_GRAVEL_SURFACE)).precipitation(Biome.RainType.RAIN).category(Biome.Category.SWAMP).depth(-0.1F).scale(0.3F).temperature(0.8F).downfall(0.9F).waterColor(6388580).waterFogColor(2302743).parent("swamp")); 15 | + this.addStructure(Feature.SWAMP_HUT, new SwampHutConfig()); // BEDROCK: swamp huts in mutated swamps 16 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 17 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CAVE_WORLD_CARVER, new ProbabilityConfig(0.14285715F))); 18 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CANYON_WORLD_CARVER, new ProbabilityConfig(0.02F))); 19 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/biome/TaigaHillsBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/biome/TaigaHillsBiome.java 2 | +++ b/net/minecraft/world/biome/TaigaHillsBiome.java 3 | @@ -16,9 +16,7 @@ 4 | import net.minecraft.world.gen.feature.ProbabilityConfig; 5 | import net.minecraft.world.gen.feature.RandomDefaultFeatureListConfig; 6 | import net.minecraft.world.gen.feature.SphereReplaceConfig; 7 | -import net.minecraft.world.gen.feature.structure.MineshaftConfig; 8 | -import net.minecraft.world.gen.feature.structure.MineshaftStructure; 9 | -import net.minecraft.world.gen.feature.structure.StrongholdConfig; 10 | +import net.minecraft.world.gen.feature.structure.*; 11 | import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig; 12 | import net.minecraft.world.gen.placement.ChanceConfig; 13 | import net.minecraft.world.gen.placement.CountRangeConfig; 14 | @@ -33,6 +31,7 @@ 15 | public final class TaigaHillsBiome extends Biome { 16 | public TaigaHillsBiome() { 17 | super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder(DEFAULT_SURFACE_BUILDER, GRASS_DIRT_GRAVEL_SURFACE)).precipitation(Biome.RainType.RAIN).category(Biome.Category.TAIGA).depth(0.45F).scale(0.3F).temperature(0.25F).downfall(0.8F).waterColor(4159204).waterFogColor(329011).parent((String)null)); 18 | + this.addStructure(Feature.VILLAGE, new VillageConfig(0, VillagePieces.Type.SPRUCE)); // BEDROCK 19 | this.addStructure(Feature.MINESHAFT, new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)); 20 | this.addStructure(Feature.STRONGHOLD, new StrongholdConfig()); 21 | this.addCarver(GenerationStage.Carving.AIR, createWorldCarverWrapper(CAVE_WORLD_CARVER, new ProbabilityConfig(0.14285715F))); 22 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/ChunkGenSettings.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/ChunkGenSettings.java 2 | +++ b/net/minecraft/world/gen/ChunkGenSettings.java 3 | @@ -4,8 +4,8 @@ 4 | import net.minecraft.init.Blocks; 5 | 6 | public class ChunkGenSettings implements IChunkGenSettings { 7 | - protected int villageDistance = 32; 8 | - protected int villageSeparation = 8; 9 | + protected int villageDistance = 40; // BEDROCK 10 | + protected int villageSeparation = 12; // BEDROCK 11 | protected int oceanMonumentSpacing = 32; 12 | protected int oceanMonumentSeparation = 5; 13 | protected int strongholdDistance = 32; 14 | @@ -13,12 +13,12 @@ 15 | protected int strongholdSpread = 3; 16 | protected int biomeFeatureDistance = 32; 17 | protected int biomeFeatureSeparation = 8; 18 | - protected int field_204027_h = 16; 19 | - protected int field_211734_k = 8; 20 | + protected int field_204027_h = 12; // BEDROCK 21 | + protected int field_211734_k = 7; // BEDROCK 22 | protected int endCityDistance = 20; 23 | protected int endCitySeparation = 11; 24 | - protected int field_204749_j = 16; 25 | - protected int field_211736_o = 8; 26 | + protected int field_204749_j = 10; // BEDROCK 27 | + protected int field_211736_o = 5; // BEDROCK 28 | protected int mansionDistance = 80; 29 | protected int field_211737_q = 20; 30 | protected IBlockState defaultBlock = Blocks.STONE.getDefaultState(); 31 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/Feature.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/Feature.java 2 | +++ b/net/minecraft/world/gen/feature/Feature.java 3 | @@ -6,6 +6,9 @@ 4 | import java.util.Locale; 5 | import java.util.Map; 6 | import java.util.Random; 7 | + 8 | +import net.earthcomputer.bedrockified.BedrockShipwreckStructure; 9 | +import net.earthcomputer.bedrockified.BedrockStrongholdStructure; 10 | import net.minecraft.block.state.IBlockState; 11 | import net.minecraft.init.Blocks; 12 | import net.minecraft.util.Util; 13 | @@ -53,10 +56,11 @@ 14 | public static final Structure JUNGLE_PYRAMID = new JunglePyramidStructure(); 15 | public static final Structure DESERT_PYRAMID = new DesertPyramidStructure(); 16 | public static final Structure IGLOO = new IglooStructure(); 17 | - public static final Structure SHIPWRECK = new ShipwreckStructure(); 18 | + //public static final Structure SHIPWRECK = new ShipwreckStructure(); // BEDROCK: move down 19 | public static final Structure SWAMP_HUT = new SwampHutStructure(); 20 | - public static final Structure STRONGHOLD = new StrongholdStructure(); 21 | + public static final Structure STRONGHOLD = new BedrockStrongholdStructure((VillageStructure) VILLAGE); // BEDROCK 22 | public static final Structure OCEAN_MONUMENT = new OceanMonumentStructure(); 23 | + public static final Structure SHIPWRECK = new BedrockShipwreckStructure((OceanMonumentStructure) OCEAN_MONUMENT); // BEDROCK 24 | public static final Structure OCEAN_RUIN = new OceanRuinStructure(); 25 | public static final Structure FORTRESS = new FortressStructure(); 26 | public static final Structure END_CITY = new EndCityStructure(); 27 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/BuriedTreasureStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/BuriedTreasureStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/BuriedTreasureStructure.java 3 | @@ -10,14 +10,27 @@ 4 | 5 | public class BuriedTreasureStructure extends Structure { 6 | protected boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 7 | - Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos((chunkPosX << 4) + 9, 0, (chunkPosZ << 4) + 9), (Biome)null); 8 | - if (chunkGen.hasStructure(biome, Feature.BURIED_TREASURE)) { 9 | - ((SharedSeedRandom)rand).setLargeFeatureSeedWithSalt(chunkGen.getSeed(), chunkPosX, chunkPosZ, 10387320); 10 | - BuriedTreasureConfig buriedtreasureconfig = (BuriedTreasureConfig)chunkGen.getStructureConfig(biome, Feature.BURIED_TREASURE); 11 | - return rand.nextFloat() < buriedtreasureconfig.chance; 12 | - } else { 13 | + // BEDROCK: replace algorithm 14 | + int gridX = chunkPosX; 15 | + int gridZ = chunkPosZ; 16 | + if (chunkPosX < 0) 17 | + gridX -= 4 - 1; 18 | + if (chunkPosZ < 0) 19 | + gridZ -= 4 - 1; 20 | + gridX /= 4; 21 | + gridZ /= 4; 22 | + ((SharedSeedRandom)rand).setLargeFeatureSeedWithSalt(chunkGen.getSeed(), gridX, gridZ, 10387320); 23 | + int featureX = gridX * 4; 24 | + int featureZ = gridZ * 4; 25 | + featureX += (rand.nextInt(2) + rand.nextInt(2)) / 2; 26 | + featureZ += (rand.nextInt(2) + rand.nextInt(2)) / 2; 27 | + if (featureX != chunkPosX || featureZ != chunkPosZ) { 28 | return false; 29 | } 30 | + for (Biome b : chunkGen.getBiomeProvider().getBiomesInSquare((featureX << 4) + 8, (featureZ << 4) + 8, 3)) 31 | + if (!chunkGen.hasStructure(b, this)) 32 | + return false; 33 | + return true; 34 | } 35 | 36 | protected boolean isEnabledIn(IWorld worldIn) { 37 | @@ -25,7 +38,7 @@ 38 | } 39 | 40 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 41 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), (Biome)null); 42 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), (Biome)null); // BEDROCK: +8, not +9 43 | return new BuriedTreasureStructure.Start(worldIn, generator, random, x, z, biome); 44 | } 45 | 46 | @@ -51,7 +64,7 @@ 47 | } 48 | 49 | public BlockPos getPos() { 50 | - return new BlockPos((this.chunkPosX << 4) + 9, 0, (this.chunkPosZ << 4) + 9); 51 | + return new BlockPos((this.chunkPosX << 4) + 8, 0, (this.chunkPosZ << 4) + 8); // BEDROCK: +8, not +9 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/DesertPyramidStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/DesertPyramidStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/DesertPyramidStructure.java 3 | @@ -17,7 +17,7 @@ 4 | } 5 | 6 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 7 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.PLAINS); 8 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.PLAINS); // BEDROCK: +8, not +9 9 | return new DesertPyramidStructure.Start(worldIn, random, x, z, biome); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/FortressStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/FortressStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/FortressStructure.java 3 | @@ -27,7 +27,7 @@ 4 | } else if (chunkPosZ != (j << 4) + 4 + rand.nextInt(8)) { 5 | return false; 6 | } else { 7 | - Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos((chunkPosX << 4) + 9, 0, (chunkPosZ << 4) + 9), Biomes.DEFAULT); 8 | + Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos((chunkPosX << 4) + 8, 0, (chunkPosZ << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 9 | return chunkGen.hasStructure(biome, Feature.FORTRESS); 10 | } 11 | } 12 | @@ -37,7 +37,7 @@ 13 | } 14 | 15 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 16 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.DEFAULT); 17 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 18 | return new FortressStructure.Start(worldIn, random, x, z, biome); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/IglooStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/IglooStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/IglooStructure.java 3 | @@ -20,12 +20,12 @@ 4 | } 5 | 6 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 7 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.PLAINS); 8 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.PLAINS); // BEDROCK: +8, not +9 9 | return new IglooStructure.Start(worldIn, generator, random, x, z, biome); 10 | } 11 | 12 | protected int getSeedModifier() { 13 | - return 14357618; 14 | + return 14357617; // BEDROCK: all temples have the same salt 15 | } 16 | 17 | public static class Start extends StructureStart { 18 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/JunglePyramidStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/JunglePyramidStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/JunglePyramidStructure.java 3 | @@ -17,12 +17,12 @@ 4 | } 5 | 6 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 7 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.PLAINS); 8 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.PLAINS); // BEDROCK: +8, not +9 9 | return new JunglePyramidStructure.Start(worldIn, random, x, z, biome); 10 | } 11 | 12 | protected int getSeedModifier() { 13 | - return 14357619; 14 | + return 14357617; // BEDROCK: all temples have the same salt 15 | } 16 | 17 | public static class Start extends StructureStart { 18 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/MineshaftStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/MineshaftStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/MineshaftStructure.java 3 | @@ -12,11 +12,16 @@ 4 | public class MineshaftStructure extends Structure { 5 | protected boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 6 | ((SharedSeedRandom)rand).setLargeFeatureSeed(chunkGen.getSeed(), chunkPosX, chunkPosZ); 7 | - Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos((chunkPosX << 4) + 9, 0, (chunkPosZ << 4) + 9), Biomes.DEFAULT); 8 | + Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos((chunkPosX << 4) + 8, 0, (chunkPosZ << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 9 | if (chunkGen.hasStructure(biome, Feature.MINESHAFT)) { 10 | - MineshaftConfig mineshaftconfig = (MineshaftConfig)chunkGen.getStructureConfig(biome, Feature.MINESHAFT); 11 | - double d0 = mineshaftconfig.field_202439_a; 12 | - return rand.nextDouble() < d0; 13 | + // BEDROCK: replace algorithm 14 | + rand.nextInt(); 15 | + float f = rand.nextFloat(); 16 | + int minDistance = rand.nextInt(80); 17 | + if (f < 0.004) { 18 | + return minDistance < Math.max(Math.abs(chunkPosX), Math.abs(chunkPosZ)); 19 | + } 20 | + return false; 21 | } else { 22 | return false; 23 | } 24 | @@ -27,7 +32,7 @@ 25 | } 26 | 27 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 28 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.DEFAULT); 29 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 30 | return new MineshaftStructure.Start(worldIn, generator, random, x, z, biome); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/OceanMonumentStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/OceanMonumentStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/OceanMonumentStructure.java 3 | @@ -41,16 +41,17 @@ 4 | return new ChunkPos(k1, l1); 5 | } 6 | 7 | - protected boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 8 | + // BEDROCK: changed access from protected to public 9 | + public boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 10 | ChunkPos chunkpos = this.getStartPositionForPosition(chunkGen, rand, chunkPosX, chunkPosZ, 0, 0); 11 | if (chunkPosX == chunkpos.x && chunkPosZ == chunkpos.z) { 12 | - for(Biome biome : chunkGen.getBiomeProvider().getBiomesInSquare(chunkPosX * 16 + 9, chunkPosZ * 16 + 9, 16)) { 13 | + for(Biome biome : chunkGen.getBiomeProvider().getBiomesInSquare(chunkPosX * 16 + 8, chunkPosZ * 16 + 8, 16)) { // BEDROCK: +8, not +9 14 | if (!chunkGen.hasStructure(biome, Feature.OCEAN_MONUMENT)) { 15 | return false; 16 | } 17 | } 18 | 19 | - for(Biome biome1 : chunkGen.getBiomeProvider().getBiomesInSquare(chunkPosX * 16 + 9, chunkPosZ * 16 + 9, 29)) { 20 | + for(Biome biome1 : chunkGen.getBiomeProvider().getBiomesInSquare(chunkPosX * 16 + 8, chunkPosZ * 16 + 8, 29)) { // BEDROCK: +8, not +9 21 | if (biome1.getCategory() != Biome.Category.OCEAN && biome1.getCategory() != Biome.Category.RIVER) { 22 | return false; 23 | } 24 | @@ -67,7 +68,7 @@ 25 | } 26 | 27 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 28 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.DEFAULT); 29 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 30 | return new OceanMonumentStructure.Start(worldIn, random, x, z, biome); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/OceanRuinStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/OceanRuinStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/OceanRuinStructure.java 3 | @@ -3,13 +3,37 @@ 4 | import net.minecraft.util.Rotation; 5 | import net.minecraft.util.SharedSeedRandom; 6 | import net.minecraft.util.math.BlockPos; 7 | +import net.minecraft.util.math.ChunkPos; 8 | import net.minecraft.world.IWorld; 9 | import net.minecraft.world.biome.Biome; 10 | import net.minecraft.world.gen.IChunkGenerator; 11 | import net.minecraft.world.gen.feature.Feature; 12 | import net.minecraft.world.gen.feature.template.TemplateManager; 13 | 14 | +import java.util.Random; 15 | + 16 | public class OceanRuinStructure extends ScatteredStructure { 17 | + // BEDROCK: double random calls, needs reimplementation 18 | + @Override 19 | + protected ChunkPos getStartPositionForPosition(IChunkGenerator chunkGenerator, Random random, int x, int z, int spacingOffsetsX, int spacingOffsetsZ) { 20 | + int ruinSpacing = getBiomeFeatureDistance(chunkGenerator); 21 | + int ruinSeparation = func_211745_b(chunkGenerator); 22 | + int gridX = x + ruinSpacing * spacingOffsetsX; 23 | + int gridZ = z + ruinSpacing * spacingOffsetsZ; 24 | + if (x < 0) 25 | + gridX -= ruinSpacing - 1; 26 | + if (z < 0) 27 | + gridZ -= ruinSpacing - 1; 28 | + gridX /= ruinSpacing; 29 | + gridZ /= ruinSpacing; 30 | + ((SharedSeedRandom) random).setLargeFeatureSeedWithSalt(chunkGenerator.getSeed(), gridX, gridZ, getSeedModifier()); 31 | + int featureX = gridX * ruinSpacing; 32 | + int featureZ = gridZ * ruinSpacing; 33 | + featureX += (random.nextInt(ruinSpacing - ruinSeparation) + random.nextInt(ruinSpacing - ruinSeparation)) / 2; 34 | + featureZ += (random.nextInt(ruinSpacing - ruinSeparation) + random.nextInt(ruinSpacing - ruinSeparation)) / 2; 35 | + return new ChunkPos(featureX, featureZ); 36 | + } 37 | + 38 | public String getStructureName() { 39 | return "Ocean_Ruin"; 40 | } 41 | @@ -27,7 +51,7 @@ 42 | } 43 | 44 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 45 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), (Biome)null); 46 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), (Biome)null); // BEDROCK: +8, not +9 47 | return new OceanRuinStructure.Start(worldIn, generator, random, x, z, biome); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/ScatteredStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/ScatteredStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/ScatteredStructure.java 3 | @@ -30,7 +30,7 @@ 4 | protected boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 5 | ChunkPos chunkpos = this.getStartPositionForPosition(chunkGen, rand, chunkPosX, chunkPosZ, 0, 0); 6 | if (chunkPosX == chunkpos.x && chunkPosZ == chunkpos.z) { 7 | - Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos(chunkPosX * 16 + 9, 0, chunkPosZ * 16 + 9), (Biome)null); 8 | + Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos(chunkPosX * 16 + 8, 0, chunkPosZ * 16 + 8), (Biome)null); // BEDROCK: +8, not +9 9 | if (chunkGen.hasStructure(biome, this)) { 10 | return true; 11 | } 12 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/ShipwreckStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/ShipwreckStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/ShipwreckStructure.java 3 | @@ -18,7 +18,7 @@ 4 | } 5 | 6 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 7 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), (Biome)null); 8 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), (Biome)null); // BEDROCK: +8, not +9 9 | return new ShipwreckStructure.Start(worldIn, generator, random, x, z, biome); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/StrongholdStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/StrongholdStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/StrongholdStructure.java 3 | @@ -51,7 +51,7 @@ 4 | } 5 | 6 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 7 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.DEFAULT); 8 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 9 | int i = 0; 10 | 11 | StrongholdStructure.Start strongholdstructure$start; 12 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/SwampHutStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/SwampHutStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/SwampHutStructure.java 3 | @@ -22,12 +22,12 @@ 4 | } 5 | 6 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 7 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.PLAINS); 8 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.PLAINS); // BEDROCK: +8, not +9 9 | return new SwampHutStructure.Start(worldIn, random, x, z, biome); 10 | } 11 | 12 | protected int getSeedModifier() { 13 | - return 14357620; 14 | + return 14357617; // BEDROCK: all temples have the same salt 15 | } 16 | 17 | public List getSpawnList() { 18 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/VillageStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/VillageStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/VillageStructure.java 3 | @@ -42,10 +42,11 @@ 4 | return new ChunkPos(k1, l1); 5 | } 6 | 7 | - protected boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 8 | + // BEDROCK: changed access from protected to public 9 | + public boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 10 | ChunkPos chunkpos = this.getStartPositionForPosition(chunkGen, rand, chunkPosX, chunkPosZ, 0, 0); 11 | if (chunkPosX == chunkpos.x && chunkPosZ == chunkpos.z) { 12 | - Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos((chunkPosX << 4) + 9, 0, (chunkPosZ << 4) + 9), Biomes.DEFAULT); 13 | + Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos((chunkPosX << 4) + 8, 0, (chunkPosZ << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 14 | return chunkGen.hasStructure(biome, Feature.VILLAGE); 15 | } else { 16 | return false; 17 | @@ -53,7 +54,7 @@ 18 | } 19 | 20 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 21 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.DEFAULT); 22 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 23 | return new VillageStructure.Start(worldIn, generator, random, x, z, biome); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/feature/structure/WoodlandMansionStructure.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/feature/structure/WoodlandMansionStructure.java 2 | +++ b/net/minecraft/world/gen/feature/structure/WoodlandMansionStructure.java 3 | @@ -39,7 +39,7 @@ 4 | protected boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 5 | ChunkPos chunkpos = this.getStartPositionForPosition(chunkGen, rand, chunkPosX, chunkPosZ, 0, 0); 6 | if (chunkPosX == chunkpos.x && chunkPosZ == chunkpos.z) { 7 | - for(Biome biome : chunkGen.getBiomeProvider().getBiomesInSquare(chunkPosX * 16 + 9, chunkPosZ * 16 + 9, 32)) { 8 | + for(Biome biome : chunkGen.getBiomeProvider().getBiomesInSquare(chunkPosX * 16 + 8, chunkPosZ * 16 + 8, 32)) { // BEDROCK: +8, not +9 9 | if (!chunkGen.hasStructure(biome, Feature.WOODLAND_MANSION)) { 10 | return false; 11 | } 12 | @@ -56,7 +56,7 @@ 13 | } 14 | 15 | protected StructureStart makeStart(IWorld worldIn, IChunkGenerator generator, SharedSeedRandom random, int x, int z) { 16 | - Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 9, 0, (z << 4) + 9), Biomes.DEFAULT); 17 | + Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((x << 4) + 8, 0, (z << 4) + 8), Biomes.DEFAULT); // BEDROCK: +8, not +9 18 | return new WoodlandMansionStructure.Start(worldIn, generator, random, x, z, biome); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/layer/GenLayerBiome.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/layer/GenLayerBiome.java 2 | +++ b/net/minecraft/world/gen/layer/GenLayerBiome.java 3 | @@ -26,7 +26,8 @@ 4 | private static final int SNOWY_TAIGA = IRegistry.BIOME.getId(Biomes.SNOWY_TAIGA); 5 | private static final int[] field_202743_q = new int[]{DESERT, FOREST, MOUNTAINS, SWAMP, PLAINS, TAIGA}; 6 | private static final int[] field_202744_r = new int[]{DESERT, DESERT, DESERT, SAVANNA, SAVANNA, PLAINS}; 7 | - private static final int[] field_202745_s = new int[]{FOREST, DARK_FOREST, MOUNTAINS, PLAINS, BIRCH_FOREST, SWAMP}; 8 | + // BEDROCK: plains has weight 3 rather than 1 9 | + private static final int[] field_202745_s = new int[]{FOREST, DARK_FOREST, MOUNTAINS, PLAINS, PLAINS, PLAINS, BIRCH_FOREST, SWAMP}; 10 | private static final int[] field_202746_t = new int[]{FOREST, MOUNTAINS, TAIGA, PLAINS}; 11 | private static final int[] field_202747_u = new int[]{SNOWY_TUNDRA, SNOWY_TUNDRA, SNOWY_TUNDRA, SNOWY_TAIGA}; 12 | private final OverworldGenSettings settings; 13 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/layer/GenLayerMixOceans.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/layer/GenLayerMixOceans.java 2 | +++ b/net/minecraft/world/gen/layer/GenLayerMixOceans.java 3 | @@ -18,6 +18,8 @@ 4 | int k = 8; 5 | int l = 4; 6 | 7 | + // BEDROCK: remove extreme shoreline check 8 | + /* 9 | for(int i1 = -8; i1 <= 8; i1 += 4) { 10 | for(int j1 = -8; j1 <= 8; j1 += 4) { 11 | int k1 = area1.getValue(x + i1, z + j1); 12 | @@ -32,6 +34,7 @@ 13 | } 14 | } 15 | } 16 | + */ 17 | 18 | if (i == LayerUtil.DEEP_OCEAN) { 19 | if (j == LayerUtil.LUKEWARM_OCEAN) { 20 | -------------------------------------------------------------------------------- /patches/net/minecraft/world/gen/layer/LayerUtil.java.patch: -------------------------------------------------------------------------------- 1 | --- a/net/minecraft/world/gen/layer/LayerUtil.java 2 | +++ b/net/minecraft/world/gen/layer/LayerUtil.java 3 | @@ -2,6 +2,9 @@ 4 | 5 | import com.google.common.collect.ImmutableList; 6 | import java.util.function.LongFunction; 7 | + 8 | +import net.earthcomputer.bedrockified.BedrockAddOceanEdgeLayer; 9 | +import net.earthcomputer.bedrockified.BedrockAddOceanTemperatureLayer; 10 | import net.minecraft.init.Biomes; 11 | import net.minecraft.util.registry.IRegistry; 12 | import net.minecraft.world.WorldType; 13 | @@ -30,7 +33,8 @@ 14 | IAreaFactory iareafactory = p_202829_3_; 15 | 16 | for(int i = 0; i < count; ++i) { 17 | - iareafactory = parent.apply((IContextExtended)contextFactory.apply(seed + (long)i), iareafactory); 18 | + // BEDROCK: adding a constant of 1 rather than i 19 | + iareafactory = parent.apply((IContextExtended)contextFactory.apply(seed + 1), iareafactory); 20 | } 21 | 22 | return iareafactory; 23 | @@ -45,7 +49,9 @@ 24 | iareafactory = GenLayerAddIsland.INSTANCE.apply((IContextExtended)contextFactory.apply(50L), iareafactory); 25 | iareafactory = GenLayerAddIsland.INSTANCE.apply((IContextExtended)contextFactory.apply(70L), iareafactory); 26 | iareafactory = GenLayerRemoveTooMuchOcean.INSTANCE.apply((IContextExtended)contextFactory.apply(2L), iareafactory); 27 | - IAreaFactory iareafactory1 = OceanLayer.INSTANCE.apply((IContextExtended)contextFactory.apply(2L)); 28 | + // BEDROCK: rewrite ocean temperature generation 29 | + IAreaFactory iareafactory1 = BedrockAddOceanTemperatureLayer.INSTANCE.apply((IContextExtended)contextFactory.apply(2L), iareafactory); 30 | + iareafactory1 = BedrockAddOceanEdgeLayer.INSTANCE.apply((IContextExtended)contextFactory.apply(2L), iareafactory1); 31 | iareafactory1 = repeat(2001L, GenLayerZoom.NORMAL, iareafactory1, 6, contextFactory); 32 | iareafactory = GenLayerAddSnow.INSTANCE.apply((IContextExtended)contextFactory.apply(2L), iareafactory); 33 | iareafactory = GenLayerAddIsland.INSTANCE.apply((IContextExtended)contextFactory.apply(3L), iareafactory); 34 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | import groovy.json.JsonSlurper 2 | 3 | def settings = new JsonSlurper().parseText(file('conf/settings.json').text) 4 | 5 | rootProject.name = settings.modname.substring(0, 1).toUpperCase(Locale.ENGLISH) + settings.modname.substring(1) 6 | 7 | include ':mcp' 8 | include ':clean' 9 | include ':' + settings.modname 10 | 11 | project(':mcp').projectDir = file('projects/mcp') 12 | project(':clean').projectDir = file('projects/clean') 13 | project(':' + settings.modname).projectDir = file('projects/' + settings.modname) 14 | -------------------------------------------------------------------------------- /src/main/java/net/earthcomputer/bedrockified/BedrockAddOceanEdgeLayer.java: -------------------------------------------------------------------------------- 1 | package net.earthcomputer.bedrockified; 2 | 3 | import net.minecraft.world.gen.IContext; 4 | import net.minecraft.world.gen.layer.traits.ICastleTransformer; 5 | 6 | import static net.earthcomputer.bedrockified.BedrockAddOceanTemperatureLayer.*; 7 | 8 | public enum BedrockAddOceanEdgeLayer implements ICastleTransformer { 9 | INSTANCE; 10 | 11 | @Override 12 | public int apply(IContext context, int north, int east, int south, int west, int middle) { 13 | // Make sure no warm ocean is next to frozen ocean 14 | if (middle == OCEAN_WARM 15 | && (north == OCEAN_FROZEN 16 | || east == OCEAN_FROZEN 17 | || west == OCEAN_FROZEN 18 | || south == OCEAN_FROZEN)) { 19 | return OCEAN; 20 | } else if (middle == OCEAN_FROZEN 21 | && (north == OCEAN_WARM 22 | || east == OCEAN_WARM 23 | || west == OCEAN_WARM 24 | || south == OCEAN_WARM)) { 25 | return OCEAN; 26 | } else { 27 | return middle; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/net/earthcomputer/bedrockified/BedrockAddOceanTemperatureLayer.java: -------------------------------------------------------------------------------- 1 | package net.earthcomputer.bedrockified; 2 | 3 | import net.minecraft.init.Biomes; 4 | import net.minecraft.util.registry.IRegistry; 5 | import net.minecraft.world.gen.IContext; 6 | import net.minecraft.world.gen.layer.traits.IC0Transformer; 7 | 8 | public enum BedrockAddOceanTemperatureLayer implements IC0Transformer { 9 | INSTANCE; 10 | 11 | static final int OCEAN = IRegistry.BIOME.getId(Biomes.OCEAN); 12 | static final int OCEAN_LUKEWARM = IRegistry.BIOME.getId(Biomes.LUKEWARM_OCEAN); 13 | static final int OCEAN_WARM = IRegistry.BIOME.getId(Biomes.WARM_OCEAN); 14 | static final int OCEAN_COLD = IRegistry.BIOME.getId(Biomes.COLD_OCEAN); 15 | static final int OCEAN_FROZEN = IRegistry.BIOME.getId(Biomes.FROZEN_OCEAN); 16 | 17 | @Override 18 | public int apply(IContext context, int value) { 19 | float f = context.random(100) / 100f; 20 | if (f < 0.075f) { 21 | return OCEAN_WARM; 22 | } else if (f < 0.4f) { 23 | return OCEAN_LUKEWARM; 24 | } else if (f < 0.675f) { 25 | return OCEAN; 26 | } else if (f < 0.95f) { 27 | return OCEAN_COLD; 28 | } else { 29 | return OCEAN_FROZEN; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/net/earthcomputer/bedrockified/BedrockRandom.java: -------------------------------------------------------------------------------- 1 | package net.earthcomputer.bedrockified; 2 | 3 | import net.minecraft.util.math.Vec3d; 4 | 5 | import java.util.Random; 6 | 7 | /** 8 | * An RNG implementation equivalent to that of Minecraft: Bedrock Edition. 9 | * 10 | * This is a version of the m19937 mersenne twister algorithm. 11 | * This version contains the improved initialization from http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c 12 | * It also contains an optimization to only generate some of the MT array when the RNG is first initialized. 13 | * 14 | * @author Earthcomputer 15 | */ 16 | public class BedrockRandom extends Random { 17 | 18 | private static final int N = 624; 19 | private static final int M = 397; 20 | private static final int MATRIX_A = 0x9908b0df; 21 | private static final int UPPER_MASK = 0x80000000; 22 | private static final int LOWER_MASK = 0x7fffffff; 23 | private static final int[] MAG_01 = {0, MATRIX_A}; 24 | private static final double TWO_POW_M32 = 1.0 / (1L << 32); 25 | 26 | private int seed; // (DWORD*) this + 0 27 | private int[] mt = new int[N]; // (DWORD*) this + 1 28 | private int mti; // (DWORD*) this + 625 29 | private boolean haveNextNextGaussian; // (DWORD*) this + 626 30 | private float nextNextGaussian; // (float*) this + 627 31 | private int mtiFast; // (DWORD*) this + 628 32 | 33 | private boolean valid = false; // Hackfix for setSeed being called too early in the superconstructor 34 | 35 | 36 | public BedrockRandom() { 37 | this(new Random().nextInt()); 38 | } 39 | 40 | public BedrockRandom(int seed) { 41 | valid = true; 42 | _setSeed(seed); 43 | } 44 | 45 | 46 | // ===== PUBLIC INTERFACE METHODS ===== // 47 | 48 | public int getSeed() { 49 | return seed; 50 | } 51 | 52 | /** 53 | * This overload exists to override the method in the base class. 54 | * Although it accepts a 64-bit long, it will be cast to a 32-bit int. 55 | */ 56 | @Override 57 | public void setSeed(long seed) { 58 | if (valid) // Hackfix for this being called too early in the superconstructor 59 | setSeed((int) seed); 60 | } 61 | 62 | public void setSeed(int seed) { 63 | _setSeed(seed); 64 | } 65 | 66 | /** 67 | * Generates a non-negative signed integer 68 | */ 69 | @Override 70 | public int nextInt() { 71 | return _genRandInt32() >>> 1; 72 | } 73 | 74 | @Override 75 | public int nextInt(int bound) { 76 | if (bound > 0) 77 | return (int) (Integer.toUnsignedLong(_genRandInt32()) % bound); 78 | else 79 | return 0; 80 | } 81 | 82 | /** 83 | * Generates a random integer k such that a <= k < b 84 | */ 85 | public int nextInt(int a, int b) { 86 | if (a < b) 87 | return a + nextInt(b - a); 88 | else 89 | return a; 90 | } 91 | 92 | /** 93 | * Generates a random integer k such that a <= k <= b 94 | */ 95 | public int nextIntInclusive(int a, int b) { 96 | return nextInt(a, b + 1); 97 | } 98 | 99 | /** 100 | * Generates a random long k such that 0 <= k < 2^32, mti.e. a random unsigned int 101 | */ 102 | public long nextUnsignedInt() { 103 | return Integer.toUnsignedLong(_genRandInt32()); 104 | } 105 | 106 | /** 107 | * Generates a random short k such that 0 <= k < 256, mti.e. a random unsigned byte 108 | */ 109 | public short nextUnsignedChar() { 110 | return (short) (_genRandInt32() & 0xff); 111 | } 112 | 113 | @Override 114 | public boolean nextBoolean() { 115 | return (_genRandInt32() & 0x8000000) != 0; 116 | } 117 | 118 | /** 119 | * Generates a uniform random float k such that 0 <= k < 1 120 | */ 121 | @Override 122 | public float nextFloat() { 123 | return (float) _genRandReal2(); 124 | } 125 | 126 | /** 127 | * Generates a uniform random float k such that 0 <= k < bound 128 | */ 129 | public float nextFloat(float bound) { 130 | return nextFloat() * bound; 131 | } 132 | 133 | /** 134 | * Generates a uniform random float k such that a <= k < b 135 | */ 136 | public float nextFloat(float a, float b) { 137 | return a + (nextFloat() * (b - a)); 138 | } 139 | 140 | /** 141 | * Generates a uniform random double k such that 0 <= k < 1. 142 | * 143 | * Note that unlike the Java RNG, there are only 2^32 possible return values for this function 144 | */ 145 | @Override 146 | public double nextDouble() { 147 | return _genRandReal2(); 148 | } 149 | 150 | /** 151 | * Generates a Gaussian distributed float with mean 0 and standard deviation 1. 152 | * 153 | * This method returns a double to override the method in the base class, but it is a 154 | * float that's generated, and it can be safely cast back to float without loss of precision. 155 | */ 156 | @Override 157 | public double nextGaussian() { 158 | if (haveNextNextGaussian) { 159 | haveNextNextGaussian = false; 160 | return nextNextGaussian; 161 | } 162 | 163 | float v1, v2, s; 164 | do { 165 | v1 = nextFloat() * 2 - 1; 166 | v2 = nextFloat() * 2 - 1; 167 | s = v1 * v1 + v2 * v2; 168 | } while (s == 0 || s > 1); 169 | 170 | float multiplier = (float) Math.sqrt(-2 * (float) Math.log(s) / s); 171 | nextNextGaussian = v2 * multiplier; 172 | haveNextNextGaussian = true; 173 | return v1 * multiplier; 174 | } 175 | 176 | /** 177 | * Returns a triangularly distributed int k with mode 0 such that -bound < k < bound. 178 | * 179 | * Note that the method name, used in the Bedrock code, incorrectly describes this as a Gaussian distribution. 180 | */ 181 | public int nextGaussianInt(int bound) { 182 | return nextInt(bound) - nextInt(bound); 183 | } 184 | 185 | /** 186 | * Returns a triangularly distributed float k with mode 0 such that -1 < k < 1. 187 | * 188 | * Note that the method name, used in the Bedrock code, incorrectly describes this as a Gaussian distribution. 189 | */ 190 | public float nextGaussianFloat() { 191 | return nextFloat() - nextFloat(); 192 | } 193 | 194 | /** 195 | * Returns uniformly distributed 3d float vector v such that 0 <= v_i < 1 for each mti. 196 | * 197 | * Note that although this method returns a double vector, the precision is only float, 198 | * and can be safely cast back to floats without loss of precision. 199 | */ 200 | public Vec3d nextVec3() { 201 | float x = nextFloat(); 202 | float y = nextFloat(); 203 | float z = nextFloat(); 204 | return new Vec3d(x, y, z); 205 | } 206 | 207 | /** 208 | * Returns a float vector containing 3 Gaussian distributed floats with mean 0 and standard deviation 1. 209 | * 210 | * Note that although this method returns a double vector, the precision is only float, 211 | * and can be safely cast back to floats without loss of precision. 212 | */ 213 | public Vec3d nextGaussianVec3() { 214 | float x = (float) nextGaussian(); 215 | float y = (float) nextGaussian(); 216 | float z = (float) nextGaussian(); 217 | return new Vec3d(x, y, z); 218 | } 219 | 220 | @Override 221 | protected int next(int bits) { 222 | return _genRandInt32() >>> (32 - bits); 223 | } 224 | 225 | 226 | // ===== m19937 MERSENNE TWISTER IMPLEMENTATION ===== // 227 | 228 | private void _setSeed(int seed) { 229 | this.seed = seed; 230 | this.mti = N + 1; // uninitialized 231 | this.haveNextNextGaussian = false; 232 | this.nextNextGaussian = 0; 233 | _initGenRandFast(seed); 234 | } 235 | 236 | private void _initGenRand(int initialValue) { 237 | this.mt[0] = initialValue; 238 | for (this.mti = 1; this.mti < N; this.mti++) { 239 | this.mt[mti] = 1812433253 240 | * ((this.mt[this.mti - 1] >>> 30) ^ this.mt[this.mti - 1]) 241 | + this.mti; 242 | } 243 | this.mtiFast = N; 244 | } 245 | 246 | private void _initGenRandFast(int initialValue) { 247 | this.mt[0] = initialValue; 248 | for (this.mtiFast = 1; this.mtiFast <= M; this.mtiFast++) { 249 | this.mt[this.mtiFast] = 1812433253 250 | * ((this.mt[this.mtiFast - 1] >>> 30) ^ this.mt[this.mtiFast - 1]) 251 | + this.mtiFast; 252 | } 253 | this.mti = N; 254 | } 255 | 256 | private int _genRandInt32() { 257 | if (this.mti == N) { 258 | this.mti = 0; 259 | } else if (this.mti > N) { 260 | _initGenRand(5489); 261 | this.mti = 0; 262 | } 263 | 264 | if (this.mti >= N - M) { 265 | if (this.mti >= N - 1) { 266 | this.mt[N - 1] = MAG_01[this.mt[0] & 1] 267 | ^ ((this.mt[0] & LOWER_MASK | this.mt[N - 1] & UPPER_MASK) >>> 1) 268 | ^ this.mt[M - 1]; 269 | } else { 270 | this.mt[this.mti] = MAG_01[this.mt[this.mti + 1] & 1] 271 | ^ ((this.mt[this.mti + 1] & LOWER_MASK | this.mt[this.mti] & UPPER_MASK) >>> 1) 272 | ^ this.mt[this.mti - (N - M)]; 273 | } 274 | } else { 275 | this.mt[this.mti] = MAG_01[this.mt[this.mti + 1] & 1] 276 | ^ ((this.mt[this.mti + 1] & LOWER_MASK | this.mt[this.mti] & UPPER_MASK) >>> 1) 277 | ^ this.mt[this.mti + M]; 278 | 279 | if (this.mtiFast < N) { 280 | this.mt[this.mtiFast] = 1812433253 281 | * ((this.mt[this.mtiFast - 1] >>> 30) ^ this.mt[this.mtiFast - 1]) 282 | + this.mtiFast; 283 | this.mtiFast++; 284 | } 285 | } 286 | 287 | int ret = this.mt[this.mti++]; 288 | ret = ((ret ^ (ret >>> 11)) << 7) & 0x9d2c5680 ^ ret ^ (ret >>> 11); 289 | ret = (ret << 15) & 0xefc60000 ^ ret ^ (((ret << 15) & 0xefc60000 ^ ret) >>> 18); 290 | return ret; 291 | } 292 | 293 | private double _genRandReal2() { 294 | return Integer.toUnsignedLong(_genRandInt32()) * TWO_POW_M32; 295 | } 296 | 297 | } 298 | -------------------------------------------------------------------------------- /src/main/java/net/earthcomputer/bedrockified/BedrockSeed.java: -------------------------------------------------------------------------------- 1 | package net.earthcomputer.bedrockified; 2 | 3 | public class BedrockSeed { 4 | 5 | public static long getBedrockSeed(String str, long _defaultLong) { 6 | int _default = (int) _defaultLong; 7 | 8 | int bedrockSeed; 9 | 10 | if (str.length() < 2) 11 | bedrockSeed = _default; 12 | else if (str.charAt(0) == '-' && str.length() == 2) 13 | bedrockSeed = _default; 14 | else { 15 | str = str.trim(); 16 | if (str.isEmpty()) 17 | bedrockSeed = _default; 18 | else if (str.charAt(0) == '0' || (str.length() > 1 && str.charAt(0) == '-' && str.charAt(1) == '0')) { // bedrock doesn't contain length check but we want to prevent a crash 19 | bedrockSeed = str.hashCode(); 20 | } else if (!isIntegral(str)) { 21 | bedrockSeed = str.hashCode(); 22 | } else { 23 | try { 24 | bedrockSeed = Integer.parseInt(str); 25 | if (!str.equals("-1") && bedrockSeed == -1) 26 | bedrockSeed = _default; 27 | } catch (NumberFormatException e) { 28 | bedrockSeed = _default; 29 | } 30 | } 31 | } 32 | 33 | return Integer.toUnsignedLong(bedrockSeed); 34 | } 35 | 36 | private static boolean isIntegral(String str) { 37 | if (str.startsWith("-")) 38 | str = str.substring(1); 39 | for (int i = 0; i < str.length(); i++) { 40 | char c = str.charAt(i); 41 | if (c < '0' || c > '9') 42 | return false; 43 | } 44 | return true; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/net/earthcomputer/bedrockified/BedrockShipwreckStructure.java: -------------------------------------------------------------------------------- 1 | package net.earthcomputer.bedrockified; 2 | 3 | import com.google.common.collect.ImmutableSet; 4 | import net.minecraft.init.Biomes; 5 | import net.minecraft.util.SharedSeedRandom; 6 | import net.minecraft.util.math.BlockPos; 7 | import net.minecraft.util.math.ChunkPos; 8 | import net.minecraft.world.biome.Biome; 9 | import net.minecraft.world.gen.IChunkGenerator; 10 | import net.minecraft.world.gen.feature.structure.OceanMonumentStructure; 11 | import net.minecraft.world.gen.feature.structure.ShipwreckStructure; 12 | 13 | import java.util.Random; 14 | 15 | public class BedrockShipwreckStructure extends ShipwreckStructure { 16 | 17 | private OceanMonumentStructure monumentGenerator; 18 | 19 | public BedrockShipwreckStructure(OceanMonumentStructure monumentGenerator) { 20 | this.monumentGenerator = monumentGenerator; 21 | } 22 | 23 | @Override 24 | protected ChunkPos getStartPositionForPosition(IChunkGenerator chunkGenerator, Random random, int x, int z, int spacingOffsetsX, int spacingOffsetsZ) { 25 | int shipwreckSpacing = getBiomeFeatureDistance(chunkGenerator); 26 | int shipwreckSeparation = func_211745_b(chunkGenerator); 27 | 28 | int gridX = x + shipwreckSpacing * spacingOffsetsX; 29 | int gridZ = z + shipwreckSpacing * spacingOffsetsZ; 30 | if (x < 0) 31 | gridX -= shipwreckSpacing - 1; 32 | if (z < 0) 33 | gridZ -= shipwreckSpacing - 1; 34 | gridX /= shipwreckSpacing; 35 | gridZ /= shipwreckSpacing; 36 | 37 | ((SharedSeedRandom) random).setLargeFeatureSeedWithSalt(chunkGenerator.getSeed(), gridX, gridZ, getSeedModifier()); 38 | 39 | int featureX = gridX * shipwreckSpacing; 40 | int featureZ = gridZ * shipwreckSpacing; 41 | featureX += (random.nextInt(shipwreckSpacing - shipwreckSeparation) + random.nextInt(shipwreckSpacing - shipwreckSeparation)) / 2; 42 | featureZ += (random.nextInt(shipwreckSpacing - shipwreckSeparation) + random.nextInt(shipwreckSpacing - shipwreckSeparation)) / 2; 43 | 44 | return new ChunkPos(featureX, featureZ); 45 | } 46 | 47 | @Override 48 | protected boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 49 | ChunkPos chunk = getStartPositionForPosition(chunkGen, rand, chunkPosX, chunkPosZ, 0, 0); 50 | if (chunk.x != chunkPosX || chunk.z != chunkPosZ) 51 | return false; 52 | 53 | for (int dx = chunkPosX - 5; dx < chunkPosX + 5; dx++) { 54 | for (int dz = chunkPosZ - 5; dz < chunkPosZ + 5; dz++) { 55 | if (monumentGenerator.hasStartAt(chunkGen, rand, chunkPosX, chunkPosZ)) { 56 | return false; 57 | } 58 | } 59 | } 60 | 61 | Biome biome = chunkGen.getBiomeProvider().getBiome(new BlockPos((chunkPosX << 4) + 8, 0, (chunkPosZ << 4) + 8), Biomes.DEFAULT); 62 | if (!chunkGen.hasStructure(biome, this)) 63 | return false; 64 | 65 | int radius = isShipwreckBeached(biome) ? 10 : 20; 66 | for (Biome b : chunkGen.getBiomeProvider().getBiomesInSquare((chunkPosX << 4) + 8, (chunkPosZ << 4) + 8, radius)) 67 | if (b != biome) 68 | return false; 69 | 70 | return true; 71 | } 72 | 73 | private boolean isShipwreckBeached(Biome biome) { 74 | return biome == Biomes.BEACH || biome == Biomes.SNOWY_BEACH || biome == Biomes.MUSHROOM_FIELD_SHORE; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/net/earthcomputer/bedrockified/BedrockSpawnPoint.java: -------------------------------------------------------------------------------- 1 | package net.earthcomputer.bedrockified; 2 | 3 | import net.minecraft.util.math.BlockPos; 4 | import net.minecraft.world.WorldSettings; 5 | import net.minecraft.world.WorldType; 6 | import net.minecraft.world.biome.Biome; 7 | import net.minecraft.world.biome.provider.BiomeProvider; 8 | 9 | import javax.annotation.Nullable; 10 | 11 | public class BedrockSpawnPoint { 12 | 13 | public static BlockPos findSpawnPosition(WorldSettings worldSettings, BiomeProvider biomeProvider) { 14 | if (worldSettings.getTerrainType() == WorldType.FLAT) { 15 | return new BlockPos(0, Short.MAX_VALUE, 0); 16 | } 17 | 18 | int x = 0; 19 | 20 | BlockPos spawnPos; 21 | 22 | do { 23 | spawnPos = findValidSpawnPosition(biomeProvider, x, 0, 10, 4); 24 | x += 40; 25 | } while (spawnPos == null); 26 | 27 | return spawnPos; 28 | } 29 | 30 | @Nullable 31 | private static BlockPos findValidSpawnPosition(BiomeProvider biomeProvider, int x, int z, int size, int scale) { 32 | Biome[] biomes = biomeProvider.getBiomes(x / scale, z / scale, size, size); 33 | 34 | assert size <= 10; // For the following assumption to work. 35 | /* 36 | * The following assumption is true for the Linux BDS. 37 | * TODO: more research is needed for other platforms. 38 | * 39 | * Here we ignore the case where dz = 0 and dz = size - 1, which would lead to out of bounds 40 | * access north and south of the area. 41 | * 42 | * For the case where dz = 0, we have to be careful this is an okay assumption since this is 43 | * the first row the game checks. When we're checking north, we're going size (10) ints left 44 | * of the current index, which may be up to 40 bytes before the beginning of the array. Since 45 | * the array is stored on the stack, these out of bounds values are very predictable and are 46 | * all local variables of this routine. All of them in this range are also pointers, except 47 | * the variable dz itself (which happens to be in this range). Since we know that dz = 0, when 48 | * we interpret this as a biome ID we get ocean, which is an invalid spawn biome. For the 49 | * pointers, the chances are negligible that the lower or upper bits hold a valid biome ID. 50 | * 51 | * For the case where dz = size - 1, first notice the fact that the chance of a given tile 52 | * being a valid biome is not independent of the chance that its neighbors are valid biomes. 53 | * That is, if there is a valid point on the bottom row, the probability is high that there 54 | * was also a valid point on the row above which would have been found first. Otherwise, the 55 | * out of bounds data on this end of the array is tricky to predict, as it depends on the data 56 | * that was there before, put there by whatever routine took up this part of the stack before. 57 | * But we can again think about probability, and the fact that it is very unlikely for 58 | * arbitrary data to be a valid biome ID. The most likely counter example is the value 1, 59 | * which corresponds to both the boolean true and the biome ID plains, which is a valid spawn 60 | * biome. 61 | * 62 | * This is why I do not claim this to be a perfect emulation of the Bedrock edition algorithm, 63 | * but it should be very close. 64 | */ 65 | for (int dz = 1; dz < size - 1; dz++) { 66 | for (int dx = 0; dx < size; dx++) { 67 | if (isValidSpawn(biomeProvider, biomes[dz * size + dx]) 68 | && isValidSpawn(biomeProvider, biomes[dz * size + (dx - 1)]) 69 | && isValidSpawn(biomeProvider, biomes[dz * size + (dx + 1)]) 70 | && isValidSpawn(biomeProvider, biomes[(dz - 1) * size + dx]) 71 | && isValidSpawn(biomeProvider, biomes[(dz + 1) * size + dx])) { 72 | return new BlockPos(scale * dx + x, Short.MAX_VALUE, scale * dz + z); 73 | } 74 | } 75 | } 76 | 77 | return null; 78 | } 79 | 80 | private static boolean isValidSpawn(BiomeProvider biomeProvider, Biome biome) { 81 | return biomeProvider.getBiomesToSpawnIn().contains(biome); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/net/earthcomputer/bedrockified/BedrockStrongholdStructure.java: -------------------------------------------------------------------------------- 1 | package net.earthcomputer.bedrockified; 2 | 3 | import net.minecraft.util.SharedSeedRandom; 4 | import net.minecraft.util.math.BlockPos; 5 | import net.minecraft.util.math.ChunkPos; 6 | import net.minecraft.util.math.MathHelper; 7 | import net.minecraft.world.IWorld; 8 | import net.minecraft.world.World; 9 | import net.minecraft.world.gen.IChunkGenSettings; 10 | import net.minecraft.world.gen.IChunkGenerator; 11 | import net.minecraft.world.gen.feature.structure.StrongholdStructure; 12 | import net.minecraft.world.gen.feature.structure.VillageStructure; 13 | 14 | import javax.annotation.Nullable; 15 | import java.util.ArrayList; 16 | import java.util.Random; 17 | 18 | public class BedrockStrongholdStructure extends StrongholdStructure { 19 | 20 | private boolean hasGeneratedVillageStrongholds = false; // (DWORD*) this + 48 21 | private ChunkPos[] villageStrongholds = new ChunkPos[3]; // (DWORD*) this + 50 22 | private VillageStructure villageGenerator; // (DWORD*) this + 56 23 | 24 | private final Object lock = new Object(); // (DWORD*) this + 58 25 | 26 | private int villageStrongholdCount = 3; // (DWORD*) this + 68 27 | private int gridSize = 200; // (DWORD*) this + 69 28 | private int gridSizeMinusMargin = 150; // (DWORD*) this + 70 29 | private int minimumDistance = 10; // (DWORD*) this + 71 30 | private float successChance = 0.25f; // (DWORD*) this + 72 31 | private int maxSearchRadius = 100; // (DWORD*) this + 73 32 | 33 | public BedrockStrongholdStructure(VillageStructure villageGenerator) { 34 | this.villageGenerator = villageGenerator; 35 | } 36 | 37 | @Override 38 | protected boolean hasStartAt(IChunkGenerator chunkGen, Random rand, int chunkPosX, int chunkPosZ) { 39 | synchronized (lock) { 40 | if (!hasGeneratedVillageStrongholds) 41 | generateVillageStrongholds(rand, chunkGen); 42 | 43 | for (ChunkPos villageStronghold : villageStrongholds) { 44 | if (villageStronghold.x == chunkPosX && villageStronghold.z == chunkPosZ) 45 | return true; 46 | } 47 | } 48 | 49 | return isScatteredStrongholdAt(chunkGen, rand, chunkPosX, chunkPosZ); 50 | } 51 | 52 | @Nullable 53 | @Override 54 | public BlockPos findNearest(World worldIn, IChunkGenerator chunkGenerator, BlockPos pos, int radius, boolean ungeneratedOnly) { 55 | if (!hasGeneratedVillageStrongholds) 56 | generateVillageStrongholds(new SharedSeedRandom(), chunkGenerator); 57 | 58 | return _getNearestStronghold(worldIn, pos); 59 | } 60 | 61 | // bedrock name: generatePositions 62 | public void generateVillageStrongholds(Random rand, IChunkGenerator chunkGen) { 63 | rand.setSeed(chunkGen.getSeed()); 64 | float angle = rand.nextFloat() * (float) Math.PI * 2.0f; 65 | int radius = rand.nextInt(16) + 40; 66 | 67 | int count = 0; 68 | while (count < villageStrongholds.length) { 69 | int cx = MathHelper.floor(radius * Math.cos(angle)); 70 | int cz = MathHelper.floor(radius * Math.sin(angle)); 71 | 72 | boolean placedStronghold = false; 73 | outerLoop: 74 | for (int offX = cx - 8; offX < cx + 8; offX++) { 75 | for (int offZ = cz - 8; offZ < cz + 8; offZ++) { 76 | if (villageGenerator.hasStartAt(chunkGen, rand, offX, offZ)) { 77 | villageStrongholds[count++] = new ChunkPos(offX, offZ); 78 | placedStronghold = true; 79 | break outerLoop; 80 | } 81 | } 82 | } 83 | if (placedStronghold) { 84 | angle += 0.6f * (float) Math.PI; 85 | radius += 8; 86 | } else { 87 | angle += 0.25f * (float) Math.PI; 88 | radius += 4; 89 | } 90 | } 91 | 92 | hasGeneratedVillageStrongholds = true; 93 | } 94 | 95 | // bedrock name: _hasAdditionalStronghold 96 | private boolean isScatteredStrongholdAt(IChunkGenerator chunkGen, Random rand, int chunkX, int chunkZ) { 97 | if (!_isBeyondMinimumDistance(chunkX, chunkZ)) 98 | return false; 99 | 100 | ChunkPos gridCenter = _getCenterOfGrid(chunkX, chunkZ); 101 | StrongholdResult result = generateScatteredStronghold(chunkGen, gridCenter); 102 | return result.successful && result.pos.x == chunkX && result.pos.z == chunkZ; 103 | } 104 | 105 | private boolean _isBeyondMinimumDistance(int chunkX, int chunkZ) { 106 | return chunkX * chunkX + chunkZ * chunkZ >= minimumDistance * minimumDistance; 107 | } 108 | 109 | private ChunkPos _getCenterOfGrid(int chunkX, int chunkZ) { 110 | ChunkPos gridCoords = _getGridCoordinates(chunkX, chunkZ); 111 | return new ChunkPos(gridCoords.x * gridSize + gridSize / 2, gridCoords.z * gridSize + gridSize / 2); 112 | } 113 | 114 | private ChunkPos _getGridCoordinates(int chunkX, int chunkZ) { 115 | return new ChunkPos(MathHelper.floor((float) chunkX / gridSize), MathHelper.floor((float) chunkZ / gridSize)); 116 | } 117 | 118 | // bedrock name: _generateStronghold 119 | private StrongholdResult generateScatteredStronghold(IChunkGenerator chunkGen, ChunkPos gridCenter) { 120 | // this check always fails because no grid center is within minimumDistance of (0, 0) 121 | if (!_isBeyondMinimumDistance(gridCenter.x, gridCenter.z)) 122 | return StrongholdResult.UNSUCCESSFUL; 123 | 124 | ChunkPos gridCoords = _getGridCoordinates(gridCenter.x, gridCenter.z); 125 | 126 | BedrockRandom rand = new BedrockRandom(); 127 | rand.setSeed(784295783249L * gridCoords.x + 827828252345L * gridCoords.z + chunkGen.getSeed() + 97858791); 128 | 129 | // This selects the middle 100x100 chunks of the 200x200 grid cell (with a 50 chunk margin) 130 | int minX = gridSize * gridCoords.x + gridSize - gridSizeMinusMargin; 131 | int maxX = gridSize * gridCoords.x + gridSizeMinusMargin; 132 | int minZ = gridSize * gridCoords.z + gridSize - gridSizeMinusMargin; 133 | int maxZ = gridSize * gridCoords.z + gridSizeMinusMargin; 134 | 135 | ChunkPos strongholdPos = new ChunkPos(rand.nextInt(minX, maxX), rand.nextInt(minZ, maxZ)); 136 | boolean successful = rand.nextFloat() < successChance; 137 | 138 | return new StrongholdResult(successful, strongholdPos); 139 | } 140 | 141 | @Nullable 142 | private BlockPos _getNearestStronghold(IWorld world, BlockPos from) { 143 | ChunkPos cp = new ChunkPos(from); 144 | ChunkPos gridCoords = _getGridCoordinates(cp.x, cp.z); 145 | 146 | ArrayList strongholds = new ArrayList<>(9); 147 | 148 | int expectedListSize = 1; 149 | 150 | for (int rad = 1; rad < maxSearchRadius; rad++) { 151 | for (int gridX = gridCoords.x - rad; gridX <= gridCoords.x + rad; gridX++) { 152 | for (int gridZ = gridCoords.z - rad; gridZ <= gridCoords.z + rad; gridZ++) { 153 | // only search the outer ring 154 | if (rad > 1 && Math.abs(gridCoords.x - gridX) < rad && Math.abs(gridCoords.z - gridZ) < rad) 155 | continue; 156 | 157 | expectedListSize += 8 * rad; 158 | if (strongholds.size() < expectedListSize) // I suppose they meant size > expected? :thonk: 159 | strongholds.ensureCapacity(expectedListSize); 160 | 161 | ChunkPos villageStronghold = isVillageStrongholdAt(gridX, gridZ); 162 | if (villageStronghold != null) { 163 | strongholds.add(new StrongholdResult(true, villageStronghold)); 164 | } else { 165 | ChunkPos gridCenter = new ChunkPos(gridX * gridSize + gridSize / 2, gridZ * gridSize + gridSize / 2); 166 | StrongholdResult result = generateScatteredStronghold(world.getChunkProvider().getChunkGenerator(), gridCenter); 167 | strongholds.add(result); 168 | } 169 | } 170 | } 171 | } 172 | 173 | if (_hasStrongholds(strongholds)) { 174 | ChunkPos strongholdChunk = _getClosestChunkPos(cp, strongholds); 175 | return new BlockPos((strongholdChunk.x << 4) + 8, 32, (strongholdChunk.z << 4) + 8); 176 | } 177 | 178 | return null; 179 | } 180 | 181 | // bedrock name: _isPregeneratedStrongholdHere 182 | @Nullable 183 | private ChunkPos isVillageStrongholdAt(int gridX, int gridZ) { 184 | synchronized (lock) { 185 | for (int i = 0; i < villageStrongholdCount; i++) { 186 | ChunkPos cp = villageStrongholds[i]; 187 | ChunkPos gridPos = _getGridCoordinates(cp.x, cp.z); 188 | if (gridPos.x == gridX && gridPos.z == gridZ) 189 | return cp; 190 | } 191 | return null; 192 | } 193 | } 194 | 195 | private boolean _hasStrongholds(ArrayList strongholds) { 196 | for (StrongholdResult stronghold : strongholds) 197 | if (stronghold.successful) 198 | return true; 199 | return false; 200 | } 201 | 202 | private ChunkPos _getClosestChunkPos(ChunkPos to, ArrayList strongholds) { 203 | int closestDistanceSq = Integer.MAX_VALUE; 204 | ChunkPos closestStronghold = null; 205 | 206 | for (StrongholdResult stronghold : strongholds) { 207 | if (stronghold.successful) { 208 | int dx = stronghold.pos.x - to.x; 209 | int dz = stronghold.pos.z - to.z; 210 | int distSq = dx * dx + dz * dz; 211 | if (distSq < closestDistanceSq) { 212 | closestDistanceSq = distSq; 213 | closestStronghold = stronghold.pos; 214 | } 215 | } 216 | } 217 | 218 | assert closestStronghold != null; 219 | return closestStronghold; 220 | } 221 | 222 | private static class StrongholdResult { 223 | boolean successful; 224 | ChunkPos pos; 225 | 226 | static StrongholdResult UNSUCCESSFUL = new StrongholdResult(false, new ChunkPos(0, 0)); 227 | 228 | StrongholdResult(boolean successful, ChunkPos pos) { 229 | this.successful = successful; 230 | this.pos = pos; 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /src/main/java/net/earthcomputer/bedrockified/package-info.java: -------------------------------------------------------------------------------- 1 | @ParametersAreNonnullByDefault 2 | @MethodsReturnNonnullByDefault 3 | package net.earthcomputer.bedrockified; 4 | 5 | import mcp.MethodsReturnNonnullByDefault; 6 | 7 | import javax.annotation.ParametersAreNonnullByDefault; --------------------------------------------------------------------------------