Compare commits

...

1418 Commits

Author SHA1 Message Date
Ran 3f37f7f02a Update Readme.md 2022-04-17 17:00:53 +00:00
TomTheFurry a88feda9ec Fix it so it build 2022-04-04 15:47:49 +08:00
TomTheFurry 07b7ecb30a Maybe fixed the light again? 2022-04-04 12:01:01 +08:00
TomTheFurry 32bbe487c0 Fix dumb stuff costing performance on world gen 2022-04-03 16:02:06 +08:00
TomTheFurry b367e5c3aa Fix dumb stuff costing performance on world gen 2022-04-03 16:01:54 +08:00
TomTheFurry a43b2b69a6 Fix up big blocks missing side faces 2022-04-03 13:06:18 +08:00
James Seibel 2a1de6f579 add missing fabric libraries for sodium 2022-04-02 23:46:31 -05:00
James Seibel 7dadff4219 automatically copy lod.accesswidener when building
By default the fabric build folder needs this file to run, but it wasn't being copied over, now it should be.
2022-04-02 23:08:33 -05:00
James Seibel 07c53a02ca Add phosphor as an option to build.gradle 2022-04-02 23:06:57 -05:00
TomTheFurry 1e54885d88 Disabled framebuffer fix for now making optifine shaders to work again 2022-04-02 22:24:17 +08:00
TomTheFurry 68f4084ab0 Fix coolGi's java-8 port 2022-04-02 22:18:40 +08:00
TomTheFurry 6fa968e016 Make lightmap fix works with Optifine shaders? 2022-04-02 21:11:38 +08:00
TomTheFurry 93c2078724 Make lightmap fix works with Optifine shaders? 2022-04-02 21:09:39 +08:00
TomTheFurry 2289d898ce Update core. 2022-04-02 15:25:28 +08:00
TomTheFurry 15e5a04ffd Maybe fixed colormatic's mod compat? 2022-04-02 13:49:28 +08:00
TomTheFurry 150ba98a4e MacOS Patch Successful! + fix missing fabric api 2022-04-01 19:46:54 +08:00
coolGi2007 d9484c9df4 Why dose the readme still say preprocessor_test 2022-04-01 08:26:59 +00:00
James Seibel a92e09c2be Merge branch '1.18.X' of gitlab.com:jeseibel/minecraft-lod-mod into 1.18.X 2022-03-31 21:23:41 -05:00
James Seibel f7e1dc378f Fix the default folder selection if sub-dimensions are disabled 2022-03-31 21:23:38 -05:00
Ran f7b84b1909 It was nice knowing you fabric-api 2022-03-31 14:49:53 +06:00
Ran abae2f6358 I forgor 2022-03-31 14:35:03 +06:00
Ran e83939f1b2 Remove fabric api as a dependency 2022-03-31 14:30:41 +06:00
James Seibel 0bddc2dcac Fix invalid files that use the server port 2022-03-30 21:18:59 -05:00
James Seibel 42a8e0e0f0 Add additional logging to getFileBasePath 2022-03-30 19:57:59 -05:00
TomTheFurry 7b77e07a7d Fix race & stuck playerData in sub-dim, add dataPoint verify 2022-03-30 18:39:10 +08:00
cola98765 db17d27823 change XZ setting 3 -> 1 made it easier to change it with static at the start of the file 2022-03-30 11:55:02 +02:00
James Seibel 362b800f25 Close #140 (no rendering if world named "No World Loaded" ) 2022-03-29 20:49:11 -05:00
TomTheFurry 29e26d659d I think test renderer is now more correct? 2022-03-29 13:09:29 +08:00
TomTheFurry afa658cc00 Add RendererType & Debug Renderer + fix Logger bug 2022-03-28 17:04:06 +08:00
James Seibel cde0d466dd Fix a null pointer error when moving empty folders 2022-03-27 21:49:26 -05:00
James Seibel 4031b55630 Fix old folders not moving if sub-dims are disabled 2022-03-27 00:09:41 -05:00
James Seibel 86e07156d1 Make multi-Dim similarity = 0 disable the new system
By default the old system of 1 world per dimension is used
2022-03-26 23:16:12 -05:00
James Seibel 1e8df274ee Update a log in Sub-Dim 2022-03-26 21:34:47 -05:00
James Seibel f0153cc4a6 Fix incorrect files/folders crashing the sub-dim system 2022-03-26 21:27:28 -05:00
James Seibel 3044c238fd Automatically move old files to the new sub-dim system 2022-03-26 20:53:53 -05:00
James Seibel ead58390cd Merge in SubDim changes 2022-03-26 11:39:31 -05:00
TomTheFurry 504d22ff37 Update core 2022-03-26 23:32:50 +08:00
TomTheFurry cc42f8667f Update core 2022-03-26 18:56:39 +08:00
James Seibel 6135b3ce7f Merge branch '1.18.X' of gitlab.com:jeseibel/minecraft-lod-mod into 1.18.X 2022-03-23 21:18:06 -05:00
James Seibel 3c8efa17d5 Add better logging and hopefully fix some issues with multi-dim support 2022-03-23 21:18:03 -05:00
James Seibel dccae0aea0 Re-add the gradle cache to hopefully improve compile speed 2022-03-23 02:06:42 +00:00
James Seibel 2728236ced Merge branch '1.18.X' of gitlab.com:jeseibel/minecraft-lod-mod into 1.18.X 2022-03-22 20:48:46 -05:00
James Seibel 76ce1d6b21 Change the deleteMerged task's folder path 2022-03-22 20:48:37 -05:00
James Seibel 94ddebaec0 Fix some YAML errors 2022-03-23 01:28:43 +00:00
James Seibel cec165176b Go back to sequential compiles, deleting the merged between compiles 2022-03-22 20:13:38 -05:00
James Seibel 99ad837441 comment out one of the artifacts and rename the caches 2022-03-22 19:52:50 -05:00
James Seibel f8be132ba2 Increase compiler memory and flip the compile order 2022-03-22 19:43:49 -05:00
James Seibel 122f5431a6 Try disabling caching and re-enabling the daemon 2022-03-23 00:31:17 +00:00
James Seibel c2884954a4 Disable the gradle daemon to hopefully fix a compiler crash 2022-03-22 12:28:25 +00:00
James Seibel 3a0453c8c5 Dummy commit to trigger a rebuild 2022-03-22 12:22:19 +00:00
TomTheFurry 9d241ab175 Add CaveCullingHeight + 'Fun' mode into config 2022-03-22 18:23:53 +08:00
TomTheFurry ee7eed8d3c Fix 0 size quad bug + improve black face filling 2022-03-22 13:05:22 +08:00
Ran 1125452a8f Fix DHJarMerger 2022-03-22 10:55:30 +06:00
James Seibel a3712c8f72 Last attempt at fixing artifacts incorrectly merging for the night
7707f55b appears to have worked correctly, now if I can just figure out if it was a fluke...
2022-03-22 04:16:35 +00:00
James Seibel e2022fab2d Make compiling sequential to fix a mystery compiler error 2022-03-22 03:36:39 +00:00
James Seibel bcea1be19b Fix the cache key being incorrectly set 2022-03-22 03:20:19 +00:00
James Seibel 8d799203c5 Update .gitlab-ci.yml file 2022-03-22 03:14:55 +00:00
James Seibel 980ce2f2af Go back to parallel builds
And potentially fix the caching
2022-03-22 03:14:25 +00:00
James Seibel c6bea3faa3 Try sequential builds in CI 2022-03-22 03:02:44 +00:00
James Seibel 7707f55b25 Update .gitlab-ci.yml file 2022-03-22 02:39:42 +00:00
James Seibel f087bb7182 Update .gitlab-ci.yml file 2022-03-22 02:38:33 +00:00
James Seibel bf269c9abf Fix an incorrect Array Index 2022-03-21 21:21:22 -05:00
tom lee a8c7405f9d Update core + forgot to undo the always getMaxRenderedChunk() 2022-03-21 17:29:33 +08:00
tom lee 43c9232e7e Update core 2022-03-21 16:56:40 +08:00
tom lee 8351c58d7b Update core + remove Manifold from core + remove awt.Colors 2022-03-21 15:16:37 +08:00
tom lee aa86381b80 Update core 2022-03-20 23:18:23 +08:00
tom lee 563840ca58 Fix some block failing to get correct colors 2022-03-20 17:15:12 +08:00
tom lee b5b9b688c3 Update core 2022-03-20 16:31:04 +08:00
tom lee 3731223087 Update core 2022-03-20 16:27:40 +08:00
tom lee 72d770c0f3 Maybe this will work? 2022-03-20 13:51:49 +08:00
tom lee ee4b83fa99 Fix StructFeatManager to work on 1.18.2 + Update core 2022-03-20 13:42:12 +08:00
James Seibel ee6e3a9876 Merge branch 'preprocessor_test' into 1.18.X 2022-03-19 20:15:18 -05:00
James Seibel 17e375bc61 Return IBlockDetailWrappers 2022-03-19 20:04:11 -05:00
James Seibel a2c8c90a5e Merge branch '1.18.2' into preprocessor_test 2022-03-19 19:56:04 -05:00
James Seibel b376014df8 Update the manifold version 2022-03-19 18:20:28 -05:00
James Seibel b9ee54f6ad add multi-dim and brightness/saturation 2022-03-19 12:39:09 -05:00
James Seibel 6c7e1900a3 Merge in fog changes 2022-03-19 11:20:44 -05:00
tom lee 6f929f40f9 Update core 2022-03-19 22:34:11 +08:00
James Seibel b6a8930855 Add a config for the MultiDimension Similarity 2022-03-18 23:57:32 -05:00
coolGi2007 7a91b258de Updated mods, readme and fixed 1 thing in the config gui 2022-03-17 17:52:19 +10:30
TomTheFurry 35bef76aeb Fix 1.18.2 WorldRenderer renderSky() mixin falling 2022-03-16 19:57:27 +08:00
TomTheFurry 780d0ad9fb Complete the push 2022-03-16 18:53:16 +08:00
TomTheFurry c0d5dd6dee ADVANCED FOGGGGGGGGGGGGGGGG~~~~~~~~~~~~~~~~ 2022-03-16 18:52:56 +08:00
TomTheFurry 3e87e625ba Pushed the stuff leetom did on my macbook 2022-03-15 21:17:07 +10:30
TomTheFurry 56f9403859 Add proper multi FrameBuffer support(And fix MacOS?) 2022-03-15 16:38:39 +08:00
TomTheFurry 8259c79e9c Fixup MixinUtilBackgroudThread+more render log 2022-03-15 18:48:27 +10:30
TomTheFurry be1e2fe7e6 Merge remote-tracking branch 'origin/preprocessor_test' into preprocessor_test 2022-03-15 12:38:10 +08:00
TomTheFurry 609ee5c70d Improve GLMessage Parser 2022-03-15 12:37:51 +08:00
James Seibel 207cab9a0f Clean up the build script 2022-03-15 04:05:12 +00:00
James Seibel c80b025ac1 Clean up the build script 2022-03-15 03:52:25 +00:00
James Seibel 8610917b86 Update .gitlab-ci.yml file 2022-03-15 03:41:17 +00:00
James Seibel fae4bee871 Update .gitlab-ci.yml file 2022-03-15 03:34:52 +00:00
James Seibel b9608498a2 Check if Gradle setup is necessary + fix artifacts not being populated 2022-03-15 03:34:29 +00:00
James Seibel fe59c6b0c9 Check if Gradle setup is necessary 2022-03-15 03:25:09 +00:00
James Seibel b082b048d6 Update .gitlab-ci.yml file 2022-03-15 03:21:59 +00:00
James Seibel 91712cee2a Rough artifact test 2022-03-15 03:21:44 +00:00
James Seibel 5adfbb2dee Update .gitlab-ci.yml 2022-03-15 03:04:50 +00:00
James Seibel ec32d09468 Try separating the archiving into a separate step
This will make adding/removing MC versions to compile easier
2022-03-15 02:51:39 +00:00
James Seibel 919990820e Fix exporting duplicate jars 2022-03-15 02:43:12 +00:00
James Seibel 5cc31efa12 Attempt to add 1.18.1 and 1.18.2 auto building 2022-03-15 02:16:04 +00:00
TomTheFurry 5f48b41693 Add Advanced Fog config entries. Actual impl is a todo. 2022-03-15 00:00:36 +08:00
TomTheFurry 9530eea287 Update core and fix serverRenderDistanceMax not being checked 2022-03-14 16:23:04 +08:00
TomTheFurry ebbf304c94 Updated core 2022-03-14 15:10:20 +08:00
TomTheFurry 7c8ac0c2ff Fix mistakes + update core 2022-03-13 22:57:42 +08:00
TomTheFurry eefad5e052 Improved getMaximumRenderedChunk and fix GLMessage on forge 2022-03-13 22:57:07 +08:00
TomTheFurry 9a1e6e29d4 Update Readme.md on switching versions 2022-03-13 16:45:41 +08:00
TomTheFurry 62ab450d98 Update Core 2022-03-13 16:16:29 +08:00
TomTheFurry b4a5da4a74 Update Config defaults 2022-03-13 16:15:29 +08:00
TomTheFurry ed82480c89 Update .gitmodules properly this time 2022-03-13 07:41:53 +00:00
TomTheFurry 82449c5edc Update and fix core branch tracking(I think?) 2022-03-13 15:40:08 +08:00
TomTheFurry b165726bc9 Add new Config: BiomeBlending 2022-03-13 15:26:24 +08:00
TomTheFurry 11910d0f28 Fix IDE not reconising preprocessor 2022-03-10 17:29:27 +08:00
TomTheFurry f66e27b077 First version where 1.18.1 & 1.18.2 is merged 2022-03-10 17:05:14 +08:00
coolGi2007 f84570a6fc Downgraded stuff from 1.18.2 to 1.18.X 2022-03-10 16:35:20 +10:30
James Seibel 835beb607d Close #207 (re-add brightness/contrast configs) 2022-03-09 23:06:34 -06:00
TomTheFurry c4e2d3fb0f Remove unused stuff 2022-03-09 16:21:44 +08:00
TomTheFurry eb3d8d9da5 Add Manifold Preprocessor plugin to gradle 2022-03-09 16:14:16 +08:00
TomTheFurry 151d548099 Update core + Fix biome blending 2022-03-08 23:27:14 +08:00
TomTheFurry c5cdc2760f Update core 2022-03-08 16:05:30 +08:00
coolGi2007 a663bf9f19 Added the multiplayer folder thing from 1.18.X to 1.18.2 and fixed building 2022-03-08 17:43:10 +10:30
James Seibel a0f5af46a2 Closes #217 (Change Server Folder Name)
Adds multiple options for formatting the server folder name.
If LODs have already been generated with a previous setting the files will have to be transferred to the new folder.
2022-03-07 22:16:00 -06:00
coolGi2007 7ddd48d132 Updated what james did from 1.18.X to 1.18.2 2022-03-07 16:56:35 +10:30
James Seibel 18074f15f5 Rename MinecraftWrapper -> MinecraftClientWrapper
closes #150
2022-03-05 18:28:36 -06:00
James Seibel bba0424c6d remove WorldWrapper.isEmpty()
It wasn't used and there was a comment saying not to use it
2022-03-05 18:14:22 -06:00
James Seibel 282f6cfbb8 Update the DependencyHandler to support circular references
Also rename "DependencySetup" To "FabricDependencySetup"
2022-03-05 17:52:22 -06:00
Ran ce10a43cc6 Fix accesswidener for 1.18.2 2022-03-03 14:34:47 +06:00
tom lee 5476af5bb3 Fixed chunkloader to work with 1.18.2 2022-03-02 19:28:16 +08:00
coolGi2007 b97b1b61b7 Reverted the commit that added 1.18.2 to this branch 2022-03-02 18:08:11 +10:30
coolGi2007 25d2cfd7b8 Quick 1.18.2 branch (**DISABLE GENERATION TO WORK**) 2022-03-02 17:43:46 +10:30
James Seibel 1b754387e0 Refactor the dependency injectors 2022-03-01 21:20:00 -06:00
James Seibel bcad40069f Merge branch '1.18.X' of gitlab.com:jeseibel/minecraft-lod-mod into 1.18.X 2022-02-28 17:57:01 -06:00
James Seibel 5aa9061006 remove the discord notification experiment
Using this changed how the messages look in a way I don't like; removing the committer's icon and commit message.
2022-02-28 17:54:41 -06:00
James Seibel 873e8cec57 Update .gitlab-ci.yml file 2022-02-28 23:37:29 +00:00
James Seibel f6f96c3aea Test pipeline discord notifications 2022-02-28 17:18:02 -06:00
tom lee aeed672295 Update core 2022-02-27 17:02:06 +08:00
tom lee 832fbe6d15 Update core 2022-02-26 16:16:00 +08:00
tom lee 03deddf666 Optimized the McObjectConverter for Direction 2022-02-26 14:04:49 +08:00
tom lee d06413d1b4 Update core 2022-02-25 15:15:51 +08:00
tom lee 8afa50d585 Update core + improved GenEvent Terminate speed 2022-02-24 22:28:59 +08:00
Morippi 9f28f1f812 Added comments 2022-02-23 18:26:35 +01:00
Morippi 985388fd90 Removed border from details circles and regions 2022-02-23 16:38:19 +01:00
tom lee e27e10082a Update core 2022-02-22 23:12:59 +08:00
tom lee 4e510d96fc Update core + fix colors. See commit in core 2022-02-22 23:10:58 +08:00
coolGi2007 c0ec02f062 forgot this like 2022-02-22 07:22:33 +00:00
coolGi2007 bd27a96bde Updated the readme and updated the DHJarMerger (now marks the jar as an executable so linux users have an easier time when runnung the jar) 2022-02-22 17:49:23 +10:30
tom lee d6aeaf8e9d Update Core 2022-02-22 11:37:22 +08:00
Ran 2b9bba4aa7 Update core 2022-02-21 17:36:08 +06:00
Ran 58b0991891 Put logger in ApiShared.java 2022-02-21 17:34:52 +06:00
Ran 59cbbef327 Merge remote-tracking branch 'origin/1.18.X' into 1.18.X 2022-02-21 17:29:41 +06:00
Ran 7047c81a2b Put logger in ApiShared.java 2022-02-21 17:27:54 +06:00
tom lee 6e2ab47359 Rework Block color / shape 2022-02-21 19:23:30 +08:00
Ran f879332e1d Client 2 Server packets 2022-02-21 13:40:42 +06:00
coolGi2007 6fcafecc61 Updated fabric, modmenu and readme 2022-02-21 16:36:10 +10:30
coolGi2007 a5af93aef1 Renamed the thing to JarMain 2022-02-20 22:26:01 +00:00
coolGi2007 4b84fd2a67 Added a way to run jar (dosnt do anything but could be used to check opengl and move mod to mods folder) 2022-02-20 22:16:21 +10:30
cola98765 924efc0cbd update core 2022-02-20 12:34:09 +01:00
tom lee 288457b5bd Update core 2022-02-20 17:35:11 +08:00
James Seibel d29fa86de6 Merge branch 'jeffthejeffthejeff-1.18.X-patch-51031' into '1.18.X'
Added an image and improved start of Readme.md

See merge request jeseibel/minecraft-lod-mod!17
2022-02-20 05:13:39 +00:00
James Seibel 97be227e3d Add a missing "s" 2022-02-20 05:12:16 +00:00
James Seibel 909d6a54c3 Slightly reword the blurb 2022-02-20 05:10:35 +00:00
Ran 228b6a80dc Merge branch '1.18.X' of https://gitlab.com/jeseibel/minecraft-lod-mod into 1.18.X 2022-02-20 09:32:44 +06:00
Ran 6936a5f96f I forgor 💀 2022-02-20 09:31:55 +06:00
cola98765 740560a50a actually fix tint on custom water textures. 2022-02-19 22:32:53 +01:00
cola98765 47c28f0f37 actually fix tint on custom water textures. 2022-02-19 22:28:35 +01:00
Ran 1c859cd7da Oops was registering channels to wrong environments 2022-02-20 00:15:33 +06:00
tom lee e4a97dd76d Update core 2022-02-20 01:01:59 +08:00
Ran 4fd1e5ea06 Update core 2022-02-19 22:58:05 +06:00
Ran 6039aeabde Server client communication! maybe 2022-02-19 22:55:53 +06:00
tom lee 17a384f074 Update core 2022-02-19 22:15:04 +08:00
coolGi2007 25e8f5ec6a Forgot to push this file 2022-02-19 08:30:06 +00:00
coolGi2007 eac8cacd42 Removed new config 2022-02-19 18:53:34 +10:30
James Seibel 75193d76a3 Update the version number to 1.6.2a 2022-02-17 20:11:13 -06:00
James Seibel aa24fd341e Update the version number to 1.6.2a 2022-02-17 20:10:02 -06:00
Dog 81adade05b Capitalised Source Code Installation to be grammatically correct 2022-02-17 23:55:38 +00:00
Dog e3808dc986 Updated title of Readme to look nicer 2022-02-17 23:45:55 +00:00
tom lee d669b2a1fe Update and merge the render_test core 2022-02-17 22:26:48 +08:00
cola98765 2bd8dab240 #159 multiply color by color... not by alpha 2022-02-15 11:50:14 +01:00
cola98765 2b423c2edd squared colour averaging as in #159
please check if it works looks better.
2022-02-15 11:37:54 +01:00
cola98765 1a4faf4bdd close #188; fix lang parts in #189 2022-02-15 11:21:23 +01:00
cola98765 b70829aceb RotatedPillarBlock colors are taken form sides, resolving #191 2022-02-15 11:06:37 +01:00
cola98765 bba771d376 Potentially fix water texture packs. 2022-02-14 17:31:36 +01:00
James Seibel 75b18f8bd8 Update the forge version to fix a potential crash with Biomes-o-plenty 2022-02-13 16:28:21 -06:00
James Seibel 60da404900 Merge branch '1.18.X' of gitlab.com:jeseibel/minecraft-lod-mod into 1.18.X 2022-02-13 07:37:43 -06:00
coolGi2007 b75eebd0dc Getting more stuff ready for new config 2022-02-13 14:48:56 +10:30
James Seibel 72cbd1167a Prepare for 1.6.1a 2022-02-12 12:01:40 -06:00
tom lee e4e51ebf5b Update core 2022-02-12 23:54:23 +08:00
tom lee dd2096bf1b Frontported the forge mixin issue fix. (It may work without that but...) 2022-02-12 23:54:23 +08:00
coolGi2007 393a94a7a1 We don’t talk about this 1 line in the gradle 2022-02-12 14:04:18 +00:00
tom lee ef0023ef39 Switch to another way to do the world gen. Now more mod compat! 2022-02-12 22:00:09 +08:00
coolGi2007 f0994fff75 Added a way to add mods in code and not run on runtime and moved issues and source to gradle.properties 2022-02-12 19:34:54 +10:30
tom lee 31f41540c0 Fix chat format color. Add failsafe stopping of generator 2022-02-12 15:13:58 +08:00
tom lee 81fe13b9c0 Add backup to VanillaRenderedChunks & many generator stuff 2022-02-12 14:30:04 +08:00
tom lee 332df13b29 Fix loadChunk try/catch missing the mark & add WRAN on modded chunkGen 2022-02-12 13:12:25 +08:00
James Seibel b3af6df0c5 Update the version number to 1.6.1a-pre and re-enable dev code 2022-02-11 22:08:35 -06:00
James Seibel 9392e618c0 I accidently removed the "a" 2022-02-11 20:00:40 -06:00
James Seibel fd361a39a1 Update the version number and homepage link for a1.6.0 2022-02-11 19:59:23 -06:00
coolGi2007 f41de59f39 Removed some file stuff that didnt work 2022-02-11 13:05:23 +00:00
coolGi2007 c701cf987b Merge remote-tracking branch 'origin/1.18.X' into 1.18.X 2022-02-11 16:07:22 +10:30
coolGi2007 f05e878600 Added version to config file for the future 2022-02-11 16:07:10 +10:30
tom lee dc028db5ed update core + change a bit for sodium get chunk so it works better 2022-02-11 13:35:39 +08:00
James Seibel c59d7a7d27 Slightly improve the tooltips for the config GUI 2022-02-10 22:07:55 -06:00
tom lee a3dd346a02 Update core + Config + fixed blindness fog 2022-02-10 22:05:57 +08:00
tom lee dba8061f71 Update core 2022-02-10 17:08:00 +08:00
tom lee 3da2d961fc Update core 2022-02-10 16:23:33 +08:00
James Seibel aa83dc7465 Update Core 2022-02-09 19:22:29 -06:00
Morippi 392821c081 Tried to fix the render distance min detail bug 2022-02-09 22:01:17 +01:00
tom lee 7e5fc979cc Impl MEM LEAK fix from 1.16, though didn't think it was an issue before 2022-02-09 18:46:37 +08:00
tom lee 7ebb555b94 Update core 2022-02-08 13:45:04 +08:00
tom lee 3612a2f9e0 Updated core 2022-02-07 14:02:12 +08:00
coolGi2007 42b67825f8 Added custom toml to forge 2022-02-07 09:46:08 +10:30
coolGi2007 30a636c840 Added toml to be able to be used in core 2022-02-07 09:14:08 +10:30
tom lee e5722c19a9 Update core and impl the changing Region Size 2022-02-06 22:55:06 +08:00
tom lee 6b6a9ab0a9 Update core 2022-02-06 21:33:58 +08:00
tom lee 6da74c6f4e Forgot to update core... 2022-02-06 19:40:03 +08:00
tom lee 0bafa37f66 Fix and unify how key events work 2022-02-06 14:58:39 +08:00
coolGi2007 6ba6b11f6b Use cursedforge rather than modrinth for sodium download 2022-02-06 05:45:58 +00:00
James Seibel 739653f37a Add an expiration to the archives 2022-02-05 15:42:15 +00:00
coolGi2007 213d70f2d1 Removed clouds 2022-02-05 09:41:53 +00:00
tom lee dda3c7636b Update core + Moved ChunkLoader to be in line with other versions 2022-02-05 16:24:24 +08:00
tom lee 3956578043 Update core 2022-02-05 14:44:30 +08:00
tom lee d11f067392 Update core 2022-02-04 14:33:55 +08:00
tom lee 9f9fe6a231 Updated core 2022-02-04 00:32:55 +08:00
tom lee 486a30cb93 Update core 2022-02-04 00:16:25 +08:00
tom lee 01545dc295 Update the generator with 1.16 changes 2022-02-03 18:01:09 +08:00
coolGi2007 165a3799f3 Put some stuff that was duplicated in gradle to the main gradle 2022-02-02 22:40:41 +00:00
coolGi2007 308f809d5d Cleaned up some gradle stuff 2022-01-30 15:53:47 +10:30
tom lee 003dbdff02 Fixed C2ME log spam compat issue 2022-01-29 17:33:57 +08:00
tom lee 99f8dbb042 Mod compat: Fixed issue with Repurposed Structures 2022-01-29 16:50:02 +08:00
tom lee 4263ea9733 Add patch for BCLib to solve patchy features gen issue 2022-01-29 16:11:52 +08:00
tom lee c09b07a21b Greatly improve speed on loading existing chunks. 2022-01-27 14:08:06 +08:00
coolGi2007 4e0160648b Fixed issue 162 (renamed stuff) 2022-01-27 02:38:13 +00:00
coolGi2007 ad367f681d (made accidentally added string at the end of something) 2022-01-27 12:51:37 +10:30
coolGi2007 a5a70cd65b Made stuff about mod get from gradle.properties so it is easier to edit 2022-01-27 12:50:19 +10:30
coolGi2007 4ff37cfdad Fxed forge version 2022-01-27 11:14:07 +10:30
cola98765 9a1abdefa1 fixed mergeMultiData and lodBuilder with connected lods 2022-01-26 09:25:50 +01:00
tom lee 37cc7e7b37 Fixed a bug causing Fast Light mode stuck in gen loop 2022-01-26 13:14:57 +08:00
coolGi2007 04cbb1e92c Fixed forge crashing on world join 2022-01-26 04:53:45 +00:00
CodeF53 5033175808 Fix small typo. 2022-01-25 17:52:45 +00:00
tom lee 689928708c Update core and fix forge serverTickEvent firing 2 times per tick 2022-01-25 18:27:21 +08:00
tom lee 98327e6fdf Update core + Config Wrapper 2022-01-25 17:08:55 +08:00
coolGi2007 5aef0977c0 I always forget to update core 2022-01-25 04:58:09 +00:00
coolGi2007 e6738f1c80 Added comments to config file (temp solution) 2022-01-25 15:26:21 +10:30
James Seibel b55c1b8f56 Delete OptiFine_1.18.1_HD_U_H4.jar 2022-01-25 00:59:34 +00:00
tom lee 3764a4cc9e Updated core and follow core changes 2022-01-24 23:37:33 +08:00
tom lee d6bbb9d8dc Updated core and followed with some tweaks for FAR_FRIST gen 2022-01-24 23:02:53 +08:00
tom lee a38e7a00e4 Update core, Change some small stuff. 2022-01-24 21:08:17 +08:00
coolGi2007 2ec84ae3cf Fixed a typoish thing 2022-01-24 09:21:51 +00:00
coolGi2007 f03035e3f9 After all these years, the ints show up correctly after restarting (it was literally a 1 line fix) 2022-01-24 19:41:33 +10:30
coolGi2007 1d914b8f8a Refactored some stuff 2022-01-24 18:54:16 +10:30
Ran ee947b36a2 maybe it'll work 2022-01-24 10:58:26 +06:00
Ran ba393f61e5 I forgor 2022-01-24 10:32:00 +06:00
Ran 796c8e7bef Update DHJarMerger-1.0.jar 2022-01-24 10:29:03 +06:00
CodeF53 fe60de314d Dummy commit to force new job 2022-01-24 03:41:08 +00:00
CodeF53 d237db3302 remove invalid yaml code from prior commmit 2022-01-24 03:23:05 +00:00
CodeF53 f665b452b0 Don't cache old builds, uncomment jar versioning. 2022-01-24 03:19:31 +00:00
James Seibel 17750691d6 comment out the jar versioning 2022-01-23 20:52:28 -06:00
James Seibel 89ba5b9d15 Update the pipeline 2022-01-23 20:33:27 -06:00
James Seibel cea44a3f8a Update the pipeline 2022-01-23 20:17:50 -06:00
James Seibel a99c9aff76 Update the pipeline 2022-01-23 19:11:15 -06:00
James Seibel 1827ab646c Update the pipeline 2022-01-23 18:56:48 -06:00
James Seibel db00f7ebec Update the pipeline 2022-01-23 18:45:23 -06:00
James Seibel 0b93c7b5dc Update the pipeline 2022-01-23 18:25:17 -06:00
James Seibel 97204f3a3c Update the pipeline 2022-01-23 18:11:18 -06:00
James Seibel 02a6db0a62 Update the pipeline 2022-01-23 18:00:43 -06:00
James Seibel 577af4d854 Update the pipeline 2022-01-23 17:58:42 -06:00
James Seibel 68155142c3 Update the pipeline 2022-01-23 17:44:11 -06:00
James Seibel 43897e1298 Add the version name override to fabric 2022-01-23 16:48:33 -06:00
James Seibel bf2c520966 Fix a typo in the pipeline 2022-01-23 16:47:24 -06:00
James Seibel ee1528f694 Merge branch '1.18.X' of gitlab.com:jeseibel/minecraft-lod-mod into 1.18.X 2022-01-23 16:26:16 -06:00
James Seibel 8bd7556c89 Add the dateTime to compiled jars and the commit to artifacts 2022-01-23 16:25:37 -06:00
James Seibel facbb174f5 Remove logo and IDE files (they are stored in Core) 2022-01-23 16:22:29 -06:00
tom lee 9d3ce5307c Updated core + cleanup imports in WorldGen 2022-01-23 23:17:04 +08:00
tom lee 54f3e9e12d Update core 2022-01-23 21:19:53 +08:00
tom lee e294fc79eb Fixed using wrong func for makeBiome(). 2022-01-23 20:28:35 +08:00
tom lee a750aaf90a Update core + cleanup some junks 2022-01-23 19:12:18 +08:00
James Seibel be8e09eb9b Update jar merging pipeline 2022-01-22 22:47:35 -06:00
James Seibel 016d26a6f7 Update jar merging pipeline 2022-01-22 22:35:51 -06:00
James Seibel 539698c456 Update jar merging pipeline 2022-01-22 22:34:35 -06:00
James Seibel bcc11b8f0c Update jar merging pipeline 2022-01-22 22:24:52 -06:00
James Seibel c2a960162e Add a link to Ran's Jar merger repo 2022-01-22 22:24:42 -06:00
James Seibel c42a3a5fb3 Update jar merging pipeline 2022-01-22 22:13:59 -06:00
James Seibel 59d6289177 Update jar merging pipeline 2022-01-22 22:04:56 -06:00
James Seibel 4f028d118d Set the default Generation Priority to NEAR_FIRST closes #160 2022-01-22 22:04:36 -06:00
James Seibel b555e35016 Update jar merging pipeline 2022-01-22 21:58:57 -06:00
James Seibel 26b4c3a2d9 Update jar merging pipeline 2022-01-22 21:34:46 -06:00
James Seibel 2a5199f851 Update jar merging pipeline 2022-01-22 21:18:32 -06:00
James Seibel 408dbc2169 Update jar merging pipeline 2022-01-22 21:05:09 -06:00
James Seibel c9ffcfb1e8 Add jar merging to the pipeline 2022-01-22 20:50:16 -06:00
tom lee 3bd1eedcb8 Fixed Lithium WorldGen NullPtr issue cause by lazyness
Detail cause: I only override the getChunk(x,y,status,bool) and not its
sub set like getChunk(x,y), getChunk(x,y,status) because... Programmer
is always lazy. Aren't they?
2022-01-22 23:05:11 +08:00
tom lee 8500ec7a00 Fixed WorldGen to provide better support for StarLight 2022-01-22 22:38:33 +08:00
tom lee 223570a0b7 Update core. Fixed WorldGen using Util.background threads 2022-01-22 18:10:53 +08:00
tom lee de8c063731 Update core + cleanup debug logging 2022-01-22 16:10:32 +08:00
tom lee 0cffa30286 Updated core 2022-01-22 13:45:51 +08:00
coolGi2007 1d3a282c60 Added optifine tough dosnt run yet since forge dependances arnt set up yet 2022-01-21 17:49:47 +10:30
tom lee 9b6cd955b5 Updated core 2022-01-20 22:54:06 +08:00
tom lee 8e1559ac61 Update core and fix under lava (and powder snow) render fog issue 2022-01-20 21:55:17 +08:00
tom lee ce597576ba Update core and fixed slight bugs 2022-01-20 19:29:22 +08:00
tom lee d53a7a5fc4 Update core 2022-01-19 23:33:09 +08:00
tom lee 35bb5cdc92 Update core 2022-01-19 19:01:50 +08:00
tom lee 26e9cc21fd Add and fix mod compat issue with Optifine 2022-01-19 13:52:05 +08:00
tom lee 71fd448b7f Dummy commit to kick start CI, hopefully. 2022-01-18 23:15:36 +08:00
tom lee 93e18230f0 GENERATE LOD FROM FILE IS HERE!!!!!!!
Noted issue:

1. Non problematic WARN of `Tried to access a block entity before it
   was created`

2. The loading is.... a bit slow due to single thread action. Will be
   improved soon.

3. Possible Chunk Status not correct issue. It... sometimes happen, but
   it's mostly fine~

Special thanks to the YouTube commentors on the a1.6 Teaser Trailer
video. If not for them, I would not notice how many people want this,
and actually look into slapping in this feature in a1.6.
2022-01-18 22:50:57 +08:00
cola98765 d305741be2 resolved warnings. part 3 2022-01-18 11:29:01 +01:00
cola98765 5830c8d87a resolved warnings. part 2 2022-01-18 11:00:08 +01:00
cola98765 5161439536 resolved warnings. now more carefully. 2022-01-18 10:38:40 +01:00
coolGi2007 deb6ada6cc Fixed a typo 2022-01-18 09:18:36 +00:00
coolGi2007 e72a0546be Cleaned up comment on gradle and made stuff more consistent 2022-01-18 19:24:36 +10:30
jas35484 e27b43f03a Increment the version from '1.5.4a' to '1.6.0a-pre' 2022-01-17 20:33:35 -06:00
jas35484 daf4f06a30 Add .gitlab-ci.yml 2022-01-17 19:51:40 -06:00
Ran e5ef93a26d Universal jar for forge & fabric 2022-01-18 00:43:13 +06:00
cola98765 b158dff2c6 Revert "resolved couple warnings. If it causes problems just revert it."
This reverts commit b390e54801.
2022-01-17 16:27:27 +01:00
cola98765 23bbbce749 reverted config changes.... it was a bit too final 2022-01-17 16:14:52 +01:00
tom lee 898be82aab Update core 2022-01-17 22:51:28 +08:00
tom lee dc9ed37de2 Update core 2022-01-17 22:04:07 +08:00
cola98765 b390e54801 resolved couple warnings. If it causes problems just revert it. 2022-01-17 14:18:14 +01:00
tom lee 9736d2169e Update core+fabric disable StarLight 2022-01-16 17:34:35 +08:00
tom lee b507f459b3 Add basic StarLight compat. (Make it not crash) 2022-01-15 21:56:48 +08:00
tom lee 51a7053d7e Update core & make LightMode easy to switch. 2022-01-15 19:10:59 +08:00
coolGi2007 3ba40dd910 Added starlight 2022-01-15 10:14:44 +00:00
tom lee 248f8e5e70 ExpWorldGen: Add LightMode support. TODO: Config. 2022-01-15 16:58:16 +08:00
coolGi2007 49b0911aaf Escape saves config and added a immersive portals comment 2022-01-14 13:52:42 +10:30
tom lee e4b40c9383 Update core + Add disableVanillaFog for Forge 2022-01-13 23:35:18 +08:00
tom lee 328ac93178 Fixed Sodium Fog Issue. 2022-01-13 20:00:36 +08:00
tom lee d91f86aed5 Update core 2022-01-12 18:18:01 +08:00
tom lee 8119cc06ad Finally a reliable onClientChunkLoad event without light issues! 2022-01-12 16:16:20 +08:00
coolGi2007 94c9d0e276 Updated core 2022-01-11 08:45:33 +00:00
coolGi2007 e262dfa14a Fixed clouds for immersive portals 2022-01-11 08:39:09 +00:00
coolGi2007 5e0b63347e Fixes all (hopefully) problems with saving the config file 2022-01-11 17:35:45 +10:30
coolGi2007 b7df3bad22 Added a warning for clouds 2022-01-10 04:54:37 +00:00
coolGi2007 6a56c0c96f Update to add mod versions 2022-01-10 04:15:41 +00:00
tom lee fd8a94d77c Impl a semi-working getRenderedChunk for Sodium 2022-01-09 14:57:42 +08:00
tom lee 7d38fac16d Update core & try patch the light issue 2022-01-09 00:31:39 +08:00
tom lee 235ffb03a5 Make light works on pre generated chunks! Changed ChunkWrapper 2022-01-08 22:53:51 +08:00
tom lee fa2702209c Impl a getVanillaRenderedChunk 2022-01-08 15:05:12 +08:00
coolGi2007 f9f9f98750 Removed FogRenderer from forge(sorry for adding) 2022-01-08 06:25:06 +00:00
tom lee 0c46947f4d Update core 2022-01-07 19:09:07 +08:00
tom lee b5b57dfaba Update core and config 2022-01-07 18:59:02 +08:00
tom lee 39e7812f8b Updated core. Fixed wrong math in VanillaRenderedChunks 2022-01-07 15:53:30 +08:00
coolGi2007 025e8b3f9b Made clouds more optimised 2022-01-07 17:33:31 +10:30
coolGi2007 35e3a4262b Added disable vanilla fog to forge 2022-01-07 11:45:51 +10:30
coolGi2007 562c8154ff Fixed some config stuff 2022-01-06 10:49:25 +00:00
tom lee e23244181a Update core & comment out debug. Fixed/Cleaned up Fabric/Forge warpper 2022-01-06 16:28:25 +08:00
tom lee 6aa6c32299 Update core and tried fixing FAR_FIRST. Failed though.
Will continue tomorrow.
2022-01-06 00:09:45 +08:00
coolGi2007 fbdabf52e7 Made a way to save 1 config entry at a time 2022-01-05 23:07:40 +10:30
tom lee f4c1f1bcd7 Updated core and fixed generator bug 2022-01-05 19:19:14 +08:00
coolGi2007 965c19d426 Save config if you set something in the config wrapper singleton 2022-01-05 20:45:06 +10:30
tom lee 239a876fcf Update core 2022-01-05 16:58:31 +08:00
tom lee d53165881f Update core and ExperWorldGen for faster >Chunk details generation 2022-01-04 18:58:58 +08:00
tom lee 40733ea1fc Update core 2022-01-04 16:47:07 +08:00
coolGi2007 66a16ee508 Made clouds get from texture rather than use noise 2022-01-04 07:57:55 +00:00
tom lee b1a9a8ac8d Update core 2022-01-04 15:11:36 +08:00
tom lee 06a2f9f336 Updated core and comment out the @ConfigAnnotations.Category 2022-01-03 00:10:11 +08:00
coolGi2007 978bc58c11 Removed the need for any config category. The config now guesses the category 2022-01-02 16:34:47 +10:30
coolGi2007 a5577e80f1 Reordered forge mixin 2022-01-02 05:16:16 +00:00
Eric 9daf5a013c Changed cloud projection matrix to have custom clip values. 2022-01-01 21:28:56 -07:00
coolGi2007 72e2cb8a64 Updated core and fixed config crash 2022-01-02 03:51:19 +00:00
cola98765 db819698af fixed updateData 2022-01-01 13:31:23 +01:00
tom lee 09e427ab97 Updated core 2022-01-01 15:26:34 +08:00
tom lee a6b3a7ea5a Update core and fixed MixinFogs and added underwater fog 2022-01-01 13:51:35 +08:00
tom lee 4d08339f79 Updated core 2022-01-01 12:05:12 +08:00
tom lee 2ba32a8c94 Update core 2021-12-31 21:03:18 +08:00
coolGi2007 ebedd5e181 Moved some resources to core 2021-12-31 10:42:10 +00:00
tom lee 357c355e26 Updated core 2021-12-31 17:02:26 +08:00
tom lee faca159721 Updated core 2021-12-31 16:10:13 +08:00
coolGi2007 3556528932 I always forget to update core 2021-12-31 07:22:37 +00:00
coolGi2007 8513e46fdc Abstracting clouds 2021-12-31 17:51:32 +10:30
coolGi2007 323eced2a4 Fixed cloud problems 2021-12-31 17:24:45 +10:30
coolGi2007 6a87539ca3 Made a way to fully disable my clouds. Will be off by defult till clouds are done 2021-12-31 16:12:47 +10:30
coolGi2007 fe725b6795 Extended clouds 2021-12-31 04:55:01 +00:00
tom lee 02862a770f Fixed rebase issues and now it builds again 2021-12-30 22:06:30 +08:00
tom lee a7759ab8e9 Update core and config 2021-12-30 22:04:29 +08:00
cola98765 da1b2051dd made config for minimum back side culling distance. actual value is using prev player pos so on long flights it works better. 2021-12-30 13:19:47 +01:00
tom lee 4fdc596474 Update core 2021-12-29 20:38:13 +08:00
tom lee d0c710b7e1 Update core 2021-12-29 18:19:23 +08:00
tom lee 41ee9dcd99 ExperWorldGen: Hopefully fixed the ArrayIndexOutOfBound in StructStart 2021-12-29 15:10:22 +08:00
tom lee 506ce87f5f Updated core 2021-12-29 13:47:18 +08:00
coolGi2007 08e42ebfe5 Fixed ConfigGui 2021-12-29 16:16:21 +10:30
coolGi2007 699d27afd2 More universal config (works with java 8 & 16) 2021-12-28 10:50:32 +00:00
tom lee 4a64ce0bed Forge Bugfix: Fixed mixins metadata 2021-12-28 15:42:36 +08:00
tom lee b3b94d29b5 Forge Bugfix: Added accesswidener to fix access violations 2021-12-28 15:40:39 +08:00
tom lee 3a30516088 Update core & changed System.out to ClientApi.debug 2021-12-28 15:28:46 +08:00
Ran 6f469737f3 Fix forge's access transformers 2021-12-28 12:58:37 +06:00
coolGi2007 183720d1e5 Updated some config stuff for less crashing 2021-12-28 05:33:18 +00:00
tom lee b2dcc66bd0 update core 2021-12-28 00:10:18 +08:00
tom lee 5c67be30de Updated core 2021-12-27 23:43:46 +08:00
tom lee 4ad4e2c29c BufferUpload: Coresponding to core commit
Changed configs. Also added some more exception logging in
ExperWorldGen. And added a flag to JVM Minecraft to force JVM to always
capture Stack Traces.
2021-12-27 16:09:20 +08:00
cola98765 d1f805d178 optimised setupColorAndTint, specifically part where it calculates if block is gray for no reason if it's not going to be tinted anyway. 2021-12-26 16:08:02 +01:00
cola98765 73071119fa forgot I'm working on wrapper... still, I need color. 2021-12-26 15:41:58 +01:00
cola98765 97c52834f5 fixed SPRUCE and BIRCH leaves, as they require hardcoded biome color. TODO azalea also is like that 2021-12-26 15:36:18 +01:00
coolGi2007 3e472e454a Fixed bugs with ConfigGui 2021-12-26 16:47:28 +10:30
coolGi2007 7ddab31337 Updated comment for config 2021-12-26 03:50:07 +00:00
coolGi2007 fd5b9be523 WAHOO. CONFIG FINALLY SAVES!!! 2021-12-26 03:39:39 +00:00
cola98765 f9dd870067 changed fabric debug key to F8 2021-12-25 13:45:34 +01:00
cola98765 4908acd7ac fixed light requiring Y offset 2021-12-25 13:19:10 +01:00
coolGi2007 87486f6825 Fixed some config stuff. Only 1 more thing to go 2021-12-25 20:52:46 +10:30
tom lee c721c14e27 ExperWorldGen: Added perf logger
set ENABLE_PERF_LOGGING at WorldGenerationStep to true to enable it
2021-12-24 23:44:00 +08:00
tom lee 3521af9792 ExperWorldGen: Make it also works with non Feature 2021-12-24 22:23:02 +08:00
tom lee ff94dba348 ExperWorldGen: Fix major bugs and improved speed 2021-12-24 22:14:04 +08:00
cola98765 31d0a45555 potential fix to cherry leaves (call me if you see gray blocks that should not be gray) 2021-12-24 12:56:00 +01:00
tom lee 41c1473e04 ExperWorldGen: Use ThreadLocal to cache stuff 2021-12-24 17:18:58 +08:00
tom lee d5f12466b2 ExperWorldGen: Fixed World gen on non Overworld 2021-12-24 14:43:07 +08:00
coolGi2007 bdd9ef6b40 Fixed tooltip. Now only the saving is needed to be fixed 2021-12-24 16:14:35 +10:30
James Seibel 9b6895ec68 Refactor and comment ConfigGui 2021-12-23 20:01:53 -06:00
Ran a3854561fc Merge remote-tracking branch 'origin/1.18.X' into 1.18.X 2021-12-23 22:50:32 +06:00
Ran a66df74ec9 BlockEvents 2021-12-23 22:50:06 +06:00
tom lee eb4b31e876 Render: Changed rendered chunk getter to return circles 2021-12-23 18:40:22 +08:00
tom lee 6015b9a1dc ExperWorldGen: Increased timeout for slow CPUs 2021-12-23 18:40:22 +08:00
tom lee 146d42bbe9 Fabric: Added no vanilla fog support.
This isn't availible due to Forge default overrides something. Note that
this noFog also won't work on custom renderer.
2021-12-23 18:40:22 +08:00
Ran 16b14bc424 Add MinecraftForge License 2021-12-23 14:53:58 +06:00
Ran a37e4ca232 Merge remote-tracking branch 'origin/1.18.X' into 1.18.X 2021-12-23 14:47:59 +06:00
Ran 8103c16064 Fix warnings & add License 2021-12-23 14:47:38 +06:00
tom lee 6ae41b0caa ExperWorldGen: Polished stuff. No more error messages. use configs.
I would say this version is the first that is playable.
2021-12-23 16:36:14 +08:00
Ran ba81f31027 Update some stuffs 2021-12-22 22:16:08 +06:00
tom lee 71c72e26e7 ExprWorldGen: Fixed lots of stuff and Features now works!
Still Features exception, which I know how to fix I think.
2021-12-22 23:02:28 +08:00
Ran 97828f465d Server-sided Incoming 2021-12-22 20:32:03 +06:00
Ran ec37803572 Merge remote-tracking branch 'origin/1.18.X' into 1.18.X 2021-12-22 19:47:45 +06:00
Ran b7a54eff7a Explain why this exists 2021-12-22 19:47:22 +06:00
coolGi2007 9604ce297c Fixed not building 2021-12-22 09:53:56 +00:00
Ran 5ad961d80e Delete random log file; Sorry if this was important 2021-12-22 14:02:54 +06:00
Ran 843ec2fef8 Disable run for core & common 2021-12-22 14:01:27 +06:00
Ran 1b3e90b669 Make gradle compatible with Java 17 2021-12-22 13:53:34 +06:00
coolGi2007 55aadb73f1 Fixed the config button on forge menu 2021-12-22 07:07:21 +00:00
coolGi2007 e3d87c70c4 Updated config to be smaller 2021-12-22 05:37:59 +00:00
tom lee 8b1205f79e Fixed Fog color 2021-12-22 11:24:25 +08:00
tom lee 291f5d247c updated core 2021-12-21 21:13:44 +08:00
tom lee ad63825194 ExprWorldGen: Fixed some bugs. Still more to go. 2021-12-21 16:11:57 +08:00
tom lee b0e0cd107d Updated core 2021-12-21 15:49:44 +08:00
tom lee 5f60cd8d4d WorldGen: Added thread timeout failsafe 2021-12-20 14:31:32 +08:00
tom lee d0e17ccab7 Modified a bit of how it determine generation range 2021-12-19 22:35:21 +08:00
tom lee 38a4643cf3 WorldGen: Reversed priority for far vs near 2021-12-19 22:03:15 +08:00
tom lee 938adca022 Changed config for world gen 2021-12-19 21:42:05 +08:00
tom lee e2ec80134e Set the UseUnstable...Config to true by default for now 2021-12-19 21:39:51 +08:00
tom lee 903f166041 ExpWorldGen: Fix DeadLocks, improved cpu utilisations
Now world gen aways try to keep a certain amount of generation events
active.
2021-12-19 18:27:42 +08:00
TomTheFurry a9bdbfda4e Merge branch '1.18' into '1.18.X'
Merge the exprimental world gen

See merge request jeseibel/minecraft-lod-mod!13
2021-12-18 16:40:44 +00:00
tom lee 378349b870 Added experimental world generator. (Features mode only for now)
Turn on the AllowUnstableFeatureGeneration button to enable it. It is a
temp setting and will be renamed later. There will be many issues with
the generator, but at least it for now works... To be fixed tomorrow.
2021-12-19 00:32:42 +08:00
coolGi2007 190ce716ff Forgot to make the forge run client actually run forge 2021-12-17 11:59:05 +00:00
coolGi2007 d2c3a87fa8 Fixed some general stuff that broke when updating to .1.8.1 2021-12-17 11:47:39 +00:00
coolGi2007 2d5acbbf45 Updated to 1.18.1 but also works on 1.18 2021-12-17 08:52:46 +00:00
coolGi2007 4e973099f9 Updated my config 2021-12-17 08:29:14 +00:00
tom lee ee4f43cc59 WorldGen: Now only somewhat lock up server TPS
Use recent change to core so that we no longer request 8 chunk
generations per server tick, but instead just 1.
2021-12-17 16:00:44 +08:00
tom lee 3e64b7400e Updated core 2021-12-17 14:56:29 +08:00
James Seibel c44daa759c Remove the Forge server mod requirement and update the credits 2021-12-16 21:47:23 -06:00
tom lee 17c662b10f Fix -64 offset color bug: Impl' getMinHeight()
It calls works by calling getMinBuildHeight()
2021-12-16 18:39:58 +08:00
tom lee 3cfbb69dd9 Update core & fix Wrappers 2021-12-15 16:45:33 +08:00
tom lee 470668265b Updated core. Cann't test if works, in a hurry. 2021-12-15 00:08:38 +08:00
tom lee b6ced30d70 Updated core 2021-12-14 21:40:15 +08:00
coolGi2007 d3e0f1e14d leetom can you check it works before updating core 2021-12-14 08:36:33 +00:00
tom lee 910350ba3a Update core to use new Renderer system 2021-12-14 15:06:32 +08:00
coolGi2007 8dcf30e776 Updated core 2021-12-13 12:27:28 +00:00
coolGi2007 30d4bcd6a1 Updated config 2021-12-13 12:11:39 +00:00
tom lee 66300cbe70 WorldGen: Fix VersionConstants and more comments
More comments in WorldGenWrapper and fix version constants to always
return true in isWorldGeneratorSingleThreaded()
2021-12-12 23:28:18 +08:00
coolGi2007 50ae719f24 Updatec core 2021-12-12 04:01:04 +00:00
coolGi2007 dccad778fb Updaterd core 2021-12-12 01:44:05 +00:00
tom lee f163e31cd2 WorldGen: Half fixed world gen
Note that currently world gen is single threaded. Below is the current
mapped settings:

BIOME_ONLY -> ChunkStatus.BIOMES : <1 tick
BIOME_ONLY_SIMULATE_HEIGHT -> ChunkStatus.NOISE : <1 tick
SURFACE -> ChunkStatus.SURFACE : <1 tick
FEATURE -> ChunkStatus.FEATURE : 1-2 tick
FULL -> ChunkStatus.FULL : ~ 1-10 tick (?? Probably because of the threaded light engine update)
2021-12-12 02:05:12 +08:00
coolGi2007 5499079ada Updated readme to say to install git 2021-12-11 10:36:25 +00:00
coolGi2007 8d1277db1b Fixed build not building 2021-12-11 09:15:38 +00:00
coolGi2007 34fcac25c2 Updated behind the scenes config stuff 2021-12-11 06:06:10 +00:00
coolGi2007 cb0516cae8 Updated core 2021-12-11 04:05:48 +00:00
cola98765 4fdad05252 Merge branch '1.18' into '1.18'
FIx lightmap flicker on pause menu

See merge request jeseibel/minecraft-lod-mod!12
2021-12-10 10:39:40 +00:00
tom lee dc785b4fe1 Bugfix: Pause menu flicker issue 2021-12-10 17:29:16 +08:00
coolGi2007 8df7e1762a Updated core 2021-12-10 05:22:18 +00:00
coolGi2007 43d9b41648 Updated readme & removed stuff from conig 2021-12-10 01:21:04 +00:00
coolGi2007 880559f94a Updated core 2021-12-10 01:07:27 +00:00
Morippi 6f04ddce87 added the get names 2021-12-09 16:10:47 +01:00
Ran 6eb065f7c9 We do a little bit of coring here 2021-12-09 17:00:34 +06:00
Ran 17ebad9141 Merge remote-tracking branch 'origin/1.18' into 1.18 2021-12-09 16:59:51 +06:00
coolGi2007 9bcc799b0b Fixed forge not building 2021-12-09 10:44:38 +00:00
Ran f247410ae4 We do a little bit of coring here 2021-12-09 16:38:45 +06:00
coolGi2007 2f3bb2ec34 Update readme to be more accurate with architectury 2021-12-09 06:27:24 +00:00
coolGi2007 5c47170ef4 Now uses Architectury and added Forge support 2021-12-09 06:14:30 +00:00
coolGi2007 29d152b312 Updated core (i really need to add a subproject) 2021-12-08 23:54:04 +00:00
coolGi2007 aa48f0f5c6 Might fix windows not working 2021-12-07 05:24:13 +00:00
coolGi2007 05ea683fcf Fixed build problem 2021-12-06 12:39:42 +00:00
coolGi2007 65163a2477 Update Readme.md 2021-12-06 11:43:42 +00:00
coolGi2007 9dc4c46b99 Initual upload to branch 2021-12-06 11:39:57 +00:00
coolGi2007 69029e6f72 Updated core and some general stuff 2021-12-06 06:15:24 +00:00
coolGi2007 faf8579b41 Added custom config 2021-12-06 02:57:56 +00:00
coolGi2007 ed6dff3b5e Updated core 2021-12-03 06:17:38 +00:00
coolGi2007 2dd2623257 Updated config button 2021-12-03 06:17:06 +00:00
coolGi2007 82dfecf04c Updated readme to be more accurate with the current branch 2021-12-02 22:32:57 +00:00
Ran bb5bb23025 Merge branch '1.17.1' of https://gitlab.com/jeseibel/minecraft-lod-mod into 1.17.1 2021-12-02 16:24:00 +06:00
Ran c73e9b3cb5 Update core 2021-12-02 16:23:20 +06:00
coolGi2007 c28ec0b1d8 Update Readme 2021-12-02 09:58:31 +00:00
coolGi2007 a587ac4b4c Fixed the forge and fabric not building and made the gradlew an executable 2021-12-02 09:45:56 +00:00
Ran 0f19b338b6 Update core 2021-12-02 11:31:01 +06:00
Ran 9453e806db SnowAndFreezeFeature 2021-12-02 11:06:55 +06:00
Ran 1bd072bf0a Remove duplicate code 2021-12-01 19:15:30 +06:00
Ran 9315fd6211 Fix forge 2021-12-01 13:25:47 +06:00
Ran 1decb3764f Start porting duplicate code to common 2021-12-01 11:45:03 +06:00
Ran 012312892a Whoops, I forgor 💀 2021-12-01 10:01:49 +06:00
Ran c9f6a753ec Update everything latest & fix some issues & new accesswideners 2021-12-01 01:02:20 +06:00
Ran 9f6e9f791c Fix gradle issues (compiling works again) 2021-11-28 12:22:05 +06:00
Ran a297cdb79a Fix gradle issues 2021-11-28 09:40:54 +06:00
Ran e0ed760cf9 Update core 2021-11-26 23:28:54 +06:00
Ran 1c2549c64f Use HTTPS instead of SSH 2021-11-26 15:47:48 +00:00
Ran 433bc9217d Update .gitmodules 2021-11-26 15:10:40 +00:00
Ran 514e12580d Architectury (pls don't fail me IntelliJ) 2021-11-24 20:22:28 +06:00
James Seibel faf38ef8e3 Add DH-Core 2021-11-22 19:24:33 -06:00
James Seibel 48741a5364 Fix rendering the wrong number of verticies 2021-11-09 20:57:07 -06:00
James Seibel 03ff908de1 Update rendering to OpenGL 3.2+ (buffers seem to be corrupted or missing)
The rendering is almost completely functional, only fog needs to be re-implemented.
2021-11-08 19:45:40 -06:00
James Seibel 5eed9dae40 Add a reminder comment to MixinWorldRenderer 2021-11-08 19:28:16 -06:00
James Seibel 47988ec0da change the todo comment in LodGenWorker 2021-11-08 19:28:03 -06:00
James Seibel b29dac3753 Add a LodRender OpenGL context 2021-10-31 15:52:18 -05:00
James Seibel 3e3e1a7cf2 Update LodBufferBuilder.java 2021-10-31 15:49:30 -05:00
James Seibel 79e6977bab implement BlockPosWrapper offset 2021-10-30 17:21:17 -05:00
James Seibel 0c4ee74254 make the OpenGL proxy capabilities more specific 2021-10-30 17:21:00 -05:00
James Seibel 45d9dbbfcf implement BlockPosWrapper.getWorldPosition 2021-10-30 16:26:12 -05:00
James Seibel 2428449ab4 add a dimension wrapper 2021-10-30 16:15:40 -05:00
James Seibel f863da105b remove the multi-frame color building (it was causing a crash) 2021-10-30 16:15:30 -05:00
James Seibel d63b2c3b12 remove a unused onChange in LodConfig 2021-10-30 16:14:36 -05:00
James Seibel 15496663f3 update gradle for Tukaani.XZ 2021-10-30 16:13:33 -05:00
James Seibel 340631eb9b reformat and update the version number
Forge wants version numbers to start with a number
2021-10-30 13:58:07 -05:00
James Seibel adcd835642 porting - finish compiler errors 2021-10-30 13:47:39 -05:00
James Seibel ff5d2e6047 porting - LodBufferBuilder 2021-10-30 13:32:06 -05:00
James Seibel bd569dad2f porting - test LodWorldGenerator 2021-10-30 13:22:54 -05:00
James Seibel 71ab3196ea remove LodRenderer depreciation warnings 2021-10-30 11:02:23 -05:00
James Seibel b051815b3c porting - LodRenderer 2021-10-30 11:00:24 -05:00
James Seibel 991b3356bb Continue porting process 2021-10-29 23:32:49 -05:00
James Seibel 58ad37c056 Start porting to 1.17.1 2021-10-27 22:42:58 -05:00
James Seibel 65c091bb63 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-27 21:25:09 -05:00
James Seibel 9b389332be update the version number to a1.5.2 2021-10-26 19:26:23 -05:00
Leonardo 1093001841 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-26 23:11:16 +02:00
cola98765 a3db8e50f5 removed NativeImage dependency outside of wrappers. Now LodRenderer only triggers regen without storing lightmap 2021-10-26 23:09:31 +02:00
Leonardo db15e8684c Another small fix to light 2021-10-26 22:44:21 +02:00
Leonardo 00ac368bba fixed light being wrong 2021-10-26 22:38:14 +02:00
Leonardo f2face9782 small change to light value getters in lod builde. Added WorldLightWrapper for future implementation 2021-10-26 21:59:35 +02:00
Leonardo 923d57b377 Fixed the colors in the lodBuilder 2021-10-26 21:46:06 +02:00
Leonardo 447325e5a1 Fixed the colors for now 2021-10-26 21:43:11 +02:00
Leonardo bf712e893e removed default color use from the BlockColorWrapper 2021-10-26 21:28:18 +02:00
Leonardo 27f9a527bc Fixed part of the colors problems 2021-10-26 21:19:09 +02:00
Leonardo bde14012d9 Divided the Block Wrapper in two different class 2021-10-26 12:31:06 +02:00
Leonardo 12a32b9fb4 Implemented the wrappers in the lodBuilder 2021-10-26 11:58:33 +02:00
James Seibel 4ad081e0c6 Add a advanced graphics option to use a extended near clip plain
This prevents some overdraw issues but causes LODs in the ocean to render incorrectly.
2021-10-25 22:20:00 -05:00
James Seibel 936a3a7ece Fix #84 (misaligned LODs in third person) 2021-10-25 21:56:22 -05:00
Leonardo 98f36936d0 smallFix 2021-10-25 22:57:37 +02:00
Leonardo f6f012c42c Added some other classes/methods to the wrappers 2021-10-25 22:51:01 +02:00
Leonardo a3e6c09268 Added more methods to the wrapper 2021-10-25 22:31:43 +02:00
Leonardo 10cb46c9f9 Added biomeWrapper 2021-10-25 21:30:44 +02:00
Leonardo 95aa9cb9ab Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-25 20:20:47 +02:00
Leonardo 638a0ddae1 BlockPosWrapper and BlockWrapper almost completed 2021-10-25 20:20:40 +02:00
James Seibel d321833335 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-25 07:21:26 -05:00
James Seibel b8cba0dc4c increase the near clip plane to 1/5 MC's vanilla render distance 2021-10-25 07:21:17 -05:00
cola98765 bd8ccb4a05 reverted las change, fixed vanillaRenderedChunksChanged at hight altitudes 2021-10-25 13:20:13 +02:00
cola98765 895895da04 update buffers only when lightmap changes. 2021-10-25 12:43:59 +02:00
Leonardo 09d5df2856 Added the main wrapper classes (empty) 2021-10-25 11:14:17 +02:00
James Seibel 668f225528 Fix the blindness potion effect 2021-10-24 23:02:30 -05:00
James Seibel 1cd71a6b50 Re-arange Vanilla Overdraw config options 2021-10-24 22:18:09 -05:00
James Seibel f041f79ae3 Close #78 (Add a config to disable vanilla MC's fog)
And change the config to use FAR fog and disable MC's fog by default.
2021-10-24 22:17:57 -05:00
James Seibel ef3ac96b2c Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-24 21:30:35 -05:00
James Seibel 59f527e6de Update 1.5 release notes.txt 2021-10-24 15:19:59 -05:00
James Seibel 16a082b17f rename "Disable Drawing" to "Enable Rendering" in the config
The config name was incorrect.
2021-10-24 15:19:54 -05:00
jas35484 a24d28b0e2 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-24 14:57:56 -05:00
jas35484 910f11f688 Fix #63 (OpenGL errors)
NVFogDistance doesn't work on low end GPUs which causes the OpenGL error I was seeing with Optifine
2021-10-24 14:57:53 -05:00
cola98765 e00de99e31 Found place where addData was used for adding whole vertical array. We have addVerticalData for that. 2021-10-24 12:11:43 +02:00
cola98765 f80af39e0e halving every array related to worldHeight, as you can't get worldHeight lods, as half of that needs to be a gaps 2021-10-24 11:57:08 +02:00
cola98765 5bba3cb3eb minor cleanup 2021-10-24 11:35:45 +02:00
cola98765 d4261d4ccf a little improvement to 'pow' changes 2021-10-24 11:01:02 +02:00
cola98765 8b854e3abd removed debug message 2021-10-24 10:33:02 +02:00
cola98765 4064155567 changed Math.pow usages with simpler (and possibly faster) x*x and 1 << x. reduced repetitions 2021-10-24 10:28:35 +02:00
cola98765 6243201f2d removed couple Math.floorDiv and Mod as for positive inputs they are slower and give the same result as standard operands 2021-10-24 10:08:12 +02:00
James Seibel c5a2944d68 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-23 12:04:26 -05:00
James Seibel 1405b7a433 Add support for OpenGL 1.5 and 3.0 2021-10-23 12:04:16 -05:00
cola98765 be00670b7e Merge branch 'CodeF53-1.16.5-patch-77785' into '1.16.5'
Update youtube video

See merge request jeseibel/minecraft-lod-mod!5
2021-10-23 13:29:09 +00:00
CodeF53 6f2c02d283 Make link open in new tab 2021-10-23 05:11:10 +00:00
CodeF53 309526e7b9 Update youtube video 2021-10-23 05:01:37 +00:00
James Seibel d5466e0fda Fix a potential null pointer exception when leaving the world
The thread dealing with these should probably be killed and recreated when leaving the world instead of just catching the problem here.
2021-10-22 20:46:26 -05:00
James Seibel 7a0b95a105 minor refactor in LodGenWorker 2021-10-22 20:45:37 -05:00
James Seibel 7c59e33aee remove some commented out code 2021-10-22 20:42:02 -05:00
James Seibel 9907d2ddd5 Temporary null pointer fix 2021-10-22 18:48:32 -05:00
cola98765 1a838d4bd8 pushed FAR fog out by *1.6. I don't know why this number, but it works ok. 2021-10-22 20:07:02 +02:00
cola98765 dce3227bf1 Fixed compression on retail. Don't change your gradle tasks 2021-10-22 08:28:30 +02:00
cola98765 ea6f3e9881 now it's game crashes on launch when build using file made by "shadowJar" option 2021-10-21 16:42:30 +02:00
Leonardo 2f57b67bdc fixed underwater problem with always overdraw 2021-10-21 13:19:23 +02:00
Leonardo be024f524d Fixed regions wall not showing (which would cause holes in the rendering) and added border as possible overdraw config 2021-10-21 12:57:40 +02:00
cola98765 e0a176c0c4 tried to make XZ actually part of the jar 2021-10-21 12:16:39 +02:00
James Seibel b00795a0ab Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-20 22:34:26 -05:00
James Seibel 8bfa8e70a1 Create 1.5 release notes.txt 2021-10-20 22:34:14 -05:00
James Seibel 2a0653419f Update Readme.md
Ah so there is a way to preview this online, that's nice.
2021-10-21 02:21:28 +00:00
James Seibel cc1b9ea28e change the version to a1.5.0 and fix a line in the readme 2021-10-20 21:19:40 -05:00
James Seibel b32bdb3807 Add a acknowledgement for the use of the XZ data compression project 2021-10-20 21:14:15 -05:00
James Seibel 42bac2bd57 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-20 21:07:21 -05:00
James Seibel 9bd89accd3 re-add dynamic overdraw 2021-10-20 21:07:18 -05:00
Leonardo 5493ef9033 removed a print 2021-10-21 02:36:57 +02:00
Leonardo 7d1df26cc5 Shading is only disabled for lod that should be transparent 2021-10-21 02:28:37 +02:00
Leonardo 63f6d4cc56 Fixed chorus plant 2021-10-21 02:17:57 +02:00
James Seibel 6066a572d9 finish two incomplete comments 2021-10-20 18:09:08 -05:00
Leonardo ea679992e8 Small change 2021-10-21 00:40:21 +02:00
Leonardo fedce10917 Overdraw should now be fixed 2021-10-21 00:39:37 +02:00
Leonardo 80448ce990 Small change to the buffer builder 2021-10-20 23:03:13 +02:00
Leonardo 89fac88b7e Added method to check water logged block 2021-10-20 23:02:35 +02:00
Leonardo 032b63208c Added IWaterLoggable blocks to block to use in the generation 2021-10-20 21:23:53 +02:00
Leonardo 9faed3a2c8 Commented the buffer builder and added a method 2021-10-20 20:18:42 +02:00
Leonardo 05800089cb Changed fog enum name 2021-10-20 19:30:42 +02:00
James Seibel 8585511007 Update two of the config overrides 2021-10-19 22:11:11 -05:00
James Seibel 890de58c72 Fix regions culled incorrectly if far from the buffer's center
This would happen if the buffer builder died or was slow
2021-10-19 22:10:28 -05:00
James Seibel 8def361f63 rename LodNodeGenWorker to LodGenWorker 2021-10-19 21:16:58 -05:00
James Seibel 58d5a8beda Update the License header to match the new mod name
LOD -> Distance Horizons
2021-10-19 21:14:57 -05:00
James Seibel 443bb64df0 Improve the wording of the config file 2021-10-19 20:43:43 -05:00
James Seibel 400e00f572 auto-indent 2021-10-19 20:11:31 -05:00
Leonardo 5c36a3df16 Small fix to push and pop of configs 2021-10-19 23:11:39 +02:00
Leonardo 8578a833b4 Fixed crash caused by config 2021-10-19 22:36:01 +02:00
Leonardo 974a9b4452 Small change to configs name + comments 2021-10-19 22:30:23 +02:00
Leonardo d35fbb0bb3 New configs 2021-10-19 22:24:21 +02:00
Leonardo 0551fbb2d4 Small fix to config 2021-10-19 19:15:07 +02:00
Leonardo fe8a847637 Reversed resolution enum order 2021-10-19 19:09:32 +02:00
Leonardo b04eec91bc Fully disabled pre-gen code 2021-10-19 18:50:11 +02:00
Leonardo 6eddef2fb0 simplified block to avoid config 2021-10-19 18:10:59 +02:00
Leonardo 10382342d8 Added some more pre-gen testing code (disabled) 2021-10-19 13:35:22 +02:00
Leonardo 9d80b81378 Now the game doesn't use Biome class to calculate colors 2021-10-19 01:21:25 +02:00
Leonardo 12abc4f018 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-19 01:20:35 +02:00
Leonardo 21e774489c Added the ability to use pregenerated chunks, (bugged still to fix) 2021-10-19 01:20:29 +02:00
cola98765 f6f7f1043e cleaned out code after save compression refactor 2021-10-18 14:32:32 +02:00
cola98765 30e9dd1aac Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-18 11:51:14 +02:00
cola98765 219f3eba17 actually read old files as compressed 2021-10-18 11:50:50 +02:00
Leonardo d737500d95 Added a new section to the LodRegion which may be useful to identify pre-generated chunk in the future 2021-10-18 11:50:38 +02:00
Leonardo 2a402ef1d6 fully disabled the pregen code 2021-10-18 11:47:56 +02:00
Leonardo 84c0fd994d Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-18 11:46:33 +02:00
Leonardo cf782c5b6f changed default thread number 2021-10-18 11:46:23 +02:00
cola98765 96c19620cb now compressing using proper algorithm 2021-10-18 11:00:58 +02:00
cola98765 d0f93a2c89 Fixed light on predicted chunks in caveworld. 2021-10-17 22:15:06 +02:00
Leonardo 85157d0da0 Disabled pre-gen loading for now + small fix 2021-10-17 20:33:28 +02:00
Leonardo 33d150b090 Disabled pre-gen loading for now + small fix 2021-10-17 19:56:29 +02:00
Leonardo e6949dcd14 Fixed shadow with no tree bug 2021-10-17 19:37:06 +02:00
Leonardo b411f083e2 Added config for pre-generated chunk loading 2021-10-17 19:21:56 +02:00
Leonardo d3cd714f48 Added pre-generated chunk loading 2021-10-17 19:17:44 +02:00
Leonardo df0d1483c7 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-17 18:52:40 +02:00
Leonardo 0e82afd6e1 Disabled config override 2021-10-17 18:52:34 +02:00
cola98765 d80253546f fixed chunks resetting after loading save 2021-10-17 16:37:48 +02:00
Leonardo 441e4ff1f2 SmallFix to generation 2021-10-17 14:41:28 +02:00
Leonardo cbdfabeaeb Real chunks are always converted in max quality (could make it a config) 2021-10-17 14:34:39 +02:00
cola98765 bdf7fb3466 fixed blocklight one more time 2021-10-17 13:34:15 +02:00
cola98765 7595248406 cleaned a bit of code 2021-10-17 12:13:17 +02:00
cola98765 b5bcab36cd cleaned a bit of code 2021-10-17 11:53:47 +02:00
cola98765 5ed1e6135b now blocklight also uses server world when applicable 2021-10-17 11:33:07 +02:00
James Seibel 636d4129bd Rename HorizontalQuality LINEAR to LOWEST 2021-10-16 21:38:28 -05:00
James Seibel a90dfb695d Make the config file more easily readable 2021-10-16 21:07:07 -05:00
James Seibel 15c1a64cfd Update the version number to b1.5.0 2021-10-16 20:58:10 -05:00
James Seibel c5f823c54e Add generation Resolution checking to Dynamic vanilla overdraw 2021-10-16 20:56:00 -05:00
James Seibel a7c2e8a6ed Update the config file to use mod name (Distant Horizons) vs the mod id (lod) 2021-10-16 18:48:25 -05:00
James Seibel cb496208f5 If avoiding non full/solid blocks use the above block's color
This fixes snow and flowers not being used.
2021-10-16 18:08:17 -05:00
James Seibel 4ff1815436 Clean up a few compiler warnings 2021-10-16 16:28:57 -05:00
cola98765 31ada4e5d2 No longer removing 1 block gaps as with new lighting it shouldn't look worse 2021-10-16 22:43:25 +02:00
cola98765 accf082309 No longer removing 1 block gaps as with new lighting it shouldn't look worse 2021-10-16 22:42:58 +02:00
cola98765 e1b1f26f37 made project actually build after removing experimental light option 2021-10-16 22:18:24 +02:00
James Seibel a0c14c86ca Improve the lighting on local worlds
ClientWorld apparently doesn't actually know what the lighting is anywhere, so we will have to find another way to determine shadows on servers.
2021-10-16 13:45:31 -05:00
Leonardo a122015f6d Experimental light system is a config now 2021-10-16 15:52:39 +02:00
Leonardo 164d407153 Experimental light system is a config now 2021-10-16 15:51:35 +02:00
cola98765 893bfa096f made new light optional with internal boolean 2021-10-16 11:25:13 +02:00
cola98765 37995af19e fixed flag setting, and changed code back as if isLightCorrect and getBrightness actually worked 2021-10-16 10:39:06 +02:00
James Seibel c637d23121 Merge branch 'CodeF53/minecraft-lod-mod-1.16.5' into 1.16.5 2021-10-15 21:00:54 -05:00
James Seibel d762508188 Only return Minecraft Chunks from the chunkLoadEvent 2021-10-15 20:26:56 -05:00
James Seibel f5437f00a2 slight refactoring 2021-10-15 20:25:33 -05:00
CodeF53 dec20962b2 Switch readme to markdown format, adding headers and misc formatting. 2021-10-15 21:24:32 +00:00
cola98765 30e796f5bf fixed side lighting 2021-10-15 23:20:54 +02:00
cola98765 4ab4dc59e7 now renders default Skylight as 0 when player is in Skylight 0 situation 2021-10-15 18:41:58 +02:00
cola98765 839a76c594 minor adjustment that was annoying me 2021-10-15 17:24:04 +02:00
Leonardo 3fb4d16e41 New sky light handling system (not complete) 2021-10-15 16:23:20 +02:00
Leonardo 002d86af9f Added comment + small refactor + removed TODO 2021-10-15 16:22:41 +02:00
cola98765 e1877f9149 Now using flag bit in data as "is light default" 2021-10-15 15:37:51 +02:00
cola98765 4da1fcc118 since new method of getting skyLight is objectively better, I've commented out old method and 'if' used to switch between those methods 2021-10-14 23:36:27 +02:00
cola98765 af123a8c80 added fast track when we want to add whole column of data, so it doesn't call 5 different methods for each lod block. 2021-10-14 23:33:14 +02:00
cola98765 94bc7fd011 now ignoring isLightCorrect completely, old method is still available 2021-10-14 19:29:50 +02:00
cola98765 905d8bddf3 made new sky lighting calculation optional with internal boolean 2021-10-14 18:56:51 +02:00
cola98765 5ee762cc78 now actually remove garbage vertical lods 2021-10-14 18:51:39 +02:00
cola98765 7c07a88b45 small fix to that light fix 2021-10-14 18:02:58 +02:00
cola98765 d8981af7aa possible fix to skylight... revert if worse than before 2021-10-14 15:11:36 +02:00
Leonardo 9906eb75f4 Changed the Far fog on fancy. Now fog start after the real game render distance 2021-10-14 14:06:11 +02:00
Leonardo d94fedc61e Changed the Far fog on fancy. Now fog start after the real game render distance 2021-10-14 14:02:47 +02:00
cola98765 3e3b979530 indents in LodConfig 2021-10-14 07:49:02 +02:00
James Seibel 6ad94d3362 Update the version number to 1.5.0 and replace the LOD name with Distant Horizons 2021-10-13 23:28:43 -05:00
James Seibel 31f8cecc92 Add the minimum OpenGL version to the readme
BufferStorage technically only requires OpenGL 4.4, but I already had 4.5 written everywhere. If it becomes a problem that going to 4.4 fixes I could probably roll back to that.
2021-10-13 22:04:41 -05:00
James Seibel b4106a8c3c Improve the buffer rebuild logic related to light change 2021-10-13 21:59:46 -05:00
James Seibel b6390c57ef auto-indent 2021-10-13 21:03:03 -05:00
James Seibel 5172c66b9b Merge branch 'CodeF53-1.16.5-patch-87033' into '1.16.5'
Update demo video to latest

See merge request jeseibel/minecraft-lod-mod!3
2021-10-14 01:59:33 +00:00
James Seibel 067fa92419 Improve the logic for vanilla overdraw to work better on different horizontal resolutions 2021-10-13 20:44:38 -05:00
Leonardo 15e80ed063 ceiled dimension now have 64 max render distance + various small changes 2021-10-14 02:29:42 +02:00
Leonardo 2c6549e815 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5
# Conflicts:
#	src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java
#	src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java
2021-10-14 02:28:24 +02:00
CodeF53 32423c07eb Update demo video to latest 2021-10-13 15:03:27 +00:00
cola98765 4a0640a219 cleaned out some code. 2021-10-13 14:27:27 +02:00
cola98765 5f9f20a064 cleaned out some code. 2021-10-13 13:45:23 +02:00
cola98765 ef4ba7208e cleaned out some code. 2021-10-13 13:31:47 +02:00
cola98765 80edf19b33 cleaned out some code. 2021-10-13 13:24:07 +02:00
cola98765 4baa649972 cleaned out some code. Applied autoformat everywhere 2021-10-13 12:45:21 +02:00
cola98765 c7dbc28a9a cleaned out some code 2021-10-13 12:08:47 +02:00
cola98765 707c55653a removed single level container 2021-10-13 12:01:56 +02:00
Leonardo 40cb7f4efc Merge remote-tracking branch 'origin/1.16.5' into 1.16.5
# Conflicts:
#	src/main/java/com/seibel/lod/objects/SingleLevelContainer.java
2021-10-13 11:35:24 +02:00
Leonardo df22a082a1 Added option to avoid block with no collision + removed SingleLevelContainer class use 2021-10-13 11:34:59 +02:00
cola98765 3a7f411aa4 cleaned java ocs in DataPointUtil 2021-10-13 10:36:29 +02:00
cola98765 11c419e503 updated some TODO's 2021-10-13 10:15:48 +02:00
James Seibel 30b82e8009 update dynamic vanilla overdraw in LodUtil 2021-10-12 22:31:51 -05:00
James Seibel 7df4a161dd Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-12 22:20:53 -05:00
James Seibel 56160db7ec comment out the buffer builder expanding console logging 2021-10-12 22:20:44 -05:00
James Seibel ac84c3707a Remove a illegal import 2021-10-12 22:20:27 -05:00
Leonardo d16f571467 Small changed to border shading + changed overdraw ratio 2021-10-12 17:12:31 +02:00
cola98765 d7bd0498a0 When there are no files for current gen mode, try to load more detailed ones instead. 2021-10-12 11:58:21 +02:00
James Seibel 57a2b956dd Improve the VanillaOverdraw config to work better in roofed dimensions 2021-10-11 23:05:49 -05:00
James Seibel 51aadc8d39 Maybe fix a OpenGL error? 2021-10-11 23:00:28 -05:00
James Seibel 70e2f7f3e6 prevent a potential out of bounds exception 2021-10-11 23:00:11 -05:00
James Seibel 0ef8615a98 Extract the main work of the buffer builder into a method for easier hot swapping 2021-10-11 22:12:35 -05:00
James Seibel 4c6412d09f comment out a debug override 2021-10-11 20:55:02 -05:00
Leonardo 27b8cfea09 Fixed the purple color bug 2021-10-11 23:17:20 +02:00
cola98765 b5ab06bfb6 resolved warning 2021-10-11 22:14:56 +02:00
James Seibel 732476b454 Add the overdraw
Overdraw renders LODs on top of vanilla chunks based with  three different settings.
2021-10-10 21:31:45 -05:00
James Seibel 9d1a9eb9f3 Remove the memory estimation code.
Buffers will now be purposely created smaller than expected and then expanded to fit the need.
2021-10-10 14:01:13 -05:00
James Seibel 6018449cbe Quick formatting change and remove a completed TODO 2021-10-10 08:10:05 -05:00
cola98765 8f43695a47 did someone say warnings and typos? 2021-10-10 13:07:23 +02:00
cola98765 30913a0c29 more typos 2021-10-10 11:36:10 +02:00
cola98765 d8cee2b10c Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-10 11:19:09 +02:00
cola98765 33a706f660 autoformat 2021-10-10 11:19:02 +02:00
cola98765 6c2b707c02 autoformat 2021-10-10 11:16:54 +02:00
cola98765 ecb01c731e Resolved "ALOT" of typos. 2021-10-10 11:09:15 +02:00
cola98765 72737a56c1 Resolved more warnings. 2021-10-10 10:38:00 +02:00
cola98765 1d1b5f6115 Resolved more warnings. Applied auto format in affected files. 2021-10-10 10:34:34 +02:00
cola98765 b67ab59a89 Resolved more warnings. Applied auto format in affected files. 2021-10-10 09:50:44 +02:00
cola98765 ca4597e3d9 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-10 08:38:00 +02:00
cola98765 efd9a5a51b merge all 1 block gaps for better look o trees 2021-10-10 08:37:47 +02:00
cola98765 4c3d19a6c6 merge all 1 block gaps for better look o trees 2021-10-10 08:36:45 +02:00
cola98765 6c4faa9103 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-10 08:24:05 +02:00
James Seibel 6066957584 Update LodConfig.java 2021-10-09 20:14:51 -05:00
James Seibel c3f8b0b677 Remove the experimental useFovSetting setting 2021-10-09 19:47:26 -05:00
James Seibel e2cdf1549a auto-indent 2021-10-09 19:42:02 -05:00
James Seibel fe9bc5e77e Delete Reference.java 2021-10-09 19:41:22 -05:00
cola98765 ea0ef9e394 boosted skylight prediction to 13 so most trees look better 2021-10-09 23:22:39 +02:00
James Seibel 27d74958bf Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-09 14:48:53 -05:00
James Seibel dc8db97f33 Fix the region at 0,0 (-X,-Z) rendering incorrectly 2021-10-09 14:48:47 -05:00
cola98765 3ec30d49be put guts of mergeSingleData into mergeMultiData and make dataPoint smaller to make it faster 2021-10-09 17:47:58 +02:00
cola98765 627327140e reversed logic in mergeMultiData to improve performance of initial compression to maxVerticalData 2021-10-09 17:07:38 +02:00
James Seibel 2ebbb6f591 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-09 09:46:33 -05:00
James Seibel 126b581e97 Add BufferStorage recreation, improving memory usage
I still want the buffers to be created the right size at the start, but this will work for now.
2021-10-09 09:46:24 -05:00
cola98765 f625e714d4 made mergeMultiData a bit faster 2021-10-09 11:00:59 +02:00
cola98765 5db7e349b9 in mergeMultiData skip empty data 2021-10-09 08:16:58 +02:00
James Seibel 272546af4d Improve the buffer expansion console logging 2021-10-08 22:16:12 -05:00
James Seibel c0a9e3061c reformatting / commenting 2021-10-08 22:13:20 -05:00
James Seibel 5872dc3be5 Fix a memory leak when changing worlds 2021-10-07 22:47:16 -05:00
James Seibel 8fe6eff36c improve the buffer expanding logging 2021-10-07 22:45:48 -05:00
James Seibel d89f2dc9b8 Refactoring / reformatting 2021-10-07 21:34:34 -05:00
James Seibel e0ac03db6c Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-07 21:25:05 -05:00
James Seibel ee58f3d9dc Use OpenGL BufferStorage to improve upload performance
I need to change how the memory is determined, right now they fill to the maximum amount; which is very bad and only for testing.
2021-10-07 20:59:45 -05:00
cola98765 b02d58227c reworked mergeMultiData 2021-10-07 20:17:37 +02:00
Leonardo 61cb27020c small change to a print 2021-10-07 18:03:09 +02:00
Leonardo 443da5eede other config change, set roofed dimension max distance to 64 2021-10-07 17:37:02 +02:00
Leonardo 78ab4b8598 Changed configs 2021-10-07 17:20:39 +02:00
cola98765 028aed53f8 resolved some more warnings and applied autoformat in affected files 2021-10-07 11:17:02 +02:00
cola98765 1ed36ba6c4 resolved some more warnings and applied autoformat in affected files 2021-10-07 11:07:10 +02:00
cola98765 6deca8e235 resolved many warnings and applied autoformat in affected files 2021-10-07 10:36:30 +02:00
Leonardo a6f3c2478e Some refactor + fixed cpu problem with near_first 2021-10-07 00:19:32 +02:00
cola98765 a66554f2dd resolved todo 2021-10-06 11:45:36 +02:00
cola98765 28cf2eb450 removed debug message when saving 2021-10-06 10:37:36 +02:00
cola98765 e154f552c7 fixed bug where only some regions were saved when player was not moving 2021-10-06 10:36:37 +02:00
Leonardo 0c275e1495 Added back the toString in the PosToGenerateContainer 2021-10-05 19:06:51 +02:00
Leonardo 2b15c089f4 Added back the toString in the PosToGenerateContainer 2021-10-05 18:59:40 +02:00
Leonardo fca926bc8f Added some comment, fixed the thread conflict problem 2021-10-05 11:25:06 +02:00
James Seibel f6ea990ab0 Reduce buffer uploading stuttering
I also included commented out versions of several other buffer uploading options and comments on how well they perform.
2021-10-04 22:52:11 -05:00
James Seibel ee6c8d597c Hopefully prevent the buffer builder from dying if an exception is thrown 2021-10-03 14:45:38 -05:00
James Seibel 1e819bd555 temporarily disable transparency in the AbstractLodTemplate 2021-10-03 14:08:55 -05:00
James Seibel a0358dd298 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-03 13:57:34 -05:00
James Seibel 90987fc389 Add a constant to LodUtil and remove a few unused ones 2021-10-03 13:57:24 -05:00
cola98765 f72c846fe5 removed old commented code 2021-10-03 09:42:50 +02:00
James Seibel 2ca8576ad7 auto-indent 2021-10-02 21:33:09 -05:00
James Seibel 0194cffaba auto indent 2021-10-02 21:28:52 -05:00
James Seibel cc52815315 update a override option in the clientProxy 2021-10-02 21:24:19 -05:00
James Seibel 900b67920c re-add transparency rendering 2021-10-02 21:24:04 -05:00
James Seibel 9c1e5c33a5 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-10-02 21:08:22 -05:00
James Seibel d7a1d330d9 Re-add Linux and (hopefully) Mac support
I have tested Windows and Ubuntu (Linux). I didn't test Mac but I am reasonably confident that it should work.
2021-10-02 21:08:15 -05:00
cola98765 3ac05c6a2b fixed multiplyRGBcolors to not make off by 1 error 2021-10-02 15:34:02 +02:00
James Seibel eeff5437b5 Hopefully add Mac and Linux support 2021-10-01 23:25:51 -05:00
James Seibel ee89d6f512 Update the Readme to include IntelliJ install instructions 2021-10-01 07:19:55 -05:00
James Seibel a577851f6b Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-09-30 21:42:00 -05:00
James Seibel 536bff2fe7 Hopefully fix the OpenGL context switching error 2021-09-30 21:41:49 -05:00
James Seibel b1995445e2 auto-format 2021-09-30 19:24:30 -05:00
Leonardo 5d4d483b16 re-added the avoidNonFullBlock and avoidSmallBlock options 2021-10-01 01:26:11 +02:00
Leonardo c13abc3b7d Added thread data for the buffer builder 2021-09-30 19:50:05 +02:00
Leonardo 1cbb15045f Added a reset when unloading and loading world 2021-09-30 19:47:04 +02:00
Leonardo 48ea096ff1 Added comment and changed some small variables 2021-09-30 17:52:51 +02:00
cola98765 2e08b61672 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-30 17:46:59 +02:00
cola98765 b0bb01fde4 reworked ThreadMapUtil to actually save arrays between uses. 2021-09-30 17:46:03 +02:00
Leonardo cc666e917e Now the border chunk only work for render distance higher than 4 2021-09-30 15:26:28 +02:00
Leonardo 9e0abd06fb Better fake chunk/ real chunk blending, less holes 2021-09-30 14:48:52 +02:00
cola98765 0f56a98499 attempt to fix grass colors by setting biome opacity to 255 2021-09-30 13:04:43 +02:00
cola98765 529c52b93f getBuilderArray wasn't initialised correctly causing a lot of new long[] 2021-09-30 12:28:04 +02:00
cola98765 8020b298fb fixed saving transparency and calculating it around biome colors 2021-09-30 11:11:23 +02:00
Leonardo 37db05d18f added a borderChunk finder function 2021-09-30 01:38:39 +02:00
Leonardo 555e5a78b5 simplified the culling (still disabled) 2021-09-30 01:37:48 +02:00
Leonardo 32d492f5f6 Changed some package and added a dimension to the buffer builders 2021-09-29 14:57:43 +02:00
James Seibel d9ee9135d7 revert the config override message 2021-09-29 07:55:46 -05:00
James Seibel d59f9dc4c6 Create pre-release a1.5.1
I made this version so hopefully someone could test if Vivecraft is just ignoring Minecraft's FOV when creating their projection matrices or if they are doing something more complicated.
2021-09-28 22:56:17 -05:00
James Seibel 8f329ac785 auto-format 2021-09-28 22:18:38 -05:00
James Seibel 9865b23e5b Move MAX_ALLOCATEABLE_DIRECT_MEMORY to LodUtil 2021-09-28 21:29:25 -05:00
James Seibel a987149aa3 Create Eclipse Auto Formatting V1.xml 2021-09-28 21:06:15 -05:00
Leonardo 22b7e46d39 small fixes 2021-09-29 02:38:19 +02:00
Leonardo e5c1e67369 Changed various names, changed the memory calculator 2021-09-29 02:16:23 +02:00
James Seibel 328792cf4e Start commenting and refactoring SingleLevelContainer 2021-09-28 07:50:07 -05:00
James Seibel 344901aad5 Comment RegionPos 2021-09-28 07:41:13 -05:00
James Seibel 5f89bd8e7d comment and refactor PosToGenerateContainer 2021-09-27 22:12:55 -05:00
James Seibel 7c5713fac2 Refactor and comment LodWorld 2021-09-27 21:59:51 -05:00
James Seibel d222854717 auto-indent 2021-09-27 21:49:11 -05:00
James Seibel 6b9be10635 Add a few missing comments and refactors to LodRegion 2021-09-27 21:48:19 -05:00
James Seibel 69a72312e4 Refactor and comment LodRegion 2021-09-27 21:43:16 -05:00
James Seibel 948b58d8e9 auto-indent and move a reminder comment 2021-09-27 20:20:26 -05:00
James Seibel 86406fd12b Rename MULTI_LOD to VOXEL 2021-09-27 20:17:33 -05:00
James Seibel cc3e1d1b12 Fix a null pointer and finish commenting/refactoring LodDimension 2021-09-27 20:13:16 -05:00
James Seibel 85a0110af6 comments and regactor LodDimension 2021-09-27 07:59:55 -05:00
James Seibel a76436b73d Bring back the drawLODs config 2021-09-26 08:20:37 -05:00
James Seibel 391c99fd21 comment and refactor LodDimensionFildHandler and ReflectionHandler 2021-09-25 23:51:14 -05:00
James Seibel fb5aceb44d auto-indent 2021-09-25 23:20:05 -05:00
James Seibel 4c76a48e84 Update comments for many enums 2021-09-25 23:17:17 -05:00
James Seibel d7a42d3a51 auto-indent 2021-09-25 20:35:12 -05:00
James Seibel e0a946673e refactor LodBuilderConfig 2021-09-25 20:30:44 -05:00
James Seibel ad793fe17e Refactor and comment LodBufferBuilder and LodBuilder 2021-09-25 18:52:53 -05:00
James Seibel 209e2579c3 refactor and comment LodWorldGenerator 2021-09-25 16:09:29 -05:00
James Seibel 8627b87aa4 auto-indent 2021-09-25 16:09:12 -05:00
James Seibel 5f855dd573 CubicLodTemplate refactoring and commenting 2021-09-25 15:34:39 -05:00
James Seibel d6c918427b have the LodRenderer recreated only when leaving a server 2021-09-25 15:34:25 -05:00
James Seibel a9bdbc4300 Potentially fix a false buffer IndexOutOfBoundsException 2021-09-25 15:32:34 -05:00
James Seibel 58a150f8de fix the ThreadMapUtil not creating arrays correctly 2021-09-25 13:22:31 -05:00
James Seibel 1a3e1dfa8c add get fresh methods to TheadMapUtil
the getFresh versions create/clear the data for the given map.
2021-09-25 11:48:05 -05:00
James Seibel 430a908829 refactor clientProxy 2021-09-25 11:42:49 -05:00
James Seibel 0ca0cd9213 auto-indent 2021-09-25 09:07:07 -05:00
James Seibel 2f392375fe Refactor and Comment Box 2021-09-25 09:04:26 -05:00
James Seibel ff43118976 Update the version number to a1.5.0-pre 2021-09-24 18:06:57 -05:00
James Seibel 3b4e28d74a Add a warning chat message for the 1.5.0 pre-release 2021-09-24 18:05:05 -05:00
James Seibel 13abed4eb8 comment out the shadingMode config since it isn't currently used 2021-09-24 07:59:26 -05:00
James Seibel ccb2c601a6 add a temporary fix to color debug mode not having shading 2021-09-24 07:59:07 -05:00
James Seibel f6816d9974 auto-indent 2021-09-24 07:45:00 -05:00
James Seibel 5156ae8e63 auto-format 2021-09-24 07:43:22 -05:00
James Seibel 55c0c95339 Improve config wording 2021-09-24 07:37:14 -05:00
James Seibel 0b8503f1fa move applyConfigOverrides 2021-09-24 07:27:07 -05:00
James Seibel 79d9ac5d56 auto-indent 2021-09-24 07:26:50 -05:00
James Seibel 6cf4e663fb Fix a potential null pointer exception and improve clientProxy error logging 2021-09-23 22:07:46 -05:00
cola98765 bf9c3ce567 fixed saving multidata in void dimentions 2021-09-23 23:52:34 +02:00
Leonardo 5bbdd22b58 light works again, changed the region_fast option, fixed a indexout of buond, added a TODO for the future for better memery use 2021-09-23 16:02:32 +02:00
Leonardo 6c1c04bb5f Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-23 15:18:39 +02:00
Leonardo 66728cc1eb fixed the memory crash problem.
Added config to draw always in generation quality (if true the game will crash with  render distance>256)
2021-09-23 15:18:33 +02:00
James Seibel d4739b9bed Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-09-23 07:55:44 -05:00
James Seibel a93bb63c44 Fix an index out of bounds exception for vanillaRenderedChunks 2021-09-23 07:55:33 -05:00
Leonardo a2e18de9f3 small fix to generation 2021-09-23 14:38:35 +02:00
Leonardo 6183152d99 small fix to culling 2021-09-23 14:37:57 +02:00
James Seibel 5d9f36bb5f Hopefully fix the openGL errors 2021-09-22 22:26:23 -05:00
James Seibel d330083d7b auto-format 2021-09-22 22:20:03 -05:00
James Seibel 6d489b498e add additional error checking to BufferBuilder vboUpload 2021-09-22 22:16:10 -05:00
James Seibel d36d836bb3 prevent a null point in LodRegion addData 2021-09-22 22:15:42 -05:00
James Seibel 29d2d1cff1 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into
1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/objects/LodDimension.java
2021-09-22 21:52:03 -05:00
James Seibel 0a9ea1dfce improve the error reporting in GlProxy 2021-09-22 21:50:05 -05:00
James Seibel b9424cbe9f Fix a index out of bounds error in ThreadMapUtil 2021-09-22 21:04:11 -05:00
Leonardo 593a014dfc fixed far and near generation, fixed holes in the rendering in near gen 2021-09-23 02:03:02 +02:00
James Seibel 83ac04dca4 auto-format 2021-09-22 18:33:20 -05:00
Leonardo c9aed389ae various changes to the generation + some small fixes 2021-09-23 01:05:54 +02:00
Leonardo 00da0e0520 Fixed tall grass and flower colors 2021-09-22 21:32:08 +02:00
Leonardo 5124739348 removed reset of bufferBuilder and added better color creation for grass, leaves, water and flowers 2021-09-22 20:47:31 +02:00
Leonardo d65bfd408e Fixed the artifacts (was caused by wrong array initialisation) and added the reset to while changing dimension 2021-09-22 19:38:04 +02:00
Leonardo da413f594e Added different detail drop off option 2021-09-22 17:17:17 +02:00
cola98765 1fcef4be96 some warnings taken care of 2021-09-22 15:10:20 +02:00
cola98765 d7cddd9b39 fixed null check 2021-09-22 15:02:08 +02:00
Leonardo fb480c2695 fix to memory use 2021-09-22 13:17:56 +02:00
James Seibel 265abb64b3 Improve the wording for a few config options 2021-09-21 21:15:02 -05:00
James Seibel 1cf4852788 auto-format 2021-09-21 20:27:55 -05:00
Leonardo 90d0fbe45b various fix to the generation 2021-09-22 01:26:55 +02:00
cola98765 ea9eac89ec podzol netherrack and other blocks now use proper top color without biome color (nether plants might still be broken didn't test it) 2021-09-22 00:26:11 +02:00
cola98765 017cc201b1 enabled save loading for vertical lods 2021-09-21 23:09:48 +02:00
Leonardo bda963036d Introduced correctly spiral generation 2021-09-21 18:35:48 +02:00
Leonardo 46bdf5763f Added spiral generation, changed how some arrays are created 2021-09-21 18:12:15 +02:00
Leonardo 8228a3b7a6 fixed a thread problem 2021-09-21 16:30:53 +02:00
cola98765 e3df6c99da added void and !exist compression to VerticalLevelContainer 2021-09-21 16:18:58 +02:00
Leonardo a4e9e22d2c fixed end bug 2021-09-21 16:09:24 +02:00
Leonardo 435c5ee73a fixed nether roof bug 2021-09-21 15:09:28 +02:00
cola98765 c6b063a380 in SingleLevelContainer made void chunks save as 1 byte instead of 8 2021-09-21 11:34:07 +02:00
cola98765 1f5c3f5bd8 in SingleLevelContainer made void chunks save as 1 byte instead of 8 2021-09-21 11:33:01 +02:00
Leonardo 688cb3f89a New memory getter system 2021-09-20 18:58:02 +02:00
Leonardo af80ff5267 Refactoring 2021-09-20 16:33:24 +02:00
Leonardo 2bc5c43b19 small fix 2021-09-20 15:51:34 +02:00
Leonardo e7c4827d08 Now the single merge use min and max depth and height and no more the mean to make it more consistent with the multi-lod 2021-09-20 15:49:22 +02:00
Leonardo 482dfb918e Refactoring + added the ability to disable lods with f6 2021-09-20 15:44:18 +02:00
Leonardo 5aaf6e0185 removed redundant toString() 2021-09-20 15:23:56 +02:00
Leonardo ab014af15d more refactoring 2021-09-20 15:15:10 +02:00
Leonardo 772de1b869 Refactoring, removed unused class/enum, fixed a small array bug 2021-09-20 14:59:42 +02:00
Leonardo cb42683774 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-20 14:01:28 +02:00
Leonardo a00698ccab added the dataPoint to the threadMaputil 2021-09-20 14:01:18 +02:00
cola98765 29ed26f023 More warnings addressed 2021-09-20 13:31:16 +02:00
cola98765 af3c4ab801 More warnings addressed 2021-09-20 13:23:22 +02:00
cola98765 1156b7dd28 now using ThreadMapUtil for temp array during saving 2021-09-20 12:50:49 +02:00
cola98765 25fd29b97e replaced short[][] with short[] in mergeMultiData hotfix 2021-09-20 12:16:47 +02:00
cola98765 a11ff5b493 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-20 12:13:32 +02:00
cola98765 7655ae03b0 replaced short[][] with short[] in mergeMultiData 2021-09-20 12:13:24 +02:00
Leonardo 075e29c617 small fixes for better gc use 2021-09-20 12:09:45 +02:00
cola98765 e482bf02a5 fixed negative numbers in mergeMultiData 2021-09-20 11:57:32 +02:00
cola98765 0dab4a2274 addressed couple warnings 2021-09-20 11:54:01 +02:00
cola98765 001335ab47 I'm stupid 2021-09-20 11:46:47 +02:00
Leonardo faedb85f41 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-20 11:35:31 +02:00
Leonardo 01b9a3f3b0 Fixed culling 2021-09-20 11:35:20 +02:00
cola98765 cfd9bd903d + 1 will not hurt anyone 2021-09-20 11:34:25 +02:00
cola98765 3e634c082a addressed couple warnings 2021-09-20 11:30:56 +02:00
cola98765 6e86a808a5 addressed couple warnings 2021-09-20 11:12:54 +02:00
cola98765 e615674246 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-20 11:03:48 +02:00
cola98765 86b5fc48a2 addressed couple warnings 2021-09-20 11:03:24 +02:00
Leonardo 2fab33fa78 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-20 10:57:28 +02:00
Leonardo b56b581bb6 Refactoring 2021-09-20 10:57:20 +02:00
cola98765 2ee5289881 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-20 10:56:36 +02:00
cola98765 3da4e4818c replaced arraycopy in mergeMultiData in favor of simpler method for debugging 2021-09-20 10:56:28 +02:00
Leonardo 686062f39c Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-20 10:46:25 +02:00
Leonardo ae857dfeae fixed a small bug in the datapoint
Simplified the code in the LodBufferBuilder
2021-09-20 10:46:14 +02:00
cola98765 686592effb fixed bug in loading vertical data 2021-09-20 10:43:12 +02:00
James Seibel 34b92d1053 Fix #67 (LODs not rotating with camera) and #68 (LODs culled based on player direction, not camera) 2021-09-19 19:25:01 -05:00
James Seibel 01a850eb9d Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-09-19 18:14:09 -05:00
James Seibel 7d6f7f35ff Fix the buffer builder failing on LodQualityMode.HEIGHTMAP 2021-09-19 18:13:48 -05:00
James Seibel 28764bc16c auto-format 2021-09-19 17:58:22 -05:00
Leonardo ee1657a798 fixed a small bug 2021-09-19 23:58:24 +02:00
cola98765 c7bf60b4e0 fixed byte cast 2021-09-19 23:34:55 +02:00
cola98765 031af5f25c Merge branch '1.16.5' of https://gitlab.com/jeseibel/minecraft-lod-mod into vertical_merging
 Conflicts:
	src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java
	src/main/java/com/seibel/lod/util/DataPointUtil.java
2021-09-19 23:31:16 +02:00
Leonardo d8200422b2 disabled the clear + small change 2021-09-19 23:18:31 +02:00
cola98765 c89cd54429 implemented multi level saving and loading. they use new long[] system instead of long[][][] 2021-09-19 23:16:03 +02:00
cola98765 ca940d5a36 reworked mergeMultiData to take in long[] instead of long[][] 2021-09-19 22:59:15 +02:00
Leonardo 2241492bc5 there is a thunderstorm i don't want to loose progress 2021-09-19 22:08:30 +02:00
Leonardo 7b807bcea2 small changes 2021-09-19 21:32:13 +02:00
Leonardo ebe2c22a28 Changed how the VerticalLevelContainer contains the data 2021-09-19 20:48:07 +02:00
cola98765 cffb17aeb1 reversed grass brightness boost as it's better that way at 4+ view distance 2021-09-19 16:35:47 +02:00
cola98765 c67a5a5e29 removed commented and now unused code 2021-09-19 16:25:53 +02:00
cola98765 1d687fd1d4 new mergeMultiData. Now actually working 2021-09-19 14:44:55 +02:00
cola98765 783d4086c6 some fixes to new mergeMultiData 2021-09-19 14:40:06 +02:00
cola98765 d5243b7d16 some fixes to new mergeMultiData 2021-09-19 14:18:42 +02:00
cola98765 43f3854068 some fixes to new mergeMultiData 2021-09-19 11:41:29 +02:00
cola98765 0025f43a2e Merge branch '1.16.5' of https://gitlab.com/jeseibel/minecraft-lod-mod into vertical_merging
 Conflicts:
	src/main/java/com/seibel/lod/util/ThreadMapUtil.java
2021-09-19 10:36:33 +02:00
James Seibel 07d792979c downgrade to frogeGradle 3.+ from 5.1.+
mixins weren't compiling correctly on the newer version
2021-09-18 23:34:15 -05:00
James Seibel a939d29357 hopefully prevent a index out of bounds exception 2021-09-18 17:44:52 -05:00
James Seibel ba1d096a48 Add error catching / logging 2021-09-18 17:44:37 -05:00
James Seibel 1c9c72cfe3 Clean up a lot of warnings related to: type casting, unused variables, and unused imports 2021-09-18 17:06:41 -05:00
James Seibel aa95361866 Refactor LodDimension and change some error reporting in PosToRenderContainer 2021-09-18 16:58:23 -05:00
James Seibel ff5139d403 Remove debug code and fix a potential OpenGL error 2021-09-18 14:52:14 -05:00
James Seibel 16fc4914fb Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-09-18 14:13:05 -05:00
James Seibel c110524c11 fix vanillaRenderedChunks having index out of bounds exceptions 2021-09-18 14:12:54 -05:00
James Seibel 400b263059 Try to fix GlProxy.setGlContext failing in the BufferBuilder 2021-09-18 14:12:33 -05:00
Leonardo dadda4bdc9 Disabled the culling until it's fixed 2021-09-18 17:32:34 +02:00
Leonardo 1888ac7adc Fixed the culling coordinate 2021-09-18 17:09:13 +02:00
James Seibel 5c59ba7a80 Prevent a error related to loading textures on a null clientWorld 2021-09-18 09:39:53 -05:00
James Seibel f3dd99e792 Improve error message in GlProxy 2021-09-18 09:38:51 -05:00
Leonardo 103ec128ac small fix 2021-09-18 14:46:18 +02:00
Leonardo b4226ec9ec small fix 2021-09-18 14:46:06 +02:00
Leonardo 7c28dd70d3 Fixed the culling 2021-09-18 13:58:19 +02:00
Leonardo d8c9a41314 fixed face culling 2021-09-18 10:09:35 +02:00
Leonardo 5a7f77479f Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-09-18 10:09:14 +02:00
James Seibel d200a5ac24 Add the ability to disable direction based culling
This is a band aid fix for #68, hopefully a better solution can be found in the future.
2021-09-17 23:33:21 -05:00
James Seibel 5099f85da6 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into
1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/render/LodRenderer.java
2021-09-17 23:11:28 -05:00
James Seibel 6e150fe378 Update to ForgeGradlew from 3.+ to 5.1.+ 2021-09-17 22:58:09 -05:00
James Seibel fd67d1ac66 Change setupProjectionMatrix to be mc version agnostic
Now the LOD projection matrix's zoom, transformation, distortion, etc. are all gotten dynamically from Minecraft's projection matrix.
Hopefully this should prevent camera mods from breaking the mod.
2021-09-17 22:57:20 -05:00
cola98765 7161bd52de reworked mergeVerticalData... not actually working 2021-09-18 00:09:22 +02:00
Leonardo 82cf25c341 fixed colors 2021-09-17 23:37:16 +02:00
Leonardo 68d279807f small fix to the vertex order 2021-09-17 22:50:48 +02:00
Leonardo 3530158def Added new culling system 2021-09-17 22:37:33 +02:00
Leonardo 62223480e2 Fixed nether roof 2021-09-17 16:58:59 +02:00
Leonardo 50ab424497 added regen for the lightmap 2021-09-17 15:57:01 +02:00
Leonardo 900467cef2 System uses lightmap now 2021-09-17 13:02:05 +02:00
cola98765 fa1d950ff9 grass is actually using texture now 2021-09-17 12:55:14 +02:00
Leonardo 83571951be Added the ability to get the top texture 2021-09-17 12:29:57 +02:00
Leonardo c31b1f4039 added the ability to avoid not full block or small block 2021-09-17 11:14:23 +02:00
James Seibel 8fcd428194 improve error handling and error messages related to contexts 2021-09-16 20:32:32 -05:00
James Seibel 87c275f768 Add improved error reporting and commenting 2021-09-16 20:32:03 -05:00
James Seibel 8df6e972cb Fix a out of memory error when changing worlds 2021-09-16 20:28:07 -05:00
James Seibel d7d88d61ee Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into
1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/wrappers/MinecraftWrapper.java
2021-09-16 19:05:05 -05:00
James Seibel 9b1c0a1125 Add the ability to access the lightmap from the MinecraftWrapper 2021-09-16 19:03:43 -05:00
cola98765 b008b70255 colors are better than it were... again 2021-09-17 00:05:29 +02:00
cola98765 b6c350f667 colors are better than it were 2021-09-16 22:21:04 +02:00
Leonardo e23bbfcd91 small changes 2021-09-16 18:53:26 +02:00
cola98765 6bc14fbb2d brightness fix with real block colors TODO foliage 2021-09-16 18:12:22 +02:00
Leonardo d911017112 new color for grass, leaf and water 2021-09-16 17:11:08 +02:00
Leonardo fc4546538f Reintroduced manual color for nether blocks 2021-09-16 16:17:38 +02:00
Leonardo a90b3e9d37 Merge remote-tracking branch 'origin/1.16.5_new_file_handling' into 1.16.5 2021-09-16 16:15:29 +02:00
Leonardo b2aca27615 Added texture mean in lod builder 2021-09-16 15:44:28 +02:00
cola98765 6bf9e187e0 this breaks old file version system by simply ignoring the old files. 2021-09-16 11:41:53 +02:00
James Seibel b5f32705e8 remove commented out code 2021-09-15 23:12:10 -05:00
James Seibel 8bc72af63f Improve rendering performance and improve buffer building stability
Specifically improve the rendering speed so we can get over 100 fps again.
2021-09-15 22:01:52 -05:00
Leonardo 0e4cf8e882 added a TODO in data util 2021-09-15 17:02:44 +02:00
Leonardo 5ede5fa202 Added fake lighting system. Improved some point 2021-09-15 16:17:26 +02:00
Leonardo cdeba2616c Re-Introduced HEIGHMAP mode correctly.
Added single get and add to the LevelContainer to avoid using temp arrays
2021-09-15 13:23:41 +02:00
Leonardo 6dc94b0cc2 Introduced lodQualityMode in config to change from 3d to 2d 2021-09-15 10:42:09 +02:00
James Seibel 7f9c7d8722 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into
1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/builders/LodBufferBuilder.java
2021-09-14 23:46:01 -05:00
James Seibel aebbeb6ade Simplify the multi-context uploading, improve stability, and refactor 2021-09-14 22:49:08 -05:00
James Seibel a945eb4579 Fully add multi-context uploading 2021-09-14 21:27:36 -05:00
Leonardo f9cf27a2c7 Changed the dataPoint, started the introduction of the lightmap use 2021-09-14 23:21:48 +02:00
Leonardo e03e09a243 Fixed various bugs and introduced more maps in the ThreadMapUtil 2021-09-14 19:02:37 +02:00
Leonardo fe02813d17 Disabled a section in the getNearbyLodChunkPosToSkip 2021-09-14 13:45:08 +02:00
Leonardo 145479267d Fixed Nether color 2021-09-14 13:15:36 +02:00
Leonardo 77ccd9eec3 changed how the valid block is determined, and added a mask and a shift for future use 2021-09-14 12:58:09 +02:00
Leonardo 9b216fedad Vertical lod now works (optimization required) 2021-09-14 01:05:41 +02:00
Leonardo e9798ace13 kinda working version 2021-09-13 23:23:55 +02:00
Leonardo 75e78d9000 First vertical data working 2021-09-13 17:34:37 +02:00
Leonardo 34776074fd added the vertical merge 2021-09-13 13:16:52 +02:00
James Seibel 8822e2d8a1 partially add different context rendering 2021-09-12 23:14:43 -05:00
Leonardo 32de70b4f0 Removed the normals 2021-09-13 01:48:11 +02:00
Leonardo 76a7baeb32 Saving works again 2021-09-13 01:47:04 +02:00
Leonardo 95d9c17e49 Added new colors for the torches 2021-09-13 01:19:39 +02:00
Leonardo a6544d3bb6 Introduced light and added normal in the template for future shading improvement 2021-09-13 00:37:23 +02:00
Leonardo c3115caa8f Re-organized the LodBuilder code 2021-09-12 16:29:41 +02:00
Leonardo 4e1e5b24ee Changed the lodBuilder to use a single function 2021-09-11 20:05:11 +02:00
Leonardo 7b73445f4d Changed the lodBuilder to use a single function 2021-09-11 19:59:30 +02:00
Leonardo 5f1f5f0948 Fixed some smalls bugs 2021-09-11 16:29:20 +02:00
Leonardo bdcc4c7755 Introduced map util and now the Loading does not create new String object. 2021-09-11 15:56:46 +02:00
Leonardo 1395e32a50 introduced the mergeSingleData function 2021-09-11 13:49:51 +02:00
Leonardo 99f7d70613 disabled the class until it's ready 2021-09-10 18:22:13 +02:00
Leonardo 59bfd739f4 Added max detail at FULL 2021-09-10 18:21:46 +02:00
Leonardo 3f1cf6c305 Added some new temporal data storing 2021-09-10 18:21:09 +02:00
Leonardo 5c05df0361 changed the thread names 2021-09-10 18:20:33 +02:00
Leonardo feebc3564a Created the single level container 2021-09-10 16:42:21 +02:00
Leonardo a9aa630aff Started convertion for vertical data 2021-09-10 15:47:43 +02:00
James Seibel 6ec146ba60 re-add depreciation warning suppressions 2021-09-09 19:06:09 -05:00
Leonardo 21140593e2 Started convertion for vertical data 2021-09-10 01:05:12 +02:00
Leonardo 878714dae3 Fixed the lod not showing at screen corner bug 2021-09-09 15:51:14 +02:00
Leonardo e876d7bec6 Fixed the lod not showing at screen corner bug 2021-09-09 14:43:04 +02:00
Leonardo 4f06395557 Fixed glass color 2021-09-09 14:36:05 +02:00
Leonardo aa3dbe8f32 Fixed the allocation of long[] 2021-09-09 14:10:45 +02:00
James Seibel b1bcdb24f0 comment out the config override for release a1.4.1 2021-09-08 18:30:37 -05:00
James Seibel cbd7f4300e Improve logging wording 2021-09-08 18:17:36 -05:00
James Seibel 4d8e30121e fix a spelling mistake 2021-09-08 18:17:17 -05:00
James Seibel fbe39542fc update the version number to a1.4.1 2021-09-08 18:13:25 -05:00
James Seibel 6a1f448b41 comment out testing code 2021-09-08 18:13:06 -05:00
James Seibel e13b23832c Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-09-08 18:09:15 -05:00
James Seibel 4c9e0edf32 Add barrier blocks to the list of blocks to ignore 2021-09-08 18:08:59 -05:00
Leonardo 8664a06d3b fixed a small bug that was causing visual artifacts 2021-09-08 19:38:17 +02:00
James Seibel 18b8359f0d rename the wrapper package to wrappers 2021-09-07 21:12:58 -05:00
James Seibel 7de4c7c72a Make the reflection handler a singleton 2021-09-07 21:12:16 -05:00
James Seibel b4bbabae42 enable debugging settings in ClientProxy 2021-09-07 19:52:27 -05:00
James Seibel 40321d6e21 Remove unused variables, imports, etc. 2021-09-07 19:52:06 -05:00
James Seibel cf1702bd0c Fix file reading/writing not working, Closes #61 2021-09-07 19:38:41 -05:00
James Seibel a9b50cdb32 remove invalid imports / organize imports 2021-09-07 19:10:30 -05:00
James Seibel 7eed472029 Fix stuttering caused by a merge 2021-09-07 19:09:50 -05:00
James Seibel 0262e452c7 Improve FileHandler info message 2021-09-07 19:04:48 -05:00
James Seibel 30287d5a7d Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-09-07 18:54:41 -05:00
James Seibel 83346fed1f Improve the error messages in the LodDimensionFileHandler 2021-09-07 18:54:24 -05:00
Leonardo e897c3edba fixed generation 2021-09-08 00:51:39 +02:00
Leonardo bd9e2acaf6 Changed the default heigth and depth and small fix to the culling 2021-09-08 00:23:44 +02:00
Leonardo 1e15d372c4 Added box caching 2021-09-07 21:22:12 +02:00
Leonardo 849d563425 Added box to replace AxisAlignedBB 2021-09-07 20:07:39 +02:00
Leonardo aa5a8aa3b8 small change 2021-09-07 19:05:58 +02:00
Leonardo b096cc53aa Working version 2021-09-07 19:02:51 +02:00
Leonardo 94d994e761 re-added the commit 2021-09-07 18:52:58 +02:00
Leonardo f76fa17e25 Removed level pos and data arrays 2021-09-07 17:23:22 +02:00
James Seibel 53a66268cb Close issue #37 (z-fighting far from the origin)
I'm not certain why in LodRenderer swapBuffers has to be called after the frame has been rendered, but otherwise it causes stuttering / rubber banding.
2021-09-06 22:51:46 -05:00
James Seibel 139867d4b8 auto-indent 2021-09-06 12:17:49 -05:00
James Seibel 81cf05ba19 fix a issue where nothing renders in the compiled version 2021-09-06 11:55:44 -05:00
James Seibel 13a1e7ed56 Add the MinecraftWrapper 2021-09-06 11:20:32 -05:00
James Seibel 42bd0fbde9 Delete 1.4 release notes.txt 2021-09-05 17:25:46 -05:00
James Seibel ebe2bd97bc Remove the compiled jars (they are now handled by CurseForge) 2021-09-05 16:51:26 -05:00
James Seibel a3ac3386d0 Update 1.4 release notes.txt 2021-09-05 16:50:42 -05:00
Leonardo 69ba83d34f small change to far Fog 2021-09-05 16:15:14 +02:00
James Seibel e048d277f8 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-09-04 11:01:26 -05:00
James Seibel 0bca47a92b Update pack.mcmeta
I don't even know if we need this file
2021-09-04 11:01:05 -05:00
James Seibel ce84b30ddb Change a println to use the logger 2021-09-04 11:00:54 -05:00
Leonardo 1843f96526 various fix to the new classes 2021-09-04 12:48:22 +02:00
Leonardo e46864431b Fixing the new classes 2021-09-03 23:33:54 +02:00
Leonardo 152a3fa108 Optimized the generation memory use 2021-09-03 22:35:08 +02:00
Leonardo 3420133bd3 Added LevelPosUtil, PosToGenerateContainer and PosToRenderContainer to be used in the future 2021-09-03 19:34:04 +02:00
Leonardo c79bf7c3f7 Fixed chunk data generation during first world loading 2021-09-03 13:10:16 +02:00
James Seibel 2219da4050 revert the fog changes 2021-09-01 21:47:31 -05:00
James Seibel a1aa90cccb Split up the configs to make it easier to understand 2021-09-01 21:39:02 -05:00
Leonardo d19abaef7b small fix to a bug that was causing crash if the player went over y 256 2021-09-01 18:20:51 +02:00
Leonardo 77625c65c7 small fix 2021-09-01 18:11:25 +02:00
Leonardo 91ba48ad4a Max draw detail now works correctly and node bigger than a chunk do not disappear if you touch a border 2021-09-01 18:11:01 +02:00
Leonardo 32e587d536 Small fix to the index of vanillaRenderedChunks 2021-09-01 17:27:37 +02:00
Leonardo e3dfe658f5 Fixed chunkPos being created multiple time in the buffer 2021-09-01 17:20:52 +02:00
Leonardo 4e249e943a Revert "Added LevelPosUtil, now the node are added using it and not with the LevelPos object"
LevelPos are useful and the small stutter in the buffer builder is probably caused by the creation of ChunkPos
2021-09-01 16:33:34 +02:00
Leonardo 1360edb459 Added LevelPosUtil, now the node are added using it and not with the LevelPos object 2021-09-01 15:15:23 +02:00
James Seibel 4c7ca395c6 Add the buffer rebuild timeouts to ClientProxy.applyConfigOverrides() 2021-08-31 21:14:19 -05:00
James Seibel a1c720d588 Fix a issue where the projection matrix was given a depth of 0
This caused the depth buffer to stop working.
2021-08-31 21:05:53 -05:00
James Seibel 7b09840d02 Organize inputs 2021-08-31 19:26:17 -05:00
Leonardo e65579f346 temporary fix to the missing region bug 2021-08-31 18:08:02 +02:00
Leonardo 78d6481a49 Another small fix 2021-08-31 12:55:42 +02:00
Leonardo 1428e72d46 small fix to the generation 2021-08-31 11:47:18 +02:00
James Seibel 2c2c6d6785 Add configs for buffer building timeouts and small refactors 2021-08-30 23:16:27 -05:00
Leonardo d5d48f2448 now the vanillaRenderedChunk is reset if the player goes to high 2021-08-30 23:41:56 +02:00
Leonardo 536de1a22d fixed a small error with the timer 2021-08-30 23:25:37 +02:00
Leonardo 193c579712 changed the generation. Added re-use of levelPos 2021-08-30 23:03:22 +02:00
Leonardo cdba7b20f5 Buffer that does not change won't be rebuilt 2021-08-30 17:55:34 +02:00
Leonardo 5467d007b8 preparing the mod for future buffer caching 2021-08-30 12:36:07 +02:00
Leonardo b24d691d8a Removed a useless temp Object in the getNodeToRender 2021-08-30 10:36:15 +02:00
James Seibel f68e6a9a13 Add a config option to disable the F4 keybinding 2021-08-29 21:23:16 -05:00
James Seibel 2dcdc854e3 Improve stone color 2021-08-29 21:09:30 -05:00
James Seibel 42da213ea9 Update the mod meta info 2021-08-29 16:35:59 -05:00
James Seibel dfea2f561a Replace the old logo files with the new logo files 2021-08-29 14:32:19 -05:00
James Seibel d8b4730ee0 Remove a unneeded depreciation suppression warning 2021-08-29 14:20:18 -05:00
Leonardo 74cbf794a1 the culling in templace can be disabled using the disableCulling boolean 2021-08-29 18:22:41 +02:00
Leonardo 812fa65054 divided the time checker for the regen 2021-08-29 17:18:21 +02:00
Leonardo ba63b44288 small change 2021-08-29 16:44:36 +02:00
Leonardo b19a80f411 Optimized the regen 2021-08-29 16:42:44 +02:00
Leonardo 450f15ad36 Finally fixed the regen problem 2021-08-29 10:56:14 +02:00
James Seibel a6ed4968f5 Add a config option for the number of buffer builder threads 2021-08-28 23:38:51 -05:00
James Seibel 65dc629771 Remove a unsettable configOverride 2021-08-28 23:38:16 -05:00
James Seibel 80aa49e28b Update 1.4 release notes.txt 2021-08-28 23:37:34 -05:00
James Seibel 2c3149ef30 Fix a potential issue with compiling to the wrong Java version 2021-08-28 17:15:38 -05:00
James Seibel cd792d7045 Fix a potential crash where Setupbuffers isn't called fast enough for the BufferBuilder 2021-08-28 17:13:17 -05:00
Leonardo 3ade43651f small Optimization to the buffer 2021-08-28 20:55:18 +02:00
Leonardo f4c3ad8bb5 Fixed the garbage collector being called too much 2021-08-28 20:32:58 +02:00
James Seibel 13d2c7b421 Create the comment for issue #62 2021-08-28 12:10:19 -05:00
James Seibel c54c2c6612 Remove the unused parameter in getBufferMemoryForSingleLod() 2021-08-28 11:55:48 -05:00
James Seibel 13878b7387 auto-format 2021-08-28 11:27:20 -05:00
James Seibel 2f20fc6b77 Update the default config options 2021-08-28 11:18:19 -05:00
James Seibel d4ada067c5 auto-indent 2021-08-28 11:05:33 -05:00
James Seibel 9277b3ad38 Add different debug modes (off, detail, detail_wireframe) 2021-08-28 11:04:59 -05:00
James Seibel c48d409015 remove the unused enum LodQuality 2021-08-28 10:18:23 -05:00
James Seibel ccdebb4242 auto-indent 2021-08-28 10:18:05 -05:00
James Seibel 18c94cea46 Update known issues 2021-08-28 10:09:32 -05:00
James Seibel fe381fc207 Rearrange ClientProxy and fix a potential saving issues 2021-08-28 10:07:20 -05:00
James Seibel acc73af666 Remove some debugging 2021-08-28 10:00:11 -05:00
Leonardo 685284f131 removed some e.printStack for the release 2021-08-28 13:40:39 +02:00
Leonardo f803bd58af fixed server not overriding lower quality 2021-08-28 13:21:50 +02:00
Leonardo 26fbdfc92c fixed memory use method and put F4 as debug key 2021-08-28 12:41:54 +02:00
Leonardo e3e8ef705a geneartionType is no longer used in LodRegion. Every region has a generationMode (+ server) 2021-08-28 12:22:09 +02:00
Leonardo e1a425dbcc fixed a small generation errore,
Now cut and gen tree are automatic
2021-08-28 11:15:34 +02:00
Leonardo d8bd4e2347 Fixed a small loading bug,
made the getDataToGenerate fully automatic, added an option to update the DetailDistanceUtil values
2021-08-28 10:38:44 +02:00
James Seibel 49cdd5702f Add 1.4 release notes
This also includes bugs that need to be fixed before 1.4 can be released
2021-08-27 21:25:26 -05:00
James Seibel 32c19eab7f move a comment 2021-08-27 20:59:41 -05:00
James Seibel a32b66aaab organize imports 2021-08-27 18:05:27 -05:00
James Seibel 425f4948dc Remove unneeded imports and a unneeded cast 2021-08-27 18:05:02 -05:00
James Seibel d05908af32 Auto-formatting 2021-08-27 18:04:50 -05:00
Leonardo 822a088096 fixed loading 2021-08-28 00:36:45 +02:00
Leonardo 36079e1624 fix to the Rendering holes 2021-08-28 00:16:44 +02:00
Leonardo 8db782a406 Now nodeToRender is fully automatic 2021-08-27 23:05:37 +02:00
Leonardo dd018f90d3 Small change 2021-08-27 18:47:42 +02:00
Leonardo af4e30588f new z fix 2021-08-27 18:27:37 +02:00
Leonardo 2630d50147 temporary z fix 2021-08-27 17:43:17 +02:00
Leonardo db2410e7fe changed indent 2021-08-27 14:34:43 +02:00
Leonardo 9990132db2 small changes 2021-08-27 14:31:13 +02:00
Leonardo 21069d6479 Optimization to getLodToRender 2021-08-27 12:02:02 +02:00
Leonardo b27afbb18c Optimized the getDataToGenerate 2021-08-27 11:34:55 +02:00
Leonardo 783c0c97a1 Preparing the BufferBuilder for new system 2021-08-27 11:28:29 +02:00
Leonardo 3dfa2d778a Fixed end bug 2021-08-27 10:59:24 +02:00
James Seibel b44a641d96 Add a TODO 2021-08-26 22:59:55 -05:00
James Seibel 8139b83a01 Fix heights saving higher then they are 2021-08-26 21:01:59 -05:00
James Seibel 456ba183da Fix updating regions where LODs contain no blocks 2021-08-26 20:28:48 -05:00
James Seibel 7525c1b257 Fix the "ffffff" error when reading files 2021-08-26 19:37:38 -05:00
James Seibel 5d4d634537 Re-add the Number Of World Generation Threads config option 2021-08-26 19:31:33 -05:00
James Seibel e1149be7c1 add a missing closing comment "/" 2021-08-26 18:14:49 -05:00
Leonardo fc0aaac69f added better shading + small changes 2021-08-27 00:54:46 +02:00
Leonardo 9786a12273 Fixed a small bug with getDataToGenerate 2021-08-26 23:34:14 +02:00
Leonardo c169cb6b7f Changed how color are calculated 2021-08-26 23:02:32 +02:00
Leonardo afcdce4667 Small fix to LevelPos 2021-08-26 20:17:00 +02:00
Leonardo ab7ed9a4c5 Optimized getDataToGenerate 2021-08-26 20:13:32 +02:00
Leonardo 120e8e5f6d small fixes and changed settings 2021-08-26 19:33:59 +02:00
Leonardo 65824a6fed fixed fog 2021-08-26 19:33:32 +02:00
Leonardo 114aaf9fe4 Update doesn't use temp object anymore 2021-08-26 19:33:15 +02:00
Leonardo 347b149037 The generation is working now 2021-08-26 17:41:01 +02:00
Leonardo 70317a37cb fixed LevelPos and colors 2021-08-26 14:28:27 +02:00
Leonardo 74e4744ff7 Correctly removed LodDataPoint and optimized the LevelPos use 2021-08-26 13:18:18 +02:00
Leonardo 98cbc30709 Small changes to how number of thread is chosen and returned to old LINEAR system 2021-08-25 16:12:18 +02:00
Leonardo b44900e3f0 Added new render/generation distance calculator 2021-08-25 13:44:53 +02:00
Leonardo 1755a252b1 Fixed how request works 2021-08-25 13:13:48 +02:00
Leonardo afcedd0c6d Improved how LINEAR is determined 2021-08-25 13:13:27 +02:00
Leonardo 525005bcb6 small changes to how the node to render are chosen 2021-08-25 12:26:16 +02:00
Leonardo 360294d37c fixed the generation Request 2021-08-25 12:24:59 +02:00
Leonardo ea05e3f9e6 fixed the cull 2021-08-25 12:24:01 +02:00
Leonardo 70a75f0543 added an offset to the cull 2021-08-25 11:09:49 +02:00
Leonardo 488d520b8f Improved the template, shared faces are not rendered 2021-08-25 10:55:05 +02:00
Leonardo 30bb175ea0 small changes 2021-08-25 08:17:39 +02:00
Leonardo 500a68e0fc Merge remote-tracking branch 'origin/1.16.5' into 1.16.5
# Conflicts:
#	src/main/java/com/seibel/lod/builders/LodBufferBuilder.java
#	src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java
#	src/main/java/com/seibel/lod/proxy/ClientProxy.java
2021-08-25 07:59:57 +02:00
James Seibel 0cd9bfaef2 Put all LOD save files in the same folder 2021-08-24 21:48:09 -05:00
James Seibel a464176a25 Close #32 (make distance generation independent of the buffer builder) 2021-08-24 21:47:51 -05:00
James Seibel a0dcde48ae Remove unneeded TODOs and unused code 2021-08-24 18:31:42 -05:00
Leonardo 8ae81d3aac added some debugging comments 2021-08-24 23:11:14 +02:00
Leonardo c4f864f0e3 changed how the distance generation mode is determined and added
zFix boolean in node to render to disable the zFighting fix
2021-08-24 23:10:29 +02:00
Leonardo cddd239fc5 Introduced try and catch were needed and fixed some small bugs 2021-08-24 14:58:22 +02:00
Leonardo 189b0ec878 Now the system work stable with SINGLE 2021-08-24 02:35:25 +02:00
Leonardo bd305a0269 small fixes to tree generator new tree cutter 2021-08-24 01:54:01 +02:00
Leonardo bbf99ed145 fixed tree generator new tree cutter 2021-08-24 00:33:46 +02:00
Leonardo cac4807986 Added tree generator and new tree cutter 2021-08-23 23:44:55 +02:00
Leonardo 181539b83b small fixes 2021-08-23 16:05:21 +02:00
Leonardo 4795ddd1ff Fixed circle generation bug 2021-08-23 15:33:51 +02:00
Leonardo c1c6680d04 small changes 2021-08-23 14:20:09 +02:00
Leonardo 81cbc7a12b added the big update function 2021-08-23 12:36:32 +02:00
Leonardo 4c6185556f Small fixes 2021-08-23 12:10:55 +02:00
Leonardo b0ed460230 small fix to the tree cutter 2021-08-23 11:45:15 +02:00
Leonardo 38e323a12f small fix to the tree cutter 2021-08-23 11:24:06 +02:00
Leonardo 9840c594e6 Added the tree cutter 2021-08-23 11:12:23 +02:00
James Seibel fdd8204a46 Add multi-threaded buffer building 2021-08-22 22:54:16 -05:00
James Seibel fb188e4819 auto indentation 2021-08-22 18:46:47 -05:00
James Seibel 9b3d9cbba3 javadoc formatting 2021-08-22 18:46:22 -05:00
James Seibel a2aa1dd081 add a lock to the buffer builder when the buffers are being used
Hopefully this should prevent some crashes and errors when generating buffers
2021-08-22 18:42:27 -05:00
James Seibel cb889d7430 auto formatting 2021-08-22 18:26:59 -05:00
James Seibel 2a88b2e746 Remove a unused method 2021-08-22 18:25:58 -05:00
James Seibel 93dd441708 Close #60 (LODs rendering on top of the player) and improve get Lod pos to skip 2021-08-22 18:24:41 -05:00
James Seibel a81ce6c28a auto reformat 2021-08-22 17:55:24 -05:00
James Seibel 967627c57e Move getRenderedChunks to LodUtil 2021-08-22 17:54:10 -05:00
Leonardo 31cb684bec Added different generation detail option 2021-08-22 19:54:10 +02:00
Leonardo d5112be385 small fixes 2021-08-22 19:18:14 +02:00
Leonardo 547d54aab1 Fixed the near clipping 2021-08-22 16:54:09 +02:00
Leonardo 397573bc08 removed lodChunkRadiusMultiplier from proxy, config and renderer 2021-08-22 16:46:55 +02:00
Leonardo b52d7e4f20 small fix to the Near fog 2021-08-22 16:33:20 +02:00
Leonardo a450f44aa7 small fix to the fog 2021-08-22 16:20:27 +02:00
Leonardo a4e8e9ef60 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5
# Conflicts:
#	src/main/java/com/seibel/lod/proxy/ClientProxy.java
2021-08-22 16:09:07 +02:00
Leonardo 3c28ed5601 small fix to fog 2021-08-22 16:06:30 +02:00
James Seibel c5ec41eb2d Add buffer recreation when changing worlds 2021-08-22 08:42:55 -05:00
Leonardo d1bb96c2dc small fix 2021-08-22 14:46:16 +02:00
James Seibel d72ba5bb82 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-22 07:40:09 -05:00
James Seibel baba54bdb8 Add error reporting and handling when unable to access the save folder 2021-08-22 07:40:00 -05:00
Leonardo aa7ea85cde New config 2021-08-22 14:34:02 +02:00
Leonardo a1f01bef78 Fixed game chunk not overriding lod chunk 2021-08-22 11:51:26 +02:00
Leonardo 1a7655e752 Added DetailUtil and it's use in the buffer builder +
small fixes
2021-08-22 11:27:40 +02:00
James Seibel e2a983e4ac comment grammar change 2021-08-21 21:54:40 -05:00
James Seibel e2f0263643 Remove synchronized from getters 2021-08-21 21:54:23 -05:00
James Seibel b280303f8f Improve vine colors 2021-08-21 20:06:22 -05:00
James Seibel ff3b2aee6b Add error catching and improve the None distance generation mode 2021-08-21 20:02:30 -05:00
James Seibel 804f830a10 fix third person backwards culling the wrong regions 2021-08-21 19:57:03 -05:00
James Seibel 68b5978135 Change the color of Mycelium to better match its block color 2021-08-21 19:45:43 -05:00
James Seibel 9ebb84bf9c Make air and Cave air act the same when generating LODs 2021-08-21 19:25:31 -05:00
James Seibel a08e08856a Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into
1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/builders/LodBufferBuilder.java
2021-08-21 18:57:39 -05:00
James Seibel 8d5c8bf7b8 Finish adding simple frustum culling 2021-08-21 18:54:20 -05:00
Leonardo 168eb537cb Improved generation 2021-08-21 22:21:41 +02:00
James Seibel ca57c15d46 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into
1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/builders/LodBufferBuilder.java
2021-08-21 15:19:04 -05:00
James Seibel 5aea9877e0 re-organize RenderUtil 2021-08-21 15:11:13 -05:00
Leonardo c20ec4ef59 added commented use of biomeUtils and terrainUtils 2021-08-21 22:01:52 +02:00
James Seibel 32fb349621 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-21 13:05:35 -05:00
James Seibel c5b4e20787 Add simple partially functioning frustum culling 2021-08-21 13:05:32 -05:00
James Seibel a246dd7561 improve a few comments 2021-08-21 13:02:21 -05:00
James Seibel 615e29451a add conversions to chunk and block pos 2021-08-21 13:01:39 -05:00
James Seibel bcac2bd7ba Update a few comments 2021-08-21 13:01:24 -05:00
Leonardo a02c232f5f improved getDataToGenerate and changed how it's used in the buffer builder 2021-08-21 17:28:11 +02:00
James Seibel d27dbbb64e Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into
1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/builders/LodBufferBuilder.java
2021-08-21 10:06:44 -05:00
James Seibel fdfbee108a minor client proxy debug setting changes/commenting 2021-08-21 09:57:14 -05:00
James Seibel de54c37cf1 Optimize Buffer Builder chunk generator queuing 2021-08-21 09:55:04 -05:00
Leonardo d4580806d1 minor fixes, fixed z fighting 2021-08-21 16:25:09 +02:00
James Seibel 5a856c65fa Update the debug colors to work up to region size 2021-08-21 08:03:35 -05:00
James Seibel 75d6da98dc Remove invalid imports (again) 2021-08-21 07:36:49 -05:00
Leonardo 7654cac01d minor fixes 2021-08-21 14:33:11 +02:00
James Seibel cbe242cd2f Remove invalid import 2021-08-21 07:23:55 -05:00
Leonardo 7f69b11ae4 minor fixes 2021-08-21 12:43:38 +02:00
Leonardo 426c9edb05 new generation system fixed 2021-08-21 12:25:49 +02:00
James Seibel 88fb9b5b21 Add debug code to the LodNodeGenWorker 2021-08-20 21:32:57 -05:00
James Seibel 163f8ca979 Remove Node from the names of LodRenderer, BufferBuilder, LodTemplates, and LodBuilder 2021-08-20 20:28:37 -05:00
James Seibel ee416a10ec Add null checking to the BufferBuilder 2021-08-20 20:24:33 -05:00
James Seibel c5ef03aa0e Add null checks and minor formatting changes 2021-08-20 20:19:46 -05:00
James Seibel 25cb08f541 Eclipse auto-formating 2021-08-20 20:19:05 -05:00
Leonardo fcd06bde87 fixed getDataToGenerate use in buffer builder,
Fixed buffers indexing
2021-08-21 02:57:57 +02:00
Leonardo 00f50a2e60 Added getNodeToGenerate to the buffer builder 2021-08-20 19:46:46 +02:00
Leonardo 550c0f1bf2 Added getDataToRender to the bufferBuilder 2021-08-20 19:02:11 +02:00
Leonardo 0f0179bd19 Various fix 2021-08-20 17:06:41 +02:00
Leonardo 7885d14a91 getDataToRender and getDataToGenerate added to dimension 2021-08-20 16:35:38 +02:00
Leonardo bd9c3bba3f added getDataTeRender 2021-08-20 16:07:27 +02:00
Leonardo 04f8cd653a getDataToGenerate should work correctly 2021-08-20 15:03:28 +02:00
James Seibel 02bfc20ae6 Fix small mushrooms using the grass color 2021-08-20 07:34:14 -05:00
James Seibel d65017366a comment out the buffer building time console printing 2021-08-20 07:25:52 -05:00
James Seibel 05d17ba9fa Close #57 (Add support for night vision) 2021-08-20 07:25:22 -05:00
Leonardo 967aab3b3b new line brackets 2021-08-20 11:46:41 +02:00
Leonardo 9f77bf4e61 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-08-20 11:32:21 +02:00
James Seibel 6aa096de57 Remove an incorrect import 2021-08-19 19:41:56 -05:00
Leonardo d312d60cd9 Fixed loading not working, started the creation of dataToGenerate and dataToRender 2021-08-20 00:50:08 +02:00
Leonardo 65fde550cb Small fix to the position 2021-08-19 15:49:36 +02:00
Leonardo 736b5ba625 new enum for render distance and quality of lods 2021-08-19 12:47:54 +02:00
Leonardo b2227688bc Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-08-19 11:31:40 +02:00
Leonardo cbe8b647b1 New fast save system 2021-08-19 11:31:26 +02:00
James Seibel 0b0f0eab2f Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-18 17:37:38 -05:00
James Seibel ffb63ce8ef Move the setupBuffers method to the ClientProxy 2021-08-18 17:37:23 -05:00
Leonardo 0e6f5d9805 Changed the save system
Now lod render distance and quality are not dependent on game render distance
2021-08-18 23:54:13 +02:00
Leonardo a0bd9648dc Conversion to new quad tree LodRegion 2021-08-18 19:46:56 +02:00
James Seibel aa1778cf82 Remove the direct memory Buffer limit
Now the LOD multiplier won't be lowered when the detail is increased.
2021-08-17 22:44:50 -05:00
Leonardo 10d66a4775 LodRegion now works (might still have bugs) 2021-08-16 23:03:21 +02:00
Leonardo 4082c97e0e LodRegion update (not yet complete) 2021-08-16 18:45:42 +02:00
Leonardo 665f979e82 LodRegion update (not yet complete) 2021-08-16 14:23:26 +02:00
Leonardo 911205ce0a Create the new LodRegion class that will replace the quadTrees 2021-08-16 12:24:49 +02:00
James Seibel 51078fde5b Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-15 19:39:55 -05:00
James Seibel adde7e8d67 Add a ThreadFactory to name executor threads 2021-08-15 19:38:51 -05:00
Leonardo 582e38eec5 Added the ability to change the save type to bin (slower method at the moment) 2021-08-16 00:05:24 +02:00
James Seibel e987e679d0 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into
1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java
2021-08-15 15:14:43 -05:00
James Seibel 6d776407a4 Optimize the BufferBuilder 2021-08-15 14:52:17 -05:00
Leonardo 8a61a5f0e7 Slightly optimize addLodToBuffer 2021-08-15 16:40:13 +02:00
James Seibel 49a9ff8640 Re-add the render.drawLODs method to clientProxy
Ops.
2021-08-15 08:32:00 -05:00
James Seibel 47ebdb4aee Remove BiomeContainer from BufferBuilder
Having it prevents server use
2021-08-15 08:19:00 -05:00
James Seibel 2b10a9d977 Remove objectSizeCalculator Java Mission Control is much better 2021-08-15 07:50:31 -05:00
James Seibel 247b7d5633 Add toString methods 2021-08-14 21:01:27 -05:00
James Seibel ae9eba0608 Add distanceGenerationMode when generating nodes 2021-08-14 19:56:16 -05:00
James Seibel 7983681b70 Update the config 2021-08-14 18:13:08 -05:00
James Seibel 85d4106f28 Add a try catch to LodQuadTreeDimension 2021-08-14 18:08:47 -05:00
James Seibel 22d329b8aa remove illegal state exception in LodQuadTreeWorld
This fixes an exception being thrown when leaving the world.
2021-08-14 18:02:25 -05:00
James Seibel 004d36ffa7 Remove old commented out code 2021-08-14 18:01:35 -05:00
James Seibel 231340d979 Comment out debug code 2021-08-14 17:38:40 -05:00
James Seibel f55f5b881f Optimize the region distance logic 2021-08-14 17:26:47 -05:00
James Seibel 03ac090e06 Refactor and improve the comments in LodNodeBufferBuilder 2021-08-14 17:26:28 -05:00
James Seibel 3b375e9c1b minor spacing change 2021-08-14 17:22:59 -05:00
James Seibel e44157fae5 Update / Fix RegionPos 2021-08-14 17:22:44 -05:00
James Seibel 997513231c Improve variable naming in LodNodeRenderer 2021-08-14 16:00:12 -05:00
James Seibel 64c3ba297b Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-14 09:34:01 -05:00
James Seibel 3ae9c49de4 Improve file writing logic 2021-08-14 09:33:46 -05:00
Leonardo 5692f9fa69 Added the cutTreeAtLevel method 2021-08-14 15:52:14 +02:00
Leonardo 72ba9f5699 Added the cutTreeAtLevel method 2021-08-14 15:50:44 +02:00
James Seibel 696be6f796 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-14 08:20:09 -05:00
James Seibel 5198335948 Improve LOD saving logic 2021-08-14 08:19:44 -05:00
Leonardo 8102063850 Added the cutTreeAtLevel method 2021-08-14 15:17:03 +02:00
Leonardo 86bf551de8 Lod not saving fix 2021-08-14 15:04:54 +02:00
Leonardo ec2933f23c Fixed generation detail not being used 2021-08-14 14:14:26 +02:00
James Seibel f6daf62c7d Add a Size calculator class 2021-08-13 23:35:41 -05:00
James Seibel 50988db28c Use a lower level biome generation method 2021-08-13 23:34:53 -05:00
James Seibel 047cef184d Update TODO comment 2021-08-13 23:34:23 -05:00
James Seibel ee5b8662d1 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-13 18:01:25 -05:00
James Seibel 9470ee2507 Add KaptainWutax TerrainUtils to build.gradle 2021-08-13 18:00:06 -05:00
James Seibel 8f63e755be Rename saveRegionToDisk to saveRegionToFile 2021-08-13 17:59:33 -05:00
Leonardo b0d62da7fe Remove QuadTreeImage and remove the start, center and end field from the LodNode 2021-08-13 20:25:28 +02:00
James Seibel 7a4347b288 Fix the try catch block in LodNodeGenWorker
Try catch finally blocks need catch to work properly, who knew.
2021-08-12 21:00:35 -05:00
James Seibel bbaa583a6d Fix a config typo 2021-08-12 19:41:09 -05:00
James Seibel c3709f726c Improve how distance based quality is determined 2021-08-11 21:52:16 -05:00
James Seibel d1417069d9 Remove the old LOD objects 2021-08-11 07:33:51 -05:00
James Seibel 412f1bead0 Start removing the old LOD objects 2021-08-11 07:29:51 -05:00
James Seibel 1095f63832 Remove unneeded code in LodDetail 2021-08-10 21:19:14 -05:00
James Seibel 89d0317c7f Add full detail to the LodNodeBufferBuilder 2021-08-10 21:15:34 -05:00
James Seibel 4f489a5272 Change the distance debug colors 2021-08-10 21:14:52 -05:00
James Seibel 8c843ba4b5 Fix the Full detail mode 2021-08-10 21:14:33 -05:00
James Seibel 77401cbfa0 Auto Reformat 2021-08-10 21:14:04 -05:00
James Seibel b983692fc1 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-10 20:49:42 -05:00
James Seibel e1a40c6868 Add a comment to LodNodeBufferBuilder 2021-08-10 20:47:28 -05:00
James Seibel 9c2add4e3b Clean up distance based detail and change debugMode 2021-08-10 20:34:06 -05:00
Leonardo 8cede4760e reduced quality to improve performance 2021-08-11 01:46:11 +02:00
Leonardo bceab238d5 Small fix to the offset 2021-08-11 01:45:18 +02:00
James Seibel 121676e661 Remove a unneeded offset in LodNodeBufferBuilder 2021-08-10 17:44:44 -05:00
Leonardo 9ec3be8a48 Added different level 2021-08-10 17:23:43 +02:00
Leonardo bb61cdad70 Added different LodDetail support 2021-08-10 17:11:36 +02:00
Leonardo 2e32e4d768 LodNodeBuilder and LodNodeGenWorker now support correctly LodDetail 2021-08-10 13:07:59 +02:00
Leonardo d4ee641362 Fixed file saving not working 2021-08-10 12:28:32 +02:00
James Seibel 953c2b2e92 Improve color generation and fix Biome Only generation 2021-08-09 22:25:49 -05:00
James Seibel 2cc78c874b Remove comment for issue #54 2021-08-09 22:23:47 -05:00
Leonardo f6f0ecb21b Fixed negative region not showing 2021-08-09 17:54:04 +02:00
Leonardo 190fef934c Added getNodeAtPos for generic node level 2021-08-09 17:01:31 +02:00
James Seibel 52608a9f3f Create issue #54 2021-08-08 22:06:45 -05:00
James Seibel 54e5fd30ab Refactor and comment 2021-08-08 22:04:13 -05:00
James Seibel 89115fd5d5 Add a text reminder when overriding the config file 2021-08-08 21:48:13 -05:00
James Seibel 5631ae52be Refactoring and Commenting 2021-08-08 16:41:25 -05:00
James Seibel 6520cdb184 Refactoring and commenting 2021-08-08 16:30:04 -05:00
James Seibel ce5f8708cd Remove unused code in LodNodeBuilder
I don't think using a 3rd party generator is a good idea; even if it is much faster than vanilla MC.
For a couple of reasons:
1. we could run into issues where the 3rd party isn't updated fast enough
2. the 3rd party generator may not generate the same terrain/biomes/etc.
3.  we wouldn't be able to generate mod terrain
2021-08-08 16:25:42 -05:00
James Seibel 270a83ddbc Refactoring and Commenting 2021-08-08 09:58:55 -05:00
James Seibel 64b8cb3556 Refactoring, reformatting, and commenting
I removed the getters from LodQuadTreeNode since they were public variables anyway.
2021-08-08 00:09:12 -05:00
James Seibel 7f7884c130 update LodNodeBufferBuilder version date 2021-08-07 23:38:14 -05:00
James Seibel 5a95613cee spacing reformatting 2021-08-07 23:38:00 -05:00
James Seibel 9a58800499 Refactoring and commenting 2021-08-07 23:31:40 -05:00
James Seibel d68e46a2d0 Refactoring 2021-08-07 19:31:31 -05:00
James Seibel 20d1ff6d49 revert LodQuadTree region to LodQuadTree and other refactors 2021-08-07 18:30:36 -05:00
James Seibel ed188448f2 Fix LodNodeBufferBuilder queueing the same chunk for generation multiple times 2021-08-07 18:29:20 -05:00
James Seibel 87c803e4c6 Minor refactoring 2021-08-07 13:40:04 -05:00
James Seibel 58f51aae91 reword a TODO 2021-08-07 13:36:15 -05:00
James Seibel 97a773176d Refactoring fixes 2021-08-07 13:30:03 -05:00
James Seibel f6d92021ed Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-07 13:29:05 -05:00
James Seibel 026cbd5da3 add fix from 2d70e8eb 2021-08-07 12:33:34 -05:00
James Seibel 3538e79a6b Reformat, Refactor, and add comments 2021-08-07 12:22:49 -05:00
Leonardo d520fb8535 previus fix was not correct 2021-08-07 19:03:56 +02:00
Leonardo d7dbf8b994 Fixed the repeating region bug 2021-08-07 18:56:51 +02:00
Leonardo 2d70e8ebe2 Fixed the repeating region bug 2021-08-07 18:54:10 +02:00
James Seibel 5eafe8f818 Improve formatting and a few variable names 2021-08-05 21:42:58 -05:00
James Seibel e875c664fd fix LODs generating multiple times (at least in single threaded gen) 2021-08-05 21:41:08 -05:00
James Seibel e313a03410 Fix/improve rendering again 2021-08-05 20:40:12 -05:00
James Seibel 781aa339bc Partially fix LodNode rendering 2021-08-05 07:56:00 -05:00
James Seibel 73e318ee38 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-08-04 23:07:12 -05:00
James Seibel 337853cdfa Start merging in 1.16.5_QuadTree
The mod does compile and render, however distance LODs don't generate or render correctly and there are other problems as well.
2021-08-04 23:07:03 -05:00
James Seibel afe4e111c3 Add release version a1.3.2 2021-08-04 22:58:06 -05:00
James Seibel 3675c5da46 Add deprecation suppressions in LodRenderer 2021-07-29 07:20:22 -05:00
James Seibel a4cc39dbac Add 400 px icons 2021-07-27 22:32:18 -05:00
James Seibel e3787079b7 Add icon files 2021-07-27 21:24:11 -05:00
James Seibel b2f98e2d92 Improve grass colors (#36) 2021-07-26 22:27:20 -05:00
James Seibel e1edd01069 Implement a few small features in LodServerWorld 2021-07-26 22:20:00 -05:00
James Seibel eb3455452b Fix getting the GPU's fancy fog capabilities 2021-07-26 20:26:24 -05:00
James Seibel 34baf923b2 Fix #45 (Half and Full qualities checkerboard) 2021-07-26 07:56:00 -05:00
James Seibel 499308870d fix a typo 2021-07-25 20:55:15 -05:00
James Seibel f852a79a0e Fix LODs rendering with an offset 2021-07-25 20:52:30 -05:00
James Seibel fa98454151 Hopefully reduce the chance of index out of bounds exceptions 2021-07-25 20:51:52 -05:00
James Seibel 286fc91db6 Slightly improve gamma lighting 2021-07-25 20:51:18 -05:00
James Seibel 99209f920d Fix a few truncation and off by 1 errors 2021-07-25 18:48:25 -05:00
James Seibel 19fd1aff98 Close #36 (Improve foliage colors)
While the colors could still be improved, I'm not sure what else to do with them to do so.
2021-07-25 18:20:34 -05:00
James Seibel 9ebc5aeb32 Improve comments in CublicLodTemplate 2021-07-25 18:06:42 -05:00
James Seibel 7c890a4627 Add a config option to change LOD brightness and saturation
Related to issue #36
2021-07-25 18:00:39 -05:00
James Seibel ccc661225e Improve the DARKEN_SIDES shading mode 2021-07-25 17:58:46 -05:00
James Seibel d7b13a2e0b fix a typo 2021-07-25 15:49:18 -05:00
James Seibel c53ce15f7d Hopefully fix #38 (teleporting causing regions to save in the wrong place) 2021-07-25 14:14:07 -05:00
James Seibel 35ac6fc756 Fix a typo 2021-07-25 14:10:08 -05:00
James Seibel 6bcf58959b Fix #46 (MC crashing when joining a server) 2021-07-25 13:18:47 -05:00
James Seibel 5051508e42 Fix #48 (Lava showing up as water) 2021-07-25 12:29:40 -05:00
James Seibel 196e02e61a Partially close #43 (add SSAO)
I am surprised how much this small change improves how things look. I may still implement SSAO in the future but for the time being this is a big improvement for how things look.
2021-07-25 12:19:14 -05:00
Leonardo bc8188beb0 Added important TODOs 2021-07-21 10:43:51 +02:00
Leonardo 0fc4c5532b Minor fixes 2021-07-19 17:00:40 +02:00
Leonardo 98586d6af9 now different generation setting can be used in the same Dimension without conflict 2021-07-19 16:23:14 +02:00
Leonardo bdd1e2410a Updated the guide 2021-07-19 11:47:26 +02:00
Leonardo c0240c71bf Updated the guide 2021-07-19 11:46:22 +02:00
Leonardo 65ffc93e0f Updated the guide 2021-07-19 11:35:38 +02:00
Leonardo 01183be383 getLevelToGenerate has been renamed getNodesToGenerate. Now it return node and not the complete level 2021-07-19 11:32:20 +02:00
Leonardo 359791ea58 Fixed getLevelToGenerate. Now it works correctly 2021-07-19 11:26:05 +02:00
Leonardo 5b3aa82817 Updated the image creation 2021-07-14 15:08:10 +02:00
Leonardo d77bb48da1 Updated the guide 2021-07-14 15:07:09 +02:00
Leonardo 8b941cb95c Updated the guide 2021-07-14 14:41:03 +02:00
Leonardo b9d991db63 Updated the guide 2021-07-14 14:37:48 +02:00
Leonardo 1a8a7be494 Updated the guide 2021-07-14 14:33:58 +02:00
Leonardo d054ac91b1 Fixed all negative coords bug 2021-07-14 14:33:17 +02:00
Leonardo e40ee20460 Added GUIDE to Readme.txt 2021-07-14 11:14:44 +02:00
Leonardo 29b3e9fadc The lodQuadTree is now correctly converted to use LodDataPoint and DistanceGenerationMode 2021-07-13 20:40:55 +02:00
Leonardo 3cc78c62a0 The lodQuadTree is now correctly converted to use LodDataPoint and DistanceGenerationMode 2021-07-13 15:38:20 +02:00
Leonardo 2c719c41d9 Various change to support LodDataPoint and the DistanceGenerationMode enum 2021-07-13 11:38:08 +02:00
Leonardo cd06b42b02 changed pc 2021-07-13 00:53:24 +02:00
Leonardo e8b46a6fd2 Converting the quadTree to use the LodDataPoint class 2021-07-13 00:52:24 +02:00
James Seibel 814ac5df84 Change distanceBiomeOnlyGeneration to distanceGenerationMode in the configHandler 2021-07-11 18:41:38 -05:00
Morippi 7854f659a3 various change 2021-07-10 15:02:26 +02:00
Morippi 6cb1d2f8f4 second fix for negative coordinate 2021-07-10 13:36:15 +02:00
Morippi f95d57ab6d Several chages to converto to quadTree + first fix for negative coordinate 2021-07-10 12:43:23 +02:00
James Seibel 55f9d142e6 Add 1.16.5 a1.3.1 to the compiled Jars 2021-07-09 23:10:36 -05:00
James Seibel 58607ab1fc Update the version to a1.3.1 2021-07-09 23:09:32 -05:00
James Seibel 433ab4f92f Fix #37 (Z fighting far from the world's origin) 2021-07-09 23:08:30 -05:00
James Seibel 8840973a1e Fix #41 (leaving a world causing Lod generation to break) 2021-07-09 22:57:32 -05:00
Morippi f91479829d Several chages to converto to quadTree 2021-07-09 21:07:00 +02:00
Morippi 829c9531fa Several chages to converto to quadTree 2021-07-09 21:01:37 +02:00
Morippi f9bb248eef Several chages to converto to quadTree 2021-07-09 21:01:17 +02:00
Morippi 03ce4d9c42 Several chages to converto to quadTree 2021-07-09 19:23:14 +02:00
Morippi f181d073a3 fixed LodQuadTreeDimension 2021-07-09 17:56:44 +02:00
Morippi 63b01f3ec7 fixed LodQuadTreeDimension 2021-07-09 15:53:32 +02:00
Morippi 14f1b6db54 fixed LodQuadTreeDimension 2021-07-09 15:26:03 +02:00
Morippi 604089cfa8 fixed LodQuadTreeDimension 2021-07-09 15:08:48 +02:00
Morippi 712d9db2fa fixed LodQuadTreeDimension 2021-07-09 14:58:48 +02:00
Morippi 2b5b023472 fixed LodQuadTreeDimension 2021-07-09 13:33:11 +02:00
Morippi 4a9bc7ca74 fixed LodQuadTreeDimension 2021-07-09 13:11:25 +02:00
Morippi 804f910584 added region in image + various fix 2021-07-08 19:31:27 +02:00
Morippi d5b2512e27 various fix 2021-07-08 13:00:29 +02:00
Morippi 280d281604 various fix 2021-07-08 12:52:50 +02:00
Morippi 95bcc71d23 various fix 2021-07-08 12:40:36 +02:00
Morippi b623f1581f various fix 2021-07-07 23:12:45 +02:00
Morippi 62b6d9ea30 Modified to used getNodeToRender 2021-07-07 22:44:53 +02:00
Morippi 6c8d0f98a6 Added circular rendering,
Fixed get node to render
2021-07-07 22:43:44 +02:00
Morippi dc353cd029 Map works correctly 2021-07-07 21:16:18 +02:00
Morippi 86e4ab7e83 Map works correctly 2021-07-07 20:22:05 +02:00
Morippi c6a96ae710 Fixed QuadTreeImage 2021-07-07 19:44:10 +02:00
Morippi 9e24ee0ef7 Fixed LodQuadTree
Added QuadTreeImage to visualize how the quadTree is builded
2021-07-07 00:53:32 +02:00
Morippi 72bcc87de7 QuadTree version, still doesn't work 2021-07-05 14:46:51 +02:00
205 changed files with 15831 additions and 7099 deletions
+30
View File
@@ -24,3 +24,33 @@ run
# Files from Forge MDK
logs
forge*changelog.txt
.architectury-transformer/
build/
*.ipr
run/
*.iws
out/
*.iml
.gradle/
output/
bin/
libs/
.classpath
.project
.idea/
classes/
.metadata
.vscode
.settings
*.launch
**/src/generated/
Merged/
# file from notepad++
*.bak
# file genearated via MC version switching using preprocessor
build.properties
+86
View File
@@ -0,0 +1,86 @@
# use Eclipse's JDK
image: gradle:eclipse-temurin
# all stages need to be defined here
stages:
- build_18_1
- build_18_2
variables:
# Pull core when building
GIT_SUBMODULE_STRATEGY: recursive
before_script:
- echo $CI_JOB_ID
# Writing GE_JOB_ID variable to environment file, will need the value in the next stage.
- echo GE_JOB_ID=$CI_JOB_ID >> generate_jars.env
# 1.18.1 build
build_18_1:
stage: build_18_1
script:
- ./gradlew deleteMerged --gradle-user-home cache/; # make sure any previously merged jars are removed before running this job
- ./gradlew build -PmcVer=1.18.1 --gradle-user-home cache/;
- ./gradlew merge --gradle-user-home cache/;
# build using Java 17
image: eclipse-temurin:17
artifacts:
name: "Merged_NightlyBuild_1_18_1-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
paths:
# relative to the root directory
- Merged
expire_in: 1 day
cache:
key: "gradleCache"
policy: pull-push
paths:
- .gradle
- cache/
# 1.18.2 build
build_18_2:
stage: build_18_2
script:
- ./gradlew deleteMerged --gradle-user-home cache/;
- ./gradlew build -PmcVer=1.18.2 --gradle-user-home cache/;
- ./gradlew merge --gradle-user-home cache/;
image: eclipse-temurin:17
artifacts:
name: "Merged_NightlyBuild_1_18_2-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
paths:
- Merged
expire_in: 1 day
cache:
key: "gradleCache"
policy: pull-push
paths:
- .gradle
- cache/
# unused deployment stage
#deploy:
# stage: deploy
# image: registry.gitlab.com/gitlab-org/release-cli:latest
# script:
# - echo 'running release_job'
# - echo 'Previous Job ID is printed below'
# - echo $GE_JOB_ID
# # Specifying that this job requires artifacts from the previous job to succeed
# needs:
# - job: build
# artifacts: true
# release:
# name: 'Unstable Jars for Latest Commit' #: $CI_COMMIT_SHORT_SHA'
# description: 'Created automatically using the release-cli.'
# # tag_name is a mendatory field and can not be an empty string
# tag_name: 'Unstable-$CI_COMMIT_SHORT_SHA'
# assets:
# links:
# - name: 'Fabric Jars'
# url: 'https://gitlab.com/jeseibel/minecraft-lod-mod/cw/-/jobs/${GE_JOB_ID}/artifacts/file/fabric/build/libs'
# - name: 'Forge Jars'
# url: 'https://gitlab.com/jeseibel/minecraft-lod-mod/cw/-/jobs/${GE_JOB_ID}/artifacts/file/forge/build/libs'
+4
View File
@@ -0,0 +1,4 @@
[submodule "core"]
path = core
url = https://gitlab.com/jeseibel/distant-horizons-core.git
branch = main
+39
View File
@@ -0,0 +1,39 @@
# 1.18.1 version based stuff
minecraft_version=1.18.1
java_version = 17
# Fabric loader
fabric_loader_version=0.13.3
fabric_api_version=0.46.6+1.18
# Fabric mod versions
modmenu_version=3.0.1
starlight_version_fabric=3554912
phosphor_version_fabric=3573395
lithium_version=mc1.18.1-0.7.7
sodium_version=3605309
iris_version=1.18.x-v1.1.4
bclib_version=1.2.5
immersive_portals_version = v1.0.4-1.18
# Fabric mod run
# 0 = Don't enable and don't run
# 1 = Can be referenced in code but doesn't run
# 2 = Can be referenced in code and runs in client
enable_starlight=0
enable_phosphor=0
enable_sodium=1
enable_lithium=0
enable_iris=0
enable_bclib=0
# Forge loader
forge_version=39.1.2
# Forge mod versions
starlight_version_forge=3559934
# Forge mod run
# 0 = Dont enable and don't run
# 1 = Can be referenced in code but doesn't run
# 2 = Can be referenced in code and runs in client
enable_starlight_forge=0
+40
View File
@@ -0,0 +1,40 @@
# 1.18.2 version based stuff
# architectury_plugin_version = 3.4-SNAPSHOT
# dev_architectury_loom_version = 0.10.0-SNAPSHOT
minecraft_version=1.18.2
java_version = 17
# Fabric loader
fabric_loader_version=0.13.3
fabric_api_version=0.48.0+1.18.2
# Fabric mod versions
modmenu_version=3.1.0
starlight_version_fabric=3667443
phosphor_version_fabric=3573395
lithium_version=mc1.18.2-0.7.9
sodium_version=3669187
iris_version=1.18.x-v1.2.2
immersive_portals_version = v1.0.4-1.18
bclib_version=0
# Fabric mod run
# 0 = Don't enable and don't run
# 1 = Can be referenced in code but doesn't run
# 2 = Can be referenced in code and runs in client
enable_starlight=0
enable_phosphor=0
enable_sodium=1
enable_lithium=0
enable_iris=0
enable_bclib=0
# Forge loader
forge_version=40.0.18
# Forge mod versions
starlight_version_forge=0
# Forge mod run
# 0 = Don't enable and don't run
# 1 = Can be referenced in code but doesn't run
# 2 = Can be referenced in code and runs in client
enable_starlight_forge=0
+119
View File
@@ -0,0 +1,119 @@
# THIS VERSION IS NO LONGER MAINTAINED! ALL DEVELOPMENT HAVE BEEN MOVED OVER TO THE MAIN BRANCH
# <img src="https://gitlab.com/jeseibel/distant-horizons-core/-/raw/main/_logo%20files/LOD%20logo%20flat%20-%20with%20boarder.png" width="32"> Distant Horizons
> A mod that adds a Level of Detail System to Minecraft
# What is Distant Horizons?
This mod adds a Level Of Detail (LOD) system to Minecraft.\
This implementation renders simplified chunks outside the normal render distance\
allowing for an increased view distance without harming performance.
Or in other words: this mod lets you see farther without turning your game into a slide show.\
If you want to see a quick demo, check out a video covering the mod here:
<a href="https://www.youtube.com/watch?v=H2tnvEVbO1c" target="_blank">![Minecraft Level Of Detail (LOD) mod - Alpha 1.5](https://i.ytimg.com/vi_webp/H2tnvEVbO1c/mqdefault.webp)</a>
### Versions
Architectury version: 3.4-SNAPSHOT\
Java Compiler plugin: Manifold Preprocessor
#### 1.18.2 mods
Forge version: 40.0.18\
Fabric version: 0.13.3\
Fabric API version: 0.48.0+1.18.2\
Modmenu version: 3.1.0
#### 1.18.1 mods
Forge version: 39.1.2\
Fabric version: 0.13.3\
Fabric API version: 0.46.6+1.18\
Modmenu version: 3.0.1
Notes:\
This version has been confirmed to work in IDE and Retail Minecraft.\
(Retail running forge version 1.18.1-39.0.5 and fabric version 1.18-0.12.12 and 1.18.1-0.13.2)
## Source Code Installation
See the Fabric Documentation online for more detailed instructions:\
https://fabricmc.net/wiki/tutorial:setup
### Prerequisites
* A Java Development Kit (JDK) for Java 17 (recommended) or newer. Visit https://www.oracle.com/java/technologies/downloads/ for installers.
* Git or someway to clone git projects. Visit https://git-scm.com/ for installers.
* (Not required) Any Java IDE with plugins that support Manifold, for example Intellij IDEA.
**If using IntelliJ:**
0. Install Manifold plugin
1. open IDEA and import the build.gradle
2. refresh the Gradle project in IDEA if required
**If using Ecplise: (Note that Eclispe currently doesn't support Manifold's preprocessor!)**
1. run the command: `./gradlew geneclipseruns`
2. run the command: `./gradlew eclipse`
3. Make sure eclipse has the JDK 17 installed. (This is needed so that eclipse can run minecraft)
4. Import the project into eclipse
## Switching Versions
This branch support 2 built versions:
- 1.18.2
- 1.18.1 (which also runs on 1.18)
To switch between active versions, change `mcVer=1.18.?` in `gradle.properties` file.
If running on IDE, to ensure IDE pickup the changed versions, you will need to run a gradle command again to allow gradle to update all the libs. (In IntellJ you will also need to do a gradle sync again if it didn't start it automatically.)
>Note: There may be a `java.nio.file.FileSystemException` thrown on running the command after switching versions. To fix it, either restart your IDE (as your IDE is locking up a file) or use tools like LockHunter to unlock the linked file. (Often a lib file under `common\build\lib` or `forge\build\lib` or `fabric\build\lib`). If anyone knows how to solve this issue please comment to this issue: https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/233
## Compiling
**Using GUI**
1. Download the zip of the project and extract it
2. Download the core from https://gitlab.com/jeseibel/distant-horizons-core and extract into a folder called `core`
3. Open a command line in the project folder
4. Run the command: `./gradlew assemble`
5. Then run command: `./gradlew mergeJars`
6. The compiled jar file will be in the folder `Merged`
**If in terminal:**
1. `git clone -b 1.18.X --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
2. `cd minecraft-lod-mod`
3. `./gradlew assemble`
4. `./gradlew mergeJars`
5. The compiled jar file will be in the folder `Merged`
>Note: You can add the arg: `-PmcVer=1.18.?` to tell gradle to build a selected MC version instead of having to manually modify the `gradle.properties` file.
## Other commands
`./gradlew --refresh-dependencies` to refresh local dependencies.
`./gradlew clean` to reset everything (this does not affect your code) and then start the process again.
## Note to self
The Minecraft source code is NOT added to your workspace in an editable way. Minecraft is treated like a normal Library. Sources are there for documentation and research purposes only.
Source code uses Mojang mappings.
## Useful commands
Build only Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build`\
Build only Forge: `./gradlew fabric:assemble` or `./gradlew forge:build`\
Run the Fabric client (for debugging): `./gradlew fabric:runClient`\
Run the Forge client (for debugging): `./gradlew forge:runClient`
## Open Source Acknowledgements
XZ for Java (data compression)\
https://tukaani.org/xz/java.html
DHJarMerger (To merge multiple mod versions into one jar)\
https://github.com/Ran-helo/DHJarMerger
-70
View File
@@ -1,70 +0,0 @@
This mod adds a Level Of Detail (LOD) system to Minecraft.
This implementation renders simplified chunks outside the normal render distance
allowing for an increased view distance without harming performance.
Or in other words: this mod let's you see farther without turning your game into a slide show.
If you want to see a quick demo, check out the video I made here:
https://youtu.be/CCT-3s02tYA
Forge version: 1.16.5-36.1.0
Notes:
This version has been confirmed to work in Eclipse and Retail Minecraft.
(Retail running forge version 1.16.5-36.1.0)
========================
source code installation
========================
See the Forge Documentation online for more detailed instructions:
http://mcforge.readthedocs.io/en/latest/gettingstarted/
Step 1: Create a system variable called "JAVA_MC_HOME" with the location of the JDK 1.8.0_251 (This is needed for gradle to work correctly)
Step 2: replace JAVA_HOME with JAVA_MC_HOME in gradle.bat
Step 3: open a command line in the project folder
Step 4: run the command: "./gradlew geneclipseruns"
Step 5: run the command: "./gradlew eclipse"
Step 6: Make sure the eclipse has the JDK 1.8.0_251 installed. (This is needed so that eclipse can run minecraft)
Step 7: Import the project into eclipse
=========
compiling
=========
Step 1: open a command line in the project folder
Step 2: run the command: "./gradlew build"
Step 3: the compiled jar file will be in the folder "build\libs"
==============
Other commands
==============
"./gradlew --refresh-dependencies" to refresh local dependencies.
"./gradlew clean" to reset everything (this does not affect your code) and then start the process again.
============
Note to self
============
The Minecraft source code is NOT added to your workspace in a editable way. Minecraft is treated like a normal Library. Sources are there for documentation and research purposes only.
Source code uses mcp mappings not Mojangs.
The source code can be 'created' with the ./eclipse command and can be found in the following path:
minecraft-lod-mod\build\fg_cache\mcp\ VERSION \joined\ RANDOM_STRING \patch\output.jar
Binary file not shown.
Binary file not shown.
+208 -177
View File
@@ -1,194 +1,225 @@
import io.github.ran.jarmerger.JarMergerPlugin
buildscript {
repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
mavenCentral()
maven { url = 'https://repo.spongepowered.org/maven/' }
// potential replacement in case of problems:
// https://dist.creeper.host/Sponge/maven
dependencies{
classpath files('plugins/DHJarMerger-1.0.jar')
}
}
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "0.10.0-SNAPSHOT" apply false
}
def writeBuildGradlePredefine() {
def excapedMCVersion = rootProject.minecraft_version.replace(".", "_")
new File(projectDir, "build.properties").text = "MC_VERSION_${excapedMCVersion}=\n"
}
def loadProperties() {
def defaultMcVersion = '1.18.2'
if (!project.hasProperty("mcVer")) {
println "No mcVer set! Defaulting to ${defaultMcVersion}."
println "Tip: Use -PmcVer='${defaultMcVersion}' in cmd arg to set mcVer."
}
def mcVersion = project.hasProperty("mcVer") ? mcVer : defaultMcVersion
println "Loading properties file at " + mcVersion + ".properties"
def props = new Properties()
props.load(new FileInputStream("$rootProject.rootDir/"+"$mcVersion"+".properties"))
props.each { prop ->
rootProject.ext.set(prop.key, prop.value)
// println "Added prop [key:" + prop.key + ", value:" + prop.value + "]"
}
writeBuildGradlePredefine()
}
loadProperties()
apply plugin: JarMergerPlugin
architectury {
minecraft = rootProject.minecraft_version
}
subprojects { p ->
apply plugin: "dev.architectury.loom"
loom {
silentMojangMappingsLicense()
}
configurations {
common
shadowMe
implementation.extendsFrom shadowMe
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT'
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
// The following line declares the mojmap mappings
mappings loom.officialMojangMappings()
//Manifold
annotationProcessor "systems.manifold:manifold-preprocessor:${rootProject.manifold_version}"
// Toml
implementation("com.electronwill.night-config:toml:${rootProject.toml_version}")
if (p != project(":forge")) {
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
// Do NOT use other classes from fabric loader unless working with fabric
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
}
if (p != project(":core")) {
common(project(":core")) { transitive false }
shadowMe(project(":core")) { transitive false }
}
}
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.spongepowered.mixin'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
version = 'a1.3'
group = 'com.backsun.lod'
archivesBaseName = 'lod_1.16.5'
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
minecraft {
// The mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD Snapshot are built nightly.
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: 'official', version: '1.16.5'
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs {
client {
workingDirectory project.file('run')
arg "-mixin.config=lod.mixins.json"
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
mods {
examplemod {
source sourceSets.main
}
}
}
server {
workingDirectory project.file('run')
arg "-mixin.config=lod.mixins.json"
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
mods {
examplemod {
source sourceSets.main
}
}
}
data {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
args '--mod', 'lod', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
mods {
examplemod {
source sourceSets.main
}
}
jar {
manifest {
attributes 'Implementation-Title': rootProject.archives_base_name,
'Implementation-Version': rootProject.mod_version,
'Main-Class': 'com.seibel.lod.core.JarMain'
}
}
}
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }
allprojects { p ->
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
minecraft 'net.minecraftforge:forge:1.16.5-36.1.0'
// these were added to hopefully allow for cloning
// configuredFeatures to allow for safe
// multi threaded feature generation. Sadly I couldn't find
// a way to duplicate lambda functions (which features use)
// so for now I'm not sure what to do.
//implementation 'io.github.kostaskougios:cloning:1.10.3'
//
//implementation ('com.esotericsoftware:kryo:5.1.1') {
// exclude group: "org.objenesis"
//}
//implementation 'org.objenesis:objenesis:3.2'
// You may put jars on which you depend on in ./libs or you may define them like so..
// compile "some.group:artifact:version:classifier"
// compile "some.group:artifact:version"
archivesBaseName = rootProject.archives_base_name
version = rootProject.mod_version
group = rootProject.maven_group
// Real examples
// compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
// compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
// The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
// provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// These dependencies get remapped to your current MCP mappings
// deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// For more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
}
// Example for how to get properties into the manifest for reading by the runtime..
jar {
manifest {
attributes([
"Specification-Title": "Level of Detail",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
"Implementation-Version": "{version}",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"MixinConfigs": "lod.mixins.json",
])
}
}
// Example configuration to allow publishing using the maven-publish task
// This is the preferred method to reobfuscate your jar file
jar.finalizedBy('reobfJar')
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
//publish.dependsOn('reobfJar')
publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
}
}
repositories {
mavenCentral()
// used to download and compile dependencies from git repos
maven { url 'https://jitpack.io' }
// For Manifold Preprocessor
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
// Required for importing Modrinth mods
maven {
url "file:///${project.projectDir}/mcmodsrepo"
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
// Required for importing CursedForge mods
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
// These 2 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
flatDir {
dirs "${rootDir}/mods/fabric"
content {
includeGroup "fabric-mod"
}
}
flatDir {
dirs "${rootDir}/mods/forge"
content {
includeGroup "forge-mod"
}
}
}
// Put stuff from gradle.properties into the mod info
processResources {
def resourceTargets = ["fabric.mod.json", "META-INF/mods.toml"] // Location of where to put
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
def replaceProperties = [
version: mod_version,
mod_name: mod_name,
authors: mod_authors,
description: mod_description,
homepage: mod_homepage,
source: mod_source,
issues: mod_issues,
minecraft_version: minecraft_version,
java_version: java_version
] // The left side is what gets replaced in the mod info and the right side is where to get it from in the gradle.properties
//TODO: Make Forge loader version also be relaced with non hardcoded value instead of "[36,41)"
inputs.properties replaceProperties
replaceProperties.put 'project', project
filesMatching(resourceTargets) {
expand replaceProperties
}
intoTargets.each { target ->
if (file(target).exists()) {
copy {
from(sourceSets.main.resources) {
include resourceTargets
expand replaceProperties
}
into target
}
}
}
}
tasks.withType(JavaCompile) {
// Add Manifold Preprocessor
// def excapedMCVersion = rootProject.minecraft_version.replace(".", "_")
// options.compilerArgs += ['-Xplugin:Manifold', "-AMC_VERSION_${excapedMCVersion}"]
//
//options.compilerArgs += ['-deprecation']
//options.compilerArgs += ['-verbose']
//options.compilerArgs += ['-Xlint:unchecked']
//options.compilerArgs += ['-Xdiags:verbose']
//options.compilerArgs += ['-Xprint']
//options.compilerArgs += ['-XprintProcessorInfo']
//options.compilerArgs += ['-XprintRounds']
// println options.compilerArgs
if (p != project(":core")) {
options.compilerArgs += ['-Xplugin:Manifold']
options.release = rootProject.java_version as Integer
}
}
java {
withSourcesJar()
}
if (p == project(":core") || p == project(":common")) {
runClient.enabled = false
runServer.enabled = false
}
// this is necessary for running the fabric build
if (p == project(":common")) {
println "Coping [common/src/main/resources/lod.accesswidner] to [fabric/build/resources/main]."
copy {
from "$rootProject.rootDir/common/src/main/resources"
into "$rootProject.rootDir/fabric/build/resources/main"
include "*.accesswidener"
}
}
}
mixin {
add sourceSets.main, "lod.refmap.json"
}
// this deletes the merged folder so we don't carry over
// the previous merges to each new build job in the CI/CD pipeline
task deleteMerged(type: Delete) {
delete files("./Merged")
}
+29
View File
@@ -0,0 +1,29 @@
loom {
accessWidenerPath.set(file("src/main/resources/lod.accesswidener"))
}
architectury {
common()
}
afterEvaluate {
tasks {
remapJar {
remapAccessWidener.set(false)
}
}
}
publishing {
publications {
mavenCommon(MavenPublication) {
artifactId = rootProject.archives_base_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}
@@ -0,0 +1,485 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common;
import com.seibel.lod.core.config.*;
import com.seibel.lod.core.enums.config.*;
import com.seibel.lod.core.enums.rendering.*;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced.*;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.*;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.IFogQuality.IAdvancedFog;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.IFogQuality.IAdvancedFog.IHeightFog;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IMultiplayer;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IWorldGenerator;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced.IDebugging.*;
/**
* This handles any configuration the user has access to.
* @author coolGi2007
* @version 12-12-2021
*/
public class Config
//public class Config extends TinyConfig
{
// CONFIG STRUCTURE
// -> Client
// |
// |-> Graphics
// | |-> Quality
// | |-> FogQuality
// | |-> AdvancedGraphics
// |
// |-> World Generation
// |
// |-> Advanced
// |-> Threads
// |-> Buffers
// |-> Debugging
// Since the original config system uses forge stuff, that means we have to rewrite the whole config system
@ConfigAnnotations.ScreenEntry
public static Client client;
@ConfigAnnotations.FileComment
public static String _optionsButton = ILodConfigWrapperSingleton.IClient.OPTIONS_BUTTON_DESC;
// I know this option should be in Client
// This is a hacky method to not show the button in the options screen but show it in the mod menu
// Tough it is in client in the wrapper singleton
@ConfigAnnotations.Entry
public static boolean optionsButton = true;
public static class Client
{
@ConfigAnnotations.ScreenEntry
public static Graphics graphics;
@ConfigAnnotations.ScreenEntry
public static WorldGenerator worldGenerator;
@ConfigAnnotations.ScreenEntry
public static Multiplayer multiplayer;
@ConfigAnnotations.ScreenEntry
public static Advanced advanced;
public static class Graphics
{
@ConfigAnnotations.ScreenEntry
public static Quality quality;
@ConfigAnnotations.ScreenEntry
public static FogQuality fogQuality;
@ConfigAnnotations.ScreenEntry
public static AdvancedGraphics advancedGraphics;
public static class Quality
{
@ConfigAnnotations.FileComment
public static String _drawResolution = IQuality.DRAW_RESOLUTION_DESC;
@ConfigAnnotations.Entry
public static HorizontalResolution drawResolution = IQuality.DRAW_RESOLUTION_DEFAULT;
@ConfigAnnotations.FileComment
public static String _lodChunkRenderDistance = IQuality.LOD_CHUNK_RENDER_DISTANCE_DESC;
@ConfigAnnotations.Entry(minValue = 16, maxValue = 2048)
public static int lodChunkRenderDistance = IQuality.LOD_CHUNK_RENDER_DISTANCE_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _verticalQuality = IQuality.VERTICAL_QUALITY_DESC;
@ConfigAnnotations.Entry
public static VerticalQuality verticalQuality = IQuality.VERTICAL_QUALITY_DEFAULT;
@ConfigAnnotations.FileComment
public static String _horizontalScale = IQuality.HORIZONTAL_SCALE_DESC;
@ConfigAnnotations.Entry(minValue = 2, maxValue = 32)
public static int horizontalScale = IQuality.HORIZONTAL_SCALE_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _horizontalQuality = IQuality.HORIZONTAL_SCALE_DESC;
@ConfigAnnotations.Entry
public static HorizontalQuality horizontalQuality = IQuality.HORIZONTAL_QUALITY_DEFAULT;
@ConfigAnnotations.FileComment
public static String _dropoffQuality = IQuality.DROPOFF_QUALITY_DESC;
@ConfigAnnotations.Entry
public static DropoffQuality dropoffQuality = IQuality.DROPOFF_QUALITY_DEFAULT;
@ConfigAnnotations.FileComment
public static String _lodBiomeBlending = IQuality.LOD_BIOME_BLENDING_DESC;
@ConfigAnnotations.Entry(minValue = 0, maxValue = 7)
public static int lodBiomeBlending = IQuality.LOD_BIOME_BLENDING_MIN_DEFAULT_MAX.defaultValue;
}
public static class FogQuality
{
@ConfigAnnotations.FileComment
public static String _fogDistance = IFogQuality.FOG_DISTANCE_DESC;
@ConfigAnnotations.Entry
public static FogDistance fogDistance = IFogQuality.FOG_DISTANCE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _fogDrawMode = IFogQuality.FOG_DRAW_MODE_DESC;
@ConfigAnnotations.Entry
public static FogDrawMode fogDrawMode = IFogQuality.FOG_DRAW_MODE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _fogColorMode = IFogQuality.FOG_COLOR_MODE_DESC;
@ConfigAnnotations.Entry
public static FogColorMode fogColorMode = IFogQuality.FOG_COLOR_MODE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _disableVanillaFog = IFogQuality.DISABLE_VANILLA_FOG_DESC;
@ConfigAnnotations.Entry
public static boolean disableVanillaFog = IFogQuality.DISABLE_VANILLA_FOG_DEFAULT;
@ConfigAnnotations.ScreenEntry
public static AdvancedFog advancedFog;
public static class AdvancedFog {
static final double SQRT2 = 1.4142135623730951;
@ConfigAnnotations.FileComment
public static String _farFogStart = IAdvancedFog.FAR_FOG_START_DESC;
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2)
public static double farFogStart = IAdvancedFog.FAR_FOG_START_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _farFogEnd = IAdvancedFog.FAR_FOG_END_DESC;
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2)
public static double farFogEnd = IAdvancedFog.FAR_FOG_END_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _farFogMin = IAdvancedFog.FAR_FOG_MIN_DESC;
@ConfigAnnotations.Entry(minValue = -5.0, maxValue = SQRT2)
public static double farFogMin = IAdvancedFog.FAR_FOG_MIN_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _farFogMax = IAdvancedFog.FAR_FOG_MAX_DESC;
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = 5.0)
public static double farFogMax = IAdvancedFog.FAR_FOG_MAX_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _farFogType = IAdvancedFog.FAR_FOG_TYPE_DESC;
@ConfigAnnotations.Entry
public static FogSetting.FogType farFogType = IAdvancedFog.FAR_FOG_TYPE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _farFogDensity = IAdvancedFog.FAR_FOG_DENSITY_DESC;
@ConfigAnnotations.Entry(minValue = 0.01, maxValue = 50.0)
public static double farFogDensity = IAdvancedFog.FAR_FOG_DENSITY_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.ScreenEntry
public static HeightFog heightFog;
public static class HeightFog {
@ConfigAnnotations.FileComment
public static String _heightFogMixMode = IHeightFog.HEIGHT_FOG_MIX_MODE_DESC;
@ConfigAnnotations.Entry
public static HeightFogMixMode heightFogMixMode = IHeightFog.HEIGHT_FOG_MIX_MODE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _heightFogMode = IHeightFog.HEIGHT_FOG_MODE_DESC;
@ConfigAnnotations.Entry
public static HeightFogMode heightFogMode = IHeightFog.HEIGHT_FOG_MODE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _heightFogHeight = IHeightFog.HEIGHT_FOG_HEIGHT_DESC;
@ConfigAnnotations.Entry(minValue = -4096.0, maxValue = 4096.0)
public static double heightFogHeight = IHeightFog.HEIGHT_FOG_HEIGHT_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _heightFogStart = IHeightFog.HEIGHT_FOG_START_DESC;
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2)
public static double heightFogStart = IHeightFog.HEIGHT_FOG_START_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _heightFogEnd = IHeightFog.HEIGHT_FOG_END_DESC;
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = SQRT2)
public static double heightFogEnd = IHeightFog.HEIGHT_FOG_END_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _heightFogMin = IHeightFog.HEIGHT_FOG_MIN_DESC;
@ConfigAnnotations.Entry(minValue = -5.0, maxValue = SQRT2)
public static double heightFogMin = IHeightFog.HEIGHT_FOG_MIN_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _heightFogMax = IHeightFog.HEIGHT_FOG_MAX_DESC;
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = 5.0)
public static double heightFogMax = IHeightFog.HEIGHT_FOG_MAX_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _heightFogType = IHeightFog.HEIGHT_FOG_TYPE_DESC;
@ConfigAnnotations.Entry
public static FogSetting.FogType heightFogType = IHeightFog.HEIGHT_FOG_TYPE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _heightFogDensity = IHeightFog.HEIGHT_FOG_DENSITY_DESC;
@ConfigAnnotations.Entry(minValue = 0.01, maxValue = 50.0)
public static double heightFogDensity = IHeightFog.HEIGHT_FOG_DENSITY_MIN_DEFAULT_MAX.defaultValue;
}
}
}
public static class AdvancedGraphics
{
@ConfigAnnotations.FileComment
public static String _disableDirectionalCulling = IAdvancedGraphics.DISABLE_DIRECTIONAL_CULLING_DESC;
@ConfigAnnotations.Entry
public static boolean disableDirectionalCulling = IAdvancedGraphics.DISABLE_DIRECTIONAL_CULLING_DEFAULT;
@ConfigAnnotations.FileComment
public static String _vanillaOverdraw = IAdvancedGraphics.VANILLA_OVERDRAW_DESC;
@ConfigAnnotations.Entry
public static VanillaOverdraw vanillaOverdraw = IAdvancedGraphics.VANILLA_OVERDRAW_DEFAULT;
@ConfigAnnotations.FileComment
public static String _overdrawOffset = IAdvancedGraphics.OVERDRAW_OFFSET_DESC;
@ConfigAnnotations.Entry(minValue = -16, maxValue = 16)
public static int overdrawOffset = IAdvancedGraphics.OVERDRAW_OFFSET_MIN_DEFAULT_MAX.defaultValue;
@ConfigAnnotations.FileComment
public static String _useExtendedNearClipPlane = IAdvancedGraphics.USE_EXTENDED_NEAR_CLIP_PLANE_DESC;
@ConfigAnnotations.Entry
public static boolean useExtendedNearClipPlane = IAdvancedGraphics.USE_EXTENDED_NEAR_CLIP_PLANE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _brightnessMultiplier = IAdvancedGraphics.BRIGHTNESS_MULTIPLIER_DESC;
@ConfigAnnotations.Entry
public static double brightnessMultiplier = IAdvancedGraphics.BRIGHTNESS_MULTIPLIER_DEFAULT;
@ConfigAnnotations.FileComment
public static String _saturationMultiplier = IAdvancedGraphics.SATURATION_MULTIPLIER_DESC;
@ConfigAnnotations.Entry
public static double saturationMultiplier = IAdvancedGraphics.SATURATION_MULTIPLIER_DEFAULT;
@ConfigAnnotations.FileComment
public static String _enableCaveCulling = IAdvancedGraphics.ENABLE_CAVE_CULLING_DESC;
@ConfigAnnotations.Entry
public static boolean enableCaveCulling = IAdvancedGraphics.ENABLE_CAVE_CULLING_DEFAULT;
@ConfigAnnotations.FileComment
public static String _caveCullingHeight = IAdvancedGraphics.CAVE_CULLING_HEIGHT_DESC;
@ConfigAnnotations.Entry(minValue = -4096, maxValue = 4096)
public static int caveCullingHeight = IAdvancedGraphics.CAVE_CULLING_HEIGHT_MIN_DEFAULT_MAX.defaultValue;
/*
@ConfigAnnotations.FileComment
public static String _backsideCullingRange = IAdvancedGraphics.VANILLA_CULLING_RANGE_DESC;
@ConfigAnnotations.Entry(minValue = 0, maxValue = 512)
public static int backsideCullingRange = IAdvancedGraphics.VANILLA_CULLING_RANGE_MIN_DEFAULT_MAX.defaultValue;
*/
}
}
public static class WorldGenerator
{
@ConfigAnnotations.FileComment
public static String _enableDistantGeneration = IWorldGenerator.ENABLE_DISTANT_GENERATION_DESC;
@ConfigAnnotations.Entry
public static boolean enableDistantGeneration = IWorldGenerator.ENABLE_DISTANT_GENERATION_DEFAULT;
// @ConfigAnnotations.FileComment
// public static String _distanceGenerationMode = IWorldGenerator.getDistanceGenerationModeDesc();
@ConfigAnnotations.Entry
public static DistanceGenerationMode distanceGenerationMode = IWorldGenerator.DISTANCE_GENERATION_MODE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _lightGenerationMode = IWorldGenerator.LIGHT_GENERATION_MODE_DESC;
@ConfigAnnotations.Entry
public static LightGenerationMode lightGenerationMode = IWorldGenerator.LIGHT_GENERATION_MODE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _generationPriority = IWorldGenerator.GENERATION_PRIORITY_DESC;
@ConfigAnnotations.Entry
public static GenerationPriority generationPriority = IWorldGenerator.GENERATION_PRIORITY_DEFAULT;
/*
@ConfigAnnotations.FileComment
public static String _allowUnstableFeatureGeneration = IWorldGenerator.ALLOW_UNSTABLE_FEATURE_GENERATION_DESC;
// FIXME: Temperary override. In 1.18, the newer Unstable gnerator is more usable
@ConfigAnnotations.Entry
public static boolean allowUnstableFeatureGeneration = true;//IWorldGenerator.ALLOW_UNSTABLE_FEATURE_GENERATION_DEFAULT;
*/
@ConfigAnnotations.FileComment
public static String _blocksToAvoid = IWorldGenerator.BLOCKS_TO_AVOID_DESC;
@ConfigAnnotations.Entry
public static BlocksToAvoid blocksToAvoid = IWorldGenerator.BLOCKS_TO_AVOID_DEFAULT;
}
public static class Multiplayer
{
@ConfigAnnotations.FileComment
public static String _serverFolderNameMode = IMultiplayer.SERVER_FOLDER_NAME_MODE_DESC;
@ConfigAnnotations.Entry
public static ServerFolderNameMode serverFolderNameMode = IMultiplayer.SERVER_FOLDER_NAME_MODE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _multiDimensionRequiredSimilarity = IMultiplayer.MULTI_DIMENSION_REQUIRED_SIMILARITY_DESC;
@ConfigAnnotations.Entry(minValue = 0.0, maxValue = 1.0)
public static double multiDimensionRequiredSimilarity = IMultiplayer.MULTI_DIMENSION_REQUIRED_SIMILARITY_MIN_DEFAULT_MAX.defaultValue;
}
public static class Advanced
{
@ConfigAnnotations.ScreenEntry
public static Threading threading;
@ConfigAnnotations.ScreenEntry
public static Debugging debugging;
@ConfigAnnotations.ScreenEntry
public static Buffers buffers;
@ConfigAnnotations.FileComment
public static String _lodOnlyMode = IAdvanced.LOD_ONLY_MODE_DESC;
@ConfigAnnotations.Entry
public static boolean lodOnlyMode = IAdvanced.LOD_ONLY_MODE_DEFAULT;
public static class Threading
{
@ConfigAnnotations.FileComment
public static String _numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DESC;
@ConfigAnnotations.Entry(minValue = 1, maxValue = 50)
public static int numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DEFAULT.defaultValue;
@ConfigAnnotations.FileComment
public static String _numberOfBufferBuilderThreads = IThreading.NUMBER_OF_BUFFER_BUILDER_THREADS_DESC;
@ConfigAnnotations.Entry(minValue = 1, maxValue = 50)
public static int numberOfBufferBuilderThreads = IThreading.NUMBER_OF_BUFFER_BUILDER_THREADS_MIN_DEFAULT_MAX.defaultValue;
}
public static class Debugging
{
@ConfigAnnotations.FileComment
public static String _rendererType = IDebugging.RENDERER_TYPE_DESC;
@ConfigAnnotations.Entry
public static RendererType rendererType = IDebugging.RENDERER_TYPE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _debugMode = IDebugging.DEBUG_MODE_DESC;
@ConfigAnnotations.Entry
public static DebugMode debugMode = IDebugging.DEBUG_MODE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _enableDebugKeybindings = IDebugging.DEBUG_KEYBINDINGS_ENABLED_DESC;
@ConfigAnnotations.Entry
public static boolean enableDebugKeybindings = IDebugging.DEBUG_KEYBINDINGS_ENABLED_DEFAULT;
@ConfigAnnotations.ScreenEntry
public static DebugSwitch debugSwitch;
public static class DebugSwitch {
/* The logging switches available:
* WorldGenEvent
* WorldGenPerformance
* WorldGenLoadEvent
* LodBuilderEvent
* RendererBufferEvent
* RendererGLEvent
* FileReadWriteEvent
* FileSubDimEvent
* NetworkEvent //NOT IMPL YET
*/
@ConfigAnnotations.FileComment
public static String _logWorldGenEvent = IDebugSwitch.LOG_WORLDGEN_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logWorldGenEvent = IDebugSwitch.LOG_WORLDGEN_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logWorldGenPerformance = IDebugSwitch.LOG_WORLDGEN_PERFORMANCE_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logWorldGenPerformance = IDebugSwitch.LOG_WORLDGEN_PERFORMANCE_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logWorldGenLoadEvent = IDebugSwitch.LOG_WORLDGEN_LOAD_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logWorldGenLoadEvent = IDebugSwitch.LOG_WORLDGEN_LOAD_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logLodBuilderEvent = IDebugSwitch.LOG_LODBUILDER_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logLodBuilderEvent = IDebugSwitch.LOG_LODBUILDER_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logRendererBufferEvent = IDebugSwitch.LOG_RENDERER_BUFFER_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logRendererBufferEvent = IDebugSwitch.LOG_RENDERER_BUFFER_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logRendererGLEvent = IDebugSwitch.LOG_RENDERER_GL_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logRendererGLEvent = IDebugSwitch.LOG_RENDERER_GL_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logFileReadWriteEvent = IDebugSwitch.LOG_FILE_READWRITE_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logFileReadWriteEvent = IDebugSwitch.LOG_FILE_READWRITE_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logFileSubDimEvent = IDebugSwitch.LOG_FILE_SUB_DIM_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logFileSubDimEvent = IDebugSwitch.LOG_FILE_SUB_DIM_EVENT_DEFAULT;
@ConfigAnnotations.FileComment
public static String _logNetworkEvent = IDebugSwitch.LOG_NETWORK_EVENT_DESC;
@ConfigAnnotations.Entry
public static LoggerMode logNetworkEvent = IDebugSwitch.LOG_NETWORK_EVENT_DEFAULT;
}
}
public static class Buffers
{
@ConfigAnnotations.FileComment
public static String _gpuUploadMethod = IBuffers.GPU_UPLOAD_METHOD_DESC;
@ConfigAnnotations.Entry
public static GpuUploadMethod gpuUploadMethod = IBuffers.GPU_UPLOAD_METHOD_DEFAULT;
@ConfigAnnotations.FileComment
public static String _gpuUploadPerMegabyteInMilliseconds = IBuffers.GPU_UPLOAD_PER_MEGABYTE_IN_MILLISECONDS_DESC;
@ConfigAnnotations.Entry(minValue = 0, maxValue = 50)
public static int gpuUploadPerMegabyteInMilliseconds = IBuffers.GPU_UPLOAD_PER_MEGABYTE_IN_MILLISECONDS_DEFAULT.defaultValue;
@ConfigAnnotations.FileComment
public static String _rebuildTimes = IBuffers.REBUILD_TIMES_DESC;
@ConfigAnnotations.Entry
public static BufferRebuildTimes rebuildTimes = IBuffers.REBUILD_TIMES_DEFAULT;
}
}
}
}
@@ -0,0 +1,39 @@
package com.seibel.lod.common;
import com.seibel.lod.common.forge.LodForgeMethodCaller;
import com.seibel.lod.common.networking.NetworkInterface;
import com.seibel.lod.common.wrappers.DependencySetup;
import com.seibel.lod.common.wrappers.config.ConfigGui;
/**
* This is the common main class
* @author Ran
*/
public class LodCommonMain {
public static boolean forge = false;
public static boolean serverSided;
public static LodForgeMethodCaller forgeMethodCaller;
public static NetworkInterface networkInterface;
public static void startup(LodForgeMethodCaller caller, boolean serverSided, NetworkInterface networkInterface) {
LodCommonMain.serverSided = serverSided;
if (caller != null) {
LodCommonMain.forge = true;
forgeMethodCaller = caller;
}
DependencySetup.createInitialBindings();
LodCommonMain.networkInterface = networkInterface;
if (!serverSided) {
networkInterface.register_Client();
} else {
networkInterface.register_Server();
}
}
public static void initConfig() {
ConfigGui.init(Config.class);
}
}
@@ -0,0 +1,19 @@
package com.seibel.lod.common.forge;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
import java.util.Random;
/**
* used for calling methods that forge modified
* (forge modifies vanilla methods for some reason)
* @author Ran
*/
public interface LodForgeMethodCaller {
List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, Random random);
}
@@ -0,0 +1,30 @@
package com.seibel.lod.common.networking;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
/**
* This is packet handler for our mod
* It basically handles the packets sent from the server & client
*
* @author Ran
*/
public class NetworkHandler {
// If you need the response sender then tell me
// I'll add extra code to get the response sender
public static void receivePacketClient(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf) {
// TODO: Server sided stuff here
// You can make client execute something by using client.execute(Runnable)
// In the fabric docs it says that client.execute is ran on the render thread?
}
// If you need the response sender then tell me
// I'll add extra code to get the response sender
public static void receivePacketServer(MinecraftServer server, ServerPlayer client, ServerGamePacketListenerImpl handler, FriendlyByteBuf buf) {
// TODO: Server sided stuff here
}
}
@@ -0,0 +1,9 @@
package com.seibel.lod.common.networking;
/**
* @author Ran
*/
public interface NetworkInterface {
void register_Client();
void register_Server();
}
@@ -0,0 +1,100 @@
package com.seibel.lod.common.networking;
import com.seibel.lod.core.ModInfo;
import io.netty.buffer.Unpooled;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import java.util.Objects;
/**
* This class holds most of the networking code for the mod.
* @author Ran
*/
public class Networking {
public static final ResourceLocation resourceLocation_meow = new ResourceLocation("lod", "meow");
public static FriendlyByteBuf createNew() {
// TODO: Probably replace the Unpooled.buffer()
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
buf.writeInt(ModInfo.PROTOCOL_VERSION);
return buf;
}
/*
* All code below is from the fabric api and might have been modified to work with Distant Horizons
* Which is licensed under the Apache License 2.0
*/
/**
* Sends a packet to a player.
*
* @param player the player to send the packet to
* @param buf the payload of the packet.
*/
public static void send(ServerPlayer player, FriendlyByteBuf buf) {
Objects.requireNonNull(player, "Server player entity cannot be null");
Objects.requireNonNull(resourceLocation_meow, "Channel name cannot be null");
Objects.requireNonNull(buf, "Packet byte buf cannot be null");
player.connection.send(createS2CPacket(resourceLocation_meow, buf));
}
/**
* Sends a packet to the connected server.
*
* @param buf the payload of the packet
* @throws IllegalStateException if the client is not connected to a server
*/
public static void send(FriendlyByteBuf buf) throws IllegalStateException {
// You cant send without a client player, so this is fine
if (Minecraft.getInstance().getConnection() != null) {
Minecraft.getInstance().getConnection().send(createC2SPacket(resourceLocation_meow, buf));
return;
}
throw new IllegalStateException("Cannot send packets when not in game!");
}
/**
* Creates a packet which may be sent to the connected client.
*
* @param channelName the channel name
* @param buf the packet byte buf which represents the payload of the packet
* @return a new packet
*/
public static Packet<?> createS2CPacket(ResourceLocation channelName, FriendlyByteBuf buf) {
Objects.requireNonNull(channelName, "Channel cannot be null");
Objects.requireNonNull(buf, "Buf cannot be null");
return createPlayS2CPacket(channelName, buf);
}
public static Packet<?> createPlayS2CPacket(ResourceLocation channel, FriendlyByteBuf buf) {
return new ClientboundCustomPayloadPacket(channel, buf);
}
/**
* Creates a packet which may be sent to a the connected server.
*
* @param channelName the channel name
* @param buf the packet byte buf which represents the payload of the packet
* @return a new packet
*/
public static Packet<?> createC2SPacket(ResourceLocation channelName, FriendlyByteBuf buf) {
Objects.requireNonNull(channelName, "Channel name cannot be null");
Objects.requireNonNull(buf, "Buf cannot be null");
return createPlayC2SPacket(channelName, buf);
}
public static Packet<?> createPlayC2SPacket(ResourceLocation channelName, FriendlyByteBuf buf) {
return new ServerboundCustomPayloadPacket(channelName, buf);
}
}
@@ -0,0 +1,38 @@
package com.seibel.lod.common.wrappers;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.lod.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.lod.core.handlers.IReflectionHandler;
import com.seibel.lod.core.handlers.ReflectionHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.IVersionConstants;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
/**
* Binds all necessary dependencies, so we
* can access them in Core. <br>
* This needs to be called before any Core classes
* are loaded.
*
* @author James Seibel
* @author Ran
* @version 12-1-2021
*/
public class DependencySetup {
public static void createInitialBindings()
{
SingletonHandler.bind(IVersionConstants.class, VersionConstants.INSTANCE);
if (!LodCommonMain.serverSided)
{
SingletonHandler.bind(IMinecraftClientWrapper.class, MinecraftClientWrapper.INSTANCE);
SingletonHandler.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE);
SingletonHandler.bind(IReflectionHandler.class, ReflectionHandler.createSingleton(MinecraftClientWrapper.INSTANCE.getOptions().getClass().getDeclaredFields(), MinecraftClientWrapper.INSTANCE.getOptions()));
}
SingletonHandler.bind(IWrapperFactory.class, WrapperFactory.INSTANCE);
DependencySetupDoneCheck.isDone = true;
}
}
@@ -0,0 +1,10 @@
package com.seibel.lod.common.wrappers;
import java.util.function.Supplier;
public class DependencySetupDoneCheck
{
public static boolean isDone = false;
public static Supplier<Boolean> getIsCurrentThreadDistantGeneratorThread = (() -> {return false;});
}
@@ -0,0 +1,79 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common.wrappers;
import java.nio.FloatBuffer;
import com.mojang.math.Matrix4f;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
/**
* This class converts to and from Minecraft objects (Ex: Matrix4f)
* and objects we created (Ex: Mat4f).
*
* @author James Seibel
* @version 11-20-2021
*/
public class McObjectConverter
{
/** 4x4 float matrix converter */
public static Mat4f Convert(Matrix4f mcMatrix)
{
FloatBuffer buffer = FloatBuffer.allocate(16);
mcMatrix.store(buffer);
Mat4f matrix = new Mat4f(buffer);
matrix.transpose();
return matrix;
}
static final Direction[] directions;
static final LodDirection[] lodDirections;
static {
LodDirection[] lodDirs = LodDirection.values();
directions = new Direction[lodDirs.length];
lodDirections = new LodDirection[lodDirs.length];
for (LodDirection lodDir : lodDirs) {
Direction dir = Direction.byName(lodDir.name());
directions[lodDir.ordinal()] = dir;
lodDirections[dir.ordinal()] = lodDir;
}
}
public static BlockPos Convert(AbstractBlockPosWrapper wrappedPos) {
return new BlockPos(wrappedPos.getX(),wrappedPos.getY(), wrappedPos.getZ());
}
public static Direction Convert(LodDirection lodDirection)
{
return directions[lodDirection.ordinal()];
}
public static LodDirection Convert(Direction direction)
{
return lodDirections[direction.ordinal()];
}
}
@@ -0,0 +1,39 @@
package com.seibel.lod.common.wrappers;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.wrapperInterfaces.IVersionConstants;
/**
* @author James Seibel
* @version 12-11-2021
*/
public class VersionConstants implements IVersionConstants
{
public static final VersionConstants INSTANCE = new VersionConstants();
private VersionConstants()
{
}
@Override
public int getMinimumWorldHeight()
{
return 0;
}
@Override
public int getWorldGenerationCountPerThread()
{
return 1;
}
@Override
public boolean isVanillaRenderedChunkSquare()
{
return false;
}
}
@@ -0,0 +1,94 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common.wrappers;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import com.seibel.lod.common.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
/**
* This handles creating abstract wrapper objects.
*
* @author James Seibel
* @version 11-20-2021
*/
public class WrapperFactory implements IWrapperFactory
{
public static final WrapperFactory INSTANCE = new WrapperFactory();
@Override
public AbstractBlockPosWrapper createBlockPos()
{
return new BlockPosWrapper();
}
@Override
public AbstractBlockPosWrapper createBlockPos(int x, int y, int z)
{
return new BlockPosWrapper(x, y, z);
}
@Override
public AbstractChunkPosWrapper createChunkPos()
{
return new ChunkPosWrapper();
}
@Override
public AbstractChunkPosWrapper createChunkPos(long xAndZPositionCombined)
{
return new ChunkPosWrapper(xAndZPositionCombined);
}
@Override
public AbstractChunkPosWrapper createChunkPos(int x, int z)
{
return new ChunkPosWrapper(x, z);
}
@Override
public AbstractChunkPosWrapper createChunkPos(AbstractChunkPosWrapper newChunkPos)
{
return new ChunkPosWrapper(newChunkPos);
}
@Override
public AbstractChunkPosWrapper createChunkPos(AbstractBlockPosWrapper blockPos)
{
return new ChunkPosWrapper(blockPos);
}
public AbstractBatchGenerationEnvionmentWrapper createBatchGenerator(LodBuilder newLodBuilder,
LodDimension newLodDimension, IWorldWrapper worldWrapper)
{
return new BatchGenerationEnvironment(worldWrapper, newLodBuilder, newLodDimension);
}
}
@@ -1,5 +1,6 @@
/*
* This file is part of the LOD Mod, licensed under the GNU GPL v3 License.
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
@@ -15,29 +16,19 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.enums;
package com.seibel.lod.common.wrappers;
import net.minecraft.world.level.levelgen.Heightmap;
/**
* NE, SE, SW, NW
*
* Stores any variables or code that
* may be shared between wrapper objects.
*
* @author James Seibel
* @version 1-20-2020
* @version 11-20-2021
*/
public enum LodCorner
{
/** -Z, +X */
NE(0),
/** +Z, +X */
SE(1),
/** +Z, -X */
SW(2),
/** -Z, -X */
NW(3);
public final int value;
private LodCorner(int newValue)
{
value = newValue;
}
public class WrapperUtil {
/** If we ever need to use a heightmap for any reason, use this one. */
public static final Heightmap.Types DEFAULT_HEIGHTMAP = Heightmap.Types.WORLD_SURFACE_WG;
}
@@ -0,0 +1,27 @@
package com.seibel.lod.common.wrappers.block;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.state.BlockState;
public class BlockDetailMap
{
private static ConcurrentHashMap<BlockState, BlockDetailWrapper> map = new ConcurrentHashMap<BlockState, BlockDetailWrapper>();
private BlockDetailMap() {}
public static BlockDetailWrapper getOrMakeBlockDetailCache(BlockState bs, BlockPos pos, LevelReader getter) {
BlockDetailWrapper cache = map.get(bs);
if (cache != null) return cache;
if (bs.getFluidState().isEmpty()) {
cache = BlockDetailWrapper.make(bs, pos, getter);
} else {
cache = BlockDetailWrapper.make(bs.getFluidState().createLegacyBlock(), pos, getter);
}
BlockDetailWrapper cacheCAS = map.putIfAbsent(bs, cache);
return cacheCAS==null ? cache : cacheCAS;
}
}
@@ -0,0 +1,326 @@
package com.seibel.lod.common.wrappers.block;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import com.seibel.lod.common.Config;
import com.seibel.lod.common.wrappers.McObjectConverter;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockTintCache;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Cursor3D;
import net.minecraft.core.Direction;
import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.FlowerBlock;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.RotatedPillarBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
public class BlockDetailWrapper extends IBlockDetailWrapper
{
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final int FLOWER_COLOR_SCALE = 5;
public static final Random random = new Random(0);
enum ColorMode {
Default,
Flower,
Leaves;
static ColorMode getColorMode(Block b) {
if (b instanceof LeavesBlock) return Leaves;
if (b instanceof FlowerBlock) return Flower;
return Default;
}
}
//TODO: Perhaps make this not just use the first frame?
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode) {
int count = 0;
double alpha = 0;
double red = 0;
double green = 0;
double blue = 0;
int tempColor;
{
// textures normally use u and v instead of x and y
for (int u = 0; u < texture.getWidth(); u++)
{
for (int v = 0; v < texture.getHeight(); v++)
{
//note: Minecraft color format is: 0xAA BB GG RR
//________ DH mod color format is: 0xAA RR GG BB
//OpenGL RGBA format native order: 0xRR GG BB AA
//_ OpenGL RGBA format Java Order: 0xAA BB GG RR
tempColor = TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v);
double r = ((tempColor & 0x000000FF) )/255.;
double g = ((tempColor & 0x0000FF00) >>> 8)/255.;
double b = ((tempColor & 0x00FF0000) >>> 16)/255.;
double a = ((tempColor & 0xFF000000) >>> 24)/255.;
int scale = 1;
if (colorMode == ColorMode.Leaves) {
r *= a;
g *= a;
b *= a;
a = 1.;
} else if (a==0.) {
continue;
} else if (colorMode == ColorMode.Flower && (g+0.1<b || g+0.1<r)) {
scale = FLOWER_COLOR_SCALE;
}
count += scale;
alpha += a*a*scale;
red += r*r*scale;
green += g*g*scale;
blue += b*b*scale;
}
}
}
if (count == 0)
// this block is entirely transparent
tempColor = ColorUtil.rgbToInt(255,255,0,255);
else
{
// determine the average color
tempColor = ColorUtil.rgbToInt(
(int) (Math.sqrt(alpha/count)*255.),
(int) (Math.sqrt(red / count)*255.),
(int) (Math.sqrt(green / count)*255.),
(int) (Math.sqrt(blue / count)*255.));
}
// TODO: Remove this when transparency is added!
double colorAlpha = ColorUtil.getAlpha(tempColor)/255.;
tempColor = ColorUtil.rgbToInt(
ColorUtil.getAlpha(tempColor),
(int)(ColorUtil.getRed(tempColor) * colorAlpha),
(int)(ColorUtil.getGreen(tempColor) * colorAlpha),
(int)(ColorUtil.getBlue(tempColor) * colorAlpha)
);
return tempColor;
}
private static final Block[] BLOCK_TO_AVOID = {Blocks.AIR, Blocks.CAVE_AIR, Blocks.BARRIER};
private static final Direction[] DIRECTION_ORDER = {Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN};
private static boolean isBlockToBeAvoid(Block b) {
for (Block bta : BLOCK_TO_AVOID)
if (bta==b) return true;
return false;
}
final BlockState state;
final BlockPos samplePos;
final LevelReader sampleGetter;
boolean isShapeResolved = false;
boolean[] dontOccludeFaces = null;
boolean noCollision = false;
boolean noFullFace = false;
boolean isColorResolved = false;
int baseColor = 0; //TODO: Impl per-face color
boolean needShade = true;
boolean needPostTinting = false;
int tintIndex = 0;
public static BlockDetailWrapper NULL_BLOCK_DETAIL = new BlockDetailWrapper();
public BlockDetailWrapper(BlockState state, BlockPos pos, LevelReader getter) {
this.state = state;
this.samplePos = pos;
this.sampleGetter = getter;
}
private BlockDetailWrapper() {
this.state = null;
this.samplePos = null;
this.sampleGetter = null;
}
static BlockDetailWrapper make(BlockState bs, BlockPos pos, LevelReader getter) {
if(!bs.getFluidState().isEmpty()) { // Is a fluidBlock
if (isBlockToBeAvoid(bs.getBlock())) return NULL_BLOCK_DETAIL;
if (bs.isAir()) return NULL_BLOCK_DETAIL;
return new BlockDetailWrapper(bs, pos, getter);
} else {
if (bs.getRenderShape() != RenderShape.MODEL) return NULL_BLOCK_DETAIL;
if (isBlockToBeAvoid(bs.getBlock())) return NULL_BLOCK_DETAIL;
return new BlockDetailWrapper(bs, pos, getter);
}
}
private void resolveShapes() {
if (isShapeResolved) return;
if (state.getFluidState().isEmpty()) {
noCollision = state.getCollisionShape(sampleGetter, samplePos).isEmpty();
dontOccludeFaces = new boolean[6];
if (state.canOcclude()) {
/* FIXME: Figure out how or if needed to impl per-face culling?
for (Direction dir : Direction.values()) {
dontOccludeFaces[McObjectConverter.Convert(dir).ordinal()]
= state.getFaceOcclusionShape(sampleGetter, samplePos, dir).isEmpty();
}*/
} else {
Arrays.fill(dontOccludeFaces, true);
}
VoxelShape voxelShape = state.getShape(sampleGetter, samplePos);
if (voxelShape.isEmpty()) {
noFullFace = true;
} else {
AABB bbox = voxelShape.bounds();
double xWidth = (bbox.maxX - bbox.minX);
double yWidth = (bbox.maxY - bbox.minY);
double zWidth = (bbox.maxZ - bbox.minZ);
noFullFace = xWidth < 1 && zWidth < 1 && yWidth < 1;
}
} else { // Liquid Block
dontOccludeFaces = new boolean[6];
}
isShapeResolved = true;
}
private void resolveColors() {
if (isColorResolved) return;
if (state.getFluidState().isEmpty()) {
List<BakedQuad> quads = null;
for (Direction direction : DIRECTION_ORDER)
{
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
getBlockModel(state).getQuads(state, direction, random);
if (!quads.isEmpty() &&
!(state.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP))
break;
};
if (quads == null || quads.isEmpty()) {
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
getBlockModel(state).getQuads(state, null, random);
}
if (quads != null && !quads.isEmpty()) {
needPostTinting = quads.get(0).isTinted();
needShade = quads.get(0).isShade();
tintIndex = quads.get(0).getTintIndex();
baseColor = calculateColorFromTexture(quads.get(0).getSprite(),
ColorMode.getColorMode(state.getBlock()));
} else { // Backup method.
needPostTinting = false;
needShade = false;
tintIndex = 0;
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(state),
ColorMode.getColorMode(state.getBlock()));
}
} else { // Liquid Block
needPostTinting = true;
needShade = false;
tintIndex = 0;
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(state),
ColorMode.getColorMode(state.getBlock()));
}
isColorResolved = true;
}
private BlockAndTintGetter wrapColorResolver(LevelReader level) {
int blendDistance = CONFIG.client().graphics().quality().getLodBiomeBlending();
if (blendDistance == 0) {
return new TintGetterOverrideFast(level);
} else {
return new TintGetterOverrideSmooth(level, blendDistance);
}
}
@Override
public int getAndResolveFaceColor(LodDirection dir, IChunkWrapper chunk, AbstractBlockPosWrapper blockPos)
{
// FIXME: impl per-face colors
resolveColors();
if (!needPostTinting) return baseColor;
int tintColor = Minecraft.getInstance().getBlockColors()
.getColor(state, wrapColorResolver(((ChunkWrapper)chunk).getColorResolver()),
McObjectConverter.Convert(blockPos), tintIndex);
if (tintColor == -1) return baseColor;
return ColorUtil.multiplyARGBwithRGB(baseColor, tintColor);
}
@Override
public boolean hasFaceCullingFor(LodDirection dir)
{
resolveShapes();
return !dontOccludeFaces[dir.ordinal()];
}
@Override
public boolean hasNoCollision()
{
resolveShapes();
return noCollision;
}
@Override
public boolean noFaceIsFullFace()
{
resolveShapes();
return noFullFace;
}
@Override
public String serialize()
{
// FIXME: Impl this for the blockState Storage stuff
return null;
}
@Override
protected boolean isSame(IBlockDetailWrapper iBlockDetail)
{
return ((BlockDetailWrapper)iBlockDetail).state.getBlock().equals(state.getBlock());
}
}
@@ -0,0 +1,84 @@
package com.seibel.lod.common.wrappers.block;
import java.util.Objects;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import net.minecraft.core.BlockPos;
/**
* @author James Seibel
* @version 11-21-2021
*/
public class BlockPosWrapper extends AbstractBlockPosWrapper
{
private final BlockPos.MutableBlockPos blockPos;
public BlockPosWrapper()
{
this.blockPos = new BlockPos.MutableBlockPos(0,0,0);
}
public BlockPosWrapper(int x, int y, int z)
{
this.blockPos = new BlockPos.MutableBlockPos(x, y, z);
}
@Override
public void set(int x, int y, int z)
{
blockPos.set(x, y, z);
}
@Override
public int getX()
{
return blockPos.getX();
}
@Override
public int getY()
{
return blockPos.getY();
}
@Override
public int getZ()
{
return blockPos.getZ();
}
@Override
public int get(LodDirection.Axis axis)
{
return axis.choose(getX(), getY(), getZ());
}
public BlockPos.MutableBlockPos getBlockPos()
{
return blockPos;
}
@Override public boolean equals(Object o)
{
return blockPos.equals(o);
}
@Override public int hashCode()
{
return Objects.hash(blockPos);
}
@Override
public BlockPosWrapper offset(int x, int y, int z)
{
blockPos.set(blockPos.getX() + x, blockPos.getY() + y, blockPos.getZ() + z);
return this;
}
}
@@ -0,0 +1,28 @@
package com.seibel.lod.common.wrappers.block;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
/**
* For wrapping/utilizing around TextureAtlasSprite
* @author Ran
*/
public class TextureAtlasSpriteWrapper {
/**
* This code is from Minecraft Forge
* Which is licensed under the terms of GNU Lesser General Public License
* as published by the Free Software Foundation version 2.1
* of the License.
*
* The code has been modified to use TextureAtlasSprite
*/
public static int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y) {
if (sprite.animatedTexture != null) {
x += sprite.animatedTexture.getFrameX(frameIndex) * sprite.width;
y += sprite.animatedTexture.getFrameY(frameIndex) * sprite.height;
}
return sprite.mainImage[0].getPixelRGBA(x, y);
}
}
@@ -0,0 +1,190 @@
package com.seibel.lod.common.wrappers.block;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.minecraft.Util;
import net.minecraft.client.color.block.BlockTintCache;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Cursor3D;
import net.minecraft.core.Direction;
import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class TintGetterOverrideFast implements BlockAndTintGetter {
LevelReader parent;
public TintGetterOverrideFast(LevelReader parent) {
this.parent = parent;
}
private Biome _getBiome(BlockPos pos) {
#if MC_VERSION_1_18_2
return parent.getBiome(pos).value();
#elif MC_VERSION_1_18_1
return parent.getBiome(pos);
#endif
}
@Override
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
Biome b = _getBiome(blockPos);
return colorResolver.getColor(b, blockPos.getX(), blockPos.getZ());
}
@Override
public float getShade(Direction direction, boolean bl) {
return parent.getShade(direction, bl);
}
@Override
public LevelLightEngine getLightEngine() {
return parent.getLightEngine();
}
@Override
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
return parent.getBrightness(lightLayer, blockPos);
}
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
return parent.getRawBrightness(blockPos, i);
}
@Override
public boolean canSeeSky(BlockPos blockPos) {
return parent.canSeeSky(blockPos);
}
@Override
@Nullable
public BlockEntity getBlockEntity(BlockPos blockPos) {
return parent.getBlockEntity(blockPos);
}
@Override
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) {
return parent.getBlockEntity(blockPos, blockEntityType);
}
@Override
public BlockState getBlockState(BlockPos blockPos) {
return parent.getBlockState(blockPos);
}
@Override
public FluidState getFluidState(BlockPos blockPos) {
return parent.getFluidState(blockPos);
}
@Override
public int getLightEmission(BlockPos blockPos) {
return parent.getLightEmission(blockPos);
}
@Override
public int getMaxLightLevel() {
return parent.getMaxLightLevel();
}
@Override
public Stream<BlockState> getBlockStates(AABB aABB) {
return parent.getBlockStates(aABB);
}
@Override
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) {
return parent.isBlockInLine(clipBlockStateContext);
}
@Override
public BlockHitResult clip(ClipContext clipContext) {
return parent.clip(clipContext);
}
@Override
@Nullable
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState) {
return parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
}
@Override
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier) {
return parent.getBlockFloorHeight(voxelShape, supplier);
}
@Override
public double getBlockFloorHeight(BlockPos blockPos) {
return parent.getBlockFloorHeight(blockPos);
}
@Override
public int getHeight() {
return parent.getHeight();
}
@Override
public int getMinBuildHeight() {
return parent.getMinBuildHeight();
}
@Override
public int getMaxBuildHeight() {
return parent.getMaxBuildHeight();
}
@Override
public int getSectionsCount() {
return parent.getSectionsCount();
}
@Override
public int getMinSection() {
return parent.getMinSection();
}
@Override
public int getMaxSection() {
return parent.getMaxSection();
}
@Override
public boolean isOutsideBuildHeight(BlockPos blockPos) {
return parent.isOutsideBuildHeight(blockPos);
}
@Override
public boolean isOutsideBuildHeight(int i) {
return parent.isOutsideBuildHeight(i);
}
@Override
public int getSectionIndex(int i) {
return parent.getSectionIndex(i);
}
@Override
public int getSectionIndexFromSectionY(int i) {
return parent.getSectionIndexFromSectionY(i);
}
@Override
public int getSectionYFromSectionIndex(int i) {
return parent.getSectionYFromSectionIndex(i);
}
}
@@ -0,0 +1,212 @@
package com.seibel.lod.common.wrappers.block;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.minecraft.Util;
import net.minecraft.client.color.block.BlockTintCache;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Cursor3D;
import net.minecraft.core.Direction;
import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class TintGetterOverrideSmooth implements BlockAndTintGetter {
LevelReader parent;
public int smoothingRange;
public TintGetterOverrideSmooth(LevelReader parent, int smoothingRange) {
this.parent = parent;
this.smoothingRange = smoothingRange;
}
private Biome _getBiome(BlockPos pos) {
#if MC_VERSION_1_18_2
return parent.getBiome(pos).value();
#elif MC_VERSION_1_18_1
return parent.getBiome(pos);
#endif
}
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
{
int i = smoothingRange;
if (i == 0)
return colorResolver.getColor(_getBiome(blockPos), blockPos.getX(), blockPos.getZ());
int j = (i * 2 + 1) * (i * 2 + 1);
int k = 0;
int l = 0;
int m = 0;
Cursor3D cursor3D = new Cursor3D(blockPos.getX() - i, blockPos.getY(), blockPos.getZ() - i, blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + i);
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
while (cursor3D.advance())
{
mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
int n = colorResolver.getColor(_getBiome(mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
k += (n & 0xFF0000) >> 16;
l += (n & 0xFF00) >> 8;
m += n & 0xFF;
}
return (k / j & 0xFF) << 16 | (l / j & 0xFF) << 8 | m / j & 0xFF;
}
@Override
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
return calculateBlockTint(blockPos, colorResolver);
}
@Override
public float getShade(Direction direction, boolean bl) {
return parent.getShade(direction, bl);
}
@Override
public LevelLightEngine getLightEngine() {
return parent.getLightEngine();
}
@Override
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
return parent.getBrightness(lightLayer, blockPos);
}
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
return parent.getRawBrightness(blockPos, i);
}
@Override
public boolean canSeeSky(BlockPos blockPos) {
return parent.canSeeSky(blockPos);
}
@Override
@Nullable
public BlockEntity getBlockEntity(BlockPos blockPos) {
return parent.getBlockEntity(blockPos);
}
@Override
public <T extends BlockEntity> Optional<T> getBlockEntity(BlockPos blockPos, BlockEntityType<T> blockEntityType) {
return parent.getBlockEntity(blockPos, blockEntityType);
}
@Override
public BlockState getBlockState(BlockPos blockPos) {
return parent.getBlockState(blockPos);
}
@Override
public FluidState getFluidState(BlockPos blockPos) {
return parent.getFluidState(blockPos);
}
@Override
public int getLightEmission(BlockPos blockPos) {
return parent.getLightEmission(blockPos);
}
@Override
public int getMaxLightLevel() {
return parent.getMaxLightLevel();
}
@Override
public Stream<BlockState> getBlockStates(AABB aABB) {
return parent.getBlockStates(aABB);
}
@Override
public BlockHitResult isBlockInLine(ClipBlockStateContext clipBlockStateContext) {
return parent.isBlockInLine(clipBlockStateContext);
}
@Override
public BlockHitResult clip(ClipContext clipContext) {
return parent.clip(clipContext);
}
@Override
@Nullable
public BlockHitResult clipWithInteractionOverride(Vec3 vec3, Vec3 vec32, BlockPos blockPos, VoxelShape voxelShape, BlockState blockState) {
return parent.clipWithInteractionOverride(vec3, vec32, blockPos, voxelShape, blockState);
}
@Override
public double getBlockFloorHeight(VoxelShape voxelShape, Supplier<VoxelShape> supplier) {
return parent.getBlockFloorHeight(voxelShape, supplier);
}
@Override
public double getBlockFloorHeight(BlockPos blockPos) {
return parent.getBlockFloorHeight(blockPos);
}
@Override
public int getHeight() {
return parent.getHeight();
}
@Override
public int getMinBuildHeight() {
return parent.getMinBuildHeight();
}
@Override
public int getMaxBuildHeight() {
return parent.getMaxBuildHeight();
}
@Override
public int getSectionsCount() {
return parent.getSectionsCount();
}
@Override
public int getMinSection() {
return parent.getMinSection();
}
@Override
public int getMaxSection() {
return parent.getMaxSection();
}
@Override
public boolean isOutsideBuildHeight(BlockPos blockPos) {
return parent.isOutsideBuildHeight(blockPos);
}
@Override
public boolean isOutsideBuildHeight(int i) {
return parent.isOutsideBuildHeight(i);
}
@Override
public int getSectionIndex(int i) {
return parent.getSectionIndex(i);
}
@Override
public int getSectionIndexFromSectionY(int i) {
return parent.getSectionIndexFromSectionY(i);
}
@Override
public int getSectionYFromSectionIndex(int i) {
return parent.getSectionYFromSectionIndex(i);
}
}
@@ -0,0 +1,136 @@
package com.seibel.lod.common.wrappers.chunk;
import java.util.Objects;
import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;
/**
* @author James Seibel
* @version 11-21-2021
*/
public class ChunkPosWrapper extends AbstractChunkPosWrapper
{
private final net.minecraft.world.level.ChunkPos chunkPos;
public ChunkPosWrapper()
{
this.chunkPos = new ChunkPos(0, 0);
}
public ChunkPosWrapper(BlockPos blockPos)
{
this.chunkPos = new ChunkPos(blockPos);
}
public ChunkPosWrapper(AbstractChunkPosWrapper newChunkPos)
{
this.chunkPos = ((ChunkPosWrapper) newChunkPos).chunkPos;
}
public ChunkPosWrapper(AbstractBlockPosWrapper blockPos)
{
this.chunkPos = new ChunkPos(((BlockPosWrapper) blockPos).getBlockPos());
}
public ChunkPosWrapper(int chunkX, int chunkZ)
{
this.chunkPos = new ChunkPos(chunkX, chunkZ);
}
public ChunkPosWrapper(long l) {
this.chunkPos = new ChunkPos(l);
}
public ChunkPosWrapper(ChunkPos pos)
{
this.chunkPos = pos;
}
@Override
public int getX()
{
return chunkPos.x;
}
@Override
public int getZ()
{
return chunkPos.z;
}
@Override
public int getMinBlockX()
{
return chunkPos.getMinBlockX();
}
@Override
public int getMinBlockZ()
{
return chunkPos.getMinBlockZ();
}
@Override
public int getRegionX()
{
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, LodUtil.REGION_DETAIL_LEVEL);
}
@Override
public int getRegionZ()
{
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.z, LodUtil.REGION_DETAIL_LEVEL);
}
@Override
public long getLong() {
return chunkPos.toLong();
}
public ChunkPos getChunkPos()
{
return chunkPos;
}
@Override
public boolean equals(Object o)
{
// If the object is compared with itself then return true
if (o == this) {
return true;
}
// Check if o is an instance of RegionPos or not
if (!(o instanceof ChunkPosWrapper)) {
return false;
}
ChunkPosWrapper c = (ChunkPosWrapper) o;
return c.chunkPos.equals(chunkPos);
}
@Override
public int hashCode()
{
return Objects.hash(chunkPos);
}
@Override
public AbstractBlockPosWrapper getWorldPosition()
{
// the parameter here is the y position
BlockPos blockPos = chunkPos.getMiddleBlockPosition(0);
return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ());
}
}
@@ -0,0 +1,208 @@
package com.seibel.lod.common.wrappers.chunk;
import com.seibel.lod.common.wrappers.block.BlockDetailWrapper;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.lod.common.wrappers.WrapperUtil;
import com.seibel.lod.common.wrappers.block.BlockDetailMap;
import com.seibel.lod.common.wrappers.world.BiomeWrapper;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
import net.minecraft.core.BlockPos;
import net.minecraft.core.QuartPos;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.block.LiquidBlockContainer;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.levelgen.Heightmap;
/**
*
* @author James Seibel
* @version 3-5-2022
*/
public class ChunkWrapper implements IChunkWrapper
{
private final ChunkAccess chunk;
private final LevelReader lightSource;
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource)
{
this.chunk = chunk;
this.lightSource = lightSource;
}
@Override
public int getHeight(){
return chunk.getHeight();
}
@Override
public int getMinBuildHeight()
{
return chunk.getMinBuildHeight();
}
@Override
public int getMaxBuildHeight()
{
return chunk.getMaxBuildHeight();
}
@Override
public int getHeightMapValue(int xRel, int zRel)
{
return chunk.getOrCreateHeightmapUnprimed(WrapperUtil.DEFAULT_HEIGHTMAP).getFirstAvailable(xRel, zRel);
}
@Override
public IBiomeWrapper getBiome(int x, int y, int z)
{
#if MC_VERSION_1_18_2
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)).value());
#elif MC_VERSION_1_18_1
return BiomeWrapper.getBiomeWrapper(chunk.getNoiseBiome(
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
#endif
}
@Override
public IBlockDetailWrapper getBlockDetail(int x, int y, int z) {
BlockPos pos = new BlockPos(x,y,z);
BlockState blockState = chunk.getBlockState(pos);
IBlockDetailWrapper blockDetail = BlockDetailMap.getOrMakeBlockDetailCache(blockState, pos, lightSource);
return blockDetail == BlockDetailWrapper.NULL_BLOCK_DETAIL ? null : blockDetail;
}
@Override
public IBlockDetailWrapper getBlockDetailAtFace(int x, int y, int z, LodDirection dir) {
int fy = y+dir.getNormal().y;
if (fy < getMinBuildHeight() || fy > getMaxBuildHeight()) return null;
BlockPos pos = new BlockPos(x+dir.getNormal().x,fy,z+dir.getNormal().z);
BlockState blockState;
if (blockPosInsideChunk(x,y,z))
blockState = chunk.getBlockState(pos);
else {
blockState = lightSource.getBlockState(pos);
}
if (blockState == null || blockState.isAir()) return null;
IBlockDetailWrapper blockDetail = BlockDetailMap.getOrMakeBlockDetailCache(blockState, pos, lightSource);
return blockDetail == BlockDetailWrapper.NULL_BLOCK_DETAIL ? null : blockDetail;
}
public ChunkAccess getChunk() {
return chunk;
}
@Override
public int getChunkPosX(){
return chunk.getPos().x;
}
@Override
public int getChunkPosZ(){
return chunk.getPos().z;
}
@Override
public int getRegionPosX(){
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, LodUtil.REGION_DETAIL_LEVEL);
}
@Override
public int getRegionPosZ(){
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().z, LodUtil.REGION_DETAIL_LEVEL);
}
@Override
public int getMaxY(int x, int z) {
return chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, Math.floorMod(x, 16), Math.floorMod(z, 16));
}
@Override
public int getMaxX(){
return chunk.getPos().getMaxBlockX();
}
@Override
public int getMaxZ(){
return chunk.getPos().getMaxBlockZ();
}
@Override
public int getMinX(){
return chunk.getPos().getMinBlockX();
}
@Override
public int getMinZ() {
return chunk.getPos().getMinBlockZ();
}
@Override
public long getLongChunkPos() {
return chunk.getPos().toLong();
}
@Override
public boolean isLightCorrect(){
//return true;
if (chunk instanceof LevelChunk) {
return ((LevelChunk) chunk).isClientLightReady();
}
return chunk.isLightCorrect();
}
public boolean isWaterLogged(int x, int y, int z)
{
BlockState blockState = chunk.getBlockState(new BlockPos(x,y,z));
//This type of block is always in water
return (!(blockState.getBlock() instanceof LiquidBlockContainer) && (blockState.getBlock() instanceof SimpleWaterloggedBlock))
&& (blockState.hasProperty(BlockStateProperties.WATERLOGGED) && blockState.getValue(BlockStateProperties.WATERLOGGED));
}
@Override
public int getEmittedBrightness(int x, int y, int z)
{
return chunk.getLightEmission(new BlockPos(x,y,z));
}
@Override
public int getBlockLight(int x, int y, int z) {
if (lightSource == null) return -1;
return lightSource.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
}
@Override
public int getSkyLight(int x, int y, int z) {
if (lightSource == null) return -1;
return lightSource.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
}
@Override
public boolean doesNearbyChunksExist() {
if (lightSource instanceof LightedWorldGenRegion) return true;
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
if (dx==0 && dz==0) continue;
if (lightSource.getChunk(dx+getChunkPosX(), dz+getChunkPosZ(), ChunkStatus.BIOMES, false) == null) return false;
}
}
return true;
}
public LevelReader getColorResolver()
{
return lightSource;
}
}
@@ -0,0 +1,762 @@
package com.seibel.lod.common.wrappers.config;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
// Logger (for debug stuff)
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
// Uses https://github.com/TheElectronWill/night-config for toml (only for Fabric since Forge already includes this)
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
// Gets info from our own mod
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.config.*;
// Minecraft imports
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.client.resources.language.I18n; // translation
import net.minecraft.client.gui.narration.NarratableEntry; // Remove in 1.16
/**
* Based upon TinyConfig
* https://github.com/Minenash/TinyConfig
*
* This config should work for both Fabric and Forge as long as you use Mojang mappings
*
* Credits to Motschen
*
* @author coolGi2007
* @version 1-14-2022
*/
@SuppressWarnings("unchecked")
public abstract class ConfigGui
{
/*
TODO list
Fix floats not working
Make a wiki
Make it so you can enable and disable buttons from showing
Make min and max not final
Move the ConfigScreenConfigs class to the config class that extends this
*/
/*
List of hacky things that are done that should be done properly
The buttons that don't show are still loaded but just not rendered
The screen with is set to double so the scroll bar doesn't show
*/
private static final Pattern INTEGER_ONLY_REGEX = Pattern.compile("(-?[0-9]*)");
private static final Pattern DECIMAL_ONLY_REGEX = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
private static final List<EntryInfo> entries = new ArrayList<>();
public static final Map<String,EntryInfo> entryMap = new HashMap<>();
// Change these to your own mod
private static final String MOD_NAME = ModInfo.NAME; // For file saving and identifying
private static final String MOD_NAME_READABLE = ModInfo.READABLE_NAME; // For logs
// private static final Logger LOGGER = ApiShared.LOGGER; // For logs
private static final Logger LOGGER = LogManager.getLogger(ModInfo.NAME); // For logs (this inits before ClientAPI so this is a temp fix)
//==============//
// Initializers //
//==============//
private static class ConfigScreenConfigs
{
// This contains all the configs for the configs
public static final int SpaceFromRightScreen = 10;
public static final int ButtonWidthSpacing = 5;
public static final int ResetButtonWidth = 40;
}
public static class EntryInfo<T>
{
Field field;
Object widget;
int width = 0;
int max;
Map.Entry<EditBox, Component> error;
Object defaultValue;
Object value;
String tempValue;
boolean inLimits = true;
TranslatableComponent name;
int index;
/** Hides the button */
boolean hideOption = false;
/** This asks if it is a button to goto a new screen */
boolean screenButton = false;
/** This is only called if button is true */
String gotoScreen = "";
String category;
Class<T> varClass;
@Deprecated
boolean fileComment = false;
}
private static Path configFilePath;
public static void init(Class<?> config)
{
Minecraft mc = Minecraft.getInstance();
configFilePath = mc.gameDirectory.toPath().resolve("config").resolve(MOD_NAME + ".toml");
initNestedClass(config, "");
for (EntryInfo info : entries) {
if (info.field.isAnnotationPresent(ConfigAnnotations.Entry.class)) {
try {
info.value = info.field.get(null);
info.tempValue = info.value.toString();
} catch (IllegalAccessException ignored) {
}
}
}
loadFromFile();
}
private static void initNestedClass(Class<?> config, String category)
{
for (Field field : config.getFields())
{
EntryInfo info = new EntryInfo();
if (field.isAnnotationPresent(ConfigAnnotations.Entry.class) || field.isAnnotationPresent(ConfigAnnotations.Comment.class) || field.isAnnotationPresent(ConfigAnnotations.ScreenEntry.class))
{
// If putting in your own mod then put your own check for server sided
info.category = category;
if (!LodCommonMain.serverSided)
initClient(field, info, category);
}
if (field.isAnnotationPresent(ConfigAnnotations.Entry.class))
{
entryMap.put((!category.isEmpty() ? category + "." : "") + field.getName(), info);
info.varClass = field.getType();
try
{
info.defaultValue = field.get(null);
}
catch (IllegalAccessException ignored) {}
}
if (field.isAnnotationPresent(ConfigAnnotations.ScreenEntry.class))
initNestedClass(field.getType(), (!category.isEmpty() ? category + "." : "") + field.getName());
// File comment (WILL BE REMOVED SOON)
if (field.isAnnotationPresent(ConfigAnnotations.FileComment.class)) {
entryMap.put((!category.isEmpty() ? category + "." : "") + field.getName(), info);
info.fileComment = true;
try
{
info.value = info.defaultValue = field.get(null);
}
catch (IllegalAccessException ignored) {}
}
info.field = field;
}
}
/** This adds the buttons to the queue to be rendered */
private static void initClient(Field field, EntryInfo info, String category)
{
Class<?> fieldClass = field.getType();
ConfigAnnotations.Entry entry = field.getAnnotation(ConfigAnnotations.Entry.class);
ConfigAnnotations.ScreenEntry screenEntry = field.getAnnotation(ConfigAnnotations.ScreenEntry.class);
if (entry != null)
info.width = entry.width();
else if (screenEntry != null)
info.width = screenEntry.width();
if (entry != null)
{
if (!entry.name().equals(""))
info.name = new TranslatableComponent(entry.name());
if (fieldClass == int.class)
{
// For int
textField(info, Integer::parseInt, INTEGER_ONLY_REGEX, entry.minValue(), entry.maxValue(), true);
}
else if (fieldClass == double.class)
{
// For double
textField(info, Double::parseDouble, DECIMAL_ONLY_REGEX, entry.minValue(), entry.maxValue(), false);
}
else if (fieldClass == String.class || fieldClass == List.class)
{
// For string or list
info.max = entry.maxValue() == Double.MAX_VALUE ? Integer.MAX_VALUE : (int) entry.maxValue();
textField(info, String::length, null, Math.min(entry.minValue(), 0), Math.max(entry.maxValue(), 1), true);
}
else if (fieldClass == boolean.class)
{
// For boolean
Function<Object, Component> func = value -> new TextComponent((Boolean) value ? "True" : "False").withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
info.widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
info.value = !(Boolean) info.value;
button.setMessage(func.apply(info.value));
}, func);
}
else if (fieldClass.isEnum())
{
// For enum
List<?> values = Arrays.asList(field.getType().getEnumConstants());
Function<Object, Component> func = value -> new TranslatableComponent(MOD_NAME + ".config." + "enum." + fieldClass.getSimpleName() + "." + info.value.toString());
info.widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
int index = values.indexOf(info.value) + 1;
info.value = values.get(index >= values.size() ? 0 : index);
button.setMessage(func.apply(info.value));
}, func);
}
}
else if (screenEntry != null)
{
if (!screenEntry.name().equals(""))
info.name = new TranslatableComponent(screenEntry.name());
info.screenButton = true;
info.gotoScreen = (!info.category.isEmpty() ? info.category + "." : "") + field.getName();
}
entries.add(info);
}
/** creates a text field */
private static void textField(EntryInfo info, Function<String, Number> func, Pattern pattern, double minValue, double maxValue, boolean cast)
{
boolean isNumber = pattern != null;
info.widget = (BiFunction<EditBox, Button, Predicate<String>>) (editBox, button) -> stringValue ->
{
stringValue = stringValue.trim();
if (!(stringValue.isEmpty() || !isNumber || pattern.matcher(stringValue).matches()))
return false;
Number value = 0;
boolean inLimits = false;
info.error = null;
if (isNumber && !stringValue.isEmpty() && !stringValue.equals("-") && !stringValue.equals("."))
{
value = func.apply(stringValue);
inLimits = value.doubleValue() >= minValue && value.doubleValue() <= maxValue;
info.error = inLimits ? null : new AbstractMap.SimpleEntry<>(editBox, new TextComponent(value.doubleValue() < minValue ?
"§cMinimum " + "length" + (cast ? " is " + (int) minValue : " is " + minValue) :
"§cMaximum " + "length" + (cast ? " is " + (int) maxValue : " is " + maxValue)));
}
info.tempValue = stringValue;
editBox.setTextColor(inLimits ? 0xFFFFFFFF : 0xFFFF7777);
info.inLimits = inLimits;
button.active = entries.stream().allMatch(e -> e.inLimits);
if (inLimits && info.field.getType() != List.class)
{
info.value = value;
}
else if (inLimits)
{
if (((List<String>) info.value).size() == info.index)
((List<String>) info.value).add("");
((List<String>) info.value).set(info.index, Arrays.stream(info.tempValue.replace("[", "").replace("]", "").split(", ")).collect(Collectors.toList()).get(0));
}
return true;
};
}
//===============//
// File Handling //
//===============//
/** Grabs what is in the config and puts it in modid.toml */
public static void saveToFile()
{
CommentedFileConfig config = CommentedFileConfig.builder(configFilePath.toFile()).build();
// First try to create a config file
try {
if (!Files.exists(configFilePath))
Files.createFile(configFilePath);
}
catch (Exception e) {
LOGGER.info("Failed creating config file for " + MOD_NAME_READABLE + " at the path [" + configFilePath.toString() + "].");
e.printStackTrace();
}
loadFileWithErrorCheck(config);
// Just put this here for the future
config.setComment("_Version", " DONT TOUCH THIS, IF YOU DO THEN CONFIG FILE WOULD BREAK");
config.set("_Versions", ModInfo.VERSION);
for (EntryInfo info : entries) {
if (info.field.isAnnotationPresent(ConfigAnnotations.Entry.class)) {
editSingleOption.saveOption(info, config);
if (editSingleOption.getEntry((info.category.isEmpty() ? "" : info.category + ".") + "_" + info.field.getName()) != null)
config.setComment((info.category.isEmpty() ? "" : info.category + ".") + info.field.getName(), String.valueOf(editSingleOption.getEntry((info.category.isEmpty() ? "" : info.category + ".") + "_" + info.field.getName()).defaultValue));
}
}
config.save();
config.close();
}
/**
* Grabs what is in modid.toml and puts it into the config
* If the file doesn't exist then it runs saveToFile
*/
public static void loadFromFile()
{
CommentedFileConfig config = CommentedFileConfig.builder(configFilePath.toFile()).autosave().build();
// First checks if the config file was already made
if (!Files.exists(configFilePath)) {
LOGGER.info("Config file not found for " + MOD_NAME_READABLE + ". Creating config...");
saveToFile();
return;
}
loadFileWithErrorCheck(config);
// Just put this here for the future
config.setComment("_Version", " DONT TOUCH THIS, IF YOU DO THEN CONFIG FILE WOULD BREAK");
config.set("_Versions", ModInfo.VERSION);
// Puts everything into its variable
for (EntryInfo info : entries) {
if (info.field.isAnnotationPresent(ConfigAnnotations.Entry.class)) {
editSingleOption.loadOption(info, config);
// File comments (WILL REMOVE SOON)
if (editSingleOption.getEntry((info.category.isEmpty() ? "" : info.category + ".") + "_" + info.field.getName()) != null)
config.setComment((info.category.isEmpty() ? "" : info.category + ".") + info.field.getName(), String.valueOf(editSingleOption.getEntry((info.category.isEmpty() ? "" : info.category + ".") + "_" + info.field.getName()).defaultValue));
}
}
config.close();
}
public static class editSingleOption {
/** Get the entry info of an item using its string name */
public static EntryInfo getEntry(String name)
{
return entryMap.get(name);
}
/** Save a single item using its string name */
public static void saveOption(String name)
{
saveOption(entryMap.get(name));
}
/** Saves a single item using entry info */
public static void saveOption(EntryInfo info)
{
CommentedFileConfig config = CommentedFileConfig.builder(configFilePath.toFile()).autosave().build();
loadFileWithErrorCheck(config);
saveOption(info, config);
config.close();
}
/** Saves a single item using its entry info and its config builder */
public static void saveOption(EntryInfo info, CommentedFileConfig config)
{
config.set((info.category.isEmpty() ? "" : info.category + ".") + info.field.getName(), info.value);
}
/** Load a single item using its string name */
public static void loadOption(String name)
{
loadOption(entryMap.get(name));
}
/** Load a single item using entry info */
public static void loadOption(EntryInfo info)
{
CommentedFileConfig config = CommentedFileConfig.builder(configFilePath.toFile()).autosave().build();
loadFileWithErrorCheck(config);
loadOption(info, config);
config.close();
}
/** Loads a single item using its entry info and its config builder */
public static void loadOption(EntryInfo info, CommentedFileConfig config)
{
String itemPath = (info.category.isEmpty() ? "" : info.category + ".") + info.field.getName();
if (config.contains(itemPath)) {
if (info.field.getType().isEnum())
info.value = config.getEnum(itemPath, info.varClass);
else
info.value = config.get(itemPath);
} else
config.set(itemPath, info.value);
try {
info.field.set(null, info.value);
} catch (IllegalAccessException ignored) {
}
}
}
/** Dose config.load(); but with error checking to avoid crashes */
public static void loadFileWithErrorCheck(CommentedFileConfig config) {
try {
config.load();
} catch (Exception e) {
LOGGER.info("Error loading config for " + MOD_NAME_READABLE + " at the path [" + configFilePath.toString() + "].");
LOGGER.info("Creating a new config...");
try {
Files.deleteIfExists(configFilePath);
saveToFile();
} catch (Exception f) {
LOGGER.info("Failed creating config file for " + MOD_NAME_READABLE + " at the path [" + configFilePath.toString() + "].");
f.printStackTrace();
}
}
}
//==============//
// GUI handling //
//==============//
public static Screen getScreen(Screen parent, String category)
{
return new ConfigScreen(parent, category);
}
private static class ConfigScreen extends Screen
{
protected ConfigScreen(Screen parent, String category)
{
super(new TranslatableComponent(
I18n.exists(MOD_NAME + ".config" + (category.isEmpty()? "." + category : "") + ".title") ?
MOD_NAME + ".config.title" :
MOD_NAME + ".config" + (category.isEmpty() ? "" : "." + category) + ".title")
);
this.parent = parent;
this.category = category;
this.translationPrefix = MOD_NAME + ".config.";
}
private final String translationPrefix;
private final Screen parent;
private final String category;
private ConfigListWidget list;
private boolean reload = false;
// Real Time config update //
@Override
public void tick()
{
super.tick();
}
/** When you close it, it goes to the previous screen and saves */
@Override
public void onClose()
{
saveToFile();
Objects.requireNonNull(minecraft).setScreen(this.parent);
}
@Override
protected void init()
{
super.init();
if (!reload)
loadFromFile();
// addRenderableWidget in 1.17 and over
// addButton in 1.16 and below
this.addRenderableWidget(new Button(this.width / 2 - 154, this.height - 28, 150, 20, CommonComponents.GUI_CANCEL, button -> {
loadFromFile();
Objects.requireNonNull(minecraft).setScreen(parent);
}));
Button done = this.addRenderableWidget(new Button(this.width / 2 + 4, this.height - 28, 150, 20, CommonComponents.GUI_DONE, (button) -> {
saveToFile();
Objects.requireNonNull(minecraft).setScreen(parent);
}));
this.list = new ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, this.height - 32, 25);
if (this.minecraft != null && this.minecraft.level != null)
this.list.setRenderBackground(false);
this.addWidget(this.list);
for (EntryInfo info : entries)
{
if (info.category.matches(category) && !info.hideOption)
{
TranslatableComponent name = (info.name == null ? new TranslatableComponent(translationPrefix + (!info.category.isEmpty() ? info.category + "." : "") + info.field.getName()) : info.name);
Button resetButton = new Button(this.width - ConfigScreenConfigs.SpaceFromRightScreen - info.width - ConfigScreenConfigs.ButtonWidthSpacing - ConfigScreenConfigs.ResetButtonWidth, 0, ConfigScreenConfigs.ResetButtonWidth, 20, new TextComponent("Reset").withStyle(ChatFormatting.RED), (button -> {
info.value = info.defaultValue;
info.tempValue = info.defaultValue.toString();
info.index = 0;
this.reload = true;
Objects.requireNonNull(minecraft).setScreen(this);
}));
if (info.widget instanceof Map.Entry)
{
Map.Entry<Button.OnPress, Function<Object, Component>> widget = (Map.Entry<Button.OnPress, Function<Object, Component>>) info.widget;
if (info.field.getType().isEnum())
widget.setValue(value -> new TranslatableComponent(translationPrefix + "enum." + info.field.getType().getSimpleName() + "." + info.value.toString()));
this.list.addButton(new Button(this.width - info.width - ConfigScreenConfigs.SpaceFromRightScreen, 0, info.width, 20, widget.getValue().apply(info.value), widget.getKey()), resetButton, null, name);
}
else if (info.field.getType() == List.class)
{
if (!reload)
info.index = 0;
EditBox widget = new EditBox(font, this.width - info.width - ConfigScreenConfigs.SpaceFromRightScreen, 0, info.width, 20, null);
widget.setMaxLength(info.width);
if (info.index < ((List<String>) info.value).size())
widget.insertText((String.valueOf(((List<String>) info.value).get(info.index))));
else
widget.insertText("");
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) info.widget).apply(widget, done);
widget.setFilter(processor);
resetButton.setWidth(20);
resetButton.setMessage(new TextComponent("R").withStyle(ChatFormatting.RED));
Button cycleButton = new Button(this.width - 185, 0, 20, 20, new TextComponent(String.valueOf(info.index)).withStyle(ChatFormatting.GOLD), (button -> {
((List<String>) info.value).remove("");
this.reload = true;
info.index = info.index + 1;
if (info.index > ((List<String>) info.value).size())
info.index = 0;
Objects.requireNonNull(minecraft).setScreen(this);
}));
this.list.addButton(widget, resetButton, cycleButton, name);
}
else if (info.widget != null)
{
EditBox widget = new EditBox(font, this.width - info.width - ConfigScreenConfigs.SpaceFromRightScreen + 2, 0, info.width - 4, 20, null);
widget.setMaxLength(info.width);
widget.insertText(String.valueOf(info.value));
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) info.widget).apply(widget, done);
widget.setFilter(processor);
this.list.addButton(widget, resetButton, null, name);
}
else if (info.screenButton)
{
Button widget = new Button(this.width / 2 - info.width, this.height - 28, info.width * 2, 20, name, (button -> {
saveToFile();
Objects.requireNonNull(minecraft).setScreen(ConfigGui.getScreen(this, info.gotoScreen));
}));
this.list.addButton(widget, null, null, null);
}
else if (!info.fileComment)
{
this.list.addButton(null, null, null, name);
}
}
}
}
@Override
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
{
this.renderBackground(matrices); // Renders background
this.list.render(matrices, mouseX, mouseY, delta); // Render buttons
drawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
// Render the tooltip only if it can find a tooltip in the language file
for (EntryInfo info : entries) {
if (info.category.matches(category) && !info.hideOption) {
if (list.getHoveredButton(mouseX,mouseY).isPresent()) {
AbstractWidget buttonWidget = list.getHoveredButton(mouseX,mouseY).get();
Component text = ButtonEntry.buttonsWithText.get(buttonWidget);
TranslatableComponent name = new TranslatableComponent(this.translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.field.getName());
String key = translationPrefix + (info.category.isEmpty() ? "" : info.category + ".") + info.field.getName() + ".@tooltip";
if (info.error != null && text.equals(name)) renderTooltip(matrices, (Component) info.error.getValue(), mouseX, mouseY);
else if (I18n.exists(key) && (text != null && text.equals(name))) {
List<Component> list = new ArrayList<>();
for (String str : I18n.get(key).split("\n"))
list.add(new TextComponent(str));
renderComponentTooltip(matrices, list, mouseX, mouseY);
}
}
}
}
super.render(matrices, mouseX, mouseY, delta);
}
}
public static class ConfigListWidget extends ContainerObjectSelectionList<ButtonEntry>
{
Font textRenderer;
public ConfigListWidget(Minecraft minecraftClient, int i, int j, int k, int l, int m)
{
super(minecraftClient, i, j, k, l, m);
this.centerListVertically = false;
textRenderer = minecraftClient.font;
}
public void addButton(AbstractWidget button, AbstractWidget resetButton, AbstractWidget indexButton, Component text)
{
this.addEntry(ButtonEntry.create(button, text, resetButton, indexButton));
}
@Override
public int getRowWidth()
{
return 10000;
}
public Optional<AbstractWidget> getHoveredButton(double mouseX, double mouseY)
{
for (ButtonEntry buttonEntry : this.children())
{
if (buttonEntry.button != null && buttonEntry.button.isMouseOver(mouseX, mouseY))
{
return Optional.of(buttonEntry.button);
}
}
return Optional.empty();
}
}
public static class ButtonEntry extends ContainerObjectSelectionList.Entry<ButtonEntry>
{
private static final Font textRenderer = Minecraft.getInstance().font;
public final AbstractWidget button;
private final AbstractWidget resetButton;
private final AbstractWidget indexButton;
private final Component text;
private final List<AbstractWidget> children = new ArrayList<>();
public static final Map<AbstractWidget, Component> buttonsWithText = new HashMap<>();
private ButtonEntry(AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton)
{
buttonsWithText.put(button, text);
this.button = button;
this.resetButton = resetButton;
this.text = text;
this.indexButton = indexButton;
if (button != null)
children.add(button);
if (resetButton != null)
children.add(resetButton);
if (indexButton != null)
children.add(indexButton);
}
public static ButtonEntry create(AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton)
{
return new ButtonEntry(button, text, resetButton, indexButton);
}
@Override
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
{
if (button != null)
{
button.y = y;
button.render(matrices, mouseX, mouseY, tickDelta);
}
if (resetButton != null)
{
resetButton.y = y;
resetButton.render(matrices, mouseX, mouseY, tickDelta);
}
if (indexButton != null)
{
indexButton.y = y;
indexButton.render(matrices, mouseX, mouseY, tickDelta);
}
if (text != null && (!text.getString().contains("spacer") || button != null))
GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF);
}
@Override
public List<? extends GuiEventListener> children()
{
return children;
}
// Only for 1.17 and over
// Remove in 1.16 and below
@Override
public List<? extends NarratableEntry> narratables()
{
return children;
}
}
}
@@ -0,0 +1,953 @@
package com.seibel.lod.common.wrappers.config;
import com.seibel.lod.core.enums.config.*;
import com.seibel.lod.core.enums.rendering.*;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.common.Config;
/**
* This holds the config defaults and setters/getters
* that should be hooked into the host mod loader (Fabric, Forge, etc.).
*
* @author James Seibel
* @version 11-16-2021
*/
public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
{
public static final LodConfigWrapperSingleton INSTANCE = new LodConfigWrapperSingleton();
private static final Client client = new Client();
@Override
public IClient client()
{
return client;
}
public static class Client implements IClient
{
public final IGraphics graphics;
public final IWorldGenerator worldGenerator;
public final IMultiplayer multiplayer;
public final IAdvanced advanced;
@Override
public IGraphics graphics()
{
return graphics;
}
@Override
public IWorldGenerator worldGenerator()
{
return worldGenerator;
}
@Override
public IMultiplayer multiplayer() {
return multiplayer;
}
@Override
public IAdvanced advanced()
{
return advanced;
}
@Override
public boolean getOptionsButton()
{
return Config.optionsButton;
}
@Override
public void setOptionsButton(boolean newOptionsButton)
{
ConfigGui.editSingleOption.getEntry("optionsButton").value = newOptionsButton;
ConfigGui.editSingleOption.saveOption("optionsButton");
}
//================//
// Client Configs //
//================//
public Client()
{
graphics = new Graphics();
worldGenerator = new WorldGenerator();
multiplayer = new Multiplayer();
advanced = new Advanced();
}
//==================//
// Graphics Configs //
//==================//
public static class Graphics implements IGraphics
{
public final IQuality quality;
public final IFogQuality fogQuality;
public final IAdvancedGraphics advancedGraphics;
@Override
public IQuality quality()
{
return quality;
}
@Override
public IFogQuality fogQuality()
{
return fogQuality;
}
@Override
public IAdvancedGraphics advancedGraphics()
{
return advancedGraphics;
}
Graphics()
{
quality = new Quality();
fogQuality = new FogQuality();
advancedGraphics = new AdvancedGraphics();
}
public static class Quality implements IQuality
{
@Override
public HorizontalResolution getDrawResolution()
{
return Config.Client.Graphics.Quality.drawResolution;
}
@Override
public void setDrawResolution(HorizontalResolution newHorizontalResolution)
{
ConfigGui.editSingleOption.getEntry("client.graphics.quality.drawResolution").value = newHorizontalResolution;
ConfigGui.editSingleOption.saveOption("client.graphics.quality.drawResolution");
}
@Override
public int getLodChunkRenderDistance()
{
return Config.Client.Graphics.Quality.lodChunkRenderDistance;
}
@Override
public void setLodChunkRenderDistance(int newLodChunkRenderDistance)
{
ConfigGui.editSingleOption.getEntry("client.graphics.quality.lodChunkRenderDistance").value = newLodChunkRenderDistance;
ConfigGui.editSingleOption.saveOption("client.graphics.quality.lodChunkRenderDistance");
}
@Override
public VerticalQuality getVerticalQuality()
{
return Config.Client.Graphics.Quality.verticalQuality;
}
@Override
public void setVerticalQuality(VerticalQuality newVerticalQuality)
{
ConfigGui.editSingleOption.getEntry("client.graphics.quality.verticalQuality").value = newVerticalQuality;
ConfigGui.editSingleOption.saveOption("client.graphics.quality.verticalQuality");
}
@Override
public int getHorizontalScale()
{
return Config.Client.Graphics.Quality.horizontalScale;
}
@Override
public void setHorizontalScale(int newHorizontalScale)
{
ConfigGui.editSingleOption.getEntry("client.graphics.quality.horizontalScale").value = newHorizontalScale;
ConfigGui.editSingleOption.saveOption("client.graphics.quality.horizontalScale");
}
@Override
public HorizontalQuality getHorizontalQuality()
{
return Config.Client.Graphics.Quality.horizontalQuality;
}
@Override
public void setHorizontalQuality(HorizontalQuality newHorizontalQuality)
{
ConfigGui.editSingleOption.getEntry("client.graphics.quality.horizontalQuality").value = newHorizontalQuality;
ConfigGui.editSingleOption.saveOption("client.graphics.quality.horizontalQuality");
}
@Override
public DropoffQuality getDropoffQuality() {
return Config.Client.Graphics.Quality.dropoffQuality;
}
@Override
public void setDropoffQuality(DropoffQuality newDropoffQuality) {
ConfigGui.editSingleOption.getEntry("client.graphics.quality.dropoffQuality").value = newDropoffQuality;
ConfigGui.editSingleOption.saveOption("client.graphics.quality.dropoffQuality");
}
@Override
public int getLodBiomeBlending() {
return Config.Client.Graphics.Quality.lodBiomeBlending;
}
@Override
public void setLodBiomeBlending(int newLodBiomeBlending) {
ConfigGui.editSingleOption.getEntry("client.graphics.quality.lodBiomeBlending").value = newLodBiomeBlending;
ConfigGui.editSingleOption.saveOption("client.graphics.quality.lodBiomeBlending");
}
}
public static class FogQuality implements IFogQuality
{
public final IAdvancedFog advancedFog;
FogQuality()
{
advancedFog = new AdvancedFog();
}
@Override
public FogDistance getFogDistance()
{
return Config.Client.Graphics.FogQuality.fogDistance;
}
@Override
public void setFogDistance(FogDistance newFogDistance)
{
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.fogDistance").value = newFogDistance;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.fogDistance");
}
@Override
public FogDrawMode getFogDrawMode()
{
return Config.Client.Graphics.FogQuality.fogDrawMode;
}
@Override
public void setFogDrawMode(FogDrawMode setFogDrawMode)
{
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.fogDrawMode").value = setFogDrawMode;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.fogDrawMode");
}
@Override
public FogColorMode getFogColorMode()
{
return Config.Client.Graphics.FogQuality.fogColorMode;
}
@Override
public void setFogColorMode(FogColorMode newFogColorMode)
{
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.fogColorMode").value = newFogColorMode;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.fogColorMode");
}
@Override
public boolean getDisableVanillaFog()
{
return Config.Client.Graphics.FogQuality.disableVanillaFog;
}
@Override
public void setDisableVanillaFog(boolean newDisableVanillaFog)
{
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.disableVanillaFog").value = newDisableVanillaFog;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.disableVanillaFog");
}
@Override
public IAdvancedFog advancedFog() {
return advancedFog;
}
public static class AdvancedFog implements IAdvancedFog {
public final IHeightFog heightFog;
public AdvancedFog() {
heightFog = new HeightFog();
}
@Override
public double getFarFogStart() {
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogStart;
}
@Override
public double getFarFogEnd() {
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogEnd;
}
@Override
public double getFarFogMin() {
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogMin;
}
@Override
public double getFarFogMax() {
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogMax;
}
@Override
public FogSetting.FogType getFarFogType() {
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogType;
}
@Override
public double getFarFogDensity() {
return Config.Client.Graphics.FogQuality.AdvancedFog.farFogDensity;
}
@Override
public void setFarFogStart(double newFarFogStart) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogStart").value = newFarFogStart;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogStart");
}
@Override
public void setFarFogEnd(double newFarFogEnd) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogEnd").value = newFarFogEnd;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogEnd");
}
@Override
public void setFarFogMin(double newFarFogMin) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogMin").value = newFarFogMin;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogMin");
}
@Override
public void setFarFogMax(double newFarFogMax) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogMax").value = newFarFogMax;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogMax");
}
@Override
public void setFarFogType(FogSetting.FogType newFarFogType) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogType").value = newFarFogType;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogType");
}
@Override
public void setFarFogDensity(double newFarFogDensity) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.farFogDensity").value = newFarFogDensity;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.farFogDensity");
}
@Override
public IHeightFog heightFog() {
return heightFog;
}
public static class HeightFog implements IHeightFog {
@Override
public HeightFogMixMode getHeightFogMixMode() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMixMode;
}
@Override
public HeightFogMode getHeightFogMode() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMode;
}
@Override
public double getHeightFogHeight() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogHeight;
}
@Override
public double getHeightFogStart() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogStart;
}
@Override
public double getHeightFogEnd() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogEnd;
}
@Override
public double getHeightFogMin() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMin;
}
@Override
public double getHeightFogMax() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogMax;
}
@Override
public FogSetting.FogType getHeightFogType() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogType;
}
@Override
public double getHeightFogDensity() {
return Config.Client.Graphics.FogQuality.AdvancedFog.heightFog.heightFogDensity;
}
@Override
public void setHeightFogMixMode(HeightFogMixMode newHeightFogMixMode) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMixMode").value = newHeightFogMixMode;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMixMode");
}
@Override
public void setHeightFogMode(HeightFogMode newHeightFogMode) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMode").value = newHeightFogMode;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMode");
}
@Override
public void setHeightFogHeight(double newHeightFogHeight) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogHeight").value = newHeightFogHeight;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogHeight");
}
@Override
public void setHeightFogStart(double newHeightFogStart) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogStart").value = newHeightFogStart;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogStart");
}
@Override
public void setHeightFogEnd(double newHeightFogEnd) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogEnd").value = newHeightFogEnd;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogEnd");
}
@Override
public void setHeightFogMin(double newHeightFogMin) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMin").value = newHeightFogMin;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMin");
}
@Override
public void setHeightFogMax(double newHeightFogMax) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogMax").value = newHeightFogMax;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogMax");
}
@Override
public void setHeightFogType(FogSetting.FogType newHeightFogType) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogType").value = newHeightFogType;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogType");
}
@Override
public void setHeightFogDensity(double newHeightFogDensity) {
ConfigGui.editSingleOption.getEntry("client.graphics.fogQuality.advancedFog.heightFog.heightFogDensity").value = newHeightFogDensity;
ConfigGui.editSingleOption.saveOption("client.graphics.fogQuality.advancedFog.heightFog.heightFogDensity");
}
}
}
}
public static class AdvancedGraphics implements IAdvancedGraphics
{
@Override
public boolean getDisableDirectionalCulling()
{
return Config.Client.Graphics.AdvancedGraphics.disableDirectionalCulling;
}
@Override
public void setDisableDirectionalCulling(boolean newDisableDirectionalCulling)
{
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.disableDirectionalCulling").value = newDisableDirectionalCulling;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.disableDirectionalCulling");
}
@Override
public VanillaOverdraw getVanillaOverdraw()
{
return Config.Client.Graphics.AdvancedGraphics.vanillaOverdraw;
}
@Override
public void setVanillaOverdraw(VanillaOverdraw newVanillaOverdraw)
{
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.vanillaOverdraw").value = newVanillaOverdraw;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.vanillaOverdraw");
}
@Override
public int getOverdrawOffset() {
return Config.Client.Graphics.AdvancedGraphics.overdrawOffset;
}
@Override
public void setOverdrawOffset(int newOverdrawOffset) {
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.overdrawOffset").value = newOverdrawOffset;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.overdrawOffset");
}
/*
@Override
public int getBacksideCullingRange()
{
return Config.Client.Graphics.AdvancedGraphics.backsideCullingRange;
}
@Override
public void setBacksideCullingRange(int newBacksideCullingRange)
{
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.backsideCullingRange").value = newBacksideCullingRange;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.backsideCullingRange");
}*/
@Override
public boolean getUseExtendedNearClipPlane()
{
return Config.Client.Graphics.AdvancedGraphics.useExtendedNearClipPlane;
}
@Override
public void setUseExtendedNearClipPlane(boolean newUseExtendedNearClipPlane)
{
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.useExtendedNearClipPlane").value = newUseExtendedNearClipPlane;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.useExtendedNearClipPlane");
}
@Override
public double getBrightnessMultiplier()
{
return Config.Client.Graphics.AdvancedGraphics.brightnessMultiplier;
}
@Override
public void setBrightnessMultiplier(double newBrightnessMultiplier)
{
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.brightnessMultiplier").value = newBrightnessMultiplier;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.brightnessMultiplier");
}
@Override
public double getSaturationMultiplier()
{
return Config.Client.Graphics.AdvancedGraphics.saturationMultiplier;
}
@Override
public void setSaturationMultiplier(double newSaturationMultiplier)
{
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.saturationMultiplier").value = newSaturationMultiplier;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.saturationMultiplier");
}
@Override
public boolean getEnableCaveCulling() {
return Config.Client.Graphics.AdvancedGraphics.enableCaveCulling;
}
@Override
public void setEnableCaveCulling(boolean newEnableCaveCulling) {
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.enableCaveCulling").value = newEnableCaveCulling;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.enableCaveCulling");
}
@Override
public int getCaveCullingHeight() {
return Config.Client.Graphics.AdvancedGraphics.caveCullingHeight;
}
@Override
public void setCaveCullingHeight(int newCaveCullingHeight) {
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.caveCullingHeight").value = newCaveCullingHeight;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.caveCullingHeight");
}
}
}
//========================//
// WorldGenerator Configs //
//========================//
public static class WorldGenerator implements IWorldGenerator
{
@Override
public GenerationPriority getGenerationPriority()
{
return Config.Client.WorldGenerator.generationPriority;
}
@Override
public void setGenerationPriority(GenerationPriority newGenerationPriority)
{
ConfigGui.editSingleOption.getEntry("client.worldGenerator.generationPriority").value = newGenerationPriority;
ConfigGui.editSingleOption.saveOption("client.worldGenerator.generationPriority");
}
@Override
public DistanceGenerationMode getDistanceGenerationMode()
{
return Config.Client.WorldGenerator.distanceGenerationMode;
}
@Override
public void setDistanceGenerationMode(DistanceGenerationMode newDistanceGenerationMode)
{
ConfigGui.editSingleOption.getEntry("client.worldGenerator.distanceGenerationMode").value = newDistanceGenerationMode;
ConfigGui.editSingleOption.saveOption("client.worldGenerator.distanceGenerationMode");
}
/*
@Override
public boolean getAllowUnstableFeatureGeneration()
{
return Config.Client.WorldGenerator.allowUnstableFeatureGeneration;
}
@Override
public void setAllowUnstableFeatureGeneration(boolean newAllowUnstableFeatureGeneration)
{
ConfigGui.editSingleOption.getEntry("client.worldGenerator.allowUnstableFeatureGeneration").value = newAllowUnstableFeatureGeneration;
ConfigGui.editSingleOption.saveOption("client.worldGenerator.allowUnstableFeatureGeneration");
}*/
@Override
public BlocksToAvoid getBlocksToAvoid()
{
return Config.Client.WorldGenerator.blocksToAvoid;
}
@Override
public void setBlockToAvoid(BlocksToAvoid newBlockToAvoid)
{
ConfigGui.editSingleOption.getEntry("client.worldGenerator.blocksToAvoid").value = newBlockToAvoid;
ConfigGui.editSingleOption.saveOption("client.worldGenerator.blocksToAvoid");
}
@Override
public boolean getEnableDistantGeneration()
{
return (boolean) ConfigGui.editSingleOption.getEntry("client.worldGenerator.enableDistantGeneration").value;
}
@Override
public void setEnableDistantGeneration(boolean newEnableDistantGeneration)
{
ConfigGui.editSingleOption.getEntry("client.worldGenerator.enableDistantGeneration").value = newEnableDistantGeneration;
ConfigGui.editSingleOption.saveOption("client.worldGenerator.enableDistantGeneration");
}
@Override
public LightGenerationMode getLightGenerationMode()
{
return Config.Client.WorldGenerator.lightGenerationMode;
}
@Override
public void setLightGenerationMode(LightGenerationMode newLightGenerationMode)
{
ConfigGui.editSingleOption.getEntry("client.worldGenerator.lightGenerationMode").value = newLightGenerationMode;
ConfigGui.editSingleOption.saveOption("client.worldGenerator.lightGenerationMode");
}
}
//=====================//
// Multiplayer Configs //
//=====================//
public static class Multiplayer implements IMultiplayer
{
@Override
public ServerFolderNameMode getServerFolderNameMode()
{
return Config.Client.Multiplayer.serverFolderNameMode;
}
@Override
public void setServerFolderNameMode(ServerFolderNameMode newServerFolderNameMode)
{
ConfigGui.editSingleOption.getEntry("client.multiplayer.serverFolderNameMode").value = newServerFolderNameMode;
ConfigGui.editSingleOption.saveOption("client.multiplayer.serverFolderNameMode");
}
@Override
public double getMultiDimensionRequiredSimilarity()
{
return Config.Client.Multiplayer.multiDimensionRequiredSimilarity;
}
@Override
public void setMultiDimensionRequiredSimilarity(double newMultiDimensionMinimumSimilarityPercent)
{
ConfigGui.editSingleOption.getEntry("client.multiplayer.multiDimensionMinimumSimilarityPercent").value = newMultiDimensionMinimumSimilarityPercent;
ConfigGui.editSingleOption.saveOption("client.multiplayer.multiDimensionMinimumSimilarityPercent");
}
}
//============================//
// AdvancedModOptions Configs //
//============================//
public static class Advanced implements IAdvanced
{
public final IThreading threading;
public final IDebugging debugging;
public final IBuffers buffers;
@Override
public IThreading threading()
{
return threading;
}
@Override
public IDebugging debugging()
{
return debugging;
}
@Override
public IBuffers buffers()
{
return buffers;
}
public Advanced()
{
threading = new Threading();
debugging = new Debugging();
buffers = new Buffers();
}
public static class Threading implements IThreading
{
@Override
public int getNumberOfWorldGenerationThreads()
{
return Config.Client.Advanced.Threading.numberOfWorldGenerationThreads;
}
@Override
public void setNumberOfWorldGenerationThreads(int newNumberOfWorldGenerationThreads)
{
ConfigGui.editSingleOption.getEntry("client.advanced.threading.numberOfWorldGenerationThreads").value = newNumberOfWorldGenerationThreads;
ConfigGui.editSingleOption.saveOption("client.advanced.threading.numberOfWorldGenerationThreads");
}
@Override
public int getNumberOfBufferBuilderThreads()
{
return Config.Client.Advanced.Threading.numberOfBufferBuilderThreads;
}
@Override
public void setNumberOfBufferBuilderThreads(int newNumberOfWorldBuilderThreads)
{
ConfigGui.editSingleOption.getEntry("client.advanced.threading.numberOfBufferBuilderThreads").value = newNumberOfWorldBuilderThreads;
ConfigGui.editSingleOption.saveOption("client.advanced.threading.numberOfBufferBuilderThreads");
}
}
//===============//
// Debug Options //
//===============//
public static class Debugging implements IDebugging
{
public final IDebugSwitch debugSwitch;
@Override
public IDebugSwitch debugSwitch()
{
return debugSwitch;
}
/* RendererType:
* DEFAULT
* DEBUG
* DISABLED
* */
@Override
public RendererType getRendererType() {
return (RendererType) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.rendererType").value;
}
@Override
public void setRendererType(RendererType newRenderType) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.rendererType").value = newRenderType;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.rendererType");
}
@Override
public DebugMode getDebugMode()
{
return (DebugMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugMode").value;
}
@Override
public void setDebugMode(DebugMode newDebugMode)
{
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugMode").value = newDebugMode;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugMode");
}
@Override
public boolean getDebugKeybindingsEnabled()
{
return (boolean) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.enableDebugKeybindings").value;
}
@Override
public void setDebugKeybindingsEnabled(boolean newEnableDebugKeybindings)
{
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.enableDebugKeybindings").value = newEnableDebugKeybindings;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.enableDebugKeybindings");
}
public Debugging()
{
debugSwitch = new DebugSwitch();
}
public static class DebugSwitch implements IDebugSwitch {
/* The logging switches available:
* WorldGenEvent
* WorldGenPerformance
* WorldGenLoadEvent
* LodBuilderEvent
* RendererBufferEvent
* RendererGLEvent
* FileReadWriteEvent
* FileSubDimEvent
* NetworkEvent //NOT IMPL YET
*/
@Override
public LoggerMode getLogWorldGenEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenEvent").value;
}
@Override
public void setLogWorldGenEvent(LoggerMode newLogWorldGenEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenEvent").value = newLogWorldGenEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenEvent");
}
@Override
public LoggerMode getLogWorldGenPerformance() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenPerformance").value;
}
@Override
public void setLogWorldGenPerformance(LoggerMode newLogWorldGenPerformance) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenPerformance").value = newLogWorldGenPerformance;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenPerformance");
}
@Override
public LoggerMode getLogWorldGenLoadEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent").value;
}
@Override
public void setLogWorldGenLoadEvent(LoggerMode newLogWorldGenLoadEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent").value = newLogWorldGenLoadEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logWorldGenLoadEvent");
}
@Override
public LoggerMode getLogLodBuilderEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logLodBuilderEvent").value;
}
@Override
public void setLogLodBuilderEvent(LoggerMode newLogLodBuilderEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logLodBuilderEvent").value = newLogLodBuilderEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logLodBuilderEvent");
}
@Override
public LoggerMode getLogRendererBufferEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererBufferEvent").value;
}
@Override
public void setLogRendererBufferEvent(LoggerMode newLogRendererBufferEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererBufferEvent").value = newLogRendererBufferEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logRendererBufferEvent");
}
@Override
public LoggerMode getLogRendererGLEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererGLEvent").value;
}
@Override
public void setLogRendererGLEvent(LoggerMode newLogRendererGLEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logRendererGLEvent").value = newLogRendererGLEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logRendererGLEvent");
}
@Override
public LoggerMode getLogFileReadWriteEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileReadWriteEvent").value;
}
@Override
public void setLogFileReadWriteEvent(LoggerMode newLogFileReadWriteEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileReadWriteEvent").value = newLogFileReadWriteEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logFileReadWriteEvent");
}
@Override
public LoggerMode getLogFileSubDimEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileSubDimEvent").value;
}
@Override
public void setLogFileSubDimEvent(LoggerMode newLogFileSubDimEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logFileSubDimEvent").value = newLogFileSubDimEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logFileSubDimEvent");
}
@Override
public LoggerMode getLogNetworkEvent() {
return (LoggerMode) ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logNetworkEvent").value;
}
@Override
public void setLogNetworkEvent(LoggerMode newLogNetworkEvent) {
ConfigGui.editSingleOption.getEntry("client.advanced.debugging.debugSwitch.logNetworkEvent").value = newLogNetworkEvent;
ConfigGui.editSingleOption.saveOption("client.advanced.debugging.debugSwitch.logNetworkEvent");
}
}
}
public static class Buffers implements IBuffers
{
@Override
public GpuUploadMethod getGpuUploadMethod()
{
return Config.Client.Advanced.Buffers.gpuUploadMethod;
}
@Override
public void setGpuUploadMethod(GpuUploadMethod newDisableVanillaFog)
{
ConfigGui.editSingleOption.getEntry("client.advanced.buffers.gpuUploadMethod").value = newDisableVanillaFog;
ConfigGui.editSingleOption.saveOption("client.advanced.buffers.gpuUploadMethod");
}
@Override
public int getGpuUploadPerMegabyteInMilliseconds()
{
return Config.Client.Advanced.Buffers.gpuUploadPerMegabyteInMilliseconds;
}
@Override
public void setGpuUploadPerMegabyteInMilliseconds(int newMilliseconds) {
ConfigGui.editSingleOption.getEntry("client.advanced.buffers.gpuUploadPerMegabyteInMilliseconds").value = newMilliseconds;
ConfigGui.editSingleOption.saveOption("client.advanced.buffers.gpuUploadPerMegabyteInMilliseconds");
}
@Override
public BufferRebuildTimes getRebuildTimes()
{
return Config.Client.Advanced.Buffers.rebuildTimes;
}
@Override
public void setRebuildTimes(BufferRebuildTimes newBufferRebuildTimes)
{
ConfigGui.editSingleOption.getEntry("client.advanced.buffers.newBufferRebuildTimes").value = newBufferRebuildTimes;
ConfigGui.editSingleOption.saveOption("client.advanced.buffers.newBufferRebuildTimes");
}
}
@Override
public boolean getLodOnlyMode() {
return Config.Client.Advanced.lodOnlyMode;
}
@Override
public void setLodOnlyMode(boolean newLodOnlyMode) {
ConfigGui.editSingleOption.getEntry("client.advanced.buffers.lodOnlyMode").value = newLodOnlyMode;
ConfigGui.editSingleOption.saveOption("client.advanced.buffers.lodOnlyMode");
}
}
}
}
@@ -0,0 +1,43 @@
package com.seibel.lod.common.wrappers.config;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.ImageButton;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
/**
* Creates a button with a texture on it
*/
public class TexturedButtonWidget extends ImageButton {
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, ResourceLocation texture, OnPress pressAction) {
super(x, y, width, height, u, v, texture, pressAction);
}
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction);
}
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction, Component text) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text);
}
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction, OnTooltip tooltipSupplier, Component text) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, tooltipSupplier, text);
}
@Override
public void renderButton(PoseStack matrices, int mouseX, int mouseY, float delta) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, WIDGETS_LOCATION);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
int i = this.getYImage(this.isHovered);
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest();
this.blit(matrices, this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height);
this.blit(matrices, this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
super.renderButton(matrices, mouseX, mouseY, delta);
}
}
@@ -0,0 +1,412 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common.wrappers.minecraft;
import java.awt.Color;
import java.io.File;
import java.util.ArrayList;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.platform.Window;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import com.seibel.lod.common.wrappers.McObjectConverter;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import com.seibel.lod.common.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.common.wrappers.misc.LightMapWrapper;
import com.seibel.lod.common.wrappers.world.DimensionTypeWrapper;
import com.seibel.lod.common.wrappers.world.WorldWrapper;
import net.minecraft.CrashReport;
import net.minecraft.client.Minecraft;
import net.minecraft.client.Options;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.server.IntegratedServer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.dimension.DimensionType;
import org.jetbrains.annotations.Nullable;
/**
* A singleton that wraps the Minecraft object.
*
* @author James Seibel
* @version 3-5-2022
*/
public class MinecraftClientWrapper implements IMinecraftClientWrapper
{
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
public final Minecraft mc = Minecraft.getInstance();
/**
* The lightmap for the current:
* Time, dimension, brightness setting, etc.
*/
private NativeImage lightMap = null;
private ProfilerWrapper profilerWrapper;
private MinecraftClientWrapper()
{
}
//================//
// helper methods //
//================//
/**
* This should be called at the beginning of every frame to
* clear any Minecraft data that becomes out of date after a frame. <br> <br>
* <p>
* LightMaps and other time sensitive objects fall in this category. <br> <br>
* <p>
* This doesn't affect OpenGL objects in any way.
*/
@Override
public void clearFrameObjectCache()
{
lightMap = null;
}
//=================//
// method wrappers //
//=================//
@Override
public float getShade(LodDirection lodDirection) {
if (mc.level != null)
{
Direction mcDir = McObjectConverter.Convert(lodDirection);
return mc.level.getShade(mcDir, true);
}
else return 0.0f;
}
@Override
public boolean hasSinglePlayerServer()
{
return mc.hasSingleplayerServer();
}
@Override
public String getCurrentServerName()
{
return mc.getCurrentServer().name;
}
@Override
public String getCurrentServerIp()
{
return mc.getCurrentServer().ip;
}
@Override
public String getCurrentServerVersion()
{
return mc.getCurrentServer().version.getString();
}
/** Returns the dimension the player is currently in */
@Override
public IDimensionTypeWrapper getCurrentDimension()
{
if (mc.player != null)
return DimensionTypeWrapper.getDimensionTypeWrapper(mc.player.level.dimensionType());
else return null;
}
@Override
public String getCurrentDimensionId()
{
return LodUtil.getDimensionIDFromWorld(WorldWrapper.getWorldWrapper(mc.level));
}
/** This texture changes every frame */
@Override
public ILightMapWrapper getCurrentLightMap()
{
// get the current lightMap if the cache is empty
if (lightMap == null)
{
LightTexture tex = mc.gameRenderer.lightTexture();
lightMap = tex.lightPixels;
}
return new LightMapWrapper(lightMap);
}
/**
* Returns the color int at the given pixel coordinates
* from the current lightmap.
* @param blockLight x location in texture space
* @param skyLight z location in texture space
*/
@Override
public int getColorIntFromLightMap(int blockLight, int skyLight)
{
if (lightMap == null)
{
//sendChatMessage("new");
// make sure the lightMap is up-to-date
getCurrentLightMap();
}
return lightMap.getPixelRGBA(blockLight, skyLight);
}
//=============//
// Simple gets //
//=============//
public LocalPlayer getPlayer()
{
return mc.player;
}
@Override
public boolean playerExists()
{
return mc.player != null;
}
@Override
public BlockPosWrapper getPlayerBlockPos()
{
BlockPos playerPos = getPlayer().blockPosition();
return new BlockPosWrapper(playerPos.getX(), playerPos.getY(), playerPos.getZ());
}
@Override
public ChunkPosWrapper getPlayerChunkPos()
{
ChunkPos playerPos = getPlayer().chunkPosition();
return new ChunkPosWrapper(playerPos.x, playerPos.z);
}
public Options getOptions()
{
return mc.options;
}
public ModelManager getModelManager()
{
return mc.getModelManager();
}
public ClientLevel getClientLevel()
{
return mc.level;
}
@Override
public IWorldWrapper getWrappedServerWorld()
{
if (mc.level == null)
return null;
DimensionType dimension = mc.level.dimensionType();
IntegratedServer server = mc.getSingleplayerServer();
if (server == null)
return null;
ServerLevel serverWorld = null;
Iterable<ServerLevel> worlds = server.getAllLevels();
for (ServerLevel world : worlds)
{
if (world.dimensionType() == dimension)
{
serverWorld = world;
break;
}
}
return WorldWrapper.getWorldWrapper(serverWorld);
}
public WorldWrapper getWrappedClientLevel()
{
return WorldWrapper.getWorldWrapper(mc.level);
}
public WorldWrapper getWrappedServerLevel()
{
if (mc.level == null)
return null;
DimensionType dimension = mc.level.dimensionType();
IntegratedServer server = mc.getSingleplayerServer();
if (server == null)
return null;
Iterable<ServerLevel> worlds = server.getAllLevels();
ServerLevel returnWorld = null;
for (ServerLevel world : worlds)
{
if (world.dimensionType() == dimension)
{
returnWorld = world;
break;
}
}
return WorldWrapper.getWorldWrapper(returnWorld);
}
@Nullable
@Override
public IWorldWrapper getWrappedClientWorld()
{
return WorldWrapper.getWorldWrapper(mc.level);
}
@Override
public File getGameDirectory()
{
return mc.gameDirectory;
}
@Override
public IProfilerWrapper getProfiler()
{
if (profilerWrapper == null)
profilerWrapper = new ProfilerWrapper(mc.getProfiler());
else if (mc.getProfiler() != profilerWrapper.profiler)
profilerWrapper.profiler = mc.getProfiler();
return profilerWrapper; }
public ClientPacketListener getConnection()
{
return mc.getConnection();
}
public GameRenderer getGameRenderer()
{
return mc.gameRenderer;
}
public Entity getCameraEntity()
{
return mc.cameraEntity;
}
public Window getWindow()
{
return mc.getWindow();
}
@Override
public float getSkyDarken(float partialTicks)
{
return mc.level.getSkyDarken(partialTicks);
}
public IntegratedServer getSinglePlayerServer()
{
return mc.getSingleplayerServer();
}
@Override
public boolean connectedToServer()
{
return mc.getCurrentServer() != null;
}
public ServerData getCurrentServer()
{
return mc.getCurrentServer();
}
public LevelRenderer getLevelRenderer()
{
return mc.levelRenderer;
}
/** Returns all worlds available to the server */
@Override
public ArrayList<IWorldWrapper> getAllServerWorlds()
{
ArrayList<IWorldWrapper> worlds = new ArrayList<IWorldWrapper>();
Iterable<ServerLevel> serverWorlds = mc.getSingleplayerServer().getAllLevels();
for (ServerLevel world : serverWorlds)
{
worlds.add(WorldWrapper.getWorldWrapper(world));
}
return worlds;
}
@Override
public void sendChatMessage(String string)
{
getPlayer().sendMessage(new TextComponent(string), getPlayer().getUUID());
}
/**
* Crashes Minecraft, displaying the given errorMessage <br> <br>
* In the following format: <br>
*
* The game crashed whilst <strong>errorMessage</strong> <br>
* Error: <strong>ExceptionClass: exceptionErrorMessage</strong> <br>
* Exit Code: -1 <br>
*/
@Override
public void crashMinecraft(String errorMessage, Throwable exception)
{
ApiShared.LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
CrashReport report = new CrashReport(errorMessage, exception);
Minecraft.crash(report);
}
}
@@ -0,0 +1,337 @@
package com.seibel.lod.common.wrappers.minecraft;
import java.awt.*;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.stream.Collectors;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.lod.common.wrappers.misc.LightMapWrapper;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
import net.minecraft.client.renderer.LightTexture;
import com.mojang.math.Vector3f;
import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.objects.math.Vec3d;
import com.seibel.lod.core.objects.math.Vec3f;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import com.seibel.lod.common.wrappers.McObjectConverter;
import com.seibel.lod.common.wrappers.WrapperFactory;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.material.FogType;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
/**
* A singleton that contains everything
* related to rendering in Minecraft.
*
* @author James Seibel
* @version 12-12-2021
*/
public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
{
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
private static final Minecraft MC = Minecraft.getInstance();
private static final GameRenderer GAME_RENDERER = MC.gameRenderer;
private static final IWrapperFactory FACTORY = WrapperFactory.INSTANCE;
@Override
public Vec3f getLookAtVector()
{
Camera camera = GAME_RENDERER.getMainCamera();
Vector3f cameraDir = camera.getLookVector();
return new Vec3f(cameraDir.x(), cameraDir.y(), cameraDir.z());
}
@Override
public AbstractBlockPosWrapper getCameraBlockPosition()
{
Camera camera = GAME_RENDERER.getMainCamera();
BlockPos blockPos = camera.getBlockPosition();
return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ());
}
@Override
public boolean playerHasBlindnessEffect()
{
return MC.player.getActiveEffectsMap().get(MobEffects.BLINDNESS) != null;
}
@Override
public Vec3d getCameraExactPosition()
{
Camera camera = GAME_RENDERER.getMainCamera();
Vec3 projectedView = camera.getPosition();
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
}
@Override
public Mat4f getDefaultProjectionMatrix(float partialTicks)
{
return McObjectConverter.Convert(GAME_RENDERER.getProjectionMatrix(GAME_RENDERER.getFov(GAME_RENDERER.getMainCamera(), partialTicks, true)));
}
@Override
public double getGamma()
{
return MC.options.gamma;
}
@Override
public Color getFogColor(float partialTicks) {
FogRenderer.setupColor(GAME_RENDERER.getMainCamera(), partialTicks, MC.level, 1, GAME_RENDERER.getDarkenWorldAmount(partialTicks));
float[] colorValues = RenderSystem.getShaderFogColor();
return new Color(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
}
// getSpecialFogColor() is the same as getFogColor()
@Override
public Color getSkyColor() {
if (MC.level.dimensionType().hasSkyLight()) {
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), MC.getFrameTime());
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
} else
return new Color(0, 0, 0);
}
@Override
public double getFov(float partialTicks)
{
return GAME_RENDERER.getFov(GAME_RENDERER.getMainCamera(), partialTicks, true);
}
/** Measured in chunks */
@Override
public int getRenderDistance()
{
return MC.options.getEffectiveRenderDistance();
}
@Override
public int getScreenWidth()
{
return MC.getWindow().getWidth();
}
@Override
public int getScreenHeight()
{
return MC.getWindow().getHeight();
}
private RenderTarget getRenderTarget() {
RenderTarget r = null; //MC.levelRenderer.getCloudsTarget();
return r!=null ? r : MC.getMainRenderTarget();
}
@Override
public int getTargetFrameBuffer() {
return getRenderTarget().frameBufferId;
}
@Override
public int getTargetFrameBufferViewportWidth() {
return getRenderTarget().viewWidth;
}
@Override
public int getTargetFrameBufferViewportHeight() {
return getRenderTarget().viewHeight;
}
/**
* This method returns the ChunkPos of all chunks that Minecraft
* is going to render this frame. <br><br>
* <p>
*/
public boolean usingBackupGetVanillaRenderedChunks = false;
@Override
public HashSet<AbstractChunkPosWrapper> getVanillaRenderedChunks()
{
ISodiumAccessor sodium = ModAccessorHandler.get(ISodiumAccessor.class);
if (sodium != null)
{
return sodium.getNormalRenderedChunks();
}
IOptifineAccessor optifine = ModAccessorHandler.get(IOptifineAccessor.class);
if (optifine != null)
{
HashSet<AbstractChunkPosWrapper> pos = optifine.getNormalRenderedChunks();
if (pos == null)
pos = getMaximumRenderedChunks();
return pos;
}
if (!usingBackupGetVanillaRenderedChunks) {
try {
LevelRenderer levelRenderer = MC.levelRenderer;
LinkedHashSet<LevelRenderer.RenderChunkInfo> chunks = levelRenderer.renderChunkStorage.get().renderChunks;
return (chunks.stream().map((chunk) -> {
#if MC_VERSION_1_18_2
AABB chunkBoundingBox = chunk.chunk.getBoundingBox();
#elif MC_VERSION_1_18_1
AABB chunkBoundingBox = chunk.chunk.bb;
#endif
return FACTORY.createChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
}).collect(Collectors.toCollection(HashSet::new)));
} catch (LinkageError e) {
try {
MinecraftClientWrapper.INSTANCE.sendChatMessage(
"\u00A7e\u00A7l\u00A7uWARNING: Distant Horizons: getVanillaRenderedChunks method failed."
+ " Using Backup Method.");
MinecraftClientWrapper.INSTANCE.sendChatMessage(
"\u00A7eOverdraw prevention will be worse than normal.");
} catch (Exception e2) {}
ApiShared.LOGGER.error("getVanillaRenderedChunks Error: ", e);
usingBackupGetVanillaRenderedChunks = true;
}
}
return getMaximumRenderedChunks();
}
@Override
@Deprecated
public int[] getLightmapPixels()
{
LightTexture tex = GAME_RENDERER.lightTexture();
//tex.tick(); // This call makes no sense, but it fixes pause menu flicker bug
NativeImage lightMapPixels = tex.lightTexture.getPixels();
LightMapWrapper lightMap = new LightMapWrapper(lightMapPixels);
int lightMapHeight = getLightmapTextureHeight();
int lightMapWidth = getLightmapTextureWidth();
int[] pixels = new int[lightMapWidth * lightMapHeight];
for (int u = 0; u < lightMapWidth; u++)
{
for (int v = 0; v < lightMapWidth; v++)
{
// this could probably be kept as a int, but
// it is easier to test and see the colors when debugging this way.
// When creating a new release this should be changed to the int version.
int col = lightMap.getLightValue(u, v);
// these should both create a totally white image
// int col =
// Integer.MAX_VALUE;
// int col =
// 0b11111111 + // red
// (0b11111111 << 8) + // green
// (0b11111111 << 16) + // blue
// (0b11111111 << 24); // blue
// int col =
// ((c.getRed() & 0xFF) << 16) | // blue
// ((c.getGreen() & 0xFF) << 8) | // green
// ((c.getBlue() & 0xFF)) | // red
// ((c.getAlpha() & 0xFF) << 24); // alpha
// 2D array stored in a 1D array.
// Thank you Tim from College ;)
pixels[u * lightMapWidth + v] = col;
}
}
return pixels;
}
@Override
public ILightMapWrapper getLightmapWrapper() {
return new LightMapWrapper(GAME_RENDERER.lightTexture());
}
@Override
@Deprecated
public int getLightmapTextureHeight()
{
int height = -1;
LightTexture lightTexture = GAME_RENDERER.lightTexture();
if (lightTexture != null)
{
NativeImage tex = lightTexture.lightPixels;
if (tex != null)
{
height = tex.getHeight();
}
}
return height;
}
@Override
@Deprecated
public int getLightmapTextureWidth()
{
int width = -1;
LightTexture lightTexture = GAME_RENDERER.lightTexture();
if (lightTexture != null)
{
NativeImage tex = lightTexture.lightPixels;
if (tex != null)
{
width = tex.getWidth();
}
}
return width;
}
@Override
@Deprecated
public int getLightmapGLFormat() {
int glFormat = -1;
LightTexture lightTexture = GAME_RENDERER.lightTexture();
if (lightTexture != null) {
NativeImage tex = lightTexture.lightPixels;
if (tex != null) {
glFormat = tex.format().glFormat();
}
}
return glFormat;
}
@Override
public boolean isFogStateSpecial() {
Entity entity = GAME_RENDERER.getMainCamera().getEntity();
boolean isBlind = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
return GAME_RENDERER.getMainCamera().getFluidInCamera() != FogType.NONE || isBlind;
}
@Override
public boolean tryDisableVanillaFog() {
return true; // Handled via MixinFogRenderer in both forge and fabric
}
}
@@ -0,0 +1,41 @@
package com.seibel.lod.common.wrappers.minecraft;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import net.minecraft.util.profiling.ProfilerFiller;
/**
* @author James Seibel
* @version 11-20-2021
*/
public class ProfilerWrapper implements IProfilerWrapper
{
public ProfilerFiller profiler;
public ProfilerWrapper(ProfilerFiller newProfiler)
{
profiler = newProfiler;
}
/** starts a new section inside the currently running section */
@Override
public void push(String newSection)
{
profiler.push(newSection);
}
/** ends the currently running section and starts a new one */
@Override
public void popPush(String newSection)
{
profiler.popPush(newSection);
}
/** ends the currently running section */
@Override
public void pop()
{
profiler.pop();
}
}
@@ -0,0 +1,47 @@
package com.seibel.lod.common.wrappers.misc;
import com.mojang.blaze3d.platform.NativeImage;
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
import net.minecraft.client.renderer.LightTexture;
import org.lwjgl.opengl.GL32;
/**
* @author James Seibel
* @version 11-21-2021
*/
public class LightMapWrapper implements ILightMapWrapper
{
static NativeImage lightMap = null;
private LightTexture tex;
public LightMapWrapper(NativeImage newLightMap)
{
lightMap = newLightMap;
}
public LightMapWrapper(LightTexture lightTexture) {
tex = lightTexture;
}
public static void setLightMap(NativeImage newLightMap)
{
lightMap = newLightMap;
}
@Override
public int getLightValue(int skyLight, int blockLight)
{
return lightMap.getPixelRGBA(skyLight, blockLight);
}
@Override
public void bind() {
GL32.glBindTexture(GL32.GL_TEXTURE_2D, tex.lightTexture.getId());
}
@Override
public void unbind() {
GL32.glBindTexture(GL32.GL_TEXTURE_2D, 0);
}
}
@@ -0,0 +1,164 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common.wrappers.world;
import java.awt.Color;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.material.MaterialColor;
//This class wraps the minecraft BlockPos.Mutable (and BlockPos) class
public class BiomeWrapper implements IBiomeWrapper
{
public static final ConcurrentMap<Biome, BiomeWrapper> biomeWrapperMap = new ConcurrentHashMap<>();
private final Biome biome;
public BiomeWrapper(Biome biome)
{
this.biome = biome;
}
static public IBiomeWrapper getBiomeWrapper(Biome biome)
{
//first we check if the biome has already been wrapped
if(biomeWrapperMap.containsKey(biome) && biomeWrapperMap.get(biome) != null)
return biomeWrapperMap.get(biome);
//if it hasn't been created yet, we create it and save it in the map
BiomeWrapper biomeWrapper = new BiomeWrapper(biome);
biomeWrapperMap.put(biome, biomeWrapper);
//we return the newly created wrapper
return biomeWrapper;
}
/** Returns a color int for the given biome. */
@Override
public int getColorForBiome(int x, int z)
{
int colorInt;
switch (biome.biomeCategory)
{
case NETHER:
colorInt = Blocks.NETHERRACK.defaultBlockState().getMaterial().getColor().col;
break;
case THEEND:
colorInt = Blocks.END_STONE.defaultBlockState().getMaterial().getColor().col;
break;
case BEACH:
case DESERT:
colorInt = Blocks.SAND.defaultBlockState().getMaterial().getColor().col;
break;
case EXTREME_HILLS:
colorInt = Blocks.STONE.defaultMaterialColor().col;
break;
case MUSHROOM:
colorInt = MaterialColor.COLOR_LIGHT_GRAY.col;
break;
case ICY:
colorInt = Blocks.SNOW.defaultMaterialColor().col;
break;
case MESA:
colorInt = Blocks.RED_SAND.defaultMaterialColor().col;
break;
case OCEAN:
case RIVER:
colorInt = biome.getWaterColor();
break;
case NONE:
case FOREST:
case TAIGA:
case JUNGLE:
case PLAINS:
case SAVANNA:
case SWAMP:
default:
colorInt = biome.getGrassColor(x,z);
//FIXME: Repair what James did - LeeTom
// Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z));
// tmp = tmp.darker();
// colorInt = LodUtil.colorToInt(tmp);
break;
}
return colorInt;
}
@Override public String getName()
{
return biome.toString();
}
@Override
public int getGrassTint(int x, int z)
{
return biome.getGrassColor(x, z);
}
@Override
public int getFolliageTint()
{
return biome.getFoliageColor();
}
@Override
public int getWaterTint()
{
return biome.getWaterColor();
}
@Override public boolean equals(Object obj)
{
if (this == obj)
return true;
if (!(obj instanceof BiomeWrapper))
return false;
BiomeWrapper that = (BiomeWrapper) obj;
return Objects.equals(biome, that.biome);
}
@Override public int hashCode()
{
return Objects.hash(biome);
}
}
@@ -0,0 +1,82 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common.wrappers.world;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import net.minecraft.world.level.dimension.DimensionType;
/**
*
* @author James Seibel
* @version 11-21-2021
*/
public class DimensionTypeWrapper implements IDimensionTypeWrapper
{
private static final ConcurrentMap<DimensionType, DimensionTypeWrapper> dimensionTypeWrapperMap = new ConcurrentHashMap<>();
private final DimensionType dimensionType;
public DimensionTypeWrapper(DimensionType dimensionType)
{
this.dimensionType = dimensionType;
}
public static DimensionTypeWrapper getDimensionTypeWrapper(DimensionType dimensionType)
{
//first we check if the biome has already been wrapped
if(dimensionTypeWrapperMap.containsKey(dimensionType) && dimensionTypeWrapperMap.get(dimensionType) != null)
return dimensionTypeWrapperMap.get(dimensionType);
//if it hasn't been created yet, we create it and save it in the map
DimensionTypeWrapper dimensionTypeWrapper = new DimensionTypeWrapper(dimensionType);
dimensionTypeWrapperMap.put(dimensionType, dimensionTypeWrapper);
//we return the newly created wrapper
return dimensionTypeWrapper;
}
public static void clearMap()
{
dimensionTypeWrapperMap.clear();
}
@Override
public String getDimensionName()
{
return dimensionType.effectsLocation().getPath();
}
@Override
public boolean hasCeiling()
{
return dimensionType.hasCeiling();
}
@Override
public boolean hasSkyLight()
{
return dimensionType.hasSkyLight();
}
}
@@ -0,0 +1,187 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common.wrappers.world;
import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.seibel.lod.core.enums.WorldType;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.level.chunk.ChunkStatus;
import org.jetbrains.annotations.Nullable;
/**
* @author James Seibel
* @author ??
* @version 11-21-2021
*/
public class WorldWrapper implements IWorldWrapper
{
private static final ConcurrentMap<LevelAccessor, WorldWrapper> worldWrapperMap = new ConcurrentHashMap<>();
private final LevelAccessor world;
public final WorldType worldType;
public WorldWrapper(LevelAccessor newWorld)
{
world = newWorld;
if (world.getClass() == ServerLevel.class)
worldType = WorldType.ServerWorld;
else if (world.getClass() == ClientLevel.class)
worldType = WorldType.ClientWorld;
else
worldType = WorldType.Unknown;
}
@Nullable
public static WorldWrapper getWorldWrapper(LevelAccessor world)
{
if (world == null) return null;
//first we check if the biome has already been wrapped
if(worldWrapperMap.containsKey(world) && worldWrapperMap.get(world) != null)
return worldWrapperMap.get(world);
//if it hasn't been created yet, we create it and save it in the map
WorldWrapper worldWrapper = new WorldWrapper(world);
worldWrapperMap.put(world, worldWrapper);
//we return the newly created wrapper
return worldWrapper;
}
public static void clearMap()
{
worldWrapperMap.clear();
}
@Override
public WorldType getWorldType()
{
return worldType;
}
@Override
public DimensionTypeWrapper getDimensionType()
{
return DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType());
}
@Override
public int getBlockLight(int x, int y, int z)
{
return world.getBrightness(LightLayer.BLOCK, new BlockPos(x,y,z));
}
@Override
public int getSkyLight(int x, int y, int z)
{
return world.getBrightness(LightLayer.SKY, new BlockPos(x,y,z));
}
public LevelAccessor getWorld()
{
return world;
}
@Override
public boolean hasCeiling()
{
return world.dimensionType().hasCeiling();
}
@Override
public boolean hasSkyLight()
{
return world.dimensionType().hasSkyLight();
}
@Override
public int getHeight()
{
return world.getHeight();
}
@Override
public short getMinHeight()
{
return (short) world.getMinBuildHeight();
}
/** @throws UnsupportedOperationException if the WorldWrapper isn't for a ServerWorld */
@Override
public File getSaveFolder() throws UnsupportedOperationException
{
if (worldType != WorldType.ServerWorld)
throw new UnsupportedOperationException("getSaveFolder can only be called for ServerWorlds.");
ServerChunkCache chunkSource = ((ServerLevel) world).getChunkSource();
return chunkSource.getDataStorage().dataFolder;
}
/** @throws UnsupportedOperationException if the WorldWrapper isn't for a ServerWorld */
public ServerLevel getServerWorld() throws UnsupportedOperationException
{
if (worldType != WorldType.ServerWorld)
throw new UnsupportedOperationException("getSaveFolder can only be called for ServerWorlds.");
return (ServerLevel) world;
}
@Override
public int getSeaLevel()
{
// TODO this is depreciated, what should we use instead?
return world.getSeaLevel();
}
@Override
public IChunkWrapper tryGetChunk(AbstractChunkPosWrapper pos) {
ChunkAccess chunk = world.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
if (chunk == null) return null;
return new ChunkWrapper(chunk, world);
}
@Override
public boolean hasChunkLoaded(int chunkX, int chunkZ) {
// world.hasChunk(chunkX, chunkZ); THIS DOES NOT WORK FOR CLIENT LEVEL CAUSE MOJANG ALWAYS RETURN TRUE FOR THAT!
ChunkSource source = world.getChunkSource();
return source.hasChunk(chunkX, chunkZ);
}
}
@@ -0,0 +1,608 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2021 Tom Lee (TomTheFurry)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.common.wrappers.worldGeneration;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.logging.ConfigBasedSpamLogger;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.LightGenerationMode;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.util.gridList.ArrayGridList;
import com.seibel.lod.core.util.LodThreadFactory;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper;
import java.time.Duration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.common.wrappers.DependencySetupDoneCheck;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import com.seibel.lod.common.wrappers.world.WorldWrapper;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.ChunkLoader;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightGetterAdaptor;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenLevelLightEngine;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepBiomes;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepFeatures;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepLight;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepNoise;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepStructureReference;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepStructureStart;
import com.seibel.lod.common.wrappers.worldGeneration.step.StepSurface;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.UpgradeData;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.lighting.LevelLightEngine;
import org.apache.logging.log4j.LogManager;
/*
Total: 3.135214124s
=====================================
Empty Chunks: 0.000558328s
StructureStart Step: 0.025177207s
StructureReference Step: 0.00189559s
Biome Step: 0.13789155s
Noise Step: 1.570347555s
Surface Step: 0.741238194s
Carver Step: 0.000009923s
Feature Step: 0.389072425s
Lod Generation: 0.269023348s
*/
public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvionmentWrapper
{
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final ConfigBasedSpamLogger PREF_LOGGER =
new ConfigBasedSpamLogger(LogManager.getLogger("LodWorldGen"),
() -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenPerformance(),1);
public static final ConfigBasedLogger EVENT_LOGGER =
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
() -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenEvent());
public static final ConfigBasedLogger LOAD_LOGGER =
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
() -> CONFIG.client().advanced().debugging().debugSwitch().getLogWorldGenLoadEvent());
//TODO: Make actual proper support for StarLight
public static class PrefEvent
{
long beginNano = 0;
long emptyNano = 0;
long structStartNano = 0;
long structRefNano = 0;
long biomeNano = 0;
long noiseNano = 0;
long surfaceNano = 0;
long carverNano = 0;
long featureNano = 0;
long lightNano = 0;
long endNano = 0;
@Override
public String toString()
{
return "beginNano: " + beginNano + ",\n" +
"emptyNano: " + emptyNano + ",\n" +
"structStartNano: " + structStartNano + ",\n" +
"structRefNano: " + structRefNano + ",\n" +
"biomeNano: " + biomeNano + ",\n" +
"noiseNano: " + noiseNano + ",\n" +
"surfaceNano: " + surfaceNano + ",\n" +
"carverNano: " + carverNano + ",\n" +
"featureNano: " + featureNano + ",\n" +
"lightNano: " + lightNano + ",\n" +
"endNano: " + endNano + "\n";
}
}
public static class PerfCalculator
{
public static final int SIZE = 50;
Rolling totalTime = new Rolling(SIZE);
Rolling emptyTime = new Rolling(SIZE);
Rolling structStartTime = new Rolling(SIZE);
Rolling structRefTime = new Rolling(SIZE);
Rolling biomeTime = new Rolling(SIZE);
Rolling noiseTime = new Rolling(SIZE);
Rolling surfaceTime = new Rolling(SIZE);
Rolling carverTime = new Rolling(SIZE);
Rolling featureTime = new Rolling(SIZE);
Rolling lightTime = new Rolling(SIZE);
Rolling lodTime = new Rolling(SIZE);
public void recordEvent(PrefEvent e)
{
long preTime = e.beginNano;
totalTime.add(e.endNano - preTime);
if (e.emptyNano != 0)
{
emptyTime.add(e.emptyNano - preTime);
preTime = e.emptyNano;
}
if (e.structStartNano != 0)
{
structStartTime.add(e.structStartNano - preTime);
preTime = e.structStartNano;
}
if (e.structRefNano != 0)
{
structRefTime.add(e.structRefNano - preTime);
preTime = e.structRefNano;
}
if (e.biomeNano != 0)
{
biomeTime.add(e.biomeNano - preTime);
preTime = e.biomeNano;
}
if (e.noiseNano != 0)
{
noiseTime.add(e.noiseNano - preTime);
preTime = e.noiseNano;
}
if (e.surfaceNano != 0)
{
surfaceTime.add(e.surfaceNano - preTime);
preTime = e.surfaceNano;
}
if (e.carverNano != 0)
{
carverTime.add(e.carverNano - preTime);
preTime = e.carverNano;
}
if (e.featureNano != 0)
{
featureTime.add(e.featureNano - preTime);
preTime = e.featureNano;
}
if (e.lightNano != 0)
{
lightTime.add(e.lightNano - preTime);
preTime = e.lightNano;
}
if (e.endNano != 0)
{
lodTime.add(e.endNano - preTime);
}
}
public String toString()
{
return "Total: " + Duration.ofNanos((long) totalTime.getAverage()) + ", Empty/LoadChunk: "
+ Duration.ofNanos((long) emptyTime.getAverage()) + ", StructStart: "
+ Duration.ofNanos((long) structStartTime.getAverage()) + ", StructRef: "
+ Duration.ofNanos((long) structRefTime.getAverage()) + ", Biome: "
+ Duration.ofNanos((long) biomeTime.getAverage()) + ", Noise: "
+ Duration.ofNanos((long) noiseTime.getAverage()) + ", Surface: "
+ Duration.ofNanos((long) surfaceTime.getAverage()) + ", Carver: "
+ Duration.ofNanos((long) carverTime.getAverage()) + ", Feature: "
+ Duration.ofNanos((long) featureTime.getAverage()) + ", Light: "
+ Duration.ofNanos((long) lightTime.getAverage()) + ", Lod: "
+ Duration.ofNanos((long) lodTime.getAverage());
}
}
public static final int TIMEOUT_SECONDS = 60;
//=================Generation Step===================
public final LinkedList<GenerationEvent> events = new LinkedList<>();
public final GlobalParameters params;
public final StepStructureStart stepStructureStart = new StepStructureStart(this);
public final StepStructureReference stepStructureReference = new StepStructureReference(this);
public final StepBiomes stepBiomes = new StepBiomes(this);
public final StepNoise stepNoise = new StepNoise(this);
public final StepSurface stepSurface = new StepSurface(this);
public final StepFeatures stepFeatures = new StepFeatures(this);
public final StepLight stepLight = new StepLight(this);
public boolean unsafeThreadingRecorded = false;
//public boolean safeMode = false;
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
public static final long EXCEPTION_TIMER_RESET_TIME = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
public static final int EXCEPTION_COUNTER_TRIGGER = 20;
public static final int RANGE_TO_RANGE_EMPTY_EXTENSION = 1;
public int unknownExceptionCount = 0;
public long lastExceptionTriggerTime = 0;
public static final LodThreadFactory threadFactory = new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY);
public static ThreadLocal<Boolean> isDistantGeneratorThread = new ThreadLocal<>();
public static boolean isCurrentThreadDistantGeneratorThread() {
return (isDistantGeneratorThread.get() != null);
}
static {
DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread;
}
public ExecutorService executors = Executors.newFixedThreadPool(
CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads(), threadFactory);
public <T> T joinSync(CompletableFuture<T> f) {
if (!unsafeThreadingRecorded && !f.isDone()) {
EVENT_LOGGER.error("Unsafe Threading in Chunk Generator: ", new RuntimeException("Concurrent future"));
EVENT_LOGGER.error("To increase stability, it is recommended to set world generation threads count to 1.");
unsafeThreadingRecorded = true;
}
return f.join();
}
public void resizeThreadPool(int newThreadCount)
{
executors = Executors.newFixedThreadPool(newThreadCount,
new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY));
}
public boolean tryAddPoint(int px, int pz, int range, Steps target, boolean genAllDetails)
{
int boxSize = range * 2 + 1;
int x = Math.floorDiv(px, boxSize) * boxSize + range;
int z = Math.floorDiv(pz, boxSize) * boxSize + range;
for (GenerationEvent event : events)
{
if (event.tooClose(x, z, range))
return false;
}
// System.out.println(x + ", "+z);
events.add(new GenerationEvent(new ChunkPos(x, z), range, this, target, genAllDetails));
return true;
}
public void updateAllFutures()
{
if (unknownExceptionCount > 0) {
if (System.nanoTime() - lastExceptionTriggerTime >= EXCEPTION_TIMER_RESET_TIME) {
unknownExceptionCount = 0;
}
}
// Update all current out standing jobs
Iterator<GenerationEvent> iter = events.iterator();
while (iter.hasNext())
{
GenerationEvent event = iter.next();
if (event.isCompleted())
{
try
{
event.join();
}
catch (Throwable e)
{
EVENT_LOGGER.error("Batching World Generator: Event {} gotten an exception", event);
EVENT_LOGGER.error("Exception: ", e);
unknownExceptionCount++;
lastExceptionTriggerTime = System.nanoTime();
}
finally
{
iter.remove();
}
}
else if (event.hasTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS))
{
EVENT_LOGGER.error("Batching World Generator: " + event + " timed out and terminated!");
EVENT_LOGGER.info("Dump PrefEvent: " + event.pEvent);
try
{
if (!event.terminate())
EVENT_LOGGER.error("Failed to terminate the stuck generation event!");
}
finally
{
iter.remove();
}
}
}
if (unknownExceptionCount > EXCEPTION_COUNTER_TRIGGER) {
EVENT_LOGGER.error("Too many exceptions in Batching World Generator! Disabling the generator.");
unknownExceptionCount = 0;
CONFIG.client().worldGenerator().setEnableDistantGeneration(false);
}
}
public BatchGenerationEnvironment(IWorldWrapper serverlevel, LodBuilder lodBuilder, LodDimension lodDim)
{
super(serverlevel, lodBuilder, lodDim);
EVENT_LOGGER.info("================WORLD_GEN_STEP_INITING=============");
ChunkGenerator generator = ((WorldWrapper) serverlevel).getServerWorld().getChunkSource().getGenerator();
if (!(generator instanceof NoiseBasedChunkGenerator ||
generator instanceof DebugLevelSource ||
generator instanceof FlatLevelSource)) {
EVENT_LOGGER.warn("Unknown Chunk Generator detected: [{}], Distant Generation May Fail!", generator.getClass());
EVENT_LOGGER.warn("If it does crash, set Distant Generation to OFF or Generation Mode to None.");
}
params = new GlobalParameters((ServerLevel) ((WorldWrapper) serverlevel).getWorld(), lodBuilder, lodDim);
}
@SuppressWarnings("resource")
public static ChunkAccess loadOrMakeChunk(ChunkPos chunkPos, ServerLevel level, LevelLightEngine lightEngine)
{
CompoundTag chunkData = null;
try
{
chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos);
}
catch (Exception e)
{
LOAD_LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
}
if (chunkData == null)
{
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null);
}
else
{
try {
return ChunkLoader.read(level, lightEngine, chunkPos, chunkData);
} catch (Exception e) {
LOAD_LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level, level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null);
}
}
}
public void generateLodFromList(GenerationEvent e)
{
EVENT_LOGGER.debug("Lod Generate Event: " + e.pos);
e.pEvent.beginNano = System.nanoTime();
ArrayGridList<ChunkAccess> referencedChunks;
ArrayGridList<ChunkAccess> genChunks;
DistanceGenerationMode generationMode;
LightedWorldGenRegion region;
WorldGenLevelLightEngine lightEngine;
LightGetterAdaptor adaptor;
int refRange = e.range + RANGE_TO_RANGE_EMPTY_EXTENSION;
int refOffsetX = e.pos.x - refRange;
int refOffsetZ = e.pos.z - refRange;
try
{
adaptor = new LightGetterAdaptor(params.level);
lightEngine = new WorldGenLevelLightEngine(adaptor);
@SuppressWarnings("resource")
EmptyChunkGenerator generator = (int x, int z) ->
{
ChunkPos chunkPos = new ChunkPos(x, z);
ChunkAccess target = null;
try
{
target = loadOrMakeChunk(chunkPos, params.level, lightEngine);
}
catch (RuntimeException e2)
{
// Continue...
}
if (target == null)
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY, params.level,
params.biomes, null);
return target;
};
referencedChunks = new ArrayGridList<>(refRange*2+1,
(x,z) -> generator.generate(x + refOffsetX,z + refOffsetZ)
);
e.pEvent.emptyNano = System.nanoTime();
e.refreshTimeout();
region = new LightedWorldGenRegion(params.level, lightEngine, referencedChunks,
ChunkStatus.STRUCTURE_STARTS, refRange, e.lightMode, generator);
adaptor.setRegion(region);
e.tParam.makeStructFeat(region, params);
genChunks = new ArrayGridList<>(referencedChunks, RANGE_TO_RANGE_EMPTY_EXTENSION,
referencedChunks.gridSize - RANGE_TO_RANGE_EMPTY_EXTENSION);
generateDirect(e, genChunks, e.target, region);
}
catch (StepStructureStart.StructStartCorruptedException f)
{
e.tParam.markAsInvalid();
return;
}
switch (e.target)
{
case Empty:
case StructureStart:
case StructureReference:
generationMode = DistanceGenerationMode.NONE;
break;
case Biomes:
generationMode = DistanceGenerationMode.BIOME_ONLY;
case Noise:
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
break;
case Surface:
case Carvers:
generationMode = DistanceGenerationMode.SURFACE;
break;
case Features:
generationMode = DistanceGenerationMode.FEATURES;
break;
case Light:
case LiquidCarvers:
default:
return;
}
for (int oy = 0; oy < genChunks.gridSize; oy++)
{
for (int ox = 0; ox < genChunks.gridSize; ox++)
{
ChunkAccess target = genChunks.get(ox, oy);
ChunkWrapper wrappedChunk = new ChunkWrapper(target, region);
if (!wrappedChunk.isLightCorrect()) {
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
}
boolean isFull = target.getStatus() == ChunkStatus.FULL || target instanceof LevelChunk;
boolean isPartial = target.isOldNoiseGeneration();
if (isFull)
{
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(DistanceGenerationMode.FULL), true, e.genAllDetails);
}
else if (isPartial)
{
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(generationMode), true, e.genAllDetails);
}
else if (target.getStatus() == ChunkStatus.EMPTY && generationMode == DistanceGenerationMode.NONE)
{
params.lodBuilder.generateLodNodeFromChunk(params.lodDim,wrappedChunk,
LodBuilderConfig.getFillVoidConfig(), true, e.genAllDetails);
}
else
{
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(generationMode), true, e.genAllDetails);
}
if (e.lightMode == LightGenerationMode.FANCY || isFull)
{
lightEngine.retainData(target.getPos(), false);
}
}
}
e.pEvent.endNano = System.nanoTime();
e.refreshTimeout();
if (PREF_LOGGER.canMaybeLog())
{
e.tParam.perf.recordEvent(e.pEvent);
PREF_LOGGER.infoInc("{}", e.tParam.perf);
}
}
public void generateDirect(GenerationEvent e, ArrayGridList<ChunkAccess> subRange, Steps step,
LightedWorldGenRegion region)
{
try
{
subRange.forEach((chunk) ->
{
if (chunk instanceof ProtoChunk)
{
((ProtoChunk) chunk).setLightEngine(region.getLightEngine());
region.getLightEngine().retainData(chunk.getPos(), true);
}
});
if (step == Steps.Empty)
return;
stepStructureStart.generateGroup(e.tParam, region, subRange);
e.pEvent.structStartNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.StructureStart)
return;
stepStructureReference.generateGroup(e.tParam, region, subRange);
e.pEvent.structRefNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.StructureReference)
return;
stepBiomes.generateGroup(e.tParam, region, subRange);
e.pEvent.biomeNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Biomes)
return;
stepNoise.generateGroup(e.tParam, region, subRange);
e.pEvent.noiseNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Noise)
return;
stepSurface.generateGroup(e.tParam, region, subRange);
e.pEvent.surfaceNano = System.nanoTime();
e.refreshTimeout();
if (step == Steps.Surface)
return;
if (step == Steps.Carvers)
return;
stepFeatures.generateGroup(e.tParam, region, subRange);
e.pEvent.featureNano = System.nanoTime();
e.refreshTimeout();
}
finally
{
switch (region.lightMode)
{
case FANCY:
stepLight.generateGroup(region.getLightEngine(), subRange);
break;
case FAST:
subRange.forEach((p) ->
{
if (p instanceof ProtoChunk)
((ProtoChunk) p).setLightCorrect(true);
if (p instanceof LevelChunk) {
((LevelChunk) p).setLightCorrect(true);
((LevelChunk) p).setClientLightReady(true);
}
});
break;
}
e.pEvent.lightNano = System.nanoTime();
e.refreshTimeout();
}
}
public interface EmptyChunkGenerator
{
ChunkAccess generate(int x, int z);
}
@Override
public int getEventCount() {
return events.size();
}
@Override
public void stop(boolean blocking) {
EVENT_LOGGER.info("Batch Chunk Generator shutting down...");
executors.shutdownNow();
if (blocking) try {
if (!executors.awaitTermination(10, TimeUnit.SECONDS)) {
EVENT_LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...");
}
} catch (InterruptedException e) {
EVENT_LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...", e);
}
}
}
@@ -0,0 +1,111 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.PrefEvent;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.enums.config.LightGenerationMode;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper.Steps;
import net.minecraft.world.level.ChunkPos;
//======================= Main Event class======================
public final class GenerationEvent
{
static private final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static int generationFutureDebugIDs = 0;
final ThreadedParameters tParam;
final ChunkPos pos;
final int range;
final Future<?> future;
long nanotime;
final int id;
final Steps target;
final LightGenerationMode lightMode;
final PrefEvent pEvent = new PrefEvent();
final boolean genAllDetails;
public GenerationEvent(ChunkPos pos, int range, BatchGenerationEnvironment generationGroup, Steps target, boolean genAllDetails)
{
nanotime = System.nanoTime();
this.pos = pos;
this.range = range;
id = generationFutureDebugIDs++;
this.target = target;
this.tParam = ThreadedParameters.getOrMake(generationGroup.params);
LightGenerationMode mode = CONFIG.client().worldGenerator().getLightGenerationMode();
this.lightMode = mode;
this.genAllDetails = genAllDetails;
future = generationGroup.executors.submit(() ->
{
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
try {
generationGroup.generateLodFromList(this);
} finally {
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
}
});
}
public boolean isCompleted()
{
return future.isDone();
}
public boolean hasTimeout(int duration, TimeUnit unit)
{
long currentTime = System.nanoTime();
long delta = currentTime - nanotime;
return (delta > TimeUnit.NANOSECONDS.convert(duration, unit));
}
public boolean terminate()
{
ApiShared.LOGGER.info("======================DUMPING ALL THREADS FOR WORLD GEN=======================");
BatchGenerationEnvironment.threadFactory.dumpAllThreadStacks();
future.cancel(true);
return future.isCancelled();
}
public void join()
{
try
{
future.get();
}
catch (InterruptedException | ExecutionException e)
{
throw new RuntimeException(e.getCause()==null? e : e.getCause());
}
}
public boolean tooClose(int cx, int cz, int cr)
{
int distX = Math.abs(cx - pos.x);
int distZ = Math.abs(cz - pos.z);
int minRange = cr + range + 1; // Need one to account for the center
minRange += 1 + 1; // Account for required empty chunks
return distX < minRange && distZ < minRange;
}
public void refreshTimeout()
{
nanotime = System.nanoTime();
LodUtil.checkInterruptsUnchecked();
}
@Override
public String toString()
{
return id + ":" + range + "@" + pos + "(" + target + ")";
}
}
@@ -0,0 +1,55 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import com.mojang.datafixers.DataFixer;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.objects.lod.LodDimension;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.storage.ChunkScanAccess;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.storage.WorldData;
public final class GlobalParameters
{
public final ChunkGenerator generator;
public final StructureManager structures;
public final BiomeManager biomeManager;
public final WorldGenSettings worldGenSettings;
public final ThreadedLevelLightEngine lightEngine;
public final LodBuilder lodBuilder;
public final LodDimension lodDim;
public final Registry<Biome> biomes;
public final RegistryAccess registry;
public final long worldSeed;
public final ChunkScanAccess chunkScanner;
public final ServerLevel level; // TODO: Figure out a way to remove this. Maybe ClientLevel also works?
public final DataFixer fixerUpper;
public GlobalParameters(ServerLevel level, LodBuilder lodBuilder, LodDimension lodDim)
{
this.lodBuilder = lodBuilder;
this.lodDim = lodDim;
this.level = level;
lightEngine = (ThreadedLevelLightEngine) level.getLightEngine();
MinecraftServer server = level.getServer();
WorldData worldData = server.getWorldData();
worldGenSettings = worldData.worldGenSettings();
registry = server.registryAccess();
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
worldSeed = worldGenSettings.seed();
biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
structures = server.getStructureManager();
generator = level.getChunkSource().getGenerator();
chunkScanner = level.getChunkSource().chunkScanner();
fixerUpper = server.getFixerUpper();
}
}
@@ -0,0 +1,34 @@
package com.seibel.lod.common.wrappers.worldGeneration;
//FIXME: Move this outside the WorldGenerationStep thingy
public class Rolling
{
private final int size;
private double total = 0d;
private int index = 0;
private final double[] samples;
public Rolling(int size)
{
this.size = size;
samples = new double[size];
for (int i = 0; i < size; i++)
samples[i] = 0d;
}
public void add(double x)
{
total -= samples[index];
samples[index] = x;
total += x;
if (++index == size)
index = 0; // cheaper than modulus
}
public double getAverage()
{
return total / size;
}
}
@@ -0,0 +1,48 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.PerfCalculator;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenStructFeatManager;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.levelgen.structure.StructureCheck;
public final class ThreadedParameters
{
private static final ThreadLocal<ThreadedParameters> localParam = new ThreadLocal<ThreadedParameters>();
final ServerLevel level;
public WorldGenStructFeatManager structFeat = null;
public final StructureCheck structCheck;
boolean isValid = true;
public final PerfCalculator perf = new PerfCalculator();
public static ThreadedParameters getOrMake(GlobalParameters param)
{
ThreadedParameters tParam = localParam.get();
if (tParam != null && tParam.isValid && tParam.level == param.level)
return tParam;
tParam = new ThreadedParameters(param);
localParam.set(tParam);
return tParam;
}
public void markAsInvalid()
{
isValid = false;
}
private ThreadedParameters(GlobalParameters param)
{
level = param.level;
structCheck = new StructureCheck(param.chunkScanner, param.registry, param.structures,
param.level.dimension(), param.generator, level, param.generator.getBiomeSource(), param.worldSeed,
param.fixerUpper);
}
public void makeStructFeat(WorldGenLevel genLevel, GlobalParameters param)
{
structFeat = new WorldGenStructFeatManager(param.worldGenSettings, genLevel, structCheck);
}
}
@@ -0,0 +1,324 @@
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
import com.google.common.collect.Maps;
import com.mojang.serialization.Codec;
import com.mojang.serialization.Dynamic;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
#if MC_VERSION_1_18_2
import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
#endif
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.UpgradeData;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.blending.BlendingData;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.ticks.LevelChunkTicks;
import org.apache.logging.log4j.Logger;
public class ChunkLoader
{
private static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codec(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER;
private static final String TAG_UPGRADE_DATA = "UpgradeData";
private static final String BLOCK_TICKS_TAG = "block_ticks";
private static final String FLUID_TICKS_TAG = "fluid_ticks";
private static BlendingData readBlendingData(CompoundTag chunkData)
{
BlendingData blendingData = null;
if (chunkData.contains("blending_data", 10))
{
@SuppressWarnings({ "unchecked", "rawtypes" })
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
}
return blendingData;
}
private static LevelChunkSection[] readSections(LevelAccessor level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag chunkData)
{
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
#if MC_VERSION_1_18_1
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
#elif MC_VERSION_1_18_2
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
#endif
int i = level.getSectionsCount();
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
boolean isLightOn = chunkData.getBoolean("isLightOn");
boolean hasSkyLight = level.dimensionType().hasSkyLight();
ListTag tagSections = chunkData.getList("sections", 10);
for (int j = 0; j < tagSections.size(); ++j)
{
CompoundTag tagSection = tagSections.getCompound(j);
byte sectionYPos = tagSection.getByte("Y");
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
if (sectionId >= 0 && sectionId < chunkSections.length)
{
PalettedContainer<BlockState> blockStateContainer;
#if MC_VERSION_1_18_1
PalettedContainer<Biome> biomeContainer;
#elif MC_VERSION_1_18_2
PalettedContainer<Holder<Biome>> biomeContainer;
#endif
blockStateContainer = tagSection.contains("block_states", 10)
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
#if MC_VERSION_1_18_1
biomeContainer = tagSection.contains("biomes", 10)
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
#elif MC_VERSION_1_18_2
biomeContainer = tagSection.contains("biomes", 10)
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, i, (String) string)).getOrThrow(false, LOGGER::error)
: new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
#endif
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
}
if (!isLightOn)
continue;
if (tagSection.contains("BlockLight", 7))
lightEngine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, sectionYPos), new DataLayer(tagSection.getByteArray("BlockLight")), true);
if (hasSkyLight && tagSection.contains("SkyLight", 7))
lightEngine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, sectionYPos), new DataLayer(tagSection.getByteArray("SkyLight")), true);
}
return chunkSections;
}
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
{
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
{
String heightmap = type.getSerializationKey();
if (tagHeightmaps.contains(heightmap, 12))
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
}
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
}
#if MC_VERSION_1_18_1
private static Map<StructureFeature<?>, StructureStart<?>> unpackStructureStart(StructurePieceSerializationContext structurePieceSerializationContext, CompoundTag compoundTag, long l)
{
HashMap<StructureFeature<?>, StructureStart<?>> map = Maps.newHashMap();
CompoundTag compoundTag2 = compoundTag.getCompound("starts");
for (String string : compoundTag2.getAllKeys())
{
String string2 = string.toLowerCase(Locale.ROOT);
StructureFeature<?> structureFeature = StructureFeature.STRUCTURES_REGISTRY.get(string2);
if (structureFeature == null)
{
LOGGER.error("Unknown structure start: {}", (Object) string2);
continue;
}
StructureStart<?> structureStart = StructureFeature.loadStaticStart(structurePieceSerializationContext, compoundTag2.getCompound(string), l);
if (structureStart == null)
continue;
map.put(structureFeature, structureStart);
}
return map;
}
private static Map<StructureFeature<?>, LongSet> unpackStructureReferences(ChunkPos chunkPos, CompoundTag compoundTag)
{
HashMap<StructureFeature<?>, LongSet> map = Maps.newHashMap();
CompoundTag compoundTag2 = compoundTag.getCompound("References");
for (String string : compoundTag2.getAllKeys())
{
String string2 = string.toLowerCase(Locale.ROOT);
StructureFeature<?> structureFeature = StructureFeature.STRUCTURES_REGISTRY.get(string2);
if (structureFeature == null)
{
LOGGER.warn("Found reference to unknown structure '{}' in chunk {}, discarding", (Object) string2, (Object) chunkPos);
continue;
}
map.put(structureFeature, new LongOpenHashSet(Arrays.stream(compoundTag2.getLongArray(string)).filter(l ->
{
ChunkPos chunkPos2 = new ChunkPos(l);
if (chunkPos2.getChessboardDistance(chunkPos) > 8)
{
LOGGER.warn("Found invalid structure reference [ {} @ {} ] for chunk {}.", (Object) string2, (Object) chunkPos2, (Object) chunkPos);
return false;
}
return true;
}).toArray()));
}
return map;
}
#elif MC_VERSION_1_18_2
private static Map<ConfiguredStructureFeature<?, ?>, StructureStart> unpackStructureStart(StructurePieceSerializationContext structurePieceSerializationContext, CompoundTag compoundTag, long l) {
Map<ConfiguredStructureFeature<?, ?>, StructureStart> map = Maps.newHashMap();
Registry<ConfiguredStructureFeature<?, ?>> structStartRegistry = structurePieceSerializationContext.registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY);
CompoundTag compoundTag2 = compoundTag.getCompound("starts");
for (String string : compoundTag2.getAllKeys()) {
ResourceLocation resourceLocation = ResourceLocation.tryParse(string);
ConfiguredStructureFeature<?, ?> structureFeature = structStartRegistry.get(resourceLocation);
// String string2 = string.toLowerCase(Locale.ROOT);
// ConfiguredStructureFeature<?, ?> structureFeature = StructureFeature.STRUCTURES_REGISTRY.get(string2);
if (structureFeature == null) {
LOGGER.error("Unknown structure start: {}", resourceLocation);
continue;
}
StructureStart structureStart = StructureFeature.loadStaticStart(structurePieceSerializationContext, compoundTag2.getCompound(string), l);
if (structureStart == null)
continue;
map.put(structureFeature, structureStart);
}
return map;
}
private static Map<ConfiguredStructureFeature<?, ?>, LongSet> unpackStructureReferences(RegistryAccess registryAccess, ChunkPos chunkPos, CompoundTag compoundTag)
{
Map<ConfiguredStructureFeature<?, ?>, LongSet> map = Maps.newHashMap();
Registry<ConfiguredStructureFeature<?, ?>> structRegistry = registryAccess.registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY);
CompoundTag compoundTag2 = compoundTag.getCompound("References");
for (String string : compoundTag2.getAllKeys())
{
ResourceLocation resourceLocation = ResourceLocation.tryParse(string);
ConfiguredStructureFeature<?, ?> structureFeature = structRegistry.get(resourceLocation);
// String string2 = string.toLowerCase(Locale.ROOT);
// ConfiguredStructureFeature<?, ?> structureFeature = StructureFeature.STRUCTURES_REGISTRY.get(string2);
if (structureFeature == null)
{
LOGGER.warn("Found reference to unknown structure '{}' in chunk {}, discarding", resourceLocation, chunkPos);
continue;
}
map.put(structureFeature, new LongOpenHashSet(Arrays.stream(compoundTag2.getLongArray(string)).filter(l ->
{
ChunkPos chunkPos2 = new ChunkPos(l);
if (chunkPos2.getChessboardDistance(chunkPos) > 8)
{
LOGGER.warn("Found invalid structure reference [ {} @ {} ] for chunk {}.", resourceLocation, chunkPos2, chunkPos);
return false;
}
return true;
}).toArray()));
}
return map;
}
#endif
private static void readStructures(WorldGenLevel level, LevelChunk chunk, CompoundTag chunkData)
{
CompoundTag tagStructures = chunkData.getCompound("structures");
chunk.setAllStarts(
unpackStructureStart(StructurePieceSerializationContext.fromLevel(level.getLevel()), tagStructures, level.getSeed()));
chunk.setAllReferences(unpackStructureReferences(#if MC_VERSION_1_18_2 level.registryAccess() ,#endif chunk.getPos(), tagStructures));
}
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
{
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
for (int n = 0; n < tagPostProcessings.size(); ++n)
{
ListTag listTag3 = tagPostProcessings.getList(n);
for (int o = 0; o < listTag3.size(); ++o)
{
chunk.addPackedPostProcess(listTag3.getShort(o), n);
}
}
}
public static ChunkStatus.ChunkType readChunkType(CompoundTag compoundTag)
{
return ChunkStatus.byName(compoundTag.getString("Status")).getChunkType();
}
public static LevelChunk read(WorldGenLevel level, LevelLightEngine lightEngine, ChunkPos chunkPos, CompoundTag chunkData)
{
ChunkPos actualPos = new ChunkPos(chunkData.getInt("xPos"), chunkData.getInt("zPos"));
if (!Objects.equals(chunkPos, actualPos))
{
LOGGER.error("Chunk file at {} is in the wrong location; Ignoring. (Expected {}, got {})", (Object) chunkPos, (Object) chunkPos, (Object) actualPos);
return null;
}
ChunkStatus.ChunkType chunkType = readChunkType(chunkData);
BlendingData blendingData = readBlendingData(chunkData);
if (chunkType == ChunkStatus.ChunkType.PROTOCHUNK && (blendingData == null || !blendingData.oldNoise()))
return null;
// Prepare the light engine
boolean isLightOn = chunkData.getBoolean("isLightOn");
if (isLightOn)
level.getLightEngine().retainData(chunkPos, true);
// Read params for making the LevelChunk
UpgradeData upgradeData = chunkData.contains(TAG_UPGRADE_DATA, 10)
? new UpgradeData(chunkData.getCompound(TAG_UPGRADE_DATA), level)
: UpgradeData.EMPTY;
LevelChunkTicks<Block> blockTicks = LevelChunkTicks.load(chunkData.getList(BLOCK_TICKS_TAG, 10),
string -> Registry.BLOCK.getOptional(ResourceLocation.tryParse(string)), chunkPos);
LevelChunkTicks<Fluid> fluidTicks = LevelChunkTicks.load(chunkData.getList(FLUID_TICKS_TAG, 10),
string -> Registry.FLUID.getOptional(ResourceLocation.tryParse(string)), chunkPos);
long inhabitedTime = chunkData.getLong("InhabitedTime");
LevelChunkSection[] chunkSections = readSections(level, lightEngine, actualPos, chunkData);
// Make chunk
LevelChunk chunk = new LevelChunk((Level) level, chunkPos, upgradeData, blockTicks, fluidTicks, inhabitedTime, chunkSections, null, blendingData);
// Set some states after object creation
chunk.setLightCorrect(isLightOn);
readHeightmaps(chunk, chunkData);
readStructures(level, chunk, chunkData);
readPostPocessings(chunk, chunkData);
return chunk;
}
private static void logErrors(ChunkPos chunkPos, int i, String string)
{
LOGGER.error("Distant Horizons: Recoverable errors when loading section [" + chunkPos.x + ", " + i + ", " + chunkPos.z + "]: " + string);
}
}
@@ -0,0 +1,40 @@
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LightChunkGetter;
public class LightGetterAdaptor implements LightChunkGetter {
private final BlockGetter heightGetter;
public LightedWorldGenRegion genRegion = null;
final boolean shouldReturnNull;
public LightGetterAdaptor(BlockGetter heightAccessor) {
this.heightGetter = heightAccessor;
shouldReturnNull = ModAccessorHandler.get(IStarlightAccessor.class) != null;
}
public void setRegion(LightedWorldGenRegion region) {
genRegion = region;
}
@Override
public BlockGetter getChunkForLighting(int chunkX, int chunkZ) {
if (genRegion == null)
throw new IllegalStateException("World Gen region has not been set!");
// May be null
return genRegion.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY, false);
}
@Override
public BlockGetter getLevel() {
return shouldReturnNull ? null : (genRegion != null ? genRegion : heightGetter);
}
public LevelHeightAccessor getLevelHeightAccessor() {
return heightGetter;
}
}
@@ -0,0 +1,280 @@
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
import java.util.List;
import com.seibel.lod.core.api.ApiShared;
import org.jetbrains.annotations.Nullable;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.EmptyChunkGenerator;
import com.seibel.lod.core.enums.config.LightGenerationMode;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockTintCache;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Cursor3D;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ImposterProtoChunk;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.lighting.LevelLightEngine;
public class LightedWorldGenRegion extends WorldGenRegion {
public final WorldGenLevelLightEngine light;
public final LightGenerationMode lightMode;
public final EmptyChunkGenerator generator;
public final int writeRadius;
public final int size;
private final ChunkPos firstPos;
private final List<ChunkAccess> cache;
Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<ChunkAccess>();
public LightedWorldGenRegion(ServerLevel serverLevel, WorldGenLevelLightEngine lightEngine,
List<ChunkAccess> list, ChunkStatus chunkStatus, int i,
LightGenerationMode lightMode, EmptyChunkGenerator generator) {
super(serverLevel, list, chunkStatus, i);
this.lightMode = lightMode;
this.firstPos = list.get(0).getPos();
this.generator = generator;
light = lightEngine;
writeRadius = i;
cache = list;
size = Mth.floor(Math.sqrt(list.size()));
this.tintCaches = Util.make(new Object2ObjectArrayMap(3), object2ObjectArrayMap -> {
object2ObjectArrayMap.put(BiomeColors.GRASS_COLOR_RESOLVER, new BlockTintCache((pos) -> {return calculateBlockTint(pos, BiomeColors.GRASS_COLOR_RESOLVER);}));
object2ObjectArrayMap.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new BlockTintCache((pos) -> {return calculateBlockTint(pos, BiomeColors.FOLIAGE_COLOR_RESOLVER);}));
object2ObjectArrayMap.put(BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache((pos) -> {return calculateBlockTint(pos, BiomeColors.WATER_COLOR_RESOLVER);}));
});
}
// Bypass BCLib mixin overrides.
@Override
public boolean ensureCanWrite(BlockPos blockPos) {
int i = SectionPos.blockToSectionCoord(blockPos.getX());
int j = SectionPos.blockToSectionCoord(blockPos.getZ());
ChunkPos chunkPos = this.getCenter();
ChunkAccess center = this.getChunk(chunkPos.x, chunkPos.z);
int k = Math.abs(chunkPos.x - i);
int l = Math.abs(chunkPos.z - j);
if (k > this.writeRadius || l > this.writeRadius) {
return false;
}
if (center.isUpgrading()) {
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
if (blockPos.getY() < levelHeightAccessor.getMinBuildHeight() || blockPos.getY() >= levelHeightAccessor.getMaxBuildHeight()) {
return false;
}
}
return true;
}
// TODO Check this
// @Override
// public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
// StructureFeature<?> structureFeature) {
// return structFeat.startsForFeature(sectionPos, structureFeature);
// }
// Skip updating the related tile entities
@Override
public boolean setBlock(BlockPos blockPos, BlockState blockState, int i, int j) {
ChunkAccess chunkAccess = this.getChunk(blockPos);
if (chunkAccess instanceof LevelChunk)
return true;
chunkAccess.setBlockState(blockPos, blockState, false);
// This is for post ticking for water on gen and stuff like that. Not enabled
// for now.
// if (blockState.hasPostProcess(this, blockPos))
// this.getChunk(blockPos).markPosForPostprocessing(blockPos);
return true;
}
// Skip Dropping the item on destroy
@Override
public boolean destroyBlock(BlockPos blockPos, boolean bl, @Nullable Entity entity, int i) {
BlockState blockState = this.getBlockState(blockPos);
if (blockState.isAir()) {
return false;
}
return this.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3, i);
}
// Skip BlockEntity stuff. It aren't really needed
@Override
public BlockEntity getBlockEntity(BlockPos blockPos) {
return null;
}
// Skip BlockEntity stuff. It aren't really needed
@Override
public boolean addFreshEntity(Entity entity) {
return true;
}
// Allays have empty chunks even if it's outside the worldGenRegion
// @Override
// public boolean hasChunk(int i, int j) {
// return true;
// }
// Override to ensure no other mod mixins cause skipping the overrided
// getChunk(...)
@Override
public ChunkAccess getChunk(int i, int j) {
return this.getChunk(i, j, ChunkStatus.EMPTY);
}
// Override to ensure no other mod mixins cause skipping the overrided
// getChunk(...)
@Override
public ChunkAccess getChunk(int i, int j, ChunkStatus chunkStatus) {
return this.getChunk(i, j, chunkStatus, true);
}
// Use this instead of super.getChunk() to bypass C2ME concurrency checks
private ChunkAccess superGetChunk(int x, int z, ChunkStatus cs) {
int k = x - firstPos.x;
int l = z - firstPos.z;
return cache.get(k + l * size);
}
// Use this instead of super.hasChunk() to bypass C2ME concurrency checks
private boolean superHasChunk(int x, int z) {
int k = x - firstPos.x;
int l = z - firstPos.z;
return l >= 0 && l < size && k >= 0 && k < size;
}
// Allow creating empty chunks even if it's outside the worldGenRegion
@Override
@Nullable
public ChunkAccess getChunk(int i, int j, ChunkStatus chunkStatus, boolean bl) {
ChunkAccess chunk = getChunkAccess(i, j, chunkStatus, bl);
if (chunk instanceof LevelChunk) {
chunk = new ImposterProtoChunk((LevelChunk) chunk, true);
}
return chunk;
}
private static ChunkStatus debugTriggeredForStatus = null;
private ChunkAccess getChunkAccess(int i, int j, ChunkStatus chunkStatus, boolean bl) {
ChunkAccess chunk = superHasChunk(i, j) ? superGetChunk(i, j, ChunkStatus.EMPTY) : null;
if (chunk != null && chunk.getStatus().isOrAfter(chunkStatus)) {
return chunk;
}
if (!bl)
return null;
if (chunk == null) {
chunk = chunkMap.get(ChunkPos.asLong(i, j));
if (chunk == null) {
chunk = generator.generate(i, j);
if (chunk == null)
throw new NullPointerException("The provided generator should not return null!");
chunkMap.put(ChunkPos.asLong(i, j), chunk);
}
}
if (chunkStatus != ChunkStatus.EMPTY && chunkStatus != debugTriggeredForStatus) {
ApiShared.LOGGER.info("WorldGen requiring " + chunkStatus
+ " outside expected range detected. Force passing EMPTY chunk and seeing if it works.");
debugTriggeredForStatus = chunkStatus;
}
return chunk;
}
// Override force use of my own light engine
@Override
public LevelLightEngine getLightEngine() {
return light;
}
// Override force use of my own light engine
@Override
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
if (lightMode != LightGenerationMode.FAST) {
return light.getLayerListener(lightLayer).getLightValue(blockPos);
}
if (lightLayer == LightLayer.BLOCK)
return 0;
BlockPos p = super.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos);
return (p.getY() <= blockPos.getY()) ? getMaxLightLevel() : 0;
}
// Override force use of my own light engine
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
if (lightMode != LightGenerationMode.FAST) {
return light.getRawBrightness(blockPos, i);
}
BlockPos p = super.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos);
return (p.getY() <= blockPos.getY()) ? getMaxLightLevel() : 0;
}
// Override force use of my own light engine
@Override
public boolean canSeeSky(BlockPos blockPos) {
return (getBrightness(LightLayer.SKY, blockPos) >= getMaxLightLevel());
}
private final Object2ObjectArrayMap<ColorResolver, BlockTintCache> tintCaches;
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver)
{
BlockTintCache blockTintCache = (BlockTintCache) this.tintCaches.get(colorResolver);
return blockTintCache.getColor(blockPos);
}
private Biome _getBiome(BlockPos pos) {
#if MC_VERSION_1_18_2
return getBiome(pos).value();
#elif MC_VERSION_1_18_1
return getBiome(pos);
#endif
}
public int calculateBlockTint(BlockPos blockPos, ColorResolver colorResolver)
{
int i = (Minecraft.getInstance()).options.biomeBlendRadius;
if (i == 0)
return colorResolver.getColor((Biome) _getBiome(blockPos), blockPos.getX(), blockPos.getZ());
int j = (i * 2 + 1) * (i * 2 + 1);
int k = 0;
int l = 0;
int m = 0;
Cursor3D cursor3D = new Cursor3D(blockPos.getX() - i, blockPos.getY(), blockPos.getZ() - i, blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + i);
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
while (cursor3D.advance())
{
mutableBlockPos.set(cursor3D.nextX(), cursor3D.nextY(), cursor3D.nextZ());
int n = colorResolver.getColor((Biome) _getBiome((BlockPos) mutableBlockPos), mutableBlockPos.getX(), mutableBlockPos.getZ());
k += (n & 0xFF0000) >> 16;
l += (n & 0xFF00) >> 8;
m += n & 0xFF;
}
return (k / j & 0xFF) << 16 | (l / j & 0xFF) << 8 | m / j & 0xFF;
}
}
@@ -0,0 +1,176 @@
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
import org.jetbrains.annotations.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.lighting.BlockLightEngine;
import net.minecraft.world.level.lighting.LayerLightEventListener;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.lighting.SkyLightEngine;
public class WorldGenLevelLightEngine extends LevelLightEngine {
public static final int MAX_SOURCE_LEVEL = 15;
public static final int LIGHT_SECTION_PADDING = 1;
protected final LevelHeightAccessor levelHeightAccessor;
@Nullable
public final BlockLightEngine blockEngine;
@Nullable
public final SkyLightEngine skyEngine;
public WorldGenLevelLightEngine(LightGetterAdaptor genRegion) {
super(genRegion, false, false);
this.levelHeightAccessor = genRegion.getLevelHeightAccessor();
this.blockEngine = new BlockLightEngine(genRegion);
this.skyEngine = new SkyLightEngine(genRegion);
}
@Override
public void checkBlock(BlockPos blockPos) {
if (this.blockEngine != null) {
this.blockEngine.checkBlock(blockPos);
}
if (this.skyEngine != null) {
this.skyEngine.checkBlock(blockPos);
}
}
@Override
public void onBlockEmissionIncrease(BlockPos blockPos, int i) {
if (this.blockEngine != null) {
this.blockEngine.onBlockEmissionIncrease(blockPos, i);
}
}
@Override
public boolean hasLightWork() {
if (this.skyEngine != null && this.skyEngine.hasLightWork()) {
return true;
}
return this.blockEngine != null && this.blockEngine.hasLightWork();
}
@Override
public int runUpdates(int i, boolean bl, boolean bl2) {
if (this.blockEngine != null && this.skyEngine != null) {
int j = i / 2;
int k = this.blockEngine.runUpdates(j, bl, bl2);
int l = i - j + k;
int m = this.skyEngine.runUpdates(l, bl, bl2);
if (k == 0 && m > 0) {
return this.blockEngine.runUpdates(m, bl, bl2);
}
return m;
}
if (this.blockEngine != null) {
return this.blockEngine.runUpdates(i, bl, bl2);
}
if (this.skyEngine != null) {
return this.skyEngine.runUpdates(i, bl, bl2);
}
return i;
}
@Override
public void updateSectionStatus(SectionPos sectionPos, boolean bl) {
if (this.blockEngine != null) {
this.blockEngine.updateSectionStatus(sectionPos, bl);
}
if (this.skyEngine != null) {
this.skyEngine.updateSectionStatus(sectionPos, bl);
}
}
@Override
public void enableLightSources(ChunkPos chunkPos, boolean bl) {
if (this.blockEngine != null) {
this.blockEngine.enableLightSources(chunkPos, bl);
}
if (this.skyEngine != null) {
this.skyEngine.enableLightSources(chunkPos, bl);
}
}
@Override
public LayerLightEventListener getLayerListener(LightLayer lightLayer) {
if (lightLayer == LightLayer.BLOCK) {
if (this.blockEngine == null) {
return LayerLightEventListener.DummyLightLayerEventListener.INSTANCE;
}
return this.blockEngine;
}
if (this.skyEngine == null) {
return LayerLightEventListener.DummyLightLayerEventListener.INSTANCE;
}
return this.skyEngine;
}
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
int j = this.skyEngine == null ? 0 : this.skyEngine.getLightValue(blockPos) - i;
int k = this.blockEngine == null ? 0 : this.blockEngine.getLightValue(blockPos);
return Math.max(k, j);
}
public void lightChunk(ChunkAccess chunkAccess, boolean needLightBlockUpdate) {
ChunkPos chunkPos = chunkAccess.getPos();
chunkAccess.setLightCorrect(false);
LevelChunkSection[] levelChunkSections = chunkAccess.getSections();
for (int i = 0; i < chunkAccess.getSectionsCount(); ++i) {
LevelChunkSection levelChunkSection = levelChunkSections[i];
if (levelChunkSection.hasOnlyAir()) continue;
int j = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
updateSectionStatus(SectionPos.of(chunkPos, j), false);
}
enableLightSources(chunkPos, true);
if (needLightBlockUpdate) {
chunkAccess.getLights().forEach(blockPos ->
onBlockEmissionIncrease(blockPos, chunkAccess.getLightEmission(blockPos)));
}
chunkAccess.setLightCorrect(true);
}
@Override
public String getDebugData(LightLayer lightLayer, SectionPos sectionPos) {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public void queueSectionData(LightLayer lightLayer, SectionPos sectionPos, @Nullable DataLayer dataLayer, boolean bl) {
if (lightLayer == LightLayer.BLOCK) {
if (this.blockEngine != null) {
this.blockEngine.queueSectionData(sectionPos.asLong(), dataLayer, bl);
}
} else if (this.skyEngine != null) {
this.skyEngine.queueSectionData(sectionPos.asLong(), dataLayer, bl);
}
}
@Override
public void retainData(ChunkPos chunkPos, boolean bl) {
if (this.blockEngine != null) {
this.blockEngine.retainData(chunkPos, bl);
}
if (this.skyEngine != null) {
this.skyEngine.retainData(chunkPos, bl);
}
}
@Override
public int getLightSectionCount() {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public int getMinLightSection() {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public int getMaxLightSection() {
throw new UnsupportedOperationException("This should never be used!");
}
}
@@ -0,0 +1,134 @@
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Predicate;
import com.google.common.collect.ImmutableList;
import it.unimi.dsi.fastutil.longs.LongIterator;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
import net.minecraft.world.level.levelgen.feature.StructureFeature;
import net.minecraft.world.level.levelgen.structure.StructureCheck;
import net.minecraft.world.level.levelgen.structure.StructureStart;
public class WorldGenStructFeatManager extends StructureFeatureManager {
final WorldGenLevel genLevel;
WorldGenSettings worldGenSettings;
StructureCheck structureCheck;
public WorldGenStructFeatManager(WorldGenSettings worldGenSettings,
WorldGenLevel genLevel, StructureCheck structureCheck) {
super(genLevel, worldGenSettings, structureCheck);
this.genLevel = genLevel;
this.worldGenSettings = worldGenSettings;
}
@Override
public WorldGenStructFeatManager forWorldGenRegion(WorldGenRegion worldGenRegion) {
if (worldGenRegion == genLevel)
return this;
return new WorldGenStructFeatManager(worldGenSettings, worldGenRegion, structureCheck);
}
private ChunkAccess _getChunk(int x, int z, ChunkStatus status) {
if (genLevel == null) return null;
return genLevel.getChunk(x, z, status, false);
}
@Override
public boolean hasAnyStructureAt(BlockPos blockPos) {
SectionPos sectionPos = SectionPos.of(blockPos);
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
if (chunk == null) return false;
return chunk.hasAnyStructureReferences();
}
#if MC_VERSION_1_18_1
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public List<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
StructureFeature<?> structureFeature) {
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
if (chunk == null) return List.of();
// Copied from StructureFeatureManager::startsForFeature(...) with slight tweaks
LongSet longSet = chunk.getReferencesForFeature(structureFeature);
ImmutableList.Builder builder = ImmutableList.builder();
LongIterator longIterator = longSet.iterator();
while (longIterator.hasNext()) {
long l = (Long)longIterator.next();
SectionPos sectPos = SectionPos.of(new ChunkPos(l), genLevel.getMinSection());
ChunkAccess startChunk = _getChunk(sectPos.x(), sectPos.z(), ChunkStatus.STRUCTURE_STARTS);
if (startChunk == null) continue;
StructureStart<?> structureStart = this.getStartForFeature(sectPos, structureFeature, startChunk);
if (structureStart == null || !structureStart.isValid()) continue;
builder.add(structureStart);
}
return builder.build();
}
#elif MC_VERSION_1_18_2
@Override
public List<StructureStart> startsForFeature(SectionPos sectionPos, Predicate<ConfiguredStructureFeature<?, ?>> predicate) {
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
if (chunk == null) return List.of();
// Copied from StructureFeatureManager::startsForFeature(...)
Map<ConfiguredStructureFeature<?, ?>, LongSet> map = chunk.getAllReferences();
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
Iterator<Map.Entry<ConfiguredStructureFeature<?, ?>, LongSet>> var5 = map.entrySet().iterator();
while(var5.hasNext()) {
Map.Entry<ConfiguredStructureFeature<?, ?>, LongSet> entry = var5.next();
ConfiguredStructureFeature<?, ?> configuredStructureFeature = entry.getKey();
if (predicate.test(configuredStructureFeature)) {
LongSet var10002 = (LongSet)entry.getValue();
Objects.requireNonNull(builder);
this.fillStartsForFeature(configuredStructureFeature, var10002, builder::add);
}
}
return builder.build();
}
@Override
public List<StructureStart> startsForFeature(SectionPos sectionPos, ConfiguredStructureFeature<?, ?> configuredStructureFeature) {
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
if (chunk == null) return List.of();
// Copied from StructureFeatureManager::startsForFeature(...)
LongSet longSet = chunk.getReferencesForFeature(configuredStructureFeature);
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
Objects.requireNonNull(builder);
this.fillStartsForFeature(configuredStructureFeature, longSet, builder::add);
return builder.build();
}
@Override
public Map<ConfiguredStructureFeature<?, ?>, LongSet> getAllStructuresAt(BlockPos blockPos) {
SectionPos sectionPos = SectionPos.of(blockPos);
ChunkAccess chunk = _getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES);
if (chunk == null) return Map.of();
return chunk.getAllReferences();
}
#endif
}
@@ -0,0 +1,55 @@
package com.seibel.lod.common.wrappers.worldGeneration.step;
import java.util.ArrayList;
import java.util.List;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.core.Registry;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.blending.Blender;
public final class StepBiomes {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepBiomes(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.BIOMES;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepBiomes: "+chunk.getPos());
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
}
}
}
@@ -0,0 +1,60 @@
package com.seibel.lod.common.wrappers.worldGeneration.step;
import java.util.ArrayList;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import com.seibel.lod.core.util.gridList.ArrayGridList;
import net.minecraft.ReportedException;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.blending.Blender;
public final class StepFeatures {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepFeatures(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.FEATURES;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
ArrayGridList<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
try {
environment.params.generator.applyBiomeDecoration(worldGenRegion, chunk,
tParams.structFeat.forWorldGenRegion(worldGenRegion));
Blender.generateBorderTicks(worldGenRegion, chunk);
} catch (ReportedException e) {
e.printStackTrace();
// FIXME: Features concurrent modification issue. Something about cocobeans just
// aren't happy
// For now just retry.
}
}/*
for (ChunkAccess chunk : chunks) {
Heightmap.primeHeightmaps(chunk,
EnumSet.of(Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES,
Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE));
}*/
}
}
@@ -0,0 +1,60 @@
package com.seibel.lod.common.wrappers.worldGeneration.step;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.WorldGenLevelLightEngine;
import com.seibel.lod.core.util.gridList.ArrayGridList;
import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.lighting.LightEventListener;
public final class StepLight {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepLight(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.LIGHT;
public void generateGroup(LightEventListener lightEngine,
ArrayGridList<ChunkAccess> chunks) {
//ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
}
for (ChunkAccess chunk : chunks) {
boolean hasCorrectBlockLight = (chunk instanceof LevelChunk && chunk.isLightCorrect());
try {
if (lightEngine == null) {
// Do nothing
} else if (lightEngine instanceof WorldGenLevelLightEngine) {
((WorldGenLevelLightEngine)lightEngine).lightChunk(chunk, !hasCorrectBlockLight);
} else if (lightEngine instanceof ThreadedLevelLightEngine) {
((ThreadedLevelLightEngine) lightEngine).lightChunk(chunk, !hasCorrectBlockLight).join();
} else {
assert(false);
}
} catch (Exception e) {
e.printStackTrace();
}
if (chunk instanceof LevelChunk) ((LevelChunk)chunk).setClientLightReady(true);
chunk.setLightCorrect(true);
}
lightEngine.runUpdates(Integer.MAX_VALUE, true, true);
}
}
@@ -0,0 +1,57 @@
package com.seibel.lod.common.wrappers.worldGeneration.step;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import com.google.common.collect.Sets;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.util.Mth;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseSettings;
import net.minecraft.world.level.levelgen.blending.Blender;
public final class StepNoise {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepNoise(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.NOISE;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepNoise: "+chunk.getPos());
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
}
}
}
@@ -0,0 +1,54 @@
package com.seibel.lod.common.wrappers.worldGeneration.step;
import java.util.ArrayList;
import java.util.List;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.structure.StructureStart;
public final class StepStructureReference {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepStructureReference(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepStructureReference: "+chunk.getPos());
environment.params.generator.createReferences(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
}
}
}
@@ -0,0 +1,67 @@
package com.seibel.lod.common.wrappers.worldGeneration.step;
import java.util.ArrayList;
import java.util.List;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
public final class StepStructureStart {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepStructureStart(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.STRUCTURE_STARTS;
public static class StructStartCorruptedException extends RuntimeException {
private static final long serialVersionUID = -8987434342051563358L;
public StructStartCorruptedException(ArrayIndexOutOfBoundsException e) {
super("StructStartCorruptedException");
super.initCause(e);
fillInStackTrace();
}
}
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
if (environment.params.worldGenSettings.generateFeatures()) {
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepStructureStart: "+chunk.getPos());
environment.params.generator.createStructures(environment.params.registry, tParams.structFeat, chunk, environment.params.structures,
environment.params.worldSeed);
try {
tParams.structCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts());
} catch (ArrayIndexOutOfBoundsException e) {
// There's a rare issue with StructStart where it throws ArrayIndexOutOfBounds
// This means the structFeat is corrupted (For some reason) and I need to reset it.
// TODO: Figure out in the future why this happens even though I am using new structFeat
throw new StepStructureStart.StructStartCorruptedException(e);
}
}
}
}
}
@@ -0,0 +1,46 @@
package com.seibel.lod.common.wrappers.worldGeneration.step;
import java.util.ArrayList;
import java.util.List;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.ProtoChunk;
public final class StepSurface {
/**
*
*/
private final BatchGenerationEnvironment environment;
/**
* @param batchGenerationEnvironment
*/
public StepSurface(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.SURFACE;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepSurface: "+chunk.getPos());
environment.params.generator.buildSurface(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion),
chunk);
}
}
}
@@ -0,0 +1,49 @@
accessWidener v1 named
# used when determining where to save files to
accessible field net/minecraft/world/level/storage/DimensionDataStorage dataFolder Ljava/io/File;
# used when rendering
accessible field com/mojang/blaze3d/vertex/VertexBuffer indexCount I
accessible field com/mojang/blaze3d/vertex/VertexBuffer vertextBufferId I
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)D
# used for grabbing vanilla rendered chunks
accessible field net/minecraft/client/renderer/LevelRenderer renderChunkStorage Ljava/util/concurrent/atomic/AtomicReference;
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkStorage
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo
accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chunk Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;
# lighting
accessible field net/minecraft/client/renderer/LightTexture lightPixels Lcom/mojang/blaze3d/platform/NativeImage;
accessible field net/minecraft/client/renderer/LightTexture lightTexture Lnet/minecraft/client/renderer/texture/DynamicTexture;
accessible field net/minecraft/world/level/lighting/LevelLightEngine blockEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine Lnet/minecraft/world/level/lighting/LayerLightEngine;
# world generation
accessible method net/minecraft/world/level/levelgen/Heightmap setHeight (III)V
accessible field net/minecraft/world/level/biome/Biome generationSettings Lnet/minecraft/world/level/biome/BiomeGenerationSettings;
accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecraft/world/level/biome/Biome$BiomeCategory;
# accessible field net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator settings Lnet/minecraft/core/Holder;
accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doFill (Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;II)Lnet/minecraft/world/level/chunk/ChunkAccess;
#accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doCreateBiomes (Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/blending/Blender;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;)V
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
# lod generation from save file
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
accessible method net/minecraft/server/level/ChunkMap readChunk (Lnet/minecraft/world/level/ChunkPos;)Lnet/minecraft/nbt/CompoundTag;
# grabbing textures
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite animatedTexture Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture;
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite width I
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite height I
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite mainImage [Lcom/mojang/blaze3d/platform/NativeImage;
accessible class net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture
accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture getFrameX (I)I
accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite$AnimatedTexture getFrameY (I)I
extendable class com/mojang/math/Matrix4f
# hacky stuff
accessible field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
mutable field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
Submodule
+1
Submodule core added at 02b0637adc
+178
View File
@@ -0,0 +1,178 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.0"
}
version = rootProject.mod_version+"-"+rootProject.minecraft_version+"-"+new Date().format("yyyy_MM_dd_HH_mm")
loom {
accessWidenerPath.set(project(":common").file("src/main/resources/lod.accesswidener"))
}
architectury {
platformSetupLoomIde()
fabric()
}
configurations {
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentFabric.extendsFrom common
addModJar
include.extendsFrom addModJar
modImplementation.extendsFrom addModJar
}
repositories {
// Required for ModMenu
maven { url "https://maven.terraformersmc.com/" }
}
def addMod(path, enabled) {
if (enabled == "2")
dependencies { modImplementation(path) }
else if (enabled == "1")
dependencies { modCompileOnly(path) }
}
dependencies {
// Fabric loader
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
// Fabric API
addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-key-binding-api-v1", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-networking-api-v1", rootProject.fabric_api_version))
// Mod Menu
modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}")
// Starlight
addMod("curse.maven:starlight-521783:${rootProject.starlight_version_fabric}", rootProject.enable_starlight)
// Phosphor
addMod("curse.maven:phosphor-372124:${rootProject.phosphor_version_fabric}", rootProject.enable_phosphor)
// Sodium
addMod("curse.maven:sodium-394468:${rootProject.sodium_version}", rootProject.enable_sodium)
implementation "org.joml:joml:1.10.2"
modImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", rootProject.fabric_api_version))
modImplementation(fabricApi.module("fabric-rendering-fluids-v1", rootProject.fabric_api_version))
// Lithium
addMod("maven.modrinth:lithium:${rootProject.lithium_version}", rootProject.enable_lithium)
// Iris
addMod("maven.modrinth:iris:${rootProject.iris_version}", rootProject.enable_iris)
// BCLib
addMod("com.github.paulevsGitch:BCLib:${rootProject.bclib_version}", rootProject.enable_bclib)
// Immersive Portals
/*
modImplementation("com.github.qouteall.ImmersivePortalsMod:build:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("com.github.qouteall.ImmersivePortalsMod:imm_ptl_core:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("com.github.qouteall.ImmersivePortalsMod:q_misc_util:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
*/
// Toml
shadowMe("com.electronwill.night-config:toml:${rootProject.toml_version}") {}
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowMe(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
// Compression
common 'org.tukaani:xz:1.9'
common 'org.apache.commons:commons-compress:1.21'
shadowMe 'org.tukaani:xz:1.9'
shadowMe 'org.apache.commons:commons-compress:1.21'
}
// This method copies the access wideners from the common project to the fabric project. And it was generated by Github Copilot
task copyAccessWidener(type: Copy) {
from project(":common").file("src/main/resources/lod.accesswidener")
into file("src/generated/resources")
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into file("build/resources/main")
}
task deleteResources(type: Delete) {
delete file("build/resources/main")
}
task copyCommonResources(type: Copy) {
from fileTree(project(":common").file("src/main/resources"))
into file("build/resources/main")
}
runClient {
dependsOn(copyCoreResources)
dependsOn(copyCommonResources)
jvmArgs "-XX:-OmitStackTraceInFastThrow"
finalizedBy(deleteResources)
}
processResources {
dependsOn(copyAccessWidener)
}
shadowJar {
configurations = [project.configurations.shadowMe]
relocate 'org.tukaani', 'shaded.tukaani'
relocate 'org.apache.commons.compress', 'shaded.apache.commons.compress'
relocate 'com.electronwill.nightconfig', 'shaded.electronwill.nightconfig'
relocate 'com.seibel.lod.common', 'fabric.com.seibel.lod.common'
classifier "dev-shadow"
}
remapJar {
input.set shadowJar.archiveFile
dependsOn shadowJar
classifier null
}
jar {
classifier "dev"
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
publishing {
publications {
mavenFabric(MavenPublication) {
artifactId = rootProject.archives_base_name + "-" + project.name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}
@@ -0,0 +1,194 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.fabric;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.api.EventApi;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.mojang.blaze3d.platform.InputConstants;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import com.seibel.lod.common.wrappers.world.DimensionTypeWrapper;
import com.seibel.lod.common.wrappers.world.WorldWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.fabric.mixins.MixinUtilBackgroudThread;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.chunk.LevelChunk;
import java.util.HashSet;
import java.util.List;
import java.util.function.Supplier;
import org.lwjgl.glfw.GLFW;
/**
* This handles all events sent to the client,
* and is the starting point for most of the mod.
*
* @author coolGi2007
* @author Ran
* @version 11-23-2021
*/
public class ClientProxy
{
private final EventApi eventApi = EventApi.INSTANCE;
private final ClientApi clientApi = ClientApi.INSTANCE;
public static Supplier<Boolean> isGenerationThreadChecker = null;
/**
* Registers Fabric Events
* @author Ran
*/
public void registerEvents() {
/* Registor the mod accessor*/
/* World Events */
//ServerTickEvents.START_SERVER_TICK.register(this::serverTickEvent);
ServerTickEvents.END_SERVER_TICK.register(this::serverTickEvent);
/* World Events */
//ServerChunkEvents.CHUNK_LOAD.register(this::chunkLoadEvent);
//ClientChunkEvents.CHUNK_LOAD.register(this::chunkLoadEvent);
/* World Events */
ServerWorldEvents.LOAD.register((server, level) -> this.worldLoadEvent(level));
ServerWorldEvents.UNLOAD.register((server, level) -> this.worldUnloadEvent(level));
/* The Client World Events are in the mixins
Client world load event is in MixinClientLevel
Client world unload event is in MixinMinecraft */
/* The save events are in MixinServerLevel */
/* Keyboard Events */
ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (client.player != null) onKeyInput();
});
isGenerationThreadChecker = BatchGenerationEnvironment::isCurrentThreadDistantGeneratorThread;
}
public void serverTickEvent(MinecraftServer server)
{
eventApi.serverTickEvent();
}
public void chunkLoadEvent(LevelAccessor level, LevelChunk chunk)
{
clientApi.clientChunkLoadEvent(new ChunkWrapper(chunk, level),
WorldWrapper.getWorldWrapper(level));
}
public void worldSaveEvent()
{
eventApi.worldSaveEvent();
}
/** This is also called when a new dimension loads */
public void worldLoadEvent(Level level)
{
if (level != null) {
eventApi.worldLoadEvent(WorldWrapper.getWorldWrapper(level));
}
}
public void worldUnloadEvent(Level level)
{
if (level != null) {
eventApi.worldUnloadEvent(WorldWrapper.getWorldWrapper(level));
}
}
/**
* Can someone tell me how to make this better
* @author Ran
*
* public void blockChangeEvent(BlockEventData event) {
* // we only care about certain block events
* if (event.getClass() == BlockEventData.BreakEvent.class ||
* event.getClass() == BlockEventData.EntityPlaceEvent.class ||
* event.getClass() == BlockEventData.EntityMultiPlaceEvent.class ||
* event.getClass() == BlockEventData.FluidPlaceBlockEvent.class ||
* event.getClass() == BlockEventData.PortalSpawnEvent.class)
* {
* IChunkWrapper chunk = new ChunkWrapper(event.getWorld().getChunk(event.getPos()));
* DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType());
*
* // recreate the LOD where the blocks were changed
* eventApi.blockChangeEvent(chunk, dimType);
* }
* }
*/
public void blockChangeEvent(LevelAccessor world, BlockPos pos) {
IChunkWrapper chunk = new ChunkWrapper(world.getChunk(pos), world);
DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType());
// recreate the LOD where the blocks were changed
eventApi.blockChangeEvent(chunk, dimType);
}
private static final List<Integer> KEY_TO_CHECK_FOR = List.of(GLFW.GLFW_KEY_F6, GLFW.GLFW_KEY_F8);
HashSet<Integer> previousKeyDown = new HashSet<Integer>();
public void onKeyInput() {
ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
if (CONFIG.client().advanced().debugging().getDebugKeybindingsEnabled())
{
HashSet<Integer> currectKeyDown = new HashSet<Integer>();
// Note: Minecraft's InputConstants is same as GLFW Key values
//TODO: Use mixin to hook directly into the GLFW Keyboard event in minecraft KeyboardHandler
// Check all keys we need
for (int i = InputConstants.KEY_A; i <= InputConstants.KEY_Z; i++) {
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), i)) {
currectKeyDown.add(i);
}
}
for (int i : KEY_TO_CHECK_FOR) {
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), i)) {
currectKeyDown.add(i);
}
}
// Diff and trigger events
for (int c : currectKeyDown) {
if (!previousKeyDown.contains(c)) {
ClientApi.INSTANCE.keyPressedEvent(c);
}
}
// Update the set
previousKeyDown = currectKeyDown;
}
}
}
@@ -0,0 +1,96 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.fabric;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
import com.seibel.lod.fabric.networking.NetworkHandler;
import com.seibel.lod.fabric.wrappers.modAccessor.ModChecker;
import com.seibel.lod.fabric.wrappers.modAccessor.OptifineAccessor;
import com.seibel.lod.fabric.wrappers.modAccessor.SodiumAccessor;
import com.seibel.lod.fabric.wrappers.modAccessor.StarlightAccessor;
import com.seibel.lod.fabric.wrappers.FabricDependencySetup;
import net.fabricmc.api.ClientModInitializer;
/**
* Initialize and setup the Mod. <br>
* If you are looking for the real start of the mod
* check out the ClientProxy.
*
* @author coolGi2007
* @author Ran
* @version 12-1-2021
*/
public class Main implements ClientModInitializer
{
// This is a client mod so it should implement ClientModInitializer and in fabric.mod.json it should have "environment": "client"
// Once it works on servers change the implement to ModInitializer and in fabric.mod.json it should be "environment": "*"
public static ClientProxy client_proxy;
// Do if implements ClientModInitializer
// This loads the mod before minecraft loads which causes a lot of issues
@Override
public void onInitializeClient() {
// no.
}
// This loads the mod after minecraft loads which doesn't causes a lot of issues
public static void init() {
LodCommonMain.initConfig();
LodCommonMain.startup(null, false, new NetworkHandler());
FabricDependencySetup.createInitialBindings();
FabricDependencySetup.finishBinding();
ApiShared.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
// Check if this works
client_proxy = new ClientProxy();
client_proxy.registerEvents();
if (SingletonHandler.get(IModChecker.class).isModLoaded("sodium")) {
ModAccessorHandler.bind(ISodiumAccessor.class, new SodiumAccessor());
}
if (SingletonHandler.get(IModChecker.class).isModLoaded("starlight")) {
ModAccessorHandler.bind(IStarlightAccessor.class, new StarlightAccessor());
}
if (SingletonHandler.get(IModChecker.class).isModLoaded("optifine")) {
ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor());
}
ModAccessorHandler.finishBinding();
}
public static void initServer() {
LodCommonMain.initConfig();
LodCommonMain.startup(null, true, new NetworkHandler());
FabricDependencySetup.createInitialBindings();
FabricDependencySetup.finishBinding();
ApiShared.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
}
}
@@ -0,0 +1,16 @@
package com.seibel.lod.fabric.mixins;
import com.seibel.lod.fabric.Main;
import net.minecraft.server.dedicated.DedicatedServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(DedicatedServer.class)
public class MixinDedicatedServer {
@Inject(method = "initServer", at = @At("TAIL"))
public void initServer(CallbackInfoReturnable<Boolean> cir) {
Main.initServer();
}
}
@@ -0,0 +1,40 @@
package com.seibel.lod.fabric.mixins;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.material.FogType;
@Mixin(FogRenderer.class)
public class MixinFogRenderer {
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
// Using this instead of Float.MAX_VALUE because Sodium don't like it.
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
@Inject(at = @At("RETURN"), method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZ)V")
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback) {
FogType fogTypes = camera.getFluidInCamera();
Entity entity = camera.getEntity();
boolean isUnderWater = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
if (!isUnderWater) {
if (fogMode == FogMode.FOG_TERRAIN && fogTypes == FogType.NONE && CONFIG.client().graphics().fogQuality().getDisableVanillaFog()) {
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
}
}
}
}
@@ -0,0 +1,21 @@
package com.seibel.lod.fabric.mixins;
import com.seibel.lod.fabric.Main;
import net.minecraft.client.Minecraft;
import net.minecraft.client.main.GameConfig;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* Loads the mod after minecraft loads.
* @author Ran
*/
@Mixin(value = Minecraft.class)
public class MixinMinecraft {
@Inject(method = "<init>", at = @At("TAIL"))
private void startMod(GameConfig gameConfig, CallbackInfo ci) {
Main.init();
}
}
@@ -0,0 +1,52 @@
package com.seibel.lod.fabric.mixins;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.seibel.lod.common.wrappers.config.TexturedButtonWidget;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import net.minecraft.client.gui.screens.OptionsScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects;
/**
* Adds a button to the menu to goto the config
*
* @author coolGi2007
* @version 12-02-2021
*/
@Mixin(OptionsScreen.class)
public class MixinOptionsScreen extends Screen {
// Get the texture for the button
private static final ResourceLocation ICON_TEXTURE = new ResourceLocation(ModInfo.ID,"textures/gui/button.png");
protected MixinOptionsScreen(Component title) {
super(title);
}
@Inject(at = @At("HEAD"),method = "init")
private void lodconfig$init(CallbackInfo ci) {
if (SingletonHandler.get(ILodConfigWrapperSingleton.class).client().getOptionsButton())
this.addRenderableWidget(new TexturedButtonWidget(
// Where the button is on the screen
this.width / 2 - 180, this.height / 6 - 12,
// Width and height of the button
20, 20,
// Offset
0, 0,
// Some textuary stuff
20, ICON_TEXTURE, 20, 40,
// Create the button and tell it where to go
// For now it goes to the client option by default
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(ConfigGui.getScreen(this, "client")),
// Add a title to the screen
new TranslatableComponent("text.autoconfig." + ModInfo.ID + ".title")));
}
}
@@ -0,0 +1,50 @@
package com.seibel.lod.fabric.mixins;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import com.seibel.lod.fabric.ClientProxy;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.seibel.lod.core.util.DummyRunExecutorService;
import net.minecraft.Util;
@Mixin(Util.class)
public class MixinUtilBackgroudThread
{
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
{
if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get())
{
//ApiShared.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered");
ci.setReturnValue(r);
}
}
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
{
if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get())
{
//ApiShared.LOGGER.info("util wrapThreadWithTaskName(Supplier) triggered");
ci.setReturnValue(r);
}
}
@Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true)
private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable<ExecutorService> ci)
{
if (ClientProxy.isGenerationThreadChecker != null && ClientProxy.isGenerationThreadChecker.get())
{
//ApiShared.LOGGER.info("util backgroundExecutor triggered");
ci.setReturnValue(new DummyRunExecutorService());
}
}
}
@@ -0,0 +1,99 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.fabric.mixins;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import com.seibel.lod.common.Config;
import com.seibel.lod.common.wrappers.McObjectConverter;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.objects.math.Mat4f;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
* If this wasn't done, and we used Forge's
* render last event, the LODs would render on top
* of the normal terrain.
*
* This is also the mixin for rendering the clouds
*
* @author coolGi2007
* @author James Seibel
* @version 12-31-2021
*/
@Mixin(LevelRenderer.class)
public class MixinWorldRenderer
{
private static float previousPartialTicks = 0;
public MixinWorldRenderer() {
throw new NullPointerException("Null cannot be cast to non-null type.");
}
@Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true)
public void renderClouds(PoseStack poseStack, Matrix4f projectionMatrix, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
// get the partial ticks since renderChunkLayer doesn't
// have access to them
previousPartialTicks = tickDelta;
}
/* Inject rendering at renderSky
// HEAD or RETURN
@Inject(at = @At("RETURN"),
method = "renderSky",
cancellable = true)
private void renderLod(PoseStack modelViewMatrixStack, Matrix4f projectionMatrix, float f,
#if MC_VERSION_1_18_2 Camera camera, boolean bl,#endif Runnable r, CallbackInfo callback) {
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}*/
// Inject rendering at first call to renderChunkLayer
// HEAD or RETURN
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V",
cancellable = true)
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
{
// only render before solid blocks
if (renderType.equals(RenderType.solid()))
{
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}
if (Config.Client.Advanced.lodOnlyMode) {
callback.cancel();
}
}
}
@@ -0,0 +1,27 @@
package com.seibel.lod.fabric.mixins.events;
import com.seibel.lod.fabric.Main;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* If someone has a better way to do this then please let me know.
*
* @author Ran
*/
@Mixin(ClientboundBlockUpdatePacket.class)
public abstract class MixinBlockUpdate {
@Shadow public abstract BlockPos getPos();
@Inject(method = "handle(Lnet/minecraft/network/protocol/game/ClientGamePacketListener;)V", at = @At("TAIL"))
private void onBlockUpdate(ClientGamePacketListener clientGamePacketListener, CallbackInfo ci) {
Main.client_proxy.blockChangeEvent(Minecraft.getInstance().player.clientLevel, this.getPos());
}
}
@@ -0,0 +1,46 @@
package com.seibel.lod.fabric.mixins.events;
import com.seibel.lod.fabric.Main;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.renderer.LevelRenderer;
#if MC_VERSION_1_18_2
import net.minecraft.core.Holder;
#endif
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.dimension.DimensionType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.function.Supplier;
/**
* This class is used for world loading events
* @author Ran
*/
@Mixin(ClientLevel.class)
public class MixinClientLevel {
#if MC_VERSION_1_18_2
@Inject(method = "<init>", at = @At("TAIL"))
private void loadWorldEvent(ClientPacketListener clientPacketListener, ClientLevel.ClientLevelData clientLevelData, ResourceKey resourceKey, Holder holder, int i, int j, Supplier supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci) {
Main.client_proxy.worldLoadEvent((ClientLevel) (Object) this);
}
#elif MC_VERSION_1_18_1
@Inject(method = "<init>", at = @At("TAIL"))
private void loadWorldEvent(ClientPacketListener clientPacketListener, ClientLevel.ClientLevelData clientLevelData, ResourceKey resourceKey, DimensionType dimensionType, int i, int j, Supplier supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci) {
Main.client_proxy.worldLoadEvent((ClientLevel) (Object) this);
}
#endif
@Inject(method = "setLightReady", at = @At("HEAD"))
private void onChunkLightReady(int x, int z, CallbackInfo ci) {
ClientLevel l = (ClientLevel) (Object) this;
LevelChunk chunk = l.getChunkSource().getChunk(x, z, false);
if (chunk!=null && !chunk.isClientLightReady())
Main.client_proxy.chunkLoadEvent(l, chunk);
}
}
@@ -0,0 +1,32 @@
package com.seibel.lod.fabric.mixins.events;
import com.seibel.lod.fabric.Main;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientLevel;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* This class is used for world unloading events
* @author Ran
*/
@Mixin(Minecraft.class)
public class MixinMinecraft {
@Shadow @Nullable public ClientLevel level;
@Inject(method = "setLevel", at = @At("HEAD"))
private void unloadWorldEvent_sL(ClientLevel clientLevel, CallbackInfo ci) {
if (level != null) Main.client_proxy.worldUnloadEvent(level);
}
@Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD"))
private void unloadWorldEvent_cL(Screen screen, CallbackInfo ci) {
if (this.level != null) Main.client_proxy.worldUnloadEvent(this.level);
}
}
@@ -0,0 +1,26 @@
package com.seibel.lod.fabric.mixins.events;
import com.seibel.lod.fabric.Main;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.ProgressListener;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* This class is used for world saving events
* @author Ran
*/
@Mixin(ServerLevel.class)
public class MixinServerLevel {
@Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;saveAll()V", shift = At.Shift.AFTER))
private void saveWorldEvent_sA(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) {
Main.client_proxy.worldSaveEvent();
}
@Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;autoSave()V", shift = At.Shift.AFTER))
private void saveWorldEvent_aS(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) {
Main.client_proxy.worldSaveEvent();
}
}
@@ -0,0 +1,26 @@
package com.seibel.lod.fabric.mixins.unsafe;
import net.minecraft.util.ThreadingDetector;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.concurrent.Semaphore;
/**
* Why does this exist? But okay! (Will be probably removed when the experimental generator is done)
*/
@Mixin(ThreadingDetector.class)
public class MixinThreadingDectector {
@Mutable
@Shadow
private Semaphore lock;
@Inject(method = "<init>", at = @At("RETURN"))
private void setSemaphore(CallbackInfo ci) {
this.lock = new Semaphore(2);
}
}
@@ -0,0 +1,25 @@
package com.seibel.lod.fabric.networking;
import com.seibel.lod.common.networking.NetworkInterface;
import com.seibel.lod.common.networking.Networking;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
/**
* @author Ran
*/
public class NetworkHandler implements NetworkInterface {
@Override
public void register_Client() {
ClientPlayNetworking.registerGlobalReceiver(Networking.resourceLocation_meow, (client, handler, buf, responseSender) -> {
com.seibel.lod.common.networking.NetworkHandler.receivePacketClient(client, handler, buf);
});
}
@Override
public void register_Server() {
ServerPlayNetworking.registerGlobalReceiver(Networking.resourceLocation_meow, (server, player, handler, buf, responseSender) -> {
com.seibel.lod.common.networking.NetworkHandler.receivePacketServer(server, player, handler, buf);
});
}
}
@@ -0,0 +1,31 @@
package com.seibel.lod.fabric.wrappers;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.common.wrappers.config.LodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.lod.fabric.wrappers.modAccessor.ModChecker;
/**
* Binds all necessary dependencies, so we
* can access them in Core. <br>
* This needs to be called before any Core classes
* are loaded.
*
* @author James Seibel
* @author Ran
* @version 3-5-2022
*/
public class FabricDependencySetup
{
public static void createInitialBindings()
{
SingletonHandler.bind(IModChecker.class, ModChecker.INSTANCE);
SingletonHandler.bind(ILodConfigWrapperSingleton.class, LodConfigWrapperSingleton.INSTANCE);
}
public static void finishBinding() {
SingletonHandler.finishBinding();
}
}
@@ -0,0 +1,19 @@
package com.seibel.lod.fabric.wrappers.config;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
/**
* For making the config show up in modmenu
*/
@Environment(EnvType.CLIENT)
public class ModMenuIntegration implements ModMenuApi {
// For the custom config code
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return parent -> ConfigGui.getScreen(parent, "");
}
}
@@ -0,0 +1,13 @@
package com.seibel.lod.fabric.wrappers.modAccessor;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
import net.fabricmc.loader.api.FabricLoader;
public class ModChecker implements IModChecker {
public static final ModChecker INSTANCE = new ModChecker();
@Override
public boolean isModLoaded(String modid) {
return FabricLoader.getInstance().isModLoaded(modid);
}
}
@@ -0,0 +1,24 @@
package com.seibel.lod.fabric.wrappers.modAccessor;
import java.util.HashSet;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
public class OptifineAccessor implements IOptifineAccessor
{
@Override
public String getModName()
{
return "Optifine-Fabric-1.18.X";
}
@Override
public HashSet<AbstractChunkPosWrapper> getNormalRenderedChunks()
{
// TODO: Impl proper methods here
return null;
}
}
@@ -0,0 +1,42 @@
package com.seibel.lod.fabric.wrappers.modAccessor;
import java.util.HashSet;
import java.util.stream.Collectors;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.world.level.LevelHeightAccessor;
public class SodiumAccessor implements ISodiumAccessor {
IWrapperFactory factory = SingletonHandler.get(IWrapperFactory.class);
@Override
public String getModName() {
return "Sodium-Fabric-1.18.X";
}
@Override
public HashSet<AbstractChunkPosWrapper> getNormalRenderedChunks() {
SodiumWorldRenderer renderer = SodiumWorldRenderer.instance();
LevelHeightAccessor height = Minecraft.getInstance().level;
// 0b11 = Lighted chunk & loaded chunk
return renderer.getChunkTracker().getChunks(0b00).filter(
(long l) -> {
return true;
//for (int i = height.getMinSection(); i<height.getMaxSection(); i++) {
// SectionPos p = SectionPos.of(new ChunkPos(l), i);
// if (renderer.isBoxVisible(p.minBlockX()+1, p.minBlockY()+1, p.minBlockZ()+1,
// p.maxBlockX()-1, p.maxBlockY()-1, p.maxBlockZ()-1)) return true;
//}
//return false;
}).mapToObj((long l) -> {
return (AbstractChunkPosWrapper)factory.createChunkPos(l);
}).collect(Collectors.toCollection(HashSet::new));
}
}
@@ -0,0 +1,16 @@
package com.seibel.lod.fabric.wrappers.modAccessor;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IStarlightAccessor;
public class StarlightAccessor implements IStarlightAccessor {
@Override
public String getModName() {
return "Starlight-Fabric-1.18.X";
}
public StarlightAccessor() {
}
}
@@ -0,0 +1,458 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
@@ -0,0 +1,26 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.seibel.lod.fabric.mixins",
"compatibilityLevel": "JAVA_17",
"mixins": [
"unsafe.MixinThreadingDectector",
"MixinUtilBackgroudThread",
"events.MixinServerLevel"
],
"client": [
"MixinMinecraft",
"MixinOptionsScreen",
"MixinWorldRenderer",
"MixinFogRenderer",
"events.MixinClientLevel",
"events.MixinMinecraft",
"events.MixinBlockUpdate"
],
"server": [
"MixinDedicatedServer"
],
"injectors": {
"defaultRequire": 1
}
}
+53
View File
@@ -0,0 +1,53 @@
{
"schemaVersion": 1,
"id": "lod",
"version": "${version}",
"name": "${mod_name}",
"description": "${description}",
"authors": ["${authors}"],
"contact": {
"homepage": "${homepage}",
"sources": "${source}",
"issues": "${issues}"
},
"license": "CC0-1.0",
"icon": "icon.png",
"environment": "client",
"entrypoints": {
"client": [
"com.seibel.lod.fabric.Main"
],
"modmenu": [
"com.seibel.lod.fabric.wrappers.config.ModMenuIntegration"
]
},
"mixins": [
"fabric.lod.mixins.json"
],
"accessWidener" : "lod.accesswidener",
"depends": {
"fabricloader": "*",
"fabric-lifecycle-events-v1": "*",
"fabric-key-binding-api-v1": "*",
"fabric-networking-api-v1": "*",
"minecraft": "${minecraft_version}",
"java": ">=${java_version}"
},
"suggests": {
"another-mod": "*"
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "https://discord.gg/xAB8G4cENx"
}
}
}
}
+123
View File
@@ -0,0 +1,123 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.0"
}
version = rootProject.mod_version+"-"+rootProject.minecraft_version+"-"+new Date().format("yyyy_MM_dd_HH_mm")
loom {
accessWidenerPath.set(project(":common").file("src/main/resources/lod.accesswidener"))
forge {
convertAccessWideners.set(true)
extraAccessWideners.add("lod.accesswidener")
mixinConfigs("lod.mixins.json")
}
}
architectury {
platformSetupLoomIde()
forge()
}
configurations {
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentForge.extendsFrom common
}
def addMod(path, enabled) {
if (enabled == "2")
dependencies { modImplementation(path) }
else if (enabled == "1")
dependencies { modCompileOnly(path) }
}
dependencies {
// Forge loader
forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}"
// Starlight
addMod("curse.maven:starlight-forge-526854:${rootProject.starlight_version_forge}", rootProject.enable_starlight_forge)
annotationProcessor "org.spongepowered:mixin:0.8.4:processor"
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowMe(project(path: ":common", configuration: "transformProductionForge")) { transitive = false }
// forgeDependencies(project(":core")) { transitive false }
// Toml
shadowMe("com.electronwill.night-config:toml:${rootProject.toml_version}") {}
// Compression
forgeDependencies('org.tukaani:xz:1.9')
forgeDependencies('org.apache.commons:commons-compress:1.21')
shadowMe 'org.tukaani:xz:1.9'
shadowMe 'org.apache.commons:commons-compress:1.21'
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into file("build/resources/main")
}
task copyCommonResources(type: Copy) {
from fileTree(project(":common").file("src/main/resources"))
into file("build/resources/main")
}
processResources {
dependsOn(copyCoreResources)
dependsOn(copyCommonResources)
}
shadowJar {
dependencies {
exclude(dependency("net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"))
}
exclude "fabric.mod.json"
configurations = [project.configurations.shadowMe]
relocate 'org.tukaani', 'shaded.tukaani'
relocate 'org.apache.commons.compress', 'shaded.apache.commons.compress'
relocate 'com.electronwill.nightconfig', 'shaded.electronwill.nightconfig' // This is already included with forge
relocate 'com.seibel.lod.common', 'forge.com.seibel.lod.common'
classifier "dev-shadow"
}
remapJar {
input.set shadowJar.archiveFile
dependsOn shadowJar
classifier null
}
jar {
classifier "dev"
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
publishing {
publications {
mavenForge(MavenPublication) {
artifactId = rootProject.archives_base_name + "-" + project.name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}
+1
View File
@@ -0,0 +1 @@
loom.platform=forge
@@ -0,0 +1,118 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.forge;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.api.EventApi;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.player.Player;
import org.lwjgl.glfw.GLFW;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import com.seibel.lod.common.wrappers.world.DimensionTypeWrapper;
import com.seibel.lod.common.wrappers.world.WorldWrapper;
import net.minecraft.client.Minecraft;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
/**
* This handles all events sent to the client,
* and is the starting point for most of the mod.
*
* @author James_Seibel
* @version 11-12-2021
*/
public class ForgeClientProxy
{
private final EventApi eventApi = EventApi.INSTANCE;
private final ClientApi clientApi = ClientApi.INSTANCE;
@SubscribeEvent
public void serverTickEvent(TickEvent.ServerTickEvent event)
{
if (event.phase != TickEvent.Phase.START) return;
eventApi.serverTickEvent();
}
@SubscribeEvent
public void chunkLoadEvent(ChunkEvent.Load event)
{
clientApi.clientChunkLoadEvent(new ChunkWrapper(event.getChunk(), event.getWorld()), WorldWrapper.getWorldWrapper(event.getWorld()));
}
@SubscribeEvent
public void worldSaveEvent(WorldEvent.Save event)
{
eventApi.worldSaveEvent();
}
/** This is also called when a new dimension loads */
@SubscribeEvent
public void worldLoadEvent(WorldEvent.Load event)
{
if (event.getWorld() != null) {
eventApi.worldLoadEvent(WorldWrapper.getWorldWrapper(event.getWorld()));
}
}
@SubscribeEvent
public void worldUnloadEvent(WorldEvent.Unload event)
{
eventApi.worldUnloadEvent(WorldWrapper.getWorldWrapper(event.getWorld()));
}
@SubscribeEvent
public void blockChangeEvent(BlockEvent event)
{
// we only care about certain block events
if (event.getClass() == BlockEvent.BreakEvent.class ||
event.getClass() == BlockEvent.EntityPlaceEvent.class ||
event.getClass() == BlockEvent.EntityMultiPlaceEvent.class ||
event.getClass() == BlockEvent.FluidPlaceBlockEvent.class ||
event.getClass() == BlockEvent.PortalSpawnEvent.class)
{
IChunkWrapper chunk = new ChunkWrapper(event.getWorld().getChunk(event.getPos()), event.getWorld());
DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType());
// recreate the LOD where the blocks were changed
eventApi.blockChangeEvent(chunk, dimType);
}
}
@SubscribeEvent
public void onKeyInput(InputEvent.KeyInputEvent event)
{
if (Minecraft.getInstance().player == null) return;
if (event.getAction() != GLFW.GLFW_PRESS) return;
clientApi.keyPressedEvent(event.getKey());
}
}
@@ -0,0 +1,105 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.forge;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.forge.LodForgeMethodCaller;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.handlers.ReflectionHandler;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.lod.forge.networking.NetworkHandler;
import com.seibel.lod.forge.wrappers.ForgeDependencySetup;
import com.seibel.lod.forge.wrappers.modAccessor.OptifineAccessor;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.ConfigGuiHandler;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLLoader;
import java.util.List;
import java.util.Random;
/**
* Initialize and setup the Mod. <br>
* If you are looking for the real start of the mod
* check out the ClientProxy.
*
* @author James Seibel
* @version 11-21-2021
*/
@Mod(ModInfo.ID)
public class ForgeMain implements LodForgeMethodCaller
{
public static ForgeClientProxy forgeClientProxy;
private void init(final FMLCommonSetupEvent event)
{
// make sure the dependencies are set up before the mod needs them
LodCommonMain.initConfig();
LodCommonMain.startup(this, !FMLLoader.getDist().isClient(), new NetworkHandler());
ForgeDependencySetup.createInitialBindings();
ForgeDependencySetup.finishBinding();
ApiShared.LOGGER.info("Distant Horizons initializing...");
}
public ForgeMain()
{
// Register the methods for server and other game events we are interested in
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onClientStart);
}
private void onClientStart(final FMLClientSetupEvent event)
{
if (ReflectionHandler.instance.optifinePresent()) {
ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor());
}
ModAccessorHandler.finishBinding();
ModAccessorHandler.finishBinding();
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> ConfigGui.getScreen(parent, "")));
forgeClientProxy = new ForgeClientProxy();
MinecraftForge.EVENT_BUS.register(forgeClientProxy);
}
private final ModelDataMap dataMap = new ModelDataMap.Builder().build();
@Override
public List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, Random random) {
return mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random, dataMap);
}
}
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.client.networking.v1;
import java.util.List;
import com.seibel.lod.forge.fabric.api.event.Event;
import com.seibel.lod.forge.fabric.api.event.EventFactory;
import com.seibel.lod.forge.fabric.api.networking.v1.PacketSender;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.resources.ResourceLocation;
/**
* Offers access to events related to the indication of a connected server's ability to receive packets in certain channels.
*/
public final class C2SPlayChannelEvents {
/**
* An event for the client play network handler receiving an update indicating the connected server's ability to receive packets in certain channels.
* This event may be invoked at any time after login and up to disconnection.
*/
public static final Event<Register> REGISTER = EventFactory.createArrayBacked(Register.class, callbacks -> (handler, sender, client, channels) -> {
for (Register callback : callbacks) {
callback.onChannelRegister(handler, sender, client, channels);
}
});
/**
* An event for the client play network handler receiving an update indicating the connected server's lack of ability to receive packets in certain channels.
* This event may be invoked at any time after login and up to disconnection.
*/
public static final Event<Unregister> UNREGISTER = EventFactory.createArrayBacked(Unregister.class, callbacks -> (handler, sender, client, channels) -> {
for (Unregister callback : callbacks) {
callback.onChannelUnregister(handler, sender, client, channels);
}
});
private C2SPlayChannelEvents() {
}
/**
* @see C2SPlayChannelEvents#REGISTER
*/
@FunctionalInterface
public interface Register {
void onChannelRegister(ClientPacketListener handler, PacketSender sender, Minecraft client, List<ResourceLocation> channels);
}
/**
* @see C2SPlayChannelEvents#UNREGISTER
*/
@FunctionalInterface
public interface Unregister {
void onChannelUnregister(ClientPacketListener handler, PacketSender sender, Minecraft client, List<ResourceLocation> channels);
}
}
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.client.networking.v1;
import com.seibel.lod.forge.fabric.api.event.Event;
import com.seibel.lod.forge.fabric.api.event.EventFactory;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl;
import net.minecraft.resources.ResourceLocation;
/**
* Offers access to events related to the connection to a server on the client while the server is processing the client's login request.
*/
public final class ClientLoginConnectionEvents {
/**
* Event indicating a connection entered the LOGIN state, ready for registering query request handlers.
* This event may be used by mods to prepare their client side state.
* This event does not guarantee that a login attempt will be successful.
*
* @see ClientLoginNetworking#registerReceiver(ResourceLocation, ClientLoginNetworking.LoginQueryRequestHandler)
*/
public static final Event<Init> INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, client) -> {
for (Init callback : callbacks) {
callback.onLoginStart(handler, client);
}
});
/**
* An event for when the client has started receiving login queries.
* A client can only start receiving login queries when a server has sent the first login query.
* Vanilla servers will typically never make the client enter this login phase, but it is not a guarantee that the
* connected server is a vanilla server since a modded server or proxy may have no login queries to send to the client
* and therefore bypass the login query phase.
* If this event is fired then it is a sign that a server is not a vanilla server or the server is behind a proxy which
* is capable of handling login queries.
*
* <p>This event may be used to {@link ClientLoginNetworking.LoginQueryRequestHandler register login query handlers}
* which may be used to send a response to a server.
*
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<QueryStart> QUERY_START = EventFactory.createArrayBacked(QueryStart.class, callbacks -> (handler, client) -> {
for (QueryStart callback : callbacks) {
callback.onLoginQueryStart(handler, client);
}
});
/**
* An event for when the client's login process has ended due to disconnection.
*
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<Disconnect> DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, client) -> {
for (Disconnect callback : callbacks) {
callback.onLoginDisconnect(handler, client);
}
});
private ClientLoginConnectionEvents() {
}
/**
* @see ClientLoginConnectionEvents#INIT
*/
@FunctionalInterface
public interface Init {
void onLoginStart(ClientHandshakePacketListenerImpl handler, Minecraft client);
}
/**
* @see ClientLoginConnectionEvents#QUERY_START
*/
@FunctionalInterface
public interface QueryStart {
void onLoginQueryStart(ClientHandshakePacketListenerImpl handler, Minecraft client);
}
/**
* @see ClientLoginConnectionEvents#DISCONNECT
*/
@FunctionalInterface
public interface Disconnect {
void onLoginDisconnect(ClientHandshakePacketListenerImpl handler, Minecraft client);
}
}
@@ -0,0 +1,161 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.client.networking.v1;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import org.jetbrains.annotations.Nullable;
import com.seibel.lod.forge.fabric.api.networking.v1.ServerLoginNetworking;
import com.seibel.lod.forge.fabric.impl.networking.client.ClientNetworkingImpl;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl;
import net.minecraft.network.Connection;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.PacketListener;
import net.minecraft.resources.ResourceLocation;
/**
* Offers access to login stage client-side networking functionalities.
*
* <p>The Minecraft login protocol only allows the client to respond to a server's request, but not initiate one of its own.
*
* @see ClientPlayNetworking
* @see ServerLoginNetworking
*/
public final class ClientLoginNetworking {
/**
* Registers a handler to a query request channel.
* A global receiver is registered to all connections, in the present and future.
*
* <p>If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterGlobalReceiver(ResourceLocation)} to unregister the existing handler.
*
* @param channelName the id of the channel
* @param queryHandler the handler
* @return false if a handler is already registered to the channel
* @see ClientLoginNetworking#unregisterGlobalReceiver(ResourceLocation)
* @see ClientLoginNetworking#registerReceiver(ResourceLocation, LoginQueryRequestHandler)
*/
public static boolean registerGlobalReceiver(ResourceLocation channelName, LoginQueryRequestHandler queryHandler) {
return ClientNetworkingImpl.LOGIN.registerGlobalReceiver(channelName, queryHandler);
}
/**
* Removes the handler of a query request channel.
* A global receiver is registered to all connections, in the present and future.
*
* <p>The {@code channel} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel
* @see ClientLoginNetworking#registerGlobalReceiver(ResourceLocation, LoginQueryRequestHandler)
* @see ClientLoginNetworking#unregisterReceiver(ResourceLocation)
*/
@Nullable
public static ClientLoginNetworking.LoginQueryRequestHandler unregisterGlobalReceiver(ResourceLocation channelName) {
return ClientNetworkingImpl.LOGIN.unregisterGlobalReceiver(channelName);
}
/**
* Gets all query request channel names which global receivers are registered for.
* A global receiver is registered to all connections, in the present and future.
*
* @return all channel names which global receivers are registered for.
*/
public static Set<ResourceLocation> getGlobalReceivers() {
return ClientNetworkingImpl.LOGIN.getChannels();
}
/**
* Registers a handler to a query request channel.
*
* <p>If a handler is already registered to the {@code channelName}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterReceiver(ResourceLocation)} to unregister the existing handler.
*
* @param channelName the id of the channel
* @param queryHandler the handler
* @return false if a handler is already registered to the channel name
* @throws IllegalStateException if the client is not logging in
*/
public static boolean registerReceiver(ResourceLocation channelName, LoginQueryRequestHandler queryHandler) throws IllegalStateException {
final Connection connection = ClientNetworkingImpl.getLoginConnection();
if (connection != null) {
final PacketListener packetListener = connection.getPacketListener();
if (packetListener instanceof ClientHandshakePacketListenerImpl) {
return ClientNetworkingImpl.getAddon(((ClientHandshakePacketListenerImpl) packetListener)).registerChannel(channelName, queryHandler);
}
}
throw new IllegalStateException("Cannot register receiver while client is not logging in!");
}
/**
* Removes the handler of a query request channel.
*
* <p>The {@code channelName} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel name
* @throws IllegalStateException if the client is not logging in
*/
@Nullable
public static LoginQueryRequestHandler unregisterReceiver(ResourceLocation channelName) throws IllegalStateException {
final Connection connection = ClientNetworkingImpl.getLoginConnection();
if (connection != null) {
final PacketListener packetListener = connection.getPacketListener();
if (packetListener instanceof ClientHandshakePacketListenerImpl) {
return ClientNetworkingImpl.getAddon(((ClientHandshakePacketListenerImpl) packetListener)).unregisterChannel(channelName);
}
}
throw new IllegalStateException("Cannot unregister receiver while client is not logging in!");
}
private ClientLoginNetworking() {
}
@FunctionalInterface
public interface LoginQueryRequestHandler {
/**
* Handles an incoming query request from a server.
*
* <p>This method is executed on {@linkplain io.netty.channel.EventLoop netty's event loops}.
* Modification to the game should be {@linkplain net.minecraft.util.thread.BlockableEventLoop#submit(Runnable) scheduled} using the provided Minecraft client instance.
*
* <p>The return value of this method is a completable future that may be used to delay the login process to the server until a task {@link CompletableFuture#isDone() is done}.
* The future should complete in reasonably time to prevent disconnection by the server.
* If your request processes instantly, you may use {@link CompletableFuture#completedFuture(Object)} to wrap your response for immediate sending.
*
* @param client the client
* @param handler the network handler that received this packet
* @param buf the payload of the packet
* @param listenerAdder listeners to be called when the response packet is sent to the server
* @return a completable future which contains the payload to respond to the server with.
* If the future contains {@code null}, then the server will be notified that the client did not understand the query.
*/
CompletableFuture<@Nullable FriendlyByteBuf> receive(Minecraft client, ClientHandshakePacketListenerImpl handler, FriendlyByteBuf buf, Consumer<GenericFutureListener<? extends Future<? super Void>>> listenerAdder);
}
}
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.client.networking.v1;
import com.seibel.lod.forge.fabric.api.event.Event;
import com.seibel.lod.forge.fabric.api.event.EventFactory;
import com.seibel.lod.forge.fabric.api.networking.v1.PacketSender;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.resources.ResourceLocation;
/**
* Offers access to events related to the connection to a server on a logical client.
*/
public final class ClientPlayConnectionEvents {
/**
* Event indicating a connection entered the PLAY state, ready for registering channel handlers.
*
* @see ClientPlayNetworking#registerReceiver(ResourceLocation, ClientPlayNetworking.PlayChannelHandler)
*/
public static final Event<Init> INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, client) -> {
for (Init callback : callbacks) {
callback.onPlayInit(handler, client);
}
});
/**
* An event for notification when the client play network handler is ready to send packets to the server.
*
* <p>At this stage, the network handler is ready to send packets to the server.
* Since the client's local state has been setup.
*/
public static final Event<Join> JOIN = EventFactory.createArrayBacked(Join.class, callbacks -> (handler, sender, client) -> {
for (Join callback : callbacks) {
callback.onPlayReady(handler, sender, client);
}
});
/**
* An event for the disconnection of the client play network handler.
*
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<Disconnect> DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, client) -> {
for (Disconnect callback : callbacks) {
callback.onPlayDisconnect(handler, client);
}
});
private ClientPlayConnectionEvents() {
}
@FunctionalInterface
public interface Init {
void onPlayInit(ClientPacketListener handler, Minecraft client);
}
@FunctionalInterface
public interface Join {
void onPlayReady(ClientPacketListener handler, PacketSender sender, Minecraft client);
}
@FunctionalInterface
public interface Disconnect {
void onPlayDisconnect(ClientPacketListener handler, Minecraft client);
}
}
@@ -0,0 +1,256 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.client.networking.v1;
import java.util.Objects;
import java.util.Set;
import org.jetbrains.annotations.Nullable;
import com.seibel.lod.forge.fabric.api.networking.v1.PacketSender;
import com.seibel.lod.forge.fabric.api.networking.v1.ServerPlayNetworking;
import com.seibel.lod.forge.fabric.impl.networking.client.ClientNetworkingImpl;
import com.seibel.lod.forge.fabric.impl.networking.client.ClientPlayNetworkAddon;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.Packet;
import net.minecraft.resources.ResourceLocation;
/**
* Offers access to play stage client-side networking functionalities.
*
* <p>Client-side networking functionalities include receiving clientbound packets,
* sending serverbound packets, and events related to client-side network handlers.
*
* <p>This class should be only used on the physical client and for the logical client.
*
* @see ClientLoginNetworking
* @see ServerPlayNetworking
*/
public final class ClientPlayNetworking {
/**
* Registers a handler to a channel.
* A global receiver is registered to all connections, in the present and future.
*
* <p>If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterGlobalReceiver(ResourceLocation)} to unregister the existing handler.
*
* @param channelName the id of the channel
* @param channelHandler the handler
* @return false if a handler is already registered to the channel
* @see ClientPlayNetworking#unregisterGlobalReceiver(ResourceLocation)
* @see ClientPlayNetworking#registerReceiver(ResourceLocation, PlayChannelHandler)
*/
public static boolean registerGlobalReceiver(ResourceLocation channelName, PlayChannelHandler channelHandler) {
return ClientNetworkingImpl.PLAY.registerGlobalReceiver(channelName, channelHandler);
}
/**
* Removes the handler of a channel.
* A global receiver is registered to all connections, in the present and future.
*
* <p>The {@code channel} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel
* @see ClientPlayNetworking#registerGlobalReceiver(ResourceLocation, PlayChannelHandler)
* @see ClientPlayNetworking#unregisterReceiver(ResourceLocation)
*/
@Nullable
public static PlayChannelHandler unregisterGlobalReceiver(ResourceLocation channelName) {
return ClientNetworkingImpl.PLAY.unregisterGlobalReceiver(channelName);
}
/**
* Gets all channel names which global receivers are registered for.
* A global receiver is registered to all connections, in the present and future.
*
* @return all channel names which global receivers are registered for.
*/
public static Set<ResourceLocation> getGlobalReceivers() {
return ClientNetworkingImpl.PLAY.getChannels();
}
/**
* Registers a handler to a channel.
*
* <p>If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterReceiver(ResourceLocation)} to unregister the existing handler.
*
* <p>For example, if you only register a receiver using this method when a {@linkplain ClientLoginNetworking#registerGlobalReceiver(ResourceLocation, ClientLoginNetworking.LoginQueryRequestHandler)}
* login query has been received, you should use {@link ClientPlayConnectionEvents#INIT} to register the channel handler.
*
* @param channelName the id of the channel
* @return false if a handler is already registered to the channel
* @throws IllegalStateException if the client is not connected to a server
* @see ClientPlayConnectionEvents#INIT
*/
public static boolean registerReceiver(ResourceLocation channelName, PlayChannelHandler channelHandler) {
final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon();
if (addon != null) {
return addon.registerChannel(channelName, channelHandler);
}
throw new IllegalStateException("Cannot register receiver while not in game!");
}
/**
* Removes the handler of a channel.
*
* <p>The {@code channelName} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel
* @throws IllegalStateException if the client is not connected to a server
*/
@Nullable
public static PlayChannelHandler unregisterReceiver(ResourceLocation channelName) throws IllegalStateException {
final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon();
if (addon != null) {
return addon.unregisterChannel(channelName);
}
throw new IllegalStateException("Cannot unregister receiver while not in game!");
}
/**
* Gets all the channel names that the client can receive packets on.
*
* @return All the channel names that the client can receive packets on
* @throws IllegalStateException if the client is not connected to a server
*/
public static Set<ResourceLocation> getReceived() throws IllegalStateException {
final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon();
if (addon != null) {
return addon.getReceivableChannels();
}
throw new IllegalStateException("Cannot get a list of channels the client can receive packets on while not in game!");
}
/**
* Gets all channel names that the connected server declared the ability to receive a packets on.
*
* @return All the channel names the connected server declared the ability to receive a packets on
* @throws IllegalStateException if the client is not connected to a server
*/
public static Set<ResourceLocation> getSendable() throws IllegalStateException {
final ClientPlayNetworkAddon addon = ClientNetworkingImpl.getClientPlayAddon();
if (addon != null) {
return addon.getSendableChannels();
}
throw new IllegalStateException("Cannot get a list of channels the server can receive packets on while not in game!");
}
/**
* Checks if the connected server declared the ability to receive a packet on a specified channel name.
*
* @param channelName the channel name
* @return True if the connected server has declared the ability to receive a packet on the specified channel.
* False if the client is not in game.
*/
public static boolean canSend(ResourceLocation channelName) throws IllegalArgumentException {
// You cant send without a client player, so this is fine
if (Minecraft.getInstance().getConnection() != null) {
return ClientNetworkingImpl.getAddon(Minecraft.getInstance().getConnection()).getSendableChannels().contains(channelName);
}
return false;
}
/**
* Creates a packet which may be sent to a the connected server.
*
* @param channelName the channel name
* @param buf the packet byte buf which represents the payload of the packet
* @return a new packet
*/
public static Packet<?> createC2SPacket(ResourceLocation channelName, FriendlyByteBuf buf) {
Objects.requireNonNull(channelName, "Channel name cannot be null");
Objects.requireNonNull(buf, "Buf cannot be null");
return ClientNetworkingImpl.createPlayC2SPacket(channelName, buf);
}
/**
* Gets the packet sender which sends packets to the connected server.
*
* @return the client's packet sender
* @throws IllegalStateException if the client is not connected to a server
*/
public static PacketSender getSender() throws IllegalStateException {
// You cant send without a client player, so this is fine
if (Minecraft.getInstance().getConnection() != null) {
return ClientNetworkingImpl.getAddon(Minecraft.getInstance().getConnection());
}
throw new IllegalStateException("Cannot get packet sender when not in game!");
}
/**
* Sends a packet to the connected server.
*
* @param channelName the channel of the packet
* @param buf the payload of the packet
* @throws IllegalStateException if the client is not connected to a server
*/
public static void send(ResourceLocation channelName, FriendlyByteBuf buf) throws IllegalStateException {
// You cant send without a client player, so this is fine
if (Minecraft.getInstance().getConnection() != null) {
Minecraft.getInstance().getConnection().send(createC2SPacket(channelName, buf));
return;
}
throw new IllegalStateException("Cannot send packets when not in game!");
}
private ClientPlayNetworking() {
}
@FunctionalInterface
public interface PlayChannelHandler {
/**
* Handles an incoming packet.
*
* <p>This method is executed on {@linkplain io.netty.channel.EventLoop netty's event loops}.
* Modification to the game should be {@linkplain net.minecraft.util.thread.BlockableEventLoop#submit(Runnable) scheduled} using the provided Minecraft client instance.
*
* <p>An example usage of this is to display an overlay message:
* <pre>{@code
* ClientPlayNetworking.registerReceiver(new Identifier("mymod", "overlay"), (client, handler, buf, responseSender) -&rt; {
* String message = buf.readString(32767);
*
* // All operations on the server or world must be executed on the server thread
* client.execute(() -&rt; {
* client.inGameHud.setOverlayMessage(message, true);
* });
* });
* }</pre>
* @param client the client
* @param handler the network handler that received this packet
* @param buf the payload of the packet
* @param responseSender the packet sender
*/
void receive(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender);
}
}
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* The Networking API (client side), version 1.
*
* <p>For login stage networking see {@link net.fabricmc.fabric.api.client.networking.v1.ClientLoginNetworking}.
* For play stage networking see {@link net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking}.
*
* <p>For events related to connection to a server see {@link net.fabricmc.fabric.api.client.networking.v1.ClientLoginConnectionEvents} for login stage
* or {@link net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents} for play stage.
*
* <p>For events related to the ability of a server to receive packets on a channel of a specific name see {@link net.fabricmc.fabric.api.client.networking.v1.C2SPlayChannelEvents}.
*/
package com.seibel.lod.forge.fabric.api.client.networking.v1;
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.event;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that this {@link Event} is auto-invoking:
* it calls the event callback implemented by a context parameter type automatically and without registration.
*
* <p>This means that this event can be listened to in two ways:
* <ul>
* <li>If the consumer is the context parameter and it implements the callback, it will be automatically invoked, don't register manually.
* <li>Otherwise, there is no invocation and the listener needs manual registration as usual.
* </ul>
*
* <p>Do note that there may be more than one context parameter.
*
* <p>A typical use case is feature augmentation, for example to expose raw clicks to slots.
* The event callback has a slot parameter - the context parameter - and the event itself is carrying this annotation.
* All the slot needs to receive slot clicks is to implement {@code SlotClickCallback} on itself.
* It shouldn't do any explicit event registration like {@code SLOT_CLICK_EVENT.register(this::onSlotClick)},
* otherwise it will see extraneous callback invocations.
*
* <p>In general, an auto-invoking event bridges the gap between the flexibility of an event with global reach,
* and the convenience of implementing an interface that gets detected automatically.
*
* <p>This is a documentation-only annotation, the event factory has to implement the functionality explicitly by checking the parameter type and invoking it.
* On top of adding this annotation, the event field or method should document which parameters are context parameters,
* and under which circumstances they are invoked.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD })
public @interface AutoInvokingEvent {
}
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.event;
import org.jetbrains.annotations.ApiStatus;
import net.minecraft.resources.ResourceLocation;
/**
* Base class for Fabric's event implementations.
*
* @param <T> The listener type.
* @see EventFactory
*/
@ApiStatus.NonExtendable // Should only be extended by fabric API.
public abstract class Event<T> {
/**
* The invoker field. This should be updated by the implementation to
* always refer to an instance containing all code that should be
* executed upon event emission.
*/
protected volatile T invoker;
/**
* Returns the invoker instance.
*
* <p>An "invoker" is an object which hides multiple registered
* listeners of type T under one instance of type T, executing
* them and leaving early as necessary.
*
* @return The invoker instance.
*/
public final T invoker() {
return invoker;
}
/**
* Register a listener to the event, in the default phase.
* Have a look at {@link #addPhaseOrdering} for an explanation of event phases.
*
* @param listener The desired listener.
*/
public abstract void register(T listener);
/**
* The ResourceLocation of the default phase.
* Have a look at {@link EventFactory#createWithPhases} for an explanation of event phases.
*/
public static final ResourceLocation DEFAULT_PHASE = new ResourceLocation("fabric", "default");
/**
* Register a listener to the event for the specified phase.
* Have a look at {@link EventFactory#createWithPhases} for an explanation of event phases.
*
* @param phase ResourceLocation of the phase this listener should be registered for. It will be created if it didn't exist yet.
* @param listener The desired listener.
*/
public void register(ResourceLocation phase, T listener) {
// This is done to keep compatibility with existing Event subclasses, but they should really not be subclassing Event.
register(listener);
}
/**
* Request that listeners registered for one phase be executed before listeners registered for another phase.
* Relying on the default phases supplied to {@link EventFactory#createWithPhases} should be preferred over manually
* registering phase ordering dependencies.
*
* <p>Incompatible ordering constraints such as cycles will lead to inconsistent behavior:
* some constraints will be respected and some will be ignored. If this happens, a warning will be logged.
*
* @param firstPhase The ResourceLocation of the phase that should run before the other. It will be created if it didn't exist yet.
* @param secondPhase The ResourceLocation of the phase that should run after the other. It will be created if it didn't exist yet.
*/
public void addPhaseOrdering(ResourceLocation firstPhase, ResourceLocation secondPhase) {
// This is not abstract to avoid breaking existing Event subclasses, but they should really not be subclassing Event.
}
}
@@ -0,0 +1,141 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.event;
import java.util.function.Function;
import net.minecraft.resources.ResourceLocation;
import com.seibel.lod.forge.fabric.impl.base.event.EventFactoryImpl;
/**
* Helper for creating {@link Event} classes.
*/
public final class EventFactory {
private static boolean profilingEnabled = true;
private EventFactory() { }
/**
* @return True if events are supposed to be profiled.
*/
public static boolean isProfilingEnabled() {
return profilingEnabled;
}
/**
* Invalidate and re-create all existing "invoker" instances across
* events created by this EventFactory. Use this if, for instance,
* the profilingEnabled field changes.
*/
// TODO: Turn this into an event?
public static void invalidate() {
EventFactoryImpl.invalidate();
}
/**
* Create an "array-backed" Event instance.
*
* <p>If your factory simply delegates to the listeners without adding custom behavior,
* consider using {@linkplain #createArrayBacked(Class, Object, Function) the other overload}
* if performance of this event is critical.
*
* @param type The listener class type.
* @param invokerFactory The invoker factory, combining multiple listeners into one instance.
* @param <T> The listener type.
* @return The Event instance.
*/
public static <T> Event<T> createArrayBacked(Class<? super T> type, Function<T[], T> invokerFactory) {
return EventFactoryImpl.createArrayBacked(type, invokerFactory);
}
/**
* Create an "array-backed" Event instance with a custom empty invoker,
* for an event whose {@code invokerFactory} only delegates to the listeners.
* <ul>
* <li>If there is no listener, the custom empty invoker will be used.</li>
* <li><b>If there is only one listener, that one will be used as the invoker
* and the factory will not be called.</b></li>
* <li>Only when there are at least two listeners will the factory be used.</li>
* </ul>
*
* <p>Having a custom empty invoker (of type (...) -&gt; {}) increases performance
* relative to iterating over an empty array; however, it only really matters
* if the event is executed thousands of times a second.
*
* @param type The listener class type.
* @param emptyInvoker The custom empty invoker.
* @param invokerFactory The invoker factory, combining multiple listeners into one instance.
* @param <T> The listener type.
* @return The Event instance.
*/
public static <T> Event<T> createArrayBacked(Class<T> type, T emptyInvoker, Function<T[], T> invokerFactory) {
return createArrayBacked(type, listeners -> {
if (listeners.length == 0) {
return emptyInvoker;
} else if (listeners.length == 1) {
return listeners[0];
} else {
return invokerFactory.apply(listeners);
}
});
}
/**
* Create an array-backed event with a list of default phases that get invoked in order.
* Exposing the ResourceLocations of the default phases as {@code public static final} constants is encouraged.
*
* <p>An event phase is a named group of listeners, which may be ordered before or after other groups of listeners.
* This allows some listeners to take priority over other listeners.
* Adding separate events should be considered before making use of multiple event phases.
*
* <p>Phases may be freely added to events created with any of the factory functions,
* however using this function is preferred for widely used event phases.
* If more phases are necessary, discussion with the author of the Event is encouraged.
*
* <p>Refer to {@link Event#addPhaseOrdering} for an explanation of event phases.
*
* @param type The listener class type.
* @param invokerFactory The invoker factory, combining multiple listeners into one instance.
* @param defaultPhases The default phases of this event, in the correct order. Must contain {@link Event#DEFAULT_PHASE}.
* @param <T> The listener type.
* @return The Event instance.
*/
public static <T> Event<T> createWithPhases(Class<? super T> type, Function<T[], T> invokerFactory, ResourceLocation... defaultPhases) {
EventFactoryImpl.ensureContainsDefault(defaultPhases);
EventFactoryImpl.ensureNoDuplicates(defaultPhases);
Event<T> event = createArrayBacked(type, invokerFactory);
for (int i = 1; i < defaultPhases.length; ++i) {
event.addPhaseOrdering(defaultPhases[i-1], defaultPhases[i]);
}
return event;
}
/**
* Get the listener object name. This can be used in debugging/profiling
* scenarios.
*
* @param handler The listener object.
* @return The listener name.
*/
public static String getHandlerName(Object handler) {
return handler.getClass().getName();
}
}
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.networking.v1;
import com.seibel.lod.forge.fabric.api.event.Event;
import com.seibel.lod.forge.fabric.api.event.EventFactory;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
/**
* Events related to a tracking entities within a player's view distance.
*/
public final class EntityTrackingEvents {
/**
* An event that is called before player starts tracking an entity.
* Typically this occurs when an entity enters a client's view distance.
* This event is called before the player's client is sent the entity's {@link Entity#getAddEntityPacket() spawn packet}.
*/
public static final Event<StartTracking> START_TRACKING = EventFactory.createArrayBacked(StartTracking.class, callbacks -> (trackedEntity, player) -> {
for (StartTracking callback : callbacks) {
callback.onStartTracking(trackedEntity, player);
}
});
/**
* An event that is called after a player has stopped tracking an entity.
* The client at this point was sent a packet to {@link net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket destroy} the entity on the client.
* The entity still exists on the server.
*/
public static final Event<StopTracking> STOP_TRACKING = EventFactory.createArrayBacked(StopTracking.class, callbacks -> (trackedEntity, player) -> {
for (StopTracking callback : callbacks) {
callback.onStopTracking(trackedEntity, player);
}
});
@FunctionalInterface
public interface StartTracking {
/**
* Called before an entity starts getting tracked by a player.
*
* @param trackedEntity the entity that will be tracked
* @param player the player that will track the entity
*/
void onStartTracking(Entity trackedEntity, ServerPlayer player);
}
@FunctionalInterface
public interface StopTracking {
/**
* Called after an entity stops getting tracked by a player.
*
* @param trackedEntity the entity that is no longer being tracked
* @param player the player that is no longer tracking the entity
*/
void onStopTracking(Entity trackedEntity, ServerPlayer player);
}
private EntityTrackingEvents() {
}
}
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.networking.v1;
import java.util.Objects;
import net.minecraft.network.FriendlyByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalServerChannel;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
import io.netty.util.concurrent.GenericFutureListener;
/**
* Utilities for working with netty's future listeners.
* @see FutureListener
* @see ChannelFutureListener
*/
public final class FutureListeners {
/**
* Returns a future listener that releases a packet byte buf when the buffer has been sent to a remote connection.
*
* @param buf the buffer
* @return the future listener
*/
public static ChannelFutureListener free(FriendlyByteBuf buf) {
Objects.requireNonNull(buf, "PacketByteBuf cannot be null");
return (future) -> {
if (!isLocalChannel(future.channel())) {
buf.release();
}
};
}
/**
* Returns whether a netty channel performs local transportation, or if the message objects in the channel are directly passed than written to and read from a byte buf.
*
* @param channel the channel to check
* @return whether the channel is local
*/
public static boolean isLocalChannel(Channel channel) {
return channel instanceof LocalServerChannel || channel instanceof LocalChannel;
}
/**
* Combines two future listeners.
*
* @param first the first future listener
* @param second the second future listener
* @param <A> the future type of the first listener, used for casting
* @param <B> the future type of the second listener, used for casting
* @return the combined future listener.
*/
// A, B exist just to allow casting
@SuppressWarnings("unchecked")
public static <A extends Future<? super Void>, B extends Future<? super Void>> GenericFutureListener<? extends Future<? super Void>> union(GenericFutureListener<A> first, GenericFutureListener<B> second) {
// Return an empty future listener in the case of both parameters somehow being null
if (first == null && second == null) {
return future -> { };
}
if (first == null) {
return second;
}
if (second == null) {
return first;
}
return future -> {
first.operationComplete((A) future);
second.operationComplete((B) future);
};
}
private FutureListeners() {
}
}
@@ -0,0 +1,204 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.seibel.lod.forge.fabric.api.networking.v1;
import java.util.Objects;
import net.minecraft.network.FriendlyByteBuf;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
/**
* Helper methods for working with and creating {@link FriendlyByteBuf}s.
*/
public final class PacketByteBufs {
private static final FriendlyByteBuf EMPTY_PACKET_BYTE_BUF = new FriendlyByteBuf(Unpooled.EMPTY_BUFFER);
/**
* Returns an empty instance of packet byte buf.
*
* @return an empty buf
*/
public static FriendlyByteBuf empty() {
return EMPTY_PACKET_BYTE_BUF;
}
/**
* Returns a new heap memory-backed instance of packet byte buf.
*
* @return a new buf
*/
public static FriendlyByteBuf create() {
return new FriendlyByteBuf(Unpooled.buffer());
}
// Convenience methods for byte buf methods that return a new byte buf
/**
* Wraps the newly created buf from {@code buf.readBytes} in a packet byte buf.
*
* @param buf the original buf
* @param length the number of bytes to transfer
* @return the transferred bytes
* @see ByteBuf#readBytes(int)
*/
public static FriendlyByteBuf readBytes(ByteBuf buf, int length) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.readBytes(length));
}
/**
* Wraps the newly created buf from {@code buf.readSlice} in a packet byte buf.
*
* @param buf the original buf
* @param length the size of the new slice
* @return the newly created slice
* @see ByteBuf#readSlice(int)
*/
public static FriendlyByteBuf readSlice(ByteBuf buf, int length) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.readSlice(length));
}
/**
* Wraps the newly created buf from {@code buf.readRetainedSlice} in a packet byte buf.
*
* @param buf the original buf
* @param length the size of the new slice
* @return the newly created slice
* @see ByteBuf#readRetainedSlice(int)
*/
public static FriendlyByteBuf readRetainedSlice(ByteBuf buf, int length) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.readRetainedSlice(length));
}
/**
* Wraps the newly created buf from {@code buf.copy} in a packet byte buf.
*
* @param buf the original buf
* @return a copy of the buf
* @see ByteBuf#copy()
*/
public static FriendlyByteBuf copy(ByteBuf buf) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.copy());
}
/**
* Wraps the newly created buf from {@code buf.copy} in a packet byte buf.
*
* @param buf the original buf
* @param index the starting index
* @param length the size of the copy
* @return a copy of the buf
* @see ByteBuf#copy(int, int)
*/
public static FriendlyByteBuf copy(ByteBuf buf, int index, int length) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.copy(index, length));
}
/**
* Wraps the newly created buf from {@code buf.slice} in a packet byte buf.
*
* @param buf the original buf
* @return a slice of the buf
* @see ByteBuf#slice()
*/
public static FriendlyByteBuf slice(ByteBuf buf) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.slice());
}
/**
* Wraps the newly created buf from {@code buf.retainedSlice} in a packet byte buf.
*
* @param buf the original buf
* @return a slice of the buf
* @see ByteBuf#retainedSlice()
*/
public static FriendlyByteBuf retainedSlice(ByteBuf buf) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.retainedSlice());
}
/**
* Wraps the newly created buf from {@code buf.slice} in a packet byte buf.
*
* @param buf the original buf
* @param index the starting index
* @param length the size of the copy
* @return a slice of the buf
* @see ByteBuf#slice(int, int)
*/
public static FriendlyByteBuf slice(ByteBuf buf, int index, int length) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.slice(index, length));
}
/**
* Wraps the newly created buf from {@code buf.retainedSlice} in a packet byte buf.
*
* @param buf the original buf
* @param index the starting index
* @param length the size of the copy
* @return a slice of the buf
* @see ByteBuf#retainedSlice(int, int)
*/
public static FriendlyByteBuf retainedSlice(ByteBuf buf, int index, int length) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.retainedSlice(index, length));
}
/**
* Wraps the newly created buf from {@code buf.duplicate} in a packet byte buf.
*
* @param buf the original buf
* @return a duplicate of the buf
* @see ByteBuf#duplicate()
*/
public static FriendlyByteBuf duplicate(ByteBuf buf) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.duplicate());
}
/**
* Wraps the newly created buf from {@code buf.retainedDuplicate} in a packet byte buf.
*
* @param buf the original buf
* @return a duplicate of the buf
* @see ByteBuf#retainedDuplicate()
*/
public static FriendlyByteBuf retainedDuplicate(ByteBuf buf) {
Objects.requireNonNull(buf, "ByteBuf cannot be null");
return new FriendlyByteBuf(buf.retainedDuplicate());
}
private PacketByteBufs() {
}
}

Some files were not shown because too many files have changed in this diff Show More