Compare commits

..

258 Commits

Author SHA1 Message Date
Ran 5a48baf498 Update Readme.md 2022-04-17 17:00:23 +00:00
coolGi2007 7afc455302 Added the multiplayer folder thing from 1.18 2022-03-08 17:33:22 +10:30
James Seibel dfd37bf969 Rename MinecraftWrapper -> MinecraftClientWrapper 2022-03-05 18:32:43 -06:00
James Seibel e48e3069e1 remove WorldWrapper.isEmpty()
It wasn't used and there was a comment saying not to use it
2022-03-05 18:15:42 -06:00
James Seibel 93b129e699 Update the DependencyHandler to support circular references 2022-03-05 17:37:04 -06:00
James Seibel f6df5ac832 Fix some compiler errors 2022-03-03 22:55:01 -06:00
coolGi2007 4fc58adb0e Fixed 1.16 (tough someone needs to fix core/objects/opengl/RenderRegion to work with java8) 2022-03-03 17:39:14 +10:30
James Seibel 7d2ee7126d Refactor the dependency injectors 2022-03-01 21:38:20 -06:00
Morippi b3e1693558 Alpha now uses max value in merge and not average value 2022-02-22 11:54:24 +01:00
coolGi2007 de60298d93 Updated the readme, made it say it works on mc 1.16.2 upto 1.16.5 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 18:31:10 +10:30
coolGi2007 4e02a3e5bf Updated readme, core, forge version, fabric version and added run jar 2022-02-21 16:46:20 +10:30
Morippi 7e83a7bee3 Fixed down (and Up even if not visible) shade 2022-02-20 00:48:55 +01:00
cola98765 e32213bd33 actually fix tint on custom water textures. 2022-02-19 22:31:17 +01:00
James Seibel 10ba97705e Update the version number to 1.6.2a 2022-02-17 20:11:40 -06:00
tom lee 775d1a7177 Update core 2022-02-17 22:33:29 +08:00
cola98765 dae3d49d62 update BlockColorWrapper, and fix "wraning" 2022-02-15 12:14:55 +01:00
coolGi2007 f9292b80c3 Updated gradle stuff to be more like 1.18 (forgot to commit this) 2022-02-15 15:29:07 +10:30
James Seibel 3dfaf58a1b Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2022-02-13 16:59:19 -06:00
James Seibel cb474ca19f Update the forge version 2022-02-13 16:58:55 -06:00
tom lee ed248157a5 Fixed it so it works 2022-02-13 19:51:17 +08:00
tom lee 08dbe8bbf8 Add TerraForged Compat via a mixin + Fix heightmap bug in StepFeature 2022-02-13 18:30:58 +08:00
James Seibel 26a1682b6c Prepare for 1.6.1a 2022-02-12 12:06:14 -06:00
tom lee c1ed040c6f Rollback some unneeded backport. And make it compile 2022-02-12 22:50:08 +08:00
tom lee ef6efae969 Backport changes from 1.18 branch 2022-02-12 22:26:48 +08:00
tom lee ae1fc0f750 Backport changes from 1.18 2022-02-12 16:13:05 +08:00
James Seibel bd7dc5ac25 Update the version number to 1.6.1a-pre and re-enable dev code 2022-02-11 22:07:32 -06:00
James Seibel 6a42d43a86 update the version number for 1.6.0a 2022-02-11 20:39:22 -06:00
coolGi2007 bd95b81a70 Fixed shodow problem with toml (i forgot something before) 2022-02-11 13:38:13 +00:00
coolGi2007 1b0e362227 Added _Version to config for future me 2022-02-11 13:09:59 +00:00
tom lee b056d10b2b Update core 2022-02-11 15:29:04 +08:00
James Seibel 1d2563cc4b Slightly improve the tooltips for the config GUI 2022-02-10 22:08:46 -06:00
Morippi 92259077f3 Added Ultra setting to vertical quality and changed the others 2022-02-10 15:10:42 +01:00
tom lee 84c2a687a1 Update core + Config + fix underwater/blindness fog 2022-02-10 21:43:41 +08:00
tom lee a6a321ff0e Updated core + Fixed debug buttons 2022-02-10 17:06:25 +08:00
coolGi2007 911c802211 Made sodium use cursedforge and added toml to core 2022-02-10 13:49:38 +10:30
tom lee 3d9228ceac Fixed critical MEM LEAKS on batch world generator 2022-02-09 18:04:37 +08:00
tom lee 389114e091 First update. NOTE MEM LEAK NOTED!!!! 2022-02-08 19:37:36 +08:00
tom lee 37e06a820f Fixed forge disable fog. (Forgot to commit this) 2022-02-08 18:05:51 +08:00
James Seibel c8f78dad5c Add an expiration to the archives 2022-02-05 15:42:45 +00:00
tom lee 767452338a Changed how Features step works for mod compat with CaveBiomesApi 2022-02-05 19:11:40 +08:00
tom lee ac12e61a2d Make it build. 2022-02-05 18:17:41 +08:00
tom lee 18d2901725 Impl proper Mixins instead of @Overwrite to increase mod compat
Did this because I wanna play Create Above and Beyond, and this is
causing mixin compat issues with caveApi mod or something like that
2022-02-05 18:14:13 +08:00
coolGi2007 3931ea7fe8 Removed clouds 2022-02-05 09:48:43 +00:00
tom lee 1222db45d6 Update core + remove duped createStructureStart() call. 2022-02-05 16:17:31 +08:00
tom lee 1f60357a95 Update core 2022-02-05 14:36:42 +08:00
coolGi2007 0894a01342 Forgot to remove this when i was downgrading to 1.16 2022-02-04 00:58:57 +00:00
tom lee b55096a3e0 Added back a missing break; in a switch/case 2022-02-03 16:54:42 +08:00
tom lee c29420b695 BatchGen: Completely refactor the ExperGen into now call BatchGen 2022-02-03 16:47:22 +08:00
tom lee 46c249e683 Update core 2022-02-02 15:56:21 +08:00
tom lee faae6de024 Fix race issue with vanilla gen. Improve mem usage a bit 2022-02-01 15:48:55 +08:00
tom lee e2afb8e47e Fix light issue and lockups in Noise step. Features are still unstable 2022-01-31 00:24:45 +08:00
tom lee 3a3fe214c4 Fix experGen loading existing chunks. (It now works.) 2022-01-30 15:31:59 +08:00
tom lee 00951329aa And merge it to head 2022-01-30 14:16:23 +08:00
tom lee 95ad811ed5 Actually commit untracked files 2022-01-30 14:15:10 +08:00
coolGi2007 f5f913d717 Cleaned up gradle and temporarily commented out the experimental generator till leetom adds it back 2022-01-30 16:14:26 +10:30
tom lee b79f47886f PORTTED EXPO WORLD GEN!!!! YAAAAAAAYYYY 2022-01-29 23:25:17 +08:00
tom lee 5d8a30567d Return true on isLightCorrect() since 1.16 seems to never set this flag 2022-01-29 19:17:20 +08:00
coolGi2007 0d67630314 Downgraded stuff from 1.17 to 1.16 2022-01-29 03:54:42 +00:00
coolGi2007 95a444781c (forgot to push this commit) downgraded stuff from 1.17 to 1.16 2022-01-27 09:49:56 +10:30
coolGi2007 04fd38dbb0 Added comments to the file 2022-01-25 15:42:47 +10:30
James Seibel 07c541f014 Delete OptiFine_1.16.5_HD_U_G8.jar 2022-01-25 01:00:22 +00:00
coolGi2007 ff9f8eef3c Fixed accesswideners 2022-01-24 23:44:22 +10:30
coolGi2007 a4a8de2ff2 After all these years, the ints show up correctly after restarting (it was literally a 1 line fix) 2022-01-24 19:55:34 +10:30
coolGi2007 b0324c76fa Ported everything from 1.17 to 1.16 2022-01-24 18:19:49 +10:30
jas35484 3cc7be7f25 Merge branch '1.16.5' into 1.16.5_architectury 2022-01-22 18:14:09 -06:00
jas35484 665a996285 Update Core 2022-01-22 18:08:46 -06:00
coolGi2007 5184cfb4da Downported stuff from 1.17 to 1.16 2022-01-21 13:53:15 +10:30
coolGi2007 75ca15ae36 Added jar merger 2022-01-21 13:29:27 +10:30
jas35484 1f58c1e5e2 Start pipeline? 2022-01-18 19:10:51 -06:00
jas35484 44f21fb953 Add the missing minor version number 1.6a -> 1.6.0a 2022-01-17 20:37:36 -06:00
jas35484 43ade5d24a Increment the version from 'a1.5.4' to 'a1.6-pre' 2022-01-17 20:24:51 -06:00
jas35484 cc34d8fb45 Add .gitlab-ci.yml 2022-01-17 19:53:29 -06:00
jas35484 d0b555e1dc Update .gitlab-ci.yml 2022-01-17 19:50:20 -06:00
jas35484 14a6e00e86 Update .gitlab-ci.yml 2022-01-16 20:55:48 -06:00
James Seibel 68614d5ff1 Delete .gitlab-ci.yml 2022-01-17 02:47:06 +00:00
jas35484 77189db253 Update .gitlab-ci.yml 2022-01-16 20:36:54 -06:00
jas35484 eb096cceaf Update .gitlab-ci.yml 2022-01-16 20:26:32 -06:00
jas35484 35df03a2cf Add .gitlab-ci.yml 2022-01-16 19:52:34 -06:00
jas35484 78670ed537 Add .gitlab-ci.yml 2022-01-16 19:41:32 -06:00
jas35484 477fa974ea Add .gitlab-ci.yml 2022-01-16 19:02:30 -06:00
jas35484 796b83136e Update .gitlab-ci.yml 2022-01-16 18:53:06 -06:00
jas35484 a1dc7a26d8 Update .gitlab-ci.yml 2022-01-16 18:51:37 -06:00
jas35484 96b61234e5 Update .gitlab-ci.yml 2022-01-16 18:42:00 -06:00
jas35484 a63131b153 Update .gitlab-ci.yml 2022-01-16 18:39:31 -06:00
jas35484 addeccd761 Update .gitlab-ci.yml 2022-01-16 18:31:39 -06:00
jas35484 b0c0b7664f Update .gitlab-ci.yml 2022-01-16 18:28:36 -06:00
James Seibel a384c49757 Add a test .gitlab-ci.yml file 2022-01-16 23:54:13 +00:00
tom lee 264d64d221 Add forge DisableVanillaFog. (And actually add the untracked file.) 2022-01-14 21:31:29 +08:00
coolGi2007 54674064f9 Fixed forge crash (forgot this existed) 2022-01-14 08:57:22 +00:00
coolGi2007 354836f098 Escape saves config 2022-01-14 14:14:55 +10:30
tom lee 68c73790bc Add forge DisableVanillaFog. UNTESTED due to gradle cache..... 2022-01-14 00:11:20 +08:00
tom lee f4d385d25b Update core + Fix Sodium fog 2022-01-13 22:32:22 +08:00
tom lee 134c25ad43 Updated core and fixed up SodiumAccessor 2022-01-12 19:59:57 +08:00
coolGi2007 8a37951f64 Added mod checker 2022-01-12 16:37:41 +10:30
coolGi2007 9d76ed67d0 Fixes all (hopefully) problems with saving the config file 2022-01-11 17:38:52 +10:30
coolGi2007 f50e818f66 Added cloud warning 2022-01-10 05:14:16 +00:00
coolGi2007 59830cdd52 Updated readme 2022-01-10 14:35:19 +10:30
coolGi2007 dd9a9addbb Removed fog from forge to stop crash 2022-01-10 14:29:00 +10:30
coolGi2007 6b88eb833d Updated everything 2022-01-09 21:32:57 +10:30
coolGi2007 6b7a80845c Forgot to remove this 2022-01-07 19:19:12 +10:30
coolGi2007 8a41734bce Updated everything 2022-01-07 18:03:31 +10:30
tom lee 6d83ec1606 Updated core and wrapper 2022-01-07 13:28:58 +08:00
coolGi2007 49012a6996 Update Config.java 2022-01-02 08:58:14 +00:00
coolGi2007 ded2ebec06 Removed the need for any config category. The config now guesses the category 2022-01-02 06:11:32 +00:00
coolGi2007 c95018a6ac Fixed forge building tough still dosnt run on ide 2022-01-02 05:14:24 +00:00
coolGi2007 4870d456c9 Updated java version in build.gradle 2022-01-02 04:54:16 +00:00
coolGi2007 0c8fdaab29 Updated fog stuff 2022-01-01 23:03:05 +10:30
coolGi2007 536ea92e5f Fixed some stuff so it can be built 2022-01-01 21:12:04 +10:30
coolGi2007 06d3469b8f Fixed a config gui crash 2022-01-01 20:11:37 +10:30
coolGi2007 8603301ab8 Updated stuff 2022-01-01 19:57:26 +10:30
tom lee f06c16bea7 Update core 2022-01-01 16:49:07 +08:00
tom lee 70b5daa510 Updated core and wrappers 2022-01-01 15:34:37 +08:00
coolGi2007 afe2e91a5b Update Readme.md 2022-01-01 07:17:34 +00:00
tom lee 6c9775481e Fabric: Fixed up config button. It now shows up! 2021-12-31 23:45:06 +08:00
tom lee 4878d56518 Fixed up most stuff so it runs on fabric. Still crashes though 2021-12-31 23:18:45 +08:00
tom lee e80889d7dd Updated core and config wrappers 2021-12-31 21:46:04 +08:00
tom lee 7d6a49c8b0 Update core and fix it to work 2021-12-29 22:21:52 +08:00
coolGi2007 47386e3aee Updated some stuff 2021-12-29 16:47:44 +10:30
coolGi2007 8179ee7ad6 Test branch for architectury 2021-12-28 09:16:03 +00:00
cola98765 bfbf987599 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:10:22 +01:00
cola98765 b80d1c784d fix SPRUCE and BIRCH leaves 2021-12-26 15:45:13 +01:00
cola98765 aeb2e31a6e potential fix to cherry leaves (call me if you see gray blocks that should not be gray) 2021-12-24 13:07:48 +01:00
tom lee 512924a646 Updated core 2021-12-21 21:15:20 +08:00
tom lee 56d8c3a96f Updated core 2021-12-21 15:56:00 +08:00
James Seibel 81a3a52436 Update the authors list
How could I forget the port devs!?
2021-12-16 21:37:07 -06:00
James Seibel 19c1cd523a Remove the server mod requirement and update the credits 2021-12-16 21:33:39 -06:00
tom lee 76cc3d0800 Updated core 2021-12-16 00:16:30 +08:00
tom lee ed5b3c56dd Updated core 2021-12-15 17:17:19 +08:00
tom lee e568e6623e Updated core 2021-12-15 16:08:04 +08:00
James Seibel 9b12cd75fb Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-12-14 23:28:54 -06:00
James Seibel 26eb0d3cfe Change the sodium support to use a flat render distance 2021-12-14 23:28:51 -06:00
tom lee 174db2ede9 Updated core 2021-12-15 11:41:41 +08:00
Morippi 2992541390 fixed new merge and data system 2021-12-14 23:00:30 +01:00
Morippi 3e54323846 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-12-14 22:01:06 +01:00
Morippi 3287ec0790 small fix 2021-12-14 22:00:57 +01:00
cola98765 5796b8b814 made getMinHeight() default, so when it's not implemented it just returns 0 2021-12-14 21:40:34 +01:00
cola98765 d6a87c252b no longer using getMinimumWorldHeight() form version constants, added replacement in WorldWrapper. 2021-12-14 21:37:13 +01:00
Morippi ff0761fe0e small fixes 2021-12-14 21:22:33 +01:00
tom lee 019c83913e Update core 2021-12-15 00:05:11 +08:00
Morippi 387e4c0598 Added slice in mergeAndAddData 2021-12-13 22:55:30 +01:00
Morippi a67cd9769b Added methods for the merge in the LevelContainer, to be implemented 2021-12-13 21:03:55 +01:00
Morippi 839d8fbfdb Changed the format 2021-12-13 18:59:43 +01:00
cola98765 a56bcfe58d I hope I fixed what james broke 2021-12-13 16:13:21 +01:00
James Seibel 925ff3a1c7 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-12-12 17:43:39 -06:00
James Seibel ff8388b1b7 Closes #85 (Sodium Overdraw incompatibility)
One minor issue: Sodium returns chunks differently than vanilla MC or Optifine. Specifically as of 1.16.5 (12-12-2021) it also returns one layer of chunks further than what is currently rendered.
2021-12-12 17:43:36 -06:00
cola98765 8a1b609b92 fixed couple errors, but floating islands are still broken 2021-12-12 12:04:17 +01:00
cola98765 f53fd04c4e clean the garbage I made in ChunkWrapper yesterday 2021-12-12 10:58:24 +01:00
James Seibel 881f3c1cc5 Update core 2021-12-11 21:50:06 -06:00
James Seibel d5ec730558 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-12-11 21:41:03 -06:00
James Seibel 7c8b7f00e6 Add support for different Core behavior in different MC versions 2021-12-11 21:40:53 -06:00
cola98765 6344fcf44c attempt to fix generation below y=0 2021-12-12 00:25:47 +01:00
cola98765 e29ec2dea6 Revert "attempt to fix generation below y=0"
This reverts commit 4dd51022fa.
2021-12-12 00:23:06 +01:00
cola98765 4dd51022fa attempt to fix generation below y=0 2021-12-12 00:16:41 +01:00
Morippi df28d2dc9d small fixes, + changed variables name 2021-12-11 01:26:03 +01:00
Morippi 25101bf8b8 Fixed position bug in the rendering 2021-12-11 00:42:09 +01:00
Morippi 234d9e1205 fixewd generation not working 2021-12-10 19:18:23 +01:00
Morippi 7dba35a9ec Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-12-10 19:05:38 +01:00
Morippi 0c91acfd2b Removed most of BlockPos and ChunkPos use 2021-12-10 19:05:28 +01:00
cola98765 4da1382246 add tex.tick(). Thanks leetom! 2021-12-10 17:27:09 +01:00
coolGi2007 3fd647be41 Made gradlew an executable 2021-12-10 05:24:29 +00:00
James Seibel 829407662e Remove the Dynamic and Triangular Lod Templates 2021-12-09 21:50:09 -06:00
Morippi 14f75c5a60 changed some parameters 2021-12-09 20:26:20 +01:00
cola98765 a6d3b5bb94 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-12-09 19:19:02 +01:00
cola98765 df085c3ec7 made it so it works with servers that don't have that mod. 2021-12-09 19:16:57 +01:00
Morippi 9d3f3cdbdd Added maps to cache the biome blocks couples 2021-12-09 17:30:43 +01:00
Morippi 5f3cb3319c added getters and creators in the new format. 2021-12-09 17:30:19 +01:00
cola98765 bbb7661f47 update core 2021-12-09 14:33:18 +01:00
cola98765 dfa4a0b663 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-12-09 14:31:43 +01:00
cola98765 ec6caf92a8 fix comments 2021-12-09 14:31:26 +01:00
Morippi fc42ba020d Fixed a small bug 2021-12-09 14:30:35 +01:00
cola98765 6b72e4d2c9 final fix to color of shared based light 2021-12-09 14:21:04 +01:00
Morippi 6d7ecaa6c3 Fixed some part of the new format 2021-12-09 13:50:59 +01:00
Morippi dcd5ae3256 Created the BlockBiomeCouple 2021-12-09 13:50:38 +01:00
Morippi 3349606413 Added new format classes 2021-12-09 12:57:35 +01:00
James Seibel 247ef0f10e Update core 2021-12-08 23:07:23 -06:00
James Seibel 911bfc8c88 Add (buggy, unfinished) shader based lighting 2021-12-08 22:59:43 -06:00
cola98765 a85a93b794 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-12-07 13:06:05 +01:00
cola98765 815238dc8f added and commented out time testing code 2021-12-07 13:05:45 +01:00
Morippi 8514e53ecd Changed how data from the level container are passed as output. Removed the Thread system 2021-12-07 11:56:13 +01:00
cola98765 f602571c61 reverted DrawResolutionOffset 2021-12-05 20:03:27 +01:00
cola98765 403175677e HorizontalScale is now a number 2-32 2021-12-05 17:03:49 +01:00
cola98765 565554311e added DrawResolutionOffset to work with DrawResolution 2021-12-05 16:38:08 +01:00
James Seibel 0827397d9a Update core 2021-12-04 22:25:51 -06:00
Morippi 56635ccbf1 Change Box to VertexOptimizer and added the DataFormat folder with empty classes 2021-12-02 23:07:09 +01:00
James Seibel a7897e45f3 Update core 2021-12-01 22:48:32 -06:00
James Seibel 751ce4afef Update the config 2021-12-01 22:40:49 -06:00
cola98765 0b2373e830 couple more warnings 2021-11-30 12:05:17 +01:00
cola98765 ddf9700804 couple warnings 2021-11-30 11:46:06 +01:00
James Seibel e93c53b1ec Update core 2021-11-29 21:23:52 -06:00
James Seibel 2852bd91f9 Update core to a1.5.4, add experimental buffer timeout option 2021-11-29 21:23:09 -06:00
James Seibel d5740c5d7f Update core 2021-11-28 18:14:37 -06:00
James Seibel 816249acdb Update core 2021-11-28 16:54:23 -06:00
James Seibel 23d9cf10d3 Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5 2021-11-28 16:28:49 -06:00
James Seibel eeea070fd1 Update core 2021-11-28 16:28:47 -06:00
James Seibel e47cdaa2e4 update the version number to a1.5.3 2021-11-28 16:09:25 -06:00
cola98765 db074a6a5b Fix Starlight (mod) once more 2021-11-28 11:28:40 +01:00
James Seibel f2f0e291d8 Add a missing comment 2021-11-27 23:28:28 -06:00
James Seibel db123072bd Add Legacy OpenGL vanilla fog removal 2021-11-27 23:24:58 -06:00
James Seibel 6bbb99ff39 Update the version number to a1.5.3 2021-11-27 21:14:50 -06:00
James Seibel 88c5fc8fde Fix gradle issues (compiling works again) 2021-11-27 21:12:42 -06:00
James Seibel a40417bbd6 Remove logo and IDE files (they are in core now) 2021-11-27 18:05:04 -06:00
James Seibel cf7373a303 Improve the config descriptions 2021-11-27 16:17:14 -06:00
James Seibel 49c0581b1d rename DistantHorizons_Server_Data -> Distant_Horizons_server_data 2021-11-27 14:48:41 -06:00
Ran 72d3b50077 Add core resources to the jar (Isn't tested yet) 2021-11-28 01:10:12 +06:00
Ran aaedc8e384 Fix NPE when loading up the world 2021-11-28 00:21:01 +06:00
James Seibel b63f24c92e rename the server data folder 2021-11-27 12:03:38 -06:00
Ran 76154aada0 Fix shadow 2021-11-27 23:41:40 +06:00
James Seibel 6b029da899 Add setUniform(color) 2021-11-27 10:32:18 -06:00
James Seibel 818c4243e0 Add FogColorMode 2021-11-27 10:10:21 -06:00
James Seibel a41a4fe77f remove a debug command 2021-11-26 21:20:41 -06:00
James Seibel 9a03a45cd7 Clean up Fog, remove Fast fog, close issue #77 (near-far incorrect center) 2021-11-26 21:14:06 -06:00
James Seibel e2eaca7869 Add fog as a fragment shader 2021-11-26 19:25:05 -06:00
James Seibel 0bfef6b3d3 change the submodule path to https instead of ssh 2021-11-26 09:43:21 -06:00
James Seibel 03345924f3 Update core 2021-11-25 11:51:45 -06:00
James Seibel 37f72980ee Downgrade Gradle to 7.1 (from 7.2) This should be the latest available to MC 1.16.5 2021-11-25 08:15:43 -06:00
James Seibel 7fd43deaca Update gradle to 7.2 (from 4.10.3) and fix the build.gradle file 2021-11-22 19:23:49 -06:00
James Seibel 05a3d4002f Add support for disabling rendering 2021-11-21 22:15:10 -06:00
James Seibel 8a574074c5 Merge branch '1.16.5_Core' into '1.16.5'
1.16.5 core

See merge request jeseibel/minecraft-lod-mod!10
2021-11-22 00:28:09 +00:00
James Seibel f801567301 Update core 2021-11-21 18:26:48 -06:00
James Seibel 632947c8ce minor spelling fix 2021-11-21 18:26:12 -06:00
James Seibel 5cb32d6181 Delete 1.5 release notes.txt 2021-11-21 16:16:26 -06:00
James Seibel 505f48cebc Add DH-Core's source folders to Gradle 2021-11-21 15:53:35 -06:00
James Seibel e2bdfcc2da Initial implementation of Core 2021-11-21 15:28:59 -06:00
cola98765 cd72edf9a6 Merge branch 'CodeF53-1.16.5-patch-42921' into '1.16.5'
Add icon for catalogue mod & Update logo displayed in configured

Closes #97

See merge request jeseibel/minecraft-lod-mod!9
2021-11-07 11:07:43 +00:00
cola98765 5172fec97f changed back how sky/block light is accessed for Starlight (mod) compatibility 2021-11-06 23:04:14 +01:00
cola98765 b1a39ce74b disabled try catch in LodGenWorker. It made logs useless 2021-11-06 22:55:26 +01:00
cola98765 563fea608e WorldWrapper -> LevelWrapper 2021-11-05 12:19:36 +01:00
cola98765 be6e52ded0 changed world to level in minecraft wrapper for consistency with other versions 2021-11-05 12:09:07 +01:00
cola98765 6d54edd74c removed client world dependency in buffer builder; minor changes 2021-11-05 11:10:56 +01:00
CodeF53 492c634cc4 Add icon for catalogue mod
Update logo displayed in configured to match new name
2021-11-05 00:01:51 +00:00
cola98765 d92cb6016f cleaned out some code 2021-11-04 11:56:43 +01:00
cola98765 0250eba715 cleaned out some code 2021-11-04 11:45:02 +01:00
cola98765 cbf1bf698d cleaned out imports 2021-11-04 11:43:13 +01:00
cola98765 2aed897b9b pulled some changes around wrappers from 1.17.1_fabric 2021-11-04 11:30:33 +01:00
cola98765 7402ad6be0 added getHashFromFile for future use with servers 2021-11-03 19:03:42 +01:00
Leonardo d4556e7f84 Biome colors is calculated using the block color wrapper 2021-11-01 22:34:39 +01:00
Leonardo 7b910ba4fd Changed waterlogged check, the biome getter and other small stuff 2021-11-01 22:34:17 +01:00
cola98765 5762c41f1a protect full regions against being overwritten by a partial one 2021-11-01 10:18:49 +01:00
cola98765 dee9fa793d cleanup 2021-10-30 17:45:32 +02:00
cola98765 1962053a2f improved adj lighting 2021-10-30 16:38:22 +02:00
cola98765 bb16cfa4fe when there are too many gaps, remove the bottom one of the smallest size first. 2021-10-30 15:52:16 +02:00
cola98765 73ddbd66b5 fixed EXCEPTION_ACCESS_VIOLATION when stitching lods on and off using F6 2021-10-30 15:43:55 +02:00
cola98765 8e727011de now recreate buffers when you reenable rendering. Doing it using debug keys can sometimes lead to crash tho 2021-10-30 13:36:00 +02:00
cola98765 717e189107 made "Enable Rendering" only affect buffer building to enable generation with no rendering 2021-10-30 12:49:58 +02:00
cola98765 cff8326810 Fixed "generate at max quality" TODO make generation work with disabled rendering at world join 2021-10-30 11:37:52 +02:00
James Seibel fd0604c7e7 Fix a few potential null pointers when on a server world 2021-10-29 19:56:03 -05:00
James Seibel f822aed285 make the fog disabler config experimental and disabled by default 2021-10-29 19:50:50 -05:00
cola98765 26535ef81c remove debug message 2021-10-29 16:03:06 +02:00
cola98765 2b0c0f89a2 cleaned up some code 2021-10-29 15:13:37 +02:00
cola98765 51e7e318ac removed weird math.ceil that was used on int 2021-10-29 14:21:23 +02:00
cola98765 e5ef7e7026 fixed index out of bounds and void air appearing purple bugs 2021-10-29 13:22:28 +02:00
cola98765 62794766c6 Merge remote-tracking branch 'origin/1.16.5' into 1.16.5 2021-10-29 12:27:14 +02:00
cola98765 e32addfd06 actually fixed non-square non-animated textures 2021-10-29 12:26:54 +02:00
cola98765 42678a27a4 clean out previous 2021-10-29 12:21:16 +02:00
cola98765 1488747075 fixed non-square non-animated textures 2021-10-29 12:07:41 +02:00
cola98765 a03ddf7339 applied autoformat to that vivecraft commit 2021-10-29 09:18:22 +02:00
cola98765 c537e0cf49 Merge branch '1.16.5' into '1.16.5'
Add vivecraft support

See merge request jeseibel/minecraft-lod-mod!7
2021-10-29 07:02:51 +00:00
Eric 853c706b77 Add vivecraft support 2021-10-28 22:16:19 -06:00
78 changed files with 2079 additions and 2292 deletions
+21 -12
View File
@@ -1,4 +1,11 @@
# Distant Horizons
# 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\
@@ -10,16 +17,15 @@ 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>
Architectury version: 3.4-SNAPSHOT\
Forge version: 37.1.0\
Fabric version: 0.12.6\
Fabric API version: 0.37.1+1.17
Forge version: 36.2.28\
Fabric version: 0.13.2\
Fabric API version: 0.42.0+1.16
Modmenu version: 2.0.14\
Sodium version: mc1.17.1-0.3.3
Modmenu version: 1.16.22
Notes:\
This version has been confirmed to work in Eclipse and Retail Minecraft.\
(Retail running forge version 1.17.1-37.1.0 and fabric version 1.17.1-0.12.6)
(Retail running forge version 1.16.5-36.1.0 and fabric version 1.16.5-0.12.3)
## source code installation
@@ -48,13 +54,15 @@ Side note: invalidate caches and restart if required
**Using GUI**
1. Open a command line in the project folder
2. Run the command: `./gradlew build`
3. The compiled jar file will be in the folder `fabric/build/libs/` and `forge/build/libs/`
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.17.1 --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
1. `git clone -b 1.16.5_architectury --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
2. `cd minecraft-lod-mod`
3. `./gradlew assemble` or `./gradlew build`
4. The build should be in `fabric/build/libs/` and `forge/build/libs/`
3. `./gradlew assemble`
5. `./gradlew mergeJars`
6. The compiled jar file will be in the folder `Merged`
## Other commands
@@ -75,7 +83,8 @@ Source code uses Mojang mappings.
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`
Run the Forge client (**THIS DOST WORK** due to a bug with architectury): `./gradlew forge:runClient`\
To use a custom version of Java use `-D` then the path for Java
## Open Source Acknowledgements
+50 -2
View File
@@ -8,7 +8,7 @@ buildscript {
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "0.10.0.195" apply false
id "dev.architectury.loom" version "0.10.0-SNAPSHOT" apply false
}
apply plugin: JarMergerPlugin
@@ -50,6 +50,14 @@ subprojects { p ->
shadowMe(project(":core")) { transitive false }
}
}
jar {
manifest {
attributes 'Implementation-Title': rootProject.archives_base_name,
'Implementation-Version': rootProject.mod_version,
'Main-Class': 'com.seibel.lod.core.JarMain'
}
}
}
allprojects {
@@ -98,9 +106,49 @@ allprojects {
}
}
// 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
] // 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
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) {
options.encoding = "UTF-8"
options.release = 16
// The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too
// JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used.
// We'll use that if it's available, but otherwise we'll use the older option.
def targetVersion = 8
if (JavaVersion.current().isJava9Compatible()) {
options.release = targetVersion
}
}
java {
@@ -27,6 +27,8 @@ 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.IWorldGenerator;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IMultiplayer;
import net.minecraft.client.renderer.DimensionSpecialEffects;
/**
* This handles any configuration the user has access to.
@@ -72,6 +74,9 @@ public class Config extends ConfigGui
@ConfigAnnotations.ScreenEntry
public static WorldGenerator worldGenerator;
@ConfigAnnotations.ScreenEntry
public static Multiplayer multiplayer;
@ConfigAnnotations.ScreenEntry
public static Advanced advanced;
@@ -145,7 +150,7 @@ public class Config extends ConfigGui
public static boolean disableVanillaFog = IFogQuality.DISABLE_VANILLA_FOG_DEFAULT;
}
public static class AdvancedGraphics
{
@ConfigAnnotations.FileComment
@@ -180,16 +185,16 @@ public class Config extends ConfigGui
@ConfigAnnotations.Entry
public static boolean enableDistantGeneration = IWorldGenerator.ENABLE_DISTANT_GENERATION_DEFAULT;
// @ConfigAnnotations.FileComment
// @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
@@ -198,17 +203,23 @@ public class Config extends ConfigGui
/*
@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;
public static boolean allowUnstableFeatureGeneration = 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;
}
public static class Advanced
{
@ConfigAnnotations.ScreenEntry
@@ -263,7 +274,7 @@ public class Config extends ConfigGui
@ConfigAnnotations.FileComment
public static String _gpuUploadPerMegabyteInMilliseconds = IBuffers.GPU_UPLOAD_PER_MEGABYTE_IN_MILLISECONDS_DESC;
@ConfigAnnotations.Entry(minValue = 0, maxValue = 5000)
@ConfigAnnotations.Entry(minValue = 0, maxValue = 50)
public static int gpuUploadPerMegabyteInMilliseconds = IBuffers.GPU_UPLOAD_PER_MEGABYTE_IN_MILLISECONDS_DEFAULT.defaultValue;
@ConfigAnnotations.FileComment
@@ -4,6 +4,7 @@ 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;
import com.seibel.lod.core.ModInfo;
/**
* This is the common main class
@@ -1,8 +1,7 @@
package com.seibel.lod.common.forge;
import com.seibel.lod.common.wrappers.minecraft.MinecraftWrapper;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
@@ -16,6 +15,5 @@ import java.util.Random;
* @author Ran
*/
public interface LodForgeMethodCaller {
List<BakedQuad> getQuads(MinecraftWrapper mc, Block block, BlockState blockState, Direction direction, Random random);
int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y);
List<BakedQuad> getQuads(MinecraftClientWrapper mc, Block block, BlockState blockState, Direction direction, Random random);
}
@@ -1,8 +1,11 @@
package com.seibel.lod.common.networking;
import com.seibel.lod.common.LodCommonMain;
import io.netty.buffer.Unpooled;
import net.minecraft.network.FriendlyByteBuf;
import java.nio.charset.StandardCharsets;
/**
* This class holds most of the networking code for the mod.
* @author Ran
@@ -1,15 +1,13 @@
package com.seibel.lod.common.wrappers;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.wrappers.block.BlockColorSingletonWrapper;
import com.seibel.lod.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.lod.common.wrappers.minecraft.MinecraftWrapper;
import com.seibel.lod.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.lod.core.handlers.IReflectionHandler;
import com.seibel.lod.core.handlers.ReflectionHandler;
import com.seibel.lod.core.util.SingletonHandler;
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.block.IBlockColorSingletonWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
@@ -25,13 +23,14 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
*/
public class DependencySetup {
public static void createInitialBindings() {
SingletonHandler.bind(IBlockColorSingletonWrapper.class, BlockColorSingletonWrapper.INSTANCE);
SingletonHandler.bind(IVersionConstants.class, VersionConstants.INSTANCE);
if (!LodCommonMain.serverSided) {
SingletonHandler.bind(IMinecraftWrapper.class, MinecraftWrapper.INSTANCE);
SingletonHandler.bind(IMinecraftWrapper.class, MinecraftClientWrapper.INSTANCE);
SingletonHandler.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE);
SingletonHandler.bind(IReflectionHandler.class, ReflectionHandler.createSingleton(MinecraftWrapper.INSTANCE.getOptions().getClass().getDeclaredFields(), MinecraftWrapper.INSTANCE.getOptions()));
SingletonHandler.bind(IReflectionHandler.class, ReflectionHandler.createSingleton(MinecraftClientWrapper.INSTANCE.getOptions().getClass().getDeclaredFields(), MinecraftClientWrapper.INSTANCE.getOptions()));
SingletonHandler.bind(IVersionConstants.class, VersionConstants.INSTANCE);
}
SingletonHandler.bind(IWrapperFactory.class, WrapperFactory.INSTANCE);
DependencySetupDoneCheck.isDone = true;
}
}
@@ -0,0 +1,7 @@
package com.seibel.lod.common.wrappers;
public class DependencySetupDoneCheck
{
public static boolean isDone = false;
}
@@ -46,9 +46,17 @@ public class McObjectConverter
return matrix;
}
static final Direction[] directions;
static {
LodDirection[] lodDirs = LodDirection.values();
directions = new Direction[lodDirs.length];
for (LodDirection lodDir : lodDirs) {
directions[lodDir.ordinal()] = Direction.byName(lodDir.name());
}
}
public static Direction Convert(LodDirection lodDirection)
{
return Direction.byName(lodDirection.name());
return directions[lodDirection.ordinal()];
}
}
@@ -52,4 +52,9 @@ public class VersionConstants implements IVersionConstants {
public boolean hasBatchGenerationImplementation() {
return true;
}
@Override
public boolean isVanillaRenderedChunkSquare() {
return true;
}
}
@@ -83,8 +83,8 @@ public class WrapperFactory implements IWrapperFactory {
}
@Override
public AbstractBatchGenerationEnvionmentWrapper createBatchGenerator(LodBuilder newLodBuilder,
LodDimension newLodDimension, IWorldWrapper worldWrapper) {
public AbstractBatchGenerationEnvionmentWrapper createBatchGenerator(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper) {
return new BatchGenerationEnvironment(worldWrapper, newLodBuilder, newLodDimension);
}
}
@@ -1,46 +0,0 @@
/*
* 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.block;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorSingletonWrapper;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper;
import net.minecraft.world.level.block.Blocks;
/**
* Contains methods that would have been static in BlockColorWrapper.
* Since interfaces can't create/implement static methods we have
* to split the object up in two.
*
* @author James Seibel
* @version 11-17-2021
*/
public class BlockColorSingletonWrapper implements IBlockColorSingletonWrapper
{
public static final BlockColorSingletonWrapper INSTANCE = new BlockColorSingletonWrapper();
@Override
public IBlockColorWrapper getWaterColor()
{
return BlockColorWrapper.getBlockColorWrapper(Blocks.WATER);
}
}
@@ -1,328 +0,0 @@
package com.seibel.lod.common.wrappers.block;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.wrappers.minecraft.MinecraftWrapper;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.BushBlock;
import net.minecraft.world.level.block.FlowerBlock;
import net.minecraft.world.level.block.GrassBlock;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.TallGrassBlock;
import net.minecraft.world.level.block.state.BlockState;
/**
* @author James Seibel
* @version 11-21-2021
*/
public class BlockColorWrapper implements IBlockColorWrapper
{
//set of block which require tint
public static final ConcurrentMap<Block, BlockColorWrapper> blockColorWrapperMap = new ConcurrentHashMap<>();
// public static final ModelDataMap dataMap = new ModelDataMap.Builder().build();
public static final AbstractBlockPosWrapper blockPos = new BlockPosWrapper(0, 0, 0);
public static final Random random = new Random(0);
//public static BlockColourWrapper WATER_COLOR = getBlockColorWrapper(Blocks.WATER);
public static final Direction[] directions = new Direction[] { Direction.UP, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.DOWN };
private final Block block;
private int color;
private boolean isColored;
private boolean toTint;
private boolean foliageTint;
private boolean grassTint;
private boolean waterTint;
/**Constructor only require for the block instance we are wrapping**/
public BlockColorWrapper(Block block)
{
this.block = block;
this.color = 0;
this.isColored = true;
this.toTint = false;
this.foliageTint = false;
this.grassTint = false;
this.waterTint = false;
setupColorAndTint();
/*StringBuilder s = new StringBuilder();
s.append(block + "\n"
+ Integer.toHexString(
Minecraft.getInstance().getBlockColors().createDefault().getColor(
block.defaultBlockState(),
(World) MinecraftWrapper.INSTANCE.getWrappedServerLevel().getLevel(),
blockPosWrapper.getBlockPos())) + "\n"
);
for(Property x : Minecraft.getInstance().getBlockColors().getColoringProperties(block))
s.append(x.getName() + " " + x.getPossibleValues() + '\n');
System.out.println(s);*/
//System.out.println(block + " color " + Integer.toHexString(color) + " to tint " + toTint + " folliageTint " + folliageTint + " grassTint " + grassTint + " waterTint " + waterTint);
}
/**
* this return a wrapper of the block in input
* @param block object of the block to wrap
*/
public static IBlockColorWrapper getBlockColorWrapper(Block block)
{
//first we check if the block has already been wrapped
if (blockColorWrapperMap.containsKey(block) && blockColorWrapperMap.get(block) != null)
return blockColorWrapperMap.get(block);
//if it hasn't been created yet, we create it and save it in the map
BlockColorWrapper blockWrapper = new BlockColorWrapper(block);
blockColorWrapperMap.put(block, blockWrapper);
//we return the newly created wrapper
return blockWrapper;
}
/**
* Generate the color of the given block from its texture
* and store it for later use.
*/
private void setupColorAndTint()
{
BlockState blockState = block.defaultBlockState();
//BlockPosWrapper blockPosWrapper = new BlockPosWrapper();
MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
TextureAtlasSprite texture;
List<BakedQuad> quads = null;
//boolean isTinted = false;
//int listSize = 0;
// first step is to check if this block has a tinted face
//for (Direction direction : directions)
//{
// quads = mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random);
// listSize = Math.max(listSize, quads.size());
// for (BakedQuad bakedQuad : quads)
// {
// isTinted |= bakedQuad.isTinted();
// }
//}
//if it contains a tinted face then we store this block in the toTint set
//if (isTinted)
// this.toTint = true;
//now we get the first non-empty face
for (Direction direction : directions)
{
quads = mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random);
if (!quads.isEmpty())
break;
}
//the quads list is not empty we extract the first one
if (!quads.isEmpty())
{
isColored = true;
texture = quads.get(0).getSprite();
}
else
{
isColored = true;
texture = mc.getModelManager().getBlockModelShaper().getParticleIcon(block.defaultBlockState());
}
int count = 0;
int alpha = 0;
int red = 0;
int green = 0;
int blue = 0;
int numberOfGreyPixel = 0;
int tempColor;
int colorMultiplier;
// generate the block's color
// for (int frameIndex = 0; frameIndex < texture.getFrameCount(); frameIndex++)
boolean lookForTint = grassInstance() || leavesInstance() || waterIstance();
int frameIndex = 0; // TODO
{
// 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++)
{
//FIXME: Better way on the TextureAtlasSpriteWrapper!!!
tempColor = LodCommonMain.forge ?
LodCommonMain.forgeMethodCaller.getPixelRGBA(texture, frameIndex, u, v)
: TextureAtlasSpriteWrapper.getPixelRGBA(texture, frameIndex, u, v);
if (tempColor == 0)
continue;
if (lookForTint)
{
// determine if this pixel is gray
int colorMax = Math.max(Math.max(ColorUtil.getBlue(tempColor), ColorUtil.getGreen(tempColor)), ColorUtil.getRed(tempColor));
int colorMin = 4 + Math.min(Math.min(ColorUtil.getBlue(tempColor), ColorUtil.getGreen(tempColor)), ColorUtil.getRed(tempColor));
boolean isGray = colorMax < colorMin;
if (isGray)
numberOfGreyPixel++;
}
// for flowers, weight their non-green color higher
if (block instanceof FlowerBlock && (!(ColorUtil.getGreen(tempColor) > (ColorUtil.getBlue(tempColor) + 30)) || !(ColorUtil.getGreen(tempColor) > (ColorUtil.getRed(tempColor) + 30))))
colorMultiplier = 5;
else
colorMultiplier = 1;
// add to the running averages
count += colorMultiplier;
alpha += ColorUtil.getAlpha(tempColor) * colorMultiplier;
red += ColorUtil.getBlue(tempColor) * colorMultiplier;
green += ColorUtil.getGreen(tempColor) * colorMultiplier;
blue += ColorUtil.getRed(tempColor) * colorMultiplier;
}
}
}
if (count == 0)
// this block is entirely transparent
tempColor = 0;
else
{
// determine the average color
alpha /= count;
red /= count;
green /= count;
blue /= count;
tempColor = ColorUtil.rgbToInt(alpha, red, green, blue);
}
// determine if this block should use the biome color tint
if (lookForTint && (float) numberOfGreyPixel / count > 0.75f)
this.toTint = true;
// we check which kind of tint we need to apply
this.grassTint = grassInstance() && toTint;
this.foliageTint = leavesInstance() && toTint;
this.waterTint = waterIstance() && toTint;
//hardcoded leaves
if (block == Blocks.SPRUCE_LEAVES)
color = ColorUtil.multiplyRGBcolors(tempColor, 0xFF619961);
else if (block == Blocks.BIRCH_LEAVES)
color = ColorUtil.multiplyRGBcolors(tempColor, 0xFF80A755);
else
color = tempColor;
}
/** determine if the given block should use the biome's grass color */
private boolean grassInstance()
{
return block instanceof GrassBlock
|| block instanceof BushBlock
// || block instanceof IGrowable
// || block instanceof AbstractPlantBlock
// || block instanceof AbstractTopPlantBlock
|| block instanceof TallGrassBlock;
}
/** determine if the given block should use the biome's foliage color */
private boolean leavesInstance()
{
return (block instanceof LeavesBlock && block != Blocks.SPRUCE_LEAVES && block != Blocks.BIRCH_LEAVES/* && block != Blocks.AZALEA_LEAVES && block != Blocks.FLOWERING_AZALEA_LEAVES*/)
|| block == Blocks.VINE
|| block == Blocks.SUGAR_CANE;
}
/** determine if the given block should use the biome's foliage color */
private boolean waterIstance()
{
return block == Blocks.WATER;
}
@Override
public String getName(){
return block.getName().toString();
}
//--------------//
//Colors getters//
//--------------//
@Override
public boolean hasColor()
{
return isColored;
}
@Override
public int getColor()
{
return color;
}
//------------//
//Tint getters//
//------------//
@Override
public boolean hasTint()
{
return toTint;
}
@Override
public boolean hasGrassTint()
{
return grassTint;
}
@Override
public boolean hasFolliageTint()
{
return foliageTint;
}
@Override
public boolean hasWaterTint()
{
return waterTint;
}
@Override public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof BlockColorWrapper))
return false;
BlockColorWrapper that = (BlockColorWrapper) o;
return Objects.equals(block, that.block);
}
@Override public int hashCode()
{
return Objects.hash(block);
}
}
@@ -0,0 +1,286 @@
package com.seibel.lod.common.wrappers.block;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.LevelReader;
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.LiquidBlock;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.RotatedPillarBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.VoxelShape;
public class BlockDetailMap
{
public static final int FLOWER_COLOR_SCALE = 5;
public static final Random random = new Random(0);
//TODO: Perhaps make this not just use the first frame?
//FIXME: Stuff is wrong.
private static int calculateColorFromTexture(TextureAtlasSprite texture, boolean useFlowerScaling, boolean useFastLeaf) {
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 (useFastLeaf) {
r *= a;
g *= a;
b *= a;
a = 1.;
} else if (a==0.) {
continue;
} else if (useFlowerScaling && (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;
}
static class BlockDetailCache {
static BlockDetailCache NULL_BLOCK_DETAIL = new BlockDetailCache();
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};
ConcurrentHashMap<Biome, BlockDetail> biomeDetailMap = null;
BlockDetail blockDetail;
BlockDetail defaultTintedDetail = null;
boolean requireResolving;
@SuppressWarnings("unused")
boolean requireShade; //TODO: Add back using this in renderer
@SuppressWarnings("unused")
boolean scaleFlowerColor; //FIXME: Do I need to scale the tint color???
int tintIndex;
static boolean isBlockToBeAvoid(Block b) {
for (Block bta : BLOCK_TO_AVOID)
if (bta==b) return true;
return false;
}
static boolean hasNoCollision(BlockState bs, BlockPos pos, LevelReader getter) {
if (!bs.getFluidState().isEmpty() || bs.getBlock() instanceof LiquidBlock) // Is blockState a fluid?
return false;
if (bs.getCollisionShape(getter, pos).isEmpty())
return true;
return false;
}
static boolean hasOnlyNonFullFace(BlockState bs, BlockPos pos, LevelReader getter) {
if (!bs.getFluidState().isEmpty() || bs.getBlock() instanceof LiquidBlock) // Is blockState a fluid?
return false;
VoxelShape voxelShape = bs.getShape(getter, pos);
if (voxelShape.isEmpty()) return true;
AABB bbox = voxelShape.bounds();
double xWidth = (bbox.maxX - bbox.minX);
double yWidth = (bbox.maxY - bbox.minY);
double zWidth = (bbox.maxZ - bbox.minZ);
return xWidth < 1 && zWidth < 1 && yWidth < 1;
}
static BlockDetailCache make(BlockState bs, BlockPos pos, LevelReader getter) {
boolean noCol, nonFull, canOcclude;
if(!bs.getFluidState().isEmpty()) {
bs = bs.getFluidState().createLegacyBlock();
FluidState fs = bs.getFluidState();
fs.getType();
noCol = false;
nonFull = false;
canOcclude = false;
BlockDetailCache result = new BlockDetailCache(fs);
//ApiShared.LOGGER.info(fs.toString()+" = ["+result+"]");
return result;
} else {
if (bs.getRenderShape() != RenderShape.MODEL) return NULL_BLOCK_DETAIL;
if (isBlockToBeAvoid(bs.getBlock())) return NULL_BLOCK_DETAIL;
//BlocksToAvoid toAvoid = CONFIG.client().worldGenerator().getBlocksToAvoid();
noCol = hasNoCollision(bs, pos, getter);
nonFull = hasOnlyNonFullFace(bs, pos, getter);
canOcclude = bs.canOcclude();
List<BakedQuad> quads = null;
for (Direction direction : DIRECTION_ORDER)
{
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().getBlockModel(bs).getQuads(bs, direction, random);
if (!quads.isEmpty() && !(bs.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP))
break;
};
if (quads == null || quads.isEmpty()) return NULL_BLOCK_DETAIL;
BlockDetailCache result = new BlockDetailCache(canOcclude, noCol, nonFull, quads.get(0),
bs.getBlock() instanceof FlowerBlock, bs.getBlock() instanceof LeavesBlock);
// ApiShared.LOGGER.info(bs.toString()+" = ["+result+"]");
return result;
}
}
BlockDetailCache(boolean isFullBlock, boolean noCol, boolean nonFull, BakedQuad quad, boolean useFlowerScaling, boolean useFastLeaf) {
requireResolving = quad.isTinted();
requireShade = quad.isShade();
tintIndex = quad.getTintIndex();
scaleFlowerColor = useFlowerScaling;
blockDetail = new BlockDetail(calculateColorFromTexture(quad.sprite, useFlowerScaling, useFastLeaf), isFullBlock, noCol, nonFull);
if (quad.isTinted()) biomeDetailMap = new ConcurrentHashMap<Biome, BlockDetail>();
}
BlockDetailCache(FluidState fluid) {
requireResolving = true; // TODO: Maybe in the future recheck that there really is no way to see if a fluid needs tinting
requireShade = false;
tintIndex = 0; // Vanilla doesn't use this index currently. (Checked at 1.18.X, See BlockColors.class)
scaleFlowerColor = false;
TextureAtlasSprite text = Minecraft.getInstance().getModelManager().getBlockModelShaper().getBlockModel(fluid.createLegacyBlock()).getParticleIcon();
blockDetail = new BlockDetail(calculateColorFromTexture(text, false, false), true, false, false);
biomeDetailMap = new ConcurrentHashMap<Biome, BlockDetail>();
}
private BlockDetailCache()
{
//DUMMY CREATOR
}
BlockDetail getResolvedBlockDetail(BlockState bs, int x, int y, int z, LevelReader getter) {
if (!requireResolving) return blockDetail;
BlockPos pos = new BlockPos(x,y,z);
Biome biome = getter.getBiome(pos);
BlockDetail tintDetail = biomeDetailMap.get(biome);
if (tintDetail == null) {
if (!bs.getFluidState().isEmpty()) bs = bs.getFluidState().createLegacyBlock();
BlockColors bc = Minecraft.getInstance().getBlockColors();
int tintColor = bc.getColor(bs, getter, pos, tintIndex);
tintColor = ColorUtil.multiplyARGBwithRGB(blockDetail.color, tintColor);
tintDetail = new BlockDetail(tintColor, blockDetail.isFullBlock,
blockDetail.hasNoCollision, blockDetail.hasOnlyNonFullFace);
BlockDetail tintDetailCAS = biomeDetailMap.putIfAbsent(biome, tintDetail);
if (tintDetailCAS != null) tintDetail = tintDetailCAS;
}
return tintDetail;
}
// Note: this one won't resolve biome based or pos based colors. (Kinda like GUI block icons)
BlockDetail getResolvedBlockDetail(BlockState bs) {
if (!requireResolving) return blockDetail;
if (defaultTintedDetail != null) return defaultTintedDetail;
BlockColors bc = Minecraft.getInstance().getBlockColors();
if (!bs.getFluidState().isEmpty()) bs = bs.getFluidState().createLegacyBlock();
int tintColor = bc.getColor(bs, null, null, tintIndex);
if (tintColor == -1) {
defaultTintedDetail = blockDetail;
}
else {
defaultTintedDetail = new BlockDetail(ColorUtil.multiplyARGBwithRGB(blockDetail.color, tintColor),
blockDetail.isFullBlock, blockDetail.hasNoCollision, blockDetail.hasOnlyNonFullFace);
}
return defaultTintedDetail;
}
@Override
public String toString() {
return "[BlockDetail: "+blockDetail+", RequireResolving: "+requireResolving+", requireShade: "+requireShade+", scaleFlowerColor: "+scaleFlowerColor+"]";
}
}
private static ConcurrentHashMap<BlockState, BlockDetailCache> map = new ConcurrentHashMap<BlockState, BlockDetailCache>();
private BlockDetailMap() {}
private static BlockDetailCache getOrMakeBlockDetailCache(BlockState bs, BlockPos pos, LevelReader getter) {
BlockDetailCache cache = map.get(bs);
if (cache != null) return cache;
if (bs.getFluidState().isEmpty()) {
cache = BlockDetailCache.make(bs, pos, getter);
} else {
cache = BlockDetailCache.make(bs.getFluidState().createLegacyBlock(), pos, getter);
}
BlockDetailCache cacheCAS = map.putIfAbsent(bs, cache);
return cacheCAS==null ? cache : cacheCAS;
}
// Return null means skip the block
public static BlockDetail getBlockDetail(BlockState bs) {
BlockDetailCache cache = getOrMakeBlockDetailCache(bs, new BlockPos(0, 0, 0), null);
if (cache == BlockDetailCache.NULL_BLOCK_DETAIL) return null;
return cache.getResolvedBlockDetail(bs);
}
// Return null means skip the block
public static BlockDetail getBlockDetailWithCompleteTint(BlockState bs, int x, int y, int z, LevelReader tintGetter) {
BlockDetailCache cache = getOrMakeBlockDetailCache(bs, new BlockPos(x,y,z), tintGetter);
if (cache == BlockDetailCache.NULL_BLOCK_DETAIL) return null;
return cache.getResolvedBlockDetail(bs, x, y, z, tintGetter);
}
}
@@ -1,158 +0,0 @@
package com.seibel.lod.common.wrappers.block;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockShapeWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.VoxelShape;
/**
* @author James Seibel
* @version 11-21-2021
*/
public class BlockShapeWrapper implements IBlockShapeWrapper
{
//set of block which require tint
public static final ConcurrentMap<Block, BlockShapeWrapper> blockShapeWrapperMap = new ConcurrentHashMap<>();
public static BlockShapeWrapper WATER_SHAPE = new BlockShapeWrapper();
private final Block block;
private final boolean toAvoid;
private boolean nonFull;
private boolean noCollision;
/**Constructor only require for the block instance we are wrapping**/
public BlockShapeWrapper(Block block, IChunkWrapper chunkWrapper, int x, int y, int z)
{
this.block = block;
this.nonFull = false;
this.noCollision = false;
this.toAvoid = ofBlockToAvoid();
setupShapes(chunkWrapper, x, y, z);
//System.out.println(block + " non full " + nonFull + " no collision " + noCollision + " to avoid " + toAvoid);
}
private BlockShapeWrapper()
{
this.block = Blocks.WATER;
this.nonFull = false;
this.noCollision = false;
this.toAvoid = false;
}
/**
* this return a wrapper of the block in input
* @param block Block object to wrap
*/
static public BlockShapeWrapper getBlockShapeWrapper(Block block, ChunkWrapper chunkWrapper, int x, int y, int z)
{
//first we check if the block has already been wrapped
if (blockShapeWrapperMap.containsKey(block) && blockShapeWrapperMap.get(block) != null)
return blockShapeWrapperMap.get(block);
//if it hasn't been created yet, we create it and save it in the map
BlockShapeWrapper blockWrapper = new BlockShapeWrapper(block, chunkWrapper, x, y, z);
blockShapeWrapperMap.put(block, blockWrapper);
//we return the newly created wrapper
return blockWrapper;
}
private void setupShapes(IChunkWrapper chunkWrapper, int x, int y, int z)
{
ChunkAccess chunk = ((ChunkWrapper) chunkWrapper).getChunk();
BlockPos blockPos = new BlockPos(x, y, z);
boolean noCollisionSetted = false;
boolean nonFullSetted = false;
if (!block.defaultBlockState().getFluidState().isEmpty())// || block instanceof SixWayBlock)
{
noCollisionSetted = true;
nonFullSetted = true;
noCollision = false;
nonFull = false;
}
if (!nonFullSetted)
{
VoxelShape voxelShape = block.defaultBlockState().getShape(chunk, blockPos);
if (!voxelShape.isEmpty())
{
AABB bbox = voxelShape.bounds();
double xWidth = (bbox.maxX - bbox.minX);
double yWidth = (bbox.maxY - bbox.minY);
double zWidth = (bbox.maxZ - bbox.minZ);
nonFull = xWidth < 1 && zWidth < 1 && yWidth < 1;
}
else
{
nonFull = false;
}
}
if (!noCollisionSetted)
{
VoxelShape collisionShape = block.defaultBlockState().getCollisionShape(chunk, blockPos);
noCollision = collisionShape.isEmpty();
}
}
@Override
public boolean ofBlockToAvoid()
{
return block.equals(Blocks.AIR)
|| block.equals(Blocks.CAVE_AIR)
|| block.equals(Blocks.BARRIER);
}
//-----------------//
//Avoidance getters//
//-----------------//
@Override
public boolean isNonFull()
{
return nonFull;
}
@Override
public boolean hasNoCollision()
{
return noCollision;
}
@Override
public boolean isToAvoid()
{
return toAvoid;
}
@Override public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof BlockShapeWrapper))
return false;
BlockShapeWrapper that = (BlockShapeWrapper) o;
return Objects.equals(block, that.block);
}
@Override public int hashCode()
{
return Objects.hash(block);
}
}
@@ -18,11 +18,7 @@ public class TextureAtlasSpriteWrapper {
* 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);
// Require access widener
return sprite.mainImage[0].getPixelRGBA(x + sprite.framesX[frameIndex] * sprite.getWidth(), y + sprite.framesY[frameIndex] * sprite.getHeight());
}
}
@@ -44,13 +44,12 @@ public class ChunkPosWrapper extends AbstractChunkPosWrapper
{
this.chunkPos = new ChunkPos(chunkX, chunkZ);
}
public ChunkPosWrapper(long l)
{
this.chunkPos = new ChunkPos(l);
}
public ChunkPosWrapper(ChunkPos pos)
{
this.chunkPos = pos;
@@ -86,13 +85,13 @@ public class ChunkPosWrapper extends AbstractChunkPosWrapper
@Override
public int getRegionX()
{
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, LodUtil.REGION_DETAIL_LEVEL);
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);
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.z, LodUtil.REGION_DETAIL_LEVEL);
}
public ChunkPos getChunkPos()
@@ -130,7 +129,7 @@ public class ChunkPosWrapper extends AbstractChunkPosWrapper
public AbstractBlockPosWrapper getWorldPosition()
{
// the parameter here is the y position
BlockPos blockPos = chunkPos.getMiddleBlockPosition(0);
BlockPos blockPos = chunkPos.getWorldPosition();
return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ());
}
@@ -1,28 +1,26 @@
package com.seibel.lod.common.wrappers.chunk;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockShapeWrapper;
import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail;
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.BlockColorWrapper;
import com.seibel.lod.common.wrappers.block.BlockShapeWrapper;
import com.seibel.lod.common.wrappers.block.BlockDetailMap;
import com.seibel.lod.common.wrappers.world.BiomeWrapper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.QuartPos;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.LiquidBlock;
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.LevelChunkSection;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.Heightmap;
/**
@@ -33,17 +31,17 @@ import net.minecraft.world.level.levelgen.Heightmap;
public class ChunkWrapper implements IChunkWrapper
{
private ChunkAccess chunk;
private BlockAndTintGetter lightSource;
private LevelReader lightSource;
@Override
public int getHeight(){
return chunk.getHeight();
return 255;
}
@Override
public int getMinBuildHeight()
{
return chunk.getMinBuildHeight();
return 0;
}
@Override
public int getMaxBuildHeight()
@@ -61,23 +59,13 @@ public class ChunkWrapper implements IChunkWrapper
public IBiomeWrapper getBiome(int x, int y, int z)
{
return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome(
QuartPos.fromBlock(x), QuartPos.fromBlock(y), QuartPos.fromBlock(z)));
x >> 2, y >> 2, z >> 2));
}
@Override
public IBlockColorWrapper getBlockColorWrapper(int x, int y, int z)
{
BlockState blockState = chunk.getBlockState(new BlockPos(x,y,z));
Block block = blockState.getBlock();
return BlockColorWrapper.getBlockColorWrapper(block);
}
@Override
public IBlockShapeWrapper getBlockShapeWrapper(int x, int y, int z)
{
BlockState blockState = chunk.getBlockState(new BlockPos(x,y,z));
Block block = blockState.getBlock();
return BlockShapeWrapper.getBlockShapeWrapper(block, this, x, y, z);
public BlockDetail getBlockDetail(int x, int y, int z) {
BlockState blockState = chunk.getBlockState(new BlockPos(x, y, z));
return BlockDetailMap.getBlockDetailWithCompleteTint(blockState, x, y, z, lightSource);
}
@Deprecated
@@ -86,8 +74,7 @@ public class ChunkWrapper implements IChunkWrapper
this.chunk = chunk;
this.lightSource = null;
}
public ChunkWrapper(ChunkAccess chunk, BlockAndTintGetter lightSource)
{
public ChunkWrapper(ChunkAccess chunk, LevelReader lightSource) {
this.chunk = chunk;
this.lightSource = lightSource;
}
@@ -108,12 +95,12 @@ public class ChunkWrapper implements IChunkWrapper
@Override
public int getRegionPosX(){
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, getChunkPosX(), LodUtil.REGION_DETAIL_LEVEL);
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, getChunkPosX(), LodUtil.REGION_DETAIL_LEVEL);
}
@Override
public int getRegionPosZ(){
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, getChunkPosZ(), LodUtil.REGION_DETAIL_LEVEL);
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, getChunkPosZ(), LodUtil.REGION_DETAIL_LEVEL);
}
@Override
@@ -138,15 +125,9 @@ public class ChunkWrapper implements IChunkWrapper
return chunk.getPos().getMinBlockZ();
}
@Override
public long getLongChunkPos() {
return chunk.getPos().toLong();
}
@Override
public boolean isLightCorrect(){
return true;
//return chunk.isLightCorrect();
return true;//chunk.isLightCorrect();
}
public boolean isWaterLogged(int x, int y, int z)
@@ -175,4 +156,22 @@ public class ChunkWrapper implements IChunkWrapper
if (lightSource == null) return -1;
return lightSource.getBrightness(LightLayer.SKY, new BlockPos(x, y, z));
}
@Override
public long getLongChunkPos() {
return chunk.getPos().toLong();
}
@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;
}
}
File diff suppressed because it is too large Load Diff
@@ -3,6 +3,7 @@ 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.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IMultiplayer;
import com.seibel.lod.common.Config;
/**
@@ -28,6 +29,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
{
public final IGraphics graphics;
public final IWorldGenerator worldGenerator;
public final IMultiplayer multiplayer;
public final IAdvanced advanced;
@@ -43,6 +45,11 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
return worldGenerator;
}
@Override
public IMultiplayer multiplayer() {
return multiplayer;
}
@Override
public IAdvanced advanced()
{
@@ -70,6 +77,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
{
graphics = new Graphics();
worldGenerator = new WorldGenerator();
multiplayer = new Multiplayer();
advanced = new Advanced();
}
@@ -177,7 +185,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
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;
@@ -261,6 +269,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.disableDirectionalCulling");
}
@Override
public VanillaOverdraw getVanillaOverdraw()
{
@@ -284,7 +293,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.backsideCullingRange").value = newBacksideCullingRange;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.backsideCullingRange");
}*/
@Override
public boolean getUseExtendedNearClipPlane()
{
@@ -332,20 +341,6 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
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()
{
@@ -360,7 +355,7 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
@Override
public boolean getEnableDistantGeneration()
{
return Config.Client.WorldGenerator.enableDistantGeneration;
return (boolean) ConfigGui.editSingleOption.getEntry("client.worldGenerator.enableDistantGeneration").value;
}
@Override
public void setEnableDistantGeneration(boolean newEnableDistantGeneration)
@@ -383,6 +378,27 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
//=====================//
// 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");
}
}
//============================//
// AdvancedModOptions Configs //
@@ -2,8 +2,9 @@ package com.seibel.lod.common.wrappers.config;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.ImageButton;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
@@ -11,9 +12,9 @@ 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, 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);
}
@@ -26,18 +27,20 @@ public class TexturedButtonWidget extends ImageButton {
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);
@Override
public void renderButton(PoseStack matrices, int mouseX, int mouseY, float delta) {
super.renderButton(matrices, mouseX, mouseY, delta);
}
Minecraft.getInstance().getTextureManager().bind(WIDGETS_LOCATION);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
int i = getYImage(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);
}
}
@@ -26,10 +26,11 @@ 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.api.ClientApi;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
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;
@@ -69,9 +70,9 @@ import org.jetbrains.annotations.Nullable;
* @author James Seibel
* @version 9-16-2021
*/
public class MinecraftWrapper implements IMinecraftWrapper
public class MinecraftClientWrapper implements IMinecraftClientWrapper
{
public static final MinecraftWrapper INSTANCE = new MinecraftWrapper();
public static final MinecraftClientWrapper INSTANCE = new MinecraftClientWrapper();
public final Minecraft mc = Minecraft.getInstance();
@@ -84,7 +85,7 @@ public class MinecraftWrapper implements IMinecraftWrapper
private ProfilerWrapper profilerWrapper;
private MinecraftWrapper()
private MinecraftClientWrapper()
{
}
@@ -240,8 +241,7 @@ public class MinecraftWrapper implements IMinecraftWrapper
@Override
public ChunkPosWrapper getPlayerChunkPos()
{
ChunkPos playerPos = getPlayer().chunkPosition();
return new ChunkPosWrapper(playerPos.x, playerPos.z);
return new ChunkPosWrapper(getPlayer().chunkPosition().x, getPlayer().chunkPosition().z);
}
public Options getOptions()
@@ -418,7 +418,7 @@ public class MinecraftWrapper implements IMinecraftWrapper
@Override
public void crashMinecraft(String errorMessage, Throwable exception)
{
ClientApi.LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
ApiShared.LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
CrashReport report = new CrashReport(errorMessage, exception);
Minecraft.crash(report);
}
@@ -5,17 +5,21 @@ import java.util.HashSet;
import java.util.stream.Collectors;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.lod.common.wrappers.WrapperFactory;
import com.seibel.lod.common.wrappers.misc.LightMapWrapper;
import com.seibel.lod.core.api.ModAccessorApi;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import it.unimi.dsi.fastutil.objects.ObjectList;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.world.phys.AABB;
import org.lwjgl.opengl.GL15;
import com.mojang.math.Vector3f;
import com.seibel.lod.core.objects.math.Mat4f;
@@ -24,22 +28,20 @@ import com.seibel.lod.core.objects.math.Vec3f;
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.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.tags.FluidTags;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.FogType;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
@@ -48,7 +50,7 @@ import net.minecraft.world.phys.Vec3;
* related to rendering in Minecraft.
*
* @author James Seibel
* @version 12-12-2021
* @version 12-14-2021
*/
public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
{
@@ -58,6 +60,8 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
private static final GameRenderer GAME_RENDERER = MC.gameRenderer;
private static final WrapperFactory FACTORY = WrapperFactory.INSTANCE;
@Override
public Vec3f getLookAtVector()
{
@@ -92,7 +96,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
@Override
public Mat4f getDefaultProjectionMatrix(float partialTicks)
{
return McObjectConverter.Convert(GAME_RENDERER.getProjectionMatrix(GAME_RENDERER.getFov(GAME_RENDERER.getMainCamera(), partialTicks, true)));
return McObjectConverter.Convert(GAME_RENDERER.getProjectionMatrix(GAME_RENDERER.getMainCamera(), partialTicks, true));
}
@Override
@@ -102,9 +106,9 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
}
@Override
public Color getFogColor(float partialTicks) {
FogRenderer.setupColor(GAME_RENDERER.getMainCamera(), partialTicks, MC.level, 1, GAME_RENDERER.getDarkenWorldAmount(partialTicks));
float[] colorValues = RenderSystem.getShaderFogColor();
public Color getFogColor(float partialTick) {
float[] colorValues = new float[4];
GL15.glGetFloatv(GL15.GL_FOG_COLOR, colorValues);
return new Color(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
}
// getSpecialFogColor() is the same as getFogColor()
@@ -147,61 +151,46 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
* is going to render this frame. <br><br>
* <p>
*/
public boolean usingBackupGetVanillaRenderedChunks = false;
@Override
public HashSet<AbstractChunkPosWrapper> getVanillaRenderedChunks()
{
ISodiumAccessor sodium = ModAccessorApi.get(ISodiumAccessor.class);
ISodiumAccessor sodium = ModAccessorHandler.get(ISodiumAccessor.class);
if (sodium != null)
{
return sodium.getNormalRenderedChunks();
}
IOptifineAccessor optifine = ModAccessorApi.get(IOptifineAccessor.class);
IOptifineAccessor optifine = ModAccessorHandler.get(IOptifineAccessor.class);
if (optifine != null)
{
HashSet<AbstractChunkPosWrapper> pos = optifine.getNormalRenderedChunks();
if (pos==null)
pos = getMaximumRenderedChunks();
if (pos==null) pos = getMaximumRenderedChunks();
return pos;
}
LevelRenderer levelRenderer = MC.levelRenderer;
ObjectArrayList<LevelRenderer.RenderChunkInfo> chunks = levelRenderer.renderChunks;
return (chunks.stream().map((chunk) -> {
AABB chunkBoundingBox = chunk.chunk.bb;
return FACTORY.createChunkPos(Math.floorDiv((int) chunkBoundingBox.minX, 16),
Math.floorDiv((int) chunkBoundingBox.minZ, 16));
}).collect(Collectors.toCollection(HashSet::new)));
if (!usingBackupGetVanillaRenderedChunks) {
try {
LevelRenderer levelRenderer = MC.levelRenderer;
ObjectList<LevelRenderer.RenderChunkInfo> chunks = levelRenderer.renderChunks;
return (chunks.stream().map((chunk) -> {
AABB chunkBoundingBox = chunk.chunk.bb;
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
public HashSet<AbstractChunkPosWrapper> getMaximumRenderedChunks()
{
//TODO: Make this a circle
IMinecraftWrapper mcWrapper = SingletonHandler.get(IMinecraftWrapper.class);
IWrapperFactory factory = SingletonHandler.get(IWrapperFactory.class);
int chunkRenderDist = this.getRenderDistance();
AbstractChunkPosWrapper centerChunkPos = mcWrapper.getPlayerChunkPos();
int startChunkX = centerChunkPos.getX() - chunkRenderDist;
int startChunkZ = centerChunkPos.getZ() - chunkRenderDist;
// add every position within render distance
HashSet<AbstractChunkPosWrapper> renderedPos = new HashSet<AbstractChunkPosWrapper>();
for (int chunkX = 0; chunkX < (chunkRenderDist * 2+1); chunkX++)
{
for(int chunkZ = 0; chunkZ < (chunkRenderDist * 2+1); chunkZ++)
{
renderedPos.add(factory.createChunkPos(startChunkX + chunkX, startChunkZ + chunkZ));
}
}
return renderedPos;
}
@Override
public int[] getLightmapPixels()
{
@@ -214,12 +203,12 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
int lightMapHeight = getLightmapTextureHeight();
int lightMapWidth = getLightmapTextureWidth();
int[] pixels = new int[lightMapWidth * lightMapHeight];
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 an int, but
// 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.
Color c = LodUtil.intToColor(lightMap.getLightValue(u, v));
@@ -235,10 +224,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
int col =
((c.getRed() & 0xFF) << 16) | // blue
((c.getGreen() & 0xFF) << 8) | // green
((c.getBlue() & 0xFF)) | // red
((c.getAlpha() & 0xFF) << 24); // alpha
((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;
@@ -303,13 +293,18 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
@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;
Camera camera = GAME_RENDERER.getMainCamera();
FogType fogType = camera.getFluidInCamera();
Entity entity = camera.getEntity();
boolean enableFog = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
enableFog |= fogType.equals(FogType.WATER);
enableFog |= fogType.equals(FogType.LAVA);
enableFog |= fogType.equals(FogType.POWDER_SNOW);
return enableFog;
}
@Override
@Override
public boolean tryDisableVanillaFog() {
return true; // Handled via MixinFogRenderer in both Fabric and Forge
return true; // Handled via the MixinFogRenderer at fabric and forge
}
}
@@ -23,11 +23,13 @@ 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 com.seibel.lod.core.enums.WorldType;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
@@ -37,7 +39,6 @@ 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.ChunkStatus;
import org.jetbrains.annotations.Nullable;
/**
@@ -128,24 +129,12 @@ public class WorldWrapper implements IWorldWrapper
return world.dimensionType().hasSkyLight();
}
@Override
public boolean isEmpty()
{
return world == null;
}
@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
@@ -175,11 +164,9 @@ public class WorldWrapper implements IWorldWrapper
}
@Override
public IChunkWrapper tryGetChunk(AbstractChunkPosWrapper pos) {
public ChunkWrapper tryGetChunk(AbstractChunkPosWrapper pos) {
ChunkAccess chunk = world.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
if (chunk == null) return null;
return new ChunkWrapper(chunk, world);
}
}
@@ -19,23 +19,24 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
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.objects.lod.LodDimension;
import com.seibel.lod.core.util.GridList;
import com.seibel.lod.core.util.LodThreadFactory;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper;
import java.io.IOException;
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;
@@ -57,10 +58,14 @@ 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.nbt.CompoundTag;
import net.minecraft.world.level.lighting.LevelLightEngine;
@@ -78,15 +83,14 @@ Feature Step: 0.389072425s
Lod Generation: 0.269023348s
*/
public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvionmentWrapper
{
public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnvionmentWrapper {
public static final boolean ENABLE_PERF_LOGGING = false;
public static final boolean ENABLE_EVENT_LOGGING = false;
public static final boolean ENABLE_LOAD_EVENT_LOGGING = false;
//TODO: Make actual proper support for StarLight
public static class PrefEvent
{
public static final boolean DISABLE_LOADING_SAVES = false;
// TODO: Make actual proper support for StarLight
public static class PrefEvent {
long beginNano = 0;
long emptyNano = 0;
long structStartNano = 0;
@@ -98,27 +102,20 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
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 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;
public static class PerfCalculator {
public static final int SIZE = 10;
private int dataCount = 0;
Rolling totalTime = new Rolling(SIZE);
Rolling emptyTime = new Rolling(SIZE);
Rolling structStartTime = new Rolling(SIZE);
@@ -130,65 +127,56 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
Rolling featureTime = new Rolling(SIZE);
Rolling lightTime = new Rolling(SIZE);
Rolling lodTime = new Rolling(SIZE);
public void recordEvent(PrefEvent e)
{
public void recordEvent(PrefEvent e) {
dataCount++;
long preTime = e.beginNano;
totalTime.add(e.endNano - preTime);
if (e.emptyNano != 0)
{
if (e.emptyNano != 0) {
emptyTime.add(e.emptyNano - preTime);
preTime = e.emptyNano;
}
if (e.structStartNano != 0)
{
if (e.structStartNano != 0) {
structStartTime.add(e.structStartNano - preTime);
preTime = e.structStartNano;
}
if (e.structRefNano != 0)
{
if (e.structRefNano != 0) {
structRefTime.add(e.structRefNano - preTime);
preTime = e.structRefNano;
}
if (e.biomeNano != 0)
{
if (e.biomeNano != 0) {
biomeTime.add(e.biomeNano - preTime);
preTime = e.biomeNano;
}
if (e.noiseNano != 0)
{
if (e.noiseNano != 0) {
noiseTime.add(e.noiseNano - preTime);
preTime = e.noiseNano;
}
if (e.surfaceNano != 0)
{
if (e.surfaceNano != 0) {
surfaceTime.add(e.surfaceNano - preTime);
preTime = e.surfaceNano;
}
if (e.carverNano != 0)
{
if (e.carverNano != 0) {
carverTime.add(e.carverNano - preTime);
preTime = e.carverNano;
}
if (e.featureNano != 0)
{
if (e.featureNano != 0) {
featureTime.add(e.featureNano - preTime);
preTime = e.featureNano;
}
if (e.lightNano != 0)
{
if (e.lightNano != 0) {
lightTime.add(e.lightNano - preTime);
preTime = e.lightNano;
}
if (e.endNano != 0)
{
if (e.endNano != 0) {
lodTime.add(e.endNano - preTime);
preTime = e.endNano;
}
}
public String toString()
{
public String toString() {
if (dataCount < SIZE)
return "Pref Calculator collecting samples...";
return "Total: " + Duration.ofNanos((long) totalTime.getAverage()) + ", Empty/LoadChunk: "
+ Duration.ofNanos((long) emptyTime.getAverage()) + ", StructStart: "
+ Duration.ofNanos((long) structStartTime.getAverage()) + ", StructRef: "
@@ -202,41 +190,56 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
+ Duration.ofNanos((long) lodTime.getAverage());
}
}
public static final int TIMEOUT_SECONDS = 30;
//=================Generation Step===================
public static final int TIMEOUT_SECONDS = 60;
// =================Generation Step===================
public final LinkedList<GenerationEvent> events = new LinkedList<GenerationEvent>();
public final GlobalParameters params;
public final StepStructureStart stepStructureStart = new StepStructureStart(this);
public final StepStructureReference stepStructureReference = new StepStructureReference(this);
public final StepStructureReference stepStructureReference = new StepStructureReference();
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);
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public boolean unsafeThreadingRecorded = false;
static private final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
public static final long EXCEPTION_TIMER_RESET_TIME = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
public static final int EXCEPTION_COUNTER_TRIGGER = 20;
public int unknownExceptionCount = 0;
public long lastExceptionTriggerTime = 0;
public static final LodThreadFactory threadFactory = new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY);
public ExecutorService executors = Executors.newFixedThreadPool(
CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads(), threadFactory);
public void resizeThreadPool(int newThreadCount)
{
public <T> T joinSync(CompletableFuture<T> f) {
if (!unsafeThreadingRecorded && !f.isDone()) {
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons: Unsafe Threading in Chunk Generator Detected!");
MC.sendChatMessage("\u00A7eTo increase stability, it is recommended to set world generation threads count to 1.");
ApiShared.LOGGER.error("Unsafe Threading in Chunk Generator: ", new RuntimeException("Concurrent future"));
unsafeThreadingRecorded = true;
}
return f.join();
}
@Override
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)
{
@Override
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)
{
for (GenerationEvent event : events) {
if (event.tooClose(x, z, range))
return false;
}
@@ -244,155 +247,142 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
events.add(new GenerationEvent(new ChunkPos(x, z), range, this, target, genAllDetails));
return true;
}
public void updateAllFutures()
{
@Override
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())
{
while (iter.hasNext()) {
GenerationEvent event = iter.next();
if (event.isCompleted())
{
try
{
if (event.isCompleted()) {
try {
event.join();
}
catch (Throwable e)
{
e.printStackTrace();
while (e.getCause() != null)
{
e = e.getCause();
e.printStackTrace();
}
}
finally
{
} catch (Throwable e) {
ApiShared.LOGGER.error("Batching World Generator: Event {} gotten an exception", event);
ApiShared.LOGGER.error("Exception: ", e);
unknownExceptionCount++;
lastExceptionTriggerTime = System.nanoTime();
} finally {
iter.remove();
}
}
else if (event.hasTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS))
{
ClientApi.LOGGER.error("Batching World Generator: " + event + " timed out and terminated!");
ClientApi.LOGGER.info("Dump PrefEvent: " + event.pEvent);
try
{
} else if (event.hasTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
ApiShared.LOGGER.error("Batching World Generator: " + event + " timed out and terminated!");
ApiShared.LOGGER.info("Dump PrefEvent: " + event.pEvent);
try {
if (!event.terminate())
ClientApi.LOGGER.error("Failed to terminate the stuck generation event!");
}
finally
{
ApiShared.LOGGER.error("Failed to terminate the stuck generation event!");
} finally {
iter.remove();
}
}
}
if (unknownExceptionCount > EXCEPTION_COUNTER_TRIGGER) {
try {
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons: Too many exceptions in Batching World Generator! Disabling the generator.");
} catch (Exception e) {}
ApiShared.LOGGER.error("Too many exceptions in Batching World Generator! Now disabling.");
unknownExceptionCount = 0;
CONFIG.client().worldGenerator().setEnableDistantGeneration(false);
}
}
public BatchGenerationEnvironment(IWorldWrapper serverlevel, LodBuilder lodBuilder, LodDimension lodDim)
{
public BatchGenerationEnvironment(IWorldWrapper serverlevel, LodBuilder lodBuilder, LodDimension lodDim) {
super(serverlevel, lodBuilder, lodDim);
ClientApi.LOGGER.info("================WORLD_GEN_STEP_INITING=============");
ApiShared.LOGGER.info("================WORLD_GEN_STEP_INITING=============");
ChunkGenerator generator = ((WorldWrapper) serverlevel).getServerWorld().getChunkSource().getGenerator();
if (!(generator instanceof NoiseBasedChunkGenerator ||
generator instanceof DebugLevelSource ||
generator instanceof FlatLevelSource)) {
MC.sendChatMessage("\u00A74\u00A7l\u00A7uWARNING: Distant Horizons: Unknown Chunk Generator Detected! Distant Generation May Fail!");
MC.sendChatMessage("\u00A7eIf it does crash, set Distant Generation to OFF or Generation Mode to None.");
ApiShared.LOGGER.warn("Unknown Chunk Generator detected: {}", generator.getClass());
}
params = new GlobalParameters((ServerLevel) ((WorldWrapper) serverlevel).getWorld(), lodBuilder, lodDim);
}
public void startLoadingAllRegionsFromFile(LodDimension lodDim)
{
ServerLevel level = params.level;
level.getChunkSource();
}
@SuppressWarnings("resource")
public static ChunkAccess loadOrMakeChunk(ChunkPos chunkPos, ServerLevel level, LevelLightEngine lightEngine)
{
private static ChunkAccess loadOrMakeChunk(ChunkPos chunkPos, ServerLevel level, LevelLightEngine lightEngine) {
if (DISABLE_LOADING_SAVES) {
return new ProtoChunk(chunkPos, UpgradeData.EMPTY);
}
CompoundTag chunkData = null;
try
{
try {
chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos);
} catch (Exception e) {
ApiShared.LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
}
catch (IOException e)
{
ClientApi.LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
if (chunkData == null) {
return new ProtoChunk(chunkPos, UpgradeData.EMPTY);
} else {
try {
return ChunkLoader.read(level, lightEngine, chunkPos, chunkData);
} catch (Exception e) {
ApiShared.LOGGER.error("DistantHorizons: Couldn't load chunk {}", chunkPos, e);
return new ProtoChunk(chunkPos, UpgradeData.EMPTY);
}
}
if (chunkData == null)
{
return new ProtoChunk(chunkPos, UpgradeData.EMPTY, level);
}
else
{
return ChunkLoader.read(level, lightEngine, chunkPos, chunkData);
}
}
public void generateLodFromList(GenerationEvent e)
{
void generateLodFromList(GenerationEvent e) {
if (ENABLE_EVENT_LOGGING)
ClientApi.LOGGER.info("Lod Generate Event: " + e.pos);
ApiShared.LOGGER.info("Lod Generate Event: " + e.pos);
e.pEvent.beginNano = System.nanoTime();
GridList<ChunkAccess> referencedChunks;
DistanceGenerationMode generationMode;
LightedWorldGenRegion region;
WorldGenLevelLightEngine lightEngine;
LightGetterAdaptor adaptor;
try
{
try {
adaptor = new LightGetterAdaptor(params.level);
lightEngine = new WorldGenLevelLightEngine(adaptor);
int cx = e.pos.x;
int cy = e.pos.z;
int rangeEmpty = e.range + 1;
GridList<ChunkAccess> chunks = new GridList<ChunkAccess>(rangeEmpty);
@SuppressWarnings("resource")
EmptyChunkGenerator generator = (int x, int z) ->
{
EmptyChunkGenerator generator = (int x, int z) -> {
ChunkPos chunkPos = new ChunkPos(x, z);
ChunkAccess target = null;
try
{
try {
target = loadOrMakeChunk(chunkPos, params.level, lightEngine);
}
catch (RuntimeException e2)
{
} catch (RuntimeException e2) {
// Continue...
e2.printStackTrace();
}
if (target == null)
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY, params.level);
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY);
return target;
};
for (int oy = -rangeEmpty; oy <= rangeEmpty; oy++)
{
for (int ox = -rangeEmpty; ox <= rangeEmpty; ox++)
{
for (int oy = -rangeEmpty; oy <= rangeEmpty; oy++) {
for (int ox = -rangeEmpty; ox <= rangeEmpty; ox++) {
ChunkAccess target = generator.generate(cx + ox, cy + oy);
chunks.add(target);
}
}
e.pEvent.emptyNano = System.nanoTime();
e.refreshTimeout();
region = new LightedWorldGenRegion(params.level, lightEngine, e.tParam.structFeat, chunks, ChunkStatus.STRUCTURE_STARTS, rangeEmpty, e.lightMode, generator);
region = new LightedWorldGenRegion(params.level, lightEngine, e.tParam.structFeat, chunks,
ChunkStatus.STRUCTURE_STARTS, rangeEmpty, e.lightMode, generator);
adaptor.setRegion(region);
e.tParam.makeStructFeat(region);
referencedChunks = chunks.subGrid(e.range);
referencedChunks = generateDirect(e, referencedChunks, e.target, region);
}
catch (StepStructureStart.StructStartCorruptedException f)
{
} catch (StructStartCorruptedException f) {
e.tParam.markAsInvalid();
return;
}
switch (e.target)
{
switch (e.target) {
case Empty:
case StructureStart:
case StructureReference:
@@ -400,6 +390,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
break;
case Biomes:
generationMode = DistanceGenerationMode.BIOME_ONLY;
break;
case Noise:
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
break;
@@ -416,62 +407,43 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
return;
}
int centreIndex = referencedChunks.size() / 2;
for (int oy = -e.range; oy <= e.range; oy++)
{
for (int ox = -e.range; ox <= e.range; ox++)
{
for (int oy = -e.range; oy <= e.range; oy++) {
for (int ox = -e.range; ox <= e.range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkAccess target = referencedChunks.get(targetIndex);
target.setLightCorrect(true);
//if (target instanceof LevelChunk)
// ((LevelChunk) target).setClientLightReady(true);
boolean isFull = target.getStatus() == ChunkStatus.FULL || target instanceof LevelChunk;
//boolean isPartial = target.isOldNoiseGeneration();
if (isFull)
{
if (isFull) {
if (ENABLE_LOAD_EVENT_LOGGING)
ClientApi.LOGGER.info("Detected full existing chunk at {}", target.getPos());
ApiShared.LOGGER.info("Detected full existing chunk at {}", target.getPos());
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target, region),
new LodBuilderConfig(DistanceGenerationMode.FULL), true, e.genAllDetails);
}
else if (target.getStatus() == ChunkStatus.EMPTY && generationMode == DistanceGenerationMode.NONE)
{
} else if (target.getStatus() == ChunkStatus.EMPTY && generationMode == DistanceGenerationMode.NONE) {
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target, region),
LodBuilderConfig.getFillVoidConfig(), true, e.genAllDetails);
}
else
{
} else {
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target, region),
new LodBuilderConfig(generationMode), true, e.genAllDetails);
}
if (e.lightMode == LightGenerationMode.FANCY || isFull)
{
lightEngine.retainData(target.getPos(), false);
}
lightEngine.retainData(target.getPos(), false);
}
}
e.pEvent.endNano = System.nanoTime();
e.refreshTimeout();
if (ENABLE_PERF_LOGGING)
{
if (ENABLE_PERF_LOGGING) {
e.tParam.perf.recordEvent(e.pEvent);
ClientApi.LOGGER.info(e.tParam.perf);
ApiShared.LOGGER.info(e.tParam.perf);
}
}
public GridList<ChunkAccess> generateDirect(GenerationEvent e, GridList<ChunkAccess> subRange, Steps step,
LightedWorldGenRegion region)
{
try
{
subRange.forEach((chunk) ->
{
if (chunk instanceof ProtoChunk)
{
GridList<ChunkAccess> generateDirect(GenerationEvent e, GridList<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);
//region.getLightEngine().retainData(chunk.getPos(), true);
}
});
if (step == Steps.Empty)
@@ -507,17 +479,13 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
e.pEvent.featureNano = System.nanoTime();
e.refreshTimeout();
return subRange;
}
finally
{
switch (region.lightMode)
{
} finally {
switch (region.lightMode) {
case FANCY:
stepLight.generateGroup(region.getLightEngine(), subRange);
break;
case FAST:
subRange.forEach((p) ->
{
subRange.forEach((p) -> {
if (p instanceof ProtoChunk)
((ProtoChunk) p).setLightCorrect(true);
});
@@ -527,9 +495,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
e.refreshTimeout();
}
}
public interface EmptyChunkGenerator
{
public interface EmptyChunkGenerator {
ChunkAccess generate(int x, int z);
}
@@ -540,14 +507,16 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
@Override
public void stop(boolean blocking) {
ClientApi.LOGGER.info("Batch Chunk Generator shutting down...");
ApiShared.LOGGER.info("Batch Chunk Generator shutting down...");
executors.shutdownNow();
if (blocking) try {
if (!executors.awaitTermination(10, TimeUnit.SECONDS)) {
ClientApi.LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...");
if (blocking) {
try {
if (!executors.awaitTermination(10, TimeUnit.SECONDS)) {
ApiShared.LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...");
}
} catch (InterruptedException e) {
ApiShared.LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...", e);
}
} catch (InterruptedException e) {
ClientApi.LOGGER.error("Batch Chunk Generator shutdown failed! Ignoring child threads...", e);
}
}
}
}
@@ -1,4 +1,3 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import java.util.concurrent.ExecutionException;
@@ -6,19 +5,19 @@ 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.api.ClientApi;
import com.seibel.lod.core.enums.config.LightGenerationMode;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
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
{
public final class GenerationEvent {
static private final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static int generationFutureDebugIDs = 0;
final ThreadedParameters tParam;
final ChunkPos pos;
@@ -30,9 +29,8 @@ public final class GenerationEvent
final LightGenerationMode lightMode;
final PrefEvent pEvent = new PrefEvent();
final boolean genAllDetails;
public GenerationEvent(ChunkPos pos, int range, BatchGenerationEnvironment generationGroup, Steps target, boolean genAllDetails)
{
public GenerationEvent(ChunkPos pos, int range, BatchGenerationEnvironment generationGroup, Steps target, boolean genAllDetails) {
nanotime = System.nanoTime();
this.pos = pos;
this.range = range;
@@ -40,65 +38,54 @@ public final class GenerationEvent
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(() ->
{
future = generationGroup.executors.submit(() -> {
generationGroup.generateLodFromList(this);
});
}
public boolean isCompleted()
{
public boolean isCompleted() {
return future.isDone();
}
public boolean hasTimeout(int duration, TimeUnit unit)
{
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()
{
public boolean terminate() {
future.cancel(true);
ClientApi.LOGGER.info("======================DUMPING ALL THREADS FOR WORLD GEN=======================");
ApiShared.LOGGER.info("======================DUMPING ALL THREADS FOR WORLD GEN=======================");
BatchGenerationEnvironment.threadFactory.dumpAllThreadStacks();
return future.isCancelled();
}
public void join()
{
try
{
public void join() {
try {
future.get();
}
catch (InterruptedException | ExecutionException e)
{
e.printStackTrace();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getCause()==null? e : e.getCause());
}
}
public boolean tooClose(int cx, int cz, int cr)
{
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()
{
public void refreshTimeout() {
nanotime = System.nanoTime();
}
@Override
public String toString()
{
public String toString() {
return id + ":" + range + "@" + pos + "(" + target + ")";
}
}
@@ -1,4 +1,3 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import com.mojang.datafixers.DataFixer;
@@ -16,11 +15,9 @@ 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 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;
@@ -30,9 +27,8 @@ public final class GlobalParameters
public final long worldSeed;
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)
{
public GlobalParameters(ServerLevel level, LodBuilder lodBuilder, LodDimension lodDim) {
this.lodBuilder = lodBuilder;
this.lodDim = lodDim;
this.level = level;
@@ -43,7 +39,8 @@ public final class GlobalParameters
registry = server.registryAccess();
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
worldSeed = worldGenSettings.seed();
//biomeManager = new BiomeManager(level, BiomeManager.obfuscateSeed(worldSeed));
// biomeManager = new BiomeManager(level,
// BiomeManager.obfuscateSeed(worldSeed));
structures = server.getStructureManager();
generator = level.getChunkSource().getGenerator();
fixerUpper = server.getFixerUpper();
@@ -1,34 +1,29 @@
package com.seibel.lod.common.wrappers.worldGeneration;
//FIXME: Move this outside the WorldGenerationStep thingy
public class Rolling
{
public class Rolling {
private final int size;
private double total = 0d;
private int index = 0;
private final double[] samples;
public Rolling(int size)
{
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)
{
public void add(double x) {
total -= samples[index];
samples[index] = x;
total += x;
if (++index == size)
index = 0; // cheaper than modulus
}
public double getAverage()
{
public double getAverage() {
return total / size;
}
}
@@ -0,0 +1,11 @@
package com.seibel.lod.common.wrappers.worldGeneration;
public class StructStartCorruptedException extends RuntimeException {
private static final long serialVersionUID = -8987434342051563358L;
public StructStartCorruptedException(ArrayIndexOutOfBoundsException e) {
super("StructStartCorruptedException");
super.initCause(e);
fillInStackTrace();
}
}
@@ -1,4 +1,3 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.PerfCalculator;
@@ -8,16 +7,14 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.levelgen.WorldGenSettings;
public final class ThreadedParameters
{
public final class ThreadedParameters {
private static final ThreadLocal<ThreadedParameters> localParam = new ThreadLocal<ThreadedParameters>();
final ServerLevel level;
public final WorldGenStructFeatManager structFeat;
boolean isValid = true;
public final PerfCalculator perf = new PerfCalculator();
public static ThreadedParameters getOrMake(GlobalParameters param)
{
public static ThreadedParameters getOrMake(GlobalParameters param) {
ThreadedParameters tParam = localParam.get();
if (tParam != null && tParam.isValid && tParam.level == param.level)
return tParam;
@@ -25,20 +22,17 @@ public final class ThreadedParameters
localParam.set(tParam);
return tParam;
}
public void markAsInvalid()
{
public void markAsInvalid() {
isValid = false;
}
private ThreadedParameters(GlobalParameters param)
{
private ThreadedParameters(GlobalParameters param) {
level = param.level;
structFeat = new WorldGenStructFeatManager(level, param.worldGenSettings, null);
}
public void makeStructFeat(WorldGenLevel genLevel)
{
public void makeStructFeat(WorldGenLevel genLevel) {
structFeat.setGenLevel(genLevel);
}
}
@@ -1,10 +1,12 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import java.util.concurrent.ExecutionException;
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.objects.lod.LodDimension;
//import com.seibel.lod.core.util.SingletonHandler;
//import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
//import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
@@ -12,141 +14,131 @@ import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractWorldGenera
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import com.seibel.lod.common.wrappers.world.WorldWrapper;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.*;
/**
* @author James Seibel
* @version 11-13-2021
*/
public class WorldGeneratorWrapper extends AbstractWorldGeneratorWrapper
{
public final ServerLevel serverWorld;
public final LodDimension lodDim;
public final LodBuilder lodBuilder;
public class WorldGeneratorWrapper extends AbstractWorldGeneratorWrapper {
public final ServerLevel serverWorld;
public final LodDimension lodDim;
public final LodBuilder lodBuilder;
public WorldGeneratorWrapper(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper)
{
super(newLodBuilder, newLodDimension, worldWrapper);
public WorldGeneratorWrapper(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper) {
super(newLodBuilder, newLodDimension, worldWrapper);
lodBuilder = newLodBuilder;
lodDim = newLodDimension;
serverWorld = ((WorldWrapper) worldWrapper).getServerWorld();
}
lodBuilder = newLodBuilder;
lodDim = newLodDimension;
serverWorld = ((WorldWrapper) worldWrapper).getServerWorld();
}
/** takes about 2-5 ms */
@Override
public void generateBiomesOnly(AbstractChunkPosWrapper pos, DistanceGenerationMode generationMode) {
generate(pos.getX(), pos.getZ(), generationMode);
}
/** takes about 2-5 ms */
@Override
public void generateBiomesOnly(AbstractChunkPosWrapper pos, DistanceGenerationMode generationMode)
{
generate(pos.getX(), pos.getZ(), generationMode);
}
/** takes about 10 - 20 ms */
@Override
public void generateSurface(AbstractChunkPosWrapper pos) {
generate(pos.getX(), pos.getZ(), DistanceGenerationMode.SURFACE);
}
/**
* takes about 15 - 20 ms
* <p>
*/
@Override
public void generateFeatures(AbstractChunkPosWrapper pos) {
generate(pos.getX(), pos.getZ(), DistanceGenerationMode.FEATURES);
}
/** takes about 10 - 20 ms */
@Override
public void generateSurface(AbstractChunkPosWrapper pos)
{
generate(pos.getX(), pos.getZ(), DistanceGenerationMode.SURFACE);
}
/**
* Generates using MC's ServerWorld.
* <p>
* on pre generated chunks 0 - 1 ms <br>
* on un generated chunks 0 - 50 ms <br>
* with the median seeming to hover around 15 - 30 ms <br>
* and outliers in the 100 - 200 ms range <br>
* <p>
* Note this should not be multithreaded and does cause server/simulation lag
* (Higher lag for generating than loading)
*/
@Override
public void generateFull(AbstractChunkPosWrapper pos) {
generate(pos.getX(), pos.getZ(), DistanceGenerationMode.FULL);
}
/**
* takes about 15 - 20 ms
* <p>
*/
@Override
public void generateFeatures(AbstractChunkPosWrapper pos)
{
generate(pos.getX(), pos.getZ(), DistanceGenerationMode.FEATURES);
}
/**
* Generates using MC's ServerWorld.
* <p>
* on pre generated chunks 0 - 1 ms <br>
* on un generated chunks 0 - 50 ms <br>
* with the median seeming to hover around 15 - 30 ms <br>
* and outliers in the 100 - 200 ms range <br>
* <p>
* Note this should not be multithreaded and does cause server/simulation lag
* (Higher lag for generating than loading)
*/
@Override
public void generateFull(AbstractChunkPosWrapper pos)
{
generate(pos.getX(), pos.getZ(), DistanceGenerationMode.FULL);
}
private void generate(int chunkX, int chunkZ, DistanceGenerationMode generationMode) {
private void generate(int chunkX, int chunkZ, DistanceGenerationMode generationMode) {
// long t = System.nanoTime();
ChunkStatus targetStatus;
switch (generationMode) {
case BIOME_ONLY:
targetStatus = ChunkStatus.BIOMES;
break;
case BIOME_ONLY_SIMULATE_HEIGHT:
targetStatus = ChunkStatus.NOISE;
break;
case SURFACE:
targetStatus = ChunkStatus.SURFACE;
break;
case FEATURES:
targetStatus = ChunkStatus.FEATURES;
break;
case FULL:
targetStatus = ChunkStatus.FULL;
break;
ChunkStatus targetStatus;
switch (generationMode) {
case NONE:
return;
case BIOME_ONLY:
targetStatus = ChunkStatus.BIOMES;
break;
case BIOME_ONLY_SIMULATE_HEIGHT:
targetStatus = ChunkStatus.NOISE;
break;
case SURFACE:
targetStatus = ChunkStatus.SURFACE;
break;
case FEATURES:
targetStatus = ChunkStatus.FEATURES;
break;
case FULL:
targetStatus = ChunkStatus.FULL;
break;
default:
return;
}
return;
}
// The bool=true means that we want to generate chunk, and that the returned ChunkAccess must not be null
// The bool=true means that we wants to generate chunk, and that the returned
// ChunkAccess must not be null
ChunkAccess ca = serverWorld.getChunkSource().getChunk(chunkX, chunkZ, targetStatus, true);
if (ca == null) throw new RuntimeException("This should NEVER be null due to bool being true");
lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(ca, serverWorld), new LodBuilderConfig(generationMode), false, true);
ChunkAccess ca = serverWorld.getChunkSource().getChunk(chunkX, chunkZ, targetStatus, true);
if (ca == null)
throw new RuntimeException("This should NEVER be null due to bool being true");
lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(ca, serverWorld),
new LodBuilderConfig(generationMode), false, true);
// long duration = System.nanoTime()-t;
// long duration = System.nanoTime()-t;
// Debug print the duration
// System.out.println("LodChunkGenFull["+chunkX+","+chunkZ+"]: "+(double)(duration)/1000.);
}
// Debug print the duration
// System.out.println("LodChunkGenFull["+chunkX+","+chunkZ+"]:
// "+(double)(duration)/1000.);
}
/* TODO: Ask leetom to update chart
* performance/generation tests related to
/*
* TODO: Ask leetom to update chart performance/generation tests related to
* serverWorld.getChunk(x, z, ChunkStatus. *** )
true/false is whether they generated blocks or not
the time is how long it took to generate
ChunkStatus.EMPTY 0 - 1 ms false (empty, what did you expect? :P)
ChunkStatus.STRUCTURE_REFERENCES 1 - 2 ms false (no height, only generates some chunks)
ChunkStatus.BIOMES 1 - 10 ms false (no height)
ChunkStatus.NOISE 4 - 15 ms true (all blocks are stone)
ChunkStatus.LIQUID_CARVERS 6 - 12 ms true (no snow/trees, just grass)
ChunkStatus.SURFACE 5 - 15 ms true (no snow/trees, just grass)
ChunkStatus.CARVERS 5 - 30 ms true (no snow/trees, just grass)
ChunkStatus.FEATURES 7 - 25 ms true
ChunkStatus.HEIGHTMAPS 20 - 40 ms true
ChunkStatus.LIGHT 20 - 40 ms true
ChunkStatus.FULL 30 - 50 ms true
ChunkStatus.SPAWN 50 - 80 ms true
At this point I would suggest using FEATURES, as it generates snow and trees
(and any other object that are needed to make biomes distinct)
Otherwise, if snow/trees aren't necessary SURFACE is the next fastest (although not by much)
*
* true/false is whether they generated blocks or not the time is how long it
* took to generate
*
* ChunkStatus.EMPTY 0 - 1 ms false (empty, what did you expect? :P)
* ChunkStatus.STRUCTURE_REFERENCES 1 - 2 ms false (no height, only generates
* some chunks) ChunkStatus.BIOMES 1 - 10 ms false (no height) ChunkStatus.NOISE
* 4 - 15 ms true (all blocks are stone) ChunkStatus.LIQUID_CARVERS 6 - 12 ms
* true (no snow/trees, just grass) ChunkStatus.SURFACE 5 - 15 ms true (no
* snow/trees, just grass) ChunkStatus.CARVERS 5 - 30 ms true (no snow/trees,
* just grass) ChunkStatus.FEATURES 7 - 25 ms true ChunkStatus.HEIGHTMAPS 20 -
* 40 ms true ChunkStatus.LIGHT 20 - 40 ms true ChunkStatus.FULL 30 - 50 ms true
* ChunkStatus.SPAWN 50 - 80 ms true
*
*
* At this point I would suggest using FEATURES, as it generates snow and trees
* (and any other object that are needed to make biomes distinct)
*
* Otherwise, if snow/trees aren't necessary SURFACE is the next fastest
* (although not by much)
*/
}
@@ -1,6 +1,7 @@
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
import java.util.Objects;
@@ -16,6 +17,7 @@ import net.minecraft.world.level.TickList;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.LevelChunk;
@@ -30,14 +32,13 @@ import net.minecraft.world.level.material.Fluids;
import org.apache.logging.log4j.Logger;
public class ChunkLoader {
private static final Logger LOGGER = ClientApi.LOGGER;
private static final Logger LOGGER = ApiShared.LOGGER;
private static LevelChunkSection[] readSections(WorldGenLevel level, LevelLightEngine lightEngine,
ChunkPos chunkPos, CompoundTag tagLevel) {
boolean isLightOn = tagLevel.getBoolean("isLightOn");
ListTag listTag = tagLevel.getList("Sections", 10);
int i = level.getSectionsCount();
LevelChunkSection[] levelChunkSections = new LevelChunkSection[i];
LevelChunkSection[] levelChunkSections = new LevelChunkSection[16];
boolean bl2 = level.getLevel().dimensionType().hasSkyLight();
if (isLightOn)
lightEngine.retainData(chunkPos, true);
@@ -50,7 +51,7 @@ public class ChunkLoader {
compoundTag3.getLongArray("BlockStates"));
levelChunkSection.recalcBlockCounts();
if (!levelChunkSection.isEmpty())
levelChunkSections[level.getSectionIndexFromSectionY(k)] = levelChunkSection;
levelChunkSections[k] = levelChunkSection;
}
if (isLightOn) {
if (compoundTag3.contains("BlockLight", 7))
@@ -109,24 +110,25 @@ public class ChunkLoader {
// ====================== Read params for making the LevelChunk
// ============================
ChunkBiomeContainer chunkBiomeContainer = new ChunkBiomeContainer(
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), level, chunkPos,
level.getLevel().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), chunkPos,
level.getLevel().getChunkSource().getGenerator().getBiomeSource(),
tagLevel.contains("Biomes", 11) ? tagLevel.getIntArray("Biomes") : null);
UpgradeData upgradeData = tagLevel.contains("UpgradeData", 10)
? new UpgradeData(tagLevel.getCompound("UpgradeData"), level)
? new UpgradeData(tagLevel.getCompound("UpgradeData"))
: UpgradeData.EMPTY;
TickList<Block> blockTicks = tagLevel.contains("TileTicks", 9)
? ChunkTickList.create(tagLevel.getList("TileTicks", 10), Registry.BLOCK::getKey, Registry.BLOCK::get)
: new ProtoTickList<Block>(block -> (block == null || block.defaultBlockState().isAir()), chunkPos,
tagLevel.getList("ToBeTicked", 9), level);
tagLevel.getList("ToBeTicked", 9));
TickList<Fluid> liquidTicks = tagLevel.contains("LiquidTicks", 9)
? ChunkTickList.create(tagLevel.getList("LiquidTicks", 10), Registry.FLUID::getKey, Registry.FLUID::get)
: new ProtoTickList<Fluid>(fluid -> (fluid == null || fluid == Fluids.EMPTY), chunkPos,
tagLevel.getList("LiquidsToBeTicked", 9), level);
tagLevel.getList("LiquidsToBeTicked", 9));
long inhabitedTime = tagLevel.getLong("InhabitedTime");
@@ -1,10 +1,9 @@
package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
import com.seibel.lod.core.api.ModAccessorApi;
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;
@@ -15,7 +14,7 @@ public class LightGetterAdaptor implements LightChunkGetter {
public LightGetterAdaptor(BlockGetter heightAccessor) {
this.heightGetter = heightAccessor;
shouldReturnNull = ModAccessorApi.get(IStarlightAccessor.class) != null;
shouldReturnNull = ModAccessorHandler.get(IStarlightAccessor.class) != null;
}
public void setRegion(LightedWorldGenRegion region) {
@@ -34,7 +33,4 @@ public class LightGetterAdaptor implements LightChunkGetter {
public BlockGetter getLevel() {
return shouldReturnNull ? null : (genRegion != null ? genRegion : heightGetter);
}
public LevelHeightAccessor getLevelHeightAccessor() {
return heightGetter;
}
}
@@ -3,6 +3,7 @@ package com.seibel.lod.common.wrappers.worldGeneration.mimicObject;
import java.util.List;
import java.util.stream.Stream;
import com.seibel.lod.core.api.ApiShared;
import org.jetbrains.annotations.Nullable;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment.EmptyChunkGenerator;
@@ -45,14 +46,18 @@ public class LightedWorldGenRegion extends WorldGenRegion {
public void setOverrideCenter(ChunkPos pos) {overrideCenterPos = pos;}
@Override
public ChunkPos getCenter() {
return overrideCenterPos==null ? super.getCenter() : overrideCenterPos;
public int getCenterX() {
return overrideCenterPos==null ? super.getCenterX() : overrideCenterPos.x;
}
@Override
public int getCenterZ() {
return overrideCenterPos==null ? super.getCenterZ() : overrideCenterPos.z;
}
public LightedWorldGenRegion(ServerLevel serverLevel, WorldGenLevelLightEngine lightEngine,
StructureFeatureManager structFeat, List<ChunkAccess> list, ChunkStatus chunkStatus, int i,
LightGenerationMode lightMode, EmptyChunkGenerator generator) {
super(serverLevel, list, chunkStatus, i);
super(serverLevel, list);
this.lightMode = lightMode;
this.firstPos = list.get(0).getPos();
this.generator = generator;
@@ -63,20 +68,6 @@ public class LightedWorldGenRegion extends WorldGenRegion {
size = Mth.floor(Math.sqrt(list.size()));
}
// 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();
int k = Math.abs(chunkPos.x - i);
int l = Math.abs(chunkPos.z - j);
if (k > this.writeRadius || l > this.writeRadius) {
return false;
}
return true;
}
@Override
public Stream<? extends StructureStart<?>> startsForFeature(SectionPos sectionPos,
StructureFeature<?> structureFeature) {
@@ -183,7 +174,7 @@ public class LightedWorldGenRegion extends WorldGenRegion {
}
}
if (chunkStatus != ChunkStatus.EMPTY && chunkStatus != debugTriggeredForStatus) {
ClientApi.LOGGER.info("WorldGen requiring " + chunkStatus
ApiShared.LOGGER.info("WorldGen requiring " + chunkStatus
+ " outside expected range detected. Force passing EMPTY chunk and seeing if it works.");
debugTriggeredForStatus = chunkStatus;
}
@@ -5,7 +5,6 @@ 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;
@@ -17,161 +16,149 @@ 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 static final int LIGHT_SECTION_PADDING = 1;
@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);
}
public WorldGenLevelLightEngine(LightGetterAdaptor genRegion) {
super(genRegion, false, false);
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 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 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 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.isEmpty(levelChunkSection)) {
int j = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
updateSectionStatus(SectionPos.of(chunkPos, j), false);
@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);
}
}
enableLightSources(chunkPos, true);
if (needLightBlockUpdate) {
chunkAccess.getLights().forEach(blockPos ->
onBlockEmissionIncrease(blockPos, chunkAccess.getLightEmission(blockPos)));
}
chunkAccess.setLightCorrect(true);
}
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 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!");
}
@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 < 16; i++) {
LevelChunkSection levelChunkSection = levelChunkSections[i];
if (!LevelChunkSection.isEmpty(levelChunkSection)) {
updateSectionStatus(SectionPos.of(chunkPos, i), 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);
}
}
}
@@ -17,6 +17,7 @@ import net.minecraft.world.level.levelgen.structure.StructureStart;
public class WorldGenStructFeatManager extends StructureFeatureManager {
WorldGenLevel genLevel;
WorldGenSettings worldGenSettings;
public WorldGenStructFeatManager(LevelAccessor levelAccessor, WorldGenSettings worldGenSettings,
WorldGenLevel genLevel) {
super(levelAccessor, worldGenSettings);
@@ -26,7 +27,7 @@ public class WorldGenStructFeatManager extends StructureFeatureManager {
public void setGenLevel(WorldGenLevel genLevel) {
this.genLevel = genLevel;
}
}
@Override
public WorldGenStructFeatManager forWorldGenRegion(WorldGenRegion worldGenRegion) {
@@ -1,6 +1,7 @@
package com.seibel.lod.common.wrappers.worldGeneration.step;
import java.util.ArrayList;
import java.util.EnumSet;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import com.seibel.lod.common.wrappers.worldGeneration.mimicObject.LightedWorldGenRegion;
@@ -11,6 +12,7 @@ import net.minecraft.ReportedException;
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.Heightmap;
public final class StepFeatures {
/**
@@ -40,6 +42,7 @@ public final class StepFeatures {
for (ChunkAccess chunk : chunksToDo) {
try {
worldGenRegion.setOverrideCenter(chunk.getPos());
Heightmap.primeHeightmaps(chunk, STATUS.heightmapsAfter());
envionment.params.generator.applyBiomeDecoration(worldGenRegion, tParams.structFeat);
} catch (ReportedException e) {
e.printStackTrace();
@@ -9,46 +9,45 @@ 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;
import net.minecraft.world.level.lighting.LevelLightEngine;
public final class StepLight {
/**
*
*/
private final BatchGenerationEnvironment environment;
private final BatchGenerationEnvironment envionment;
/**
* @param batchGenerationEnvironment
* @param worldGenerationEnvironment
*/
public StepLight(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
public StepLight(BatchGenerationEnvironment worldGenerationEnvironment) {
envionment = worldGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.LIGHT;
public void generateGroup(LightEventListener lightEngine,
GridList<ChunkAccess> chunks) {
//ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
public void generateGroup(LevelLightEngine lightEngine, GridList<ChunkAccess> chunks) {
// ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
for (ChunkAccess chunk : chunks) {
if (chunk.getStatus().isOrAfter(STATUS)) continue;
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);
((WorldGenLevelLightEngine) lightEngine).lightChunk(chunk, !hasCorrectBlockLight);
} else if (lightEngine instanceof ThreadedLevelLightEngine) {
((ThreadedLevelLightEngine) lightEngine).lightChunk(chunk, !hasCorrectBlockLight).join();
} else {
assert(false);
assert (false);
}
} catch (Exception e) {
e.printStackTrace();
}
@@ -1,93 +1,45 @@
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 com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import net.minecraft.core.QuartPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.util.Mth;
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;
public final class StepNoise {
/**
*
*/
private final BatchGenerationEnvironment environment;
private final BatchGenerationEnvironment envionment;
/**
* @param batchGenerationEnvironment
* @param worldGenerationEnvironment
*/
public StepNoise(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
}
private static <T> T joinSync(CompletableFuture<T> f) {
if (!f.isDone()) throw new RuntimeException("The future is concurrent!");
return f.join();
public StepNoise(BatchGenerationEnvironment worldGenerationEnvironment) {
envionment = worldGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.NOISE;
private ChunkAccess NoiseBased$fillFromNoise(NoiseBasedChunkGenerator generator, StructureFeatureManager structureFeatureManager, ChunkAccess chunkAccess) {
NoiseSettings noiseSettings = generator.settings.get().noiseSettings();
int i = Math.max(noiseSettings.minY(), chunkAccess.getMinBuildHeight());
int j = Math.min(noiseSettings.minY() + noiseSettings.height(), chunkAccess.getMaxBuildHeight());
int cellHeight = QuartPos.toBlock(noiseSettings.noiseSizeVertical());
int k = Mth.intFloorDiv(i, cellHeight);
int l = Mth.intFloorDiv(j - i, cellHeight);
if (l <= 0) {
return chunkAccess;
}
int m = chunkAccess.getSectionIndex(l * cellHeight - 1 + i);
int n = chunkAccess.getSectionIndex(i);
HashSet<LevelChunkSection> set = Sets.newHashSet();
try {
for (int o = m; o >= n; --o) {
LevelChunkSection levelChunkSection = chunkAccess.getOrCreateSection(o);
levelChunkSection.acquire();
set.add(levelChunkSection);
}
chunkAccess = generator.doFill(structureFeatureManager, chunkAccess, k, l);
return chunkAccess;
} finally {
for (LevelChunkSection levelChunkSection : set) {
levelChunkSection.release();
};
}
}
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
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;
if (chunk.getStatus().isOrAfter(STATUS))
continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepNoise: "+chunk.getPos());
if (environment.params.generator instanceof NoiseBasedChunkGenerator) {
chunk = NoiseBased$fillFromNoise((NoiseBasedChunkGenerator)environment.params.generator,
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
} else {
chunk = joinSync(environment.params.generator.fillFromNoise(Runnable::run,
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
}
envionment.params.generator.fillFromNoise(worldGenRegion, tParams.structFeat, chunk);
}
}
}
@@ -3,8 +3,8 @@ 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 com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
@@ -20,19 +20,6 @@ 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;
private void createReferences(WorldGenRegion worldGenLevel, StructureFeatureManager structureFeatureManager,
@@ -43,7 +30,7 @@ public final class StepStructureReference {
int l = chunkPos.getMinBlockX();
int m = chunkPos.getMinBlockZ();
SectionPos sectionPos = SectionPos.bottomOf(chunkAccess);
SectionPos sectionPos = SectionPos.of(chunkAccess.getPos(), 0);
for (int n = j - 8; n <= j + 8; n++) {
for (int o = k - 8; o <= k + 8; o++) {
@@ -54,12 +41,11 @@ public final class StepStructureReference {
try {
if (structureStart.isValid()
&& structureStart.getBoundingBox().intersects(l, m, l + 15, m + 15)) {
structureFeatureManager.addReferenceForFeature(sectionPos, structureStart.getFeature(),
p, chunkAccess);
structureFeatureManager.addReferenceForFeature(sectionPos, structureStart.getFeature(), p,
chunkAccess);
}
} catch (Exception exception) {
CrashReport crashReport = CrashReport.forThrowable(exception,
"Generating structure reference");
CrashReport crashReport = CrashReport.forThrowable(exception, "Generating structure reference");
CrashReportCategory crashReportCategory = crashReport.addCategory("Structure");
crashReportCategory.setDetail("Id",
() -> Registry.STRUCTURE_FEATURE.getKey(structureStart.getFeature()).toString());
@@ -73,17 +59,17 @@ public final class StepStructureReference {
}
}
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
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;
if (chunk.getStatus().isOrAfter(STATUS))
continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepStructureReference: "+chunk.getPos());
createReferences(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
@@ -3,8 +3,8 @@ 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 com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.chunk.ChunkAccess;
@@ -15,44 +15,33 @@ public final class StepStructureStart {
/**
*
*/
private final BatchGenerationEnvironment environment;
private final BatchGenerationEnvironment envionment;
/**
* @param batchGenerationEnvironment
* @param worldGenerationEnvironment
*/
public StepStructureStart(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
public StepStructureStart(BatchGenerationEnvironment worldGenerationEnvironment) {
envionment = worldGenerationEnvironment;
}
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) {
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;
if (chunk.getStatus().isOrAfter(STATUS))
continue;
((ProtoChunk) chunk).setStatus(STATUS);
chunksToDo.add(chunk);
}
if (environment.params.worldGenSettings.generateFeatures()) {
if (envionment.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);
envionment.params.generator.createStructures(envionment.params.registry, tParams.structFeat, chunk,
envionment.params.structures, envionment.params.worldSeed);
}
}
}
@@ -3,8 +3,8 @@ 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 com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.chunk.ChunkAccess;
@@ -15,31 +15,30 @@ public final class StepSurface {
/**
*
*/
private final BatchGenerationEnvironment environment;
private final BatchGenerationEnvironment envionment;
/**
* @param batchGenerationEnvironment
* @param worldGenerationEnvironment
*/
public StepSurface(BatchGenerationEnvironment batchGenerationEnvironment)
{
environment = batchGenerationEnvironment;
public StepSurface(BatchGenerationEnvironment worldGenerationEnvironment) {
envionment = worldGenerationEnvironment;
}
public final ChunkStatus STATUS = ChunkStatus.SURFACE;
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
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;
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.buildSurfaceAndBedrock(worldGenRegion, chunk);
envionment.params.generator.buildSurfaceAndBedrock(worldGenRegion, chunk);
}
}
}
+4 -20
View File
@@ -4,16 +4,10 @@ accessWidener v1 named
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
# pre-render setup
accessible field net/minecraft/client/renderer/LevelRenderer renderChunks Lit/unimi/dsi/fastutil/objects/ObjectArrayList;
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo
accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chunk Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;
# used for grabbing vanilla rendered chunks
accessible field net/minecraft/client/renderer/LevelRenderer renderChunks Lit/unimi/dsi/fastutil/objects/ObjectList;
accessible class net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo
accessible field net/minecraft/client/renderer/LevelRenderer$RenderChunkInfo chunk Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;
@@ -25,9 +19,6 @@ accessible field net/minecraft/world/level/lighting/LevelLightEngine skyEngine L
# 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/levelgen/NoiseBasedChunkGenerator settings Ljava/util/function/Supplier;
accessible method net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator doFill (Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkAccess;II)Lnet/minecraft/world/level/chunk/ChunkAccess;
accessible method net/minecraft/world/level/lighting/LayerLightEngine queueSectionData (JLnet/minecraft/world/level/chunk/DataLayer;Z)V
accessible field net/minecraft/world/level/chunk/ChunkGenerator biomeSource Lnet/minecraft/world/level/biome/BiomeSource;
@@ -36,14 +27,7 @@ accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/min
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/block/model/BakedQuad sprite Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite framesX [I
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite framesY [I
accessible field net/minecraft/client/renderer/texture/TextureAtlasSprite mainImage [Lcom/mojang/blaze3d/platform/NativeImage;
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/world/level/chunk/PalettedContainer lock Ljava/util/concurrent/Semaphore;
mutable field net/minecraft/world/level/chunk/PalettedContainer lock Ljava/util/concurrent/Semaphore;
+1 -1
Submodule core updated: 67f12c136c...510058b7df
+10 -46
View File
@@ -1,5 +1,6 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.0.0"
id "com.modrinth.minotaur" version "1.2.1"
}
version = rootProject.mod_version+"-"+rootProject.minecraft_version+"-"+new Date().format("yyyy_MM_dd_HH_mm")
@@ -24,6 +25,12 @@ repositories {
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
@@ -38,30 +45,14 @@ dependencies {
}
// Sodium
modImplementation "curse.maven:sodium-394468:${rootProject.sodium_version}"
addMod("curse.maven:sodium-394468:${rootProject.sodium_version}", rootProject.enable_sodium)
implementation "org.joml:joml:1.10.2"
// Lithium
// modImplementation "maven.modrinth:lithium:${rootProject.lithium_version}"
addMod("maven.modrinth:lithium:${rootProject.lithium_version}", rootProject.enable_lithium)
// Iris
// modImplementation "maven.modrinth:iris:${rootProject.iris_version}"
// 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)
}
*/
addMod("maven.modrinth:iris:${rootProject.iris_version}", rootProject.enable_iris)
@@ -105,35 +96,8 @@ runClient {
finalizedBy(deleteResources)
}
// Put stuff from gradle.properties into the mod info stuff
def resourceTargets = ["fabric.mod.json"]
def intoTargets = ["$buildDir/resources/main/"]
def replaceProperties = [
version: mod_version,
mod_name: mod_name,
authors: mod_authors,
description: mod_description
]
processResources {
dependsOn(copyAccessWidener)
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
}
}
}
}
shadowJar {
@@ -26,15 +26,22 @@ 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.util.SingletonHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.fabric.mixins.events.MixinClientLevel;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
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.ServerChunkEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.mixin.event.lifecycle.client.ClientChunkManagerMixin;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientChunkCache;
import net.minecraft.core.BlockPos;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.Level;
@@ -42,6 +49,7 @@ import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.chunk.LevelChunk;
import java.util.HashSet;
import java.util.List;
import org.lwjgl.glfw.GLFW;
@@ -66,8 +74,6 @@ public class ClientProxy
public void registerEvents() {
// TODO: Fix this if it's wrong
/* Registor the mod accessor*/
/* World Events */
//ServerTickEvents.START_SERVER_TICK.register(this::serverTickEvent);
ServerTickEvents.END_SERVER_TICK.register(this::serverTickEvent);
@@ -76,6 +82,8 @@ public class ClientProxy
//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));
@@ -21,16 +21,18 @@ 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.api.ModAccessorApi;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.handlers.dependencyInjection.DependencyHandler;
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.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.DependencySetup;
import com.seibel.lod.fabric.wrappers.FabricDependencySetup;
import net.fabricmc.api.ClientModInitializer;
@@ -43,9 +45,9 @@ import net.fabricmc.api.ClientModInitializer;
* @author Ran
* @version 12-1-2021
*/
public class Main implements ClientModInitializer
public class FabricMain implements ClientModInitializer
{
// This is a client mod, so it should implement ClientModInitializer and in fabric.mod.json it should have "environment": "client"
// 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;
@@ -62,25 +64,37 @@ public class Main implements ClientModInitializer
public static void init() {
LodCommonMain.initConfig();
LodCommonMain.startup(null, false);
DependencySetup.createInitialBindings();
SingletonHandler.bind(IModChecker.class, ModChecker.INSTANCE);
ClientApi.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
ApiShared.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
// make sure the dependencies are set up before the mod needs them
FabricDependencySetup.createInitialBindings();
FabricDependencySetup.finishBinding();
// mod dependencies
if (SingletonHandler.get(IModChecker.class).isModLoaded("sodium")) {
ModAccessorHandler.bind(ISodiumAccessor.class, new SodiumAccessor());
}
if (SingletonHandler.get(IModChecker.class).isModLoaded("optifine")) {
ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor());
}
ModAccessorHandler.finishBinding();
// Check if this works
client_proxy = new ClientProxy();
client_proxy.registerEvents();
if (SingletonHandler.get(IModChecker.class).isModLoaded("sodium")) {
ModAccessorApi.bind(ISodiumAccessor.class, new SodiumAccessor());
}
if (SingletonHandler.get(IModChecker.class).isModLoaded("optifine")) {
ModAccessorApi.bind(IOptifineAccessor.class, new OptifineAccessor());
}
}
public static void initServer() {
LodCommonMain.initConfig();
LodCommonMain.startup(null, true);
DependencySetup.createInitialBindings();
ClientApi.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
ApiShared.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
FabricDependencySetup.createInitialBindings();
FabricDependencySetup.finishBinding();
}
}
@@ -6,15 +6,18 @@ 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.util.SingletonHandler;
import com.seibel.lod.core.api.ClientApi;
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.tags.FluidTags;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.FogType;
@Mixin(FogRenderer.class)
@@ -22,19 +25,23 @@ 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;
private static final float A_REALLY_REALLY_BIG_VALUE = 4206942069.F;
private static final float A_EVEN_LARGER_VALUE = 420694206942069.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();
private static final void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, CallbackInfo callback) {
FogType fogType = 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()) {
boolean enableFog = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
enableFog |= fogType.equals(FogType.WATER);
enableFog |= fogType.equals(FogType.LAVA);
enableFog |= fogType.equals(FogType.POWDER_SNOW);
if (!enableFog) {
if (fogMode == FogMode.FOG_TERRAIN && CONFIG.client().graphics().fogQuality().getDisableVanillaFog()) {
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
}
}
}
}
}
@@ -1,6 +1,6 @@
package com.seibel.lod.fabric.mixins;
import com.seibel.lod.fabric.Main;
import com.seibel.lod.fabric.FabricMain;
import net.minecraft.client.Minecraft;
import net.minecraft.client.main.GameConfig;
import org.spongepowered.asm.mixin.Mixin;
@@ -16,6 +16,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public class MixinMinecraft {
@Inject(method = "<init>", at = @At("TAIL"))
private void startMod(GameConfig gameConfig, CallbackInfo ci) {
Main.init();
FabricMain.init();
}
}
@@ -3,7 +3,7 @@ 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.util.SingletonHandler;
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;
@@ -34,7 +34,7 @@ public class MixinOptionsScreen extends Screen {
@Inject(at = @At("HEAD"),method = "init")
private void lodconfig$init(CallbackInfo ci) {
if (SingletonHandler.get(ILodConfigWrapperSingleton.class).client().getOptionsButton())
this.addRenderableWidget(new TexturedButtonWidget(
this.addButton(new TexturedButtonWidget(
// Where the button is on the screen
this.width / 2 - 180, this.height / 6 - 12,
// Width and height of the button
@@ -20,17 +20,19 @@
package com.seibel.lod.fabric.mixins;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
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.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
import org.lwjgl.opengl.GL15;
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.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.objects.math.Mat4f;
import net.minecraft.client.renderer.RenderType;
/**
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
@@ -47,28 +49,35 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LevelRenderer.class)
public class MixinWorldRenderer
{
// TODO: Fix clouds
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
@Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/vertex/PoseStack;F)V")
private void renderSky(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback)
{
// get the partial ticks since renderBlockLayer doesn't
// have access to them
previousPartialTicks = tickDelta;
previousPartialTicks = partialTicks;
}
// HEAD or RETURN
@Inject(at = @At("HEAD"), method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V")
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
@Inject(at = @At("HEAD"), method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V")
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
{
// only render before solid blocks
if (renderType.equals(RenderType.solid()))
{
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
// get MC's current projection matrix
float[] mcProjMatrixRaw = new float[16];
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
// OpenGl outputs their matrices in col,row form instead of row,col
// (or maybe vice versa I have no idea :P)
mcProjectionMatrix.transpose();
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}
@@ -1,6 +1,6 @@
package com.seibel.lod.fabric.mixins.events;
import com.seibel.lod.fabric.Main;
import com.seibel.lod.fabric.FabricMain;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
@@ -23,6 +23,6 @@ public abstract class MixinBlockUpdate {
@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());
FabricMain.client_proxy.blockChangeEvent(Minecraft.getInstance().player.clientLevel, this.getPos());
}
}
@@ -1,6 +1,6 @@
package com.seibel.lod.fabric.mixins.events;
import com.seibel.lod.fabric.Main;
import com.seibel.lod.fabric.FabricMain;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.renderer.LevelRenderer;
@@ -23,6 +23,6 @@ import java.util.function.Supplier;
public class MixinClientLevel {
@Inject(method = "<init>", at = @At("TAIL"))
private void loadWorldEvent(ClientPacketListener clientPacketListener, ClientLevel.ClientLevelData clientLevelData, ResourceKey<Level> resourceKey, DimensionType dimensionType, int i, Supplier<ProfilerFiller> supplier, LevelRenderer levelRenderer, boolean bl, long l, CallbackInfo ci) {
Main.client_proxy.worldLoadEvent((ClientLevel) (Object) this);
FabricMain.client_proxy.worldLoadEvent((ClientLevel) (Object) this);
}
}
@@ -1,9 +1,10 @@
package com.seibel.lod.fabric.mixins.events;
import com.seibel.lod.fabric.Main;
import com.seibel.lod.fabric.FabricMain;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.server.level.ServerLevel;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
@@ -22,11 +23,11 @@ public class MixinMinecraft {
@Inject(method = "setLevel", at = @At("HEAD"))
private void unloadWorldEvent_sL(ClientLevel clientLevel, CallbackInfo ci) {
if (level != null) Main.client_proxy.worldUnloadEvent(level);
if (level != null) FabricMain.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);
if (this.level != null) FabricMain.client_proxy.worldUnloadEvent(this.level);
}
}
@@ -1,6 +1,6 @@
package com.seibel.lod.fabric.mixins.events;
import com.seibel.lod.fabric.Main;
import com.seibel.lod.fabric.FabricMain;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.ProgressListener;
import org.spongepowered.asm.mixin.Mixin;
@@ -14,13 +14,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
*/
@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();
@Inject(method = "save", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;save(Z)V", shift = At.Shift.AFTER))
private void saveWorldEvent(ProgressListener progressListener, boolean bl, boolean bl2, CallbackInfo ci) {
FabricMain.client_proxy.worldSaveEvent();
}
}
@@ -1,8 +1,10 @@
package com.seibel.lod.fabric.mixins.unsafe;
import net.minecraft.world.level.chunk.PalettedContainer;
import org.spongepowered.asm.mixin.Final;
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;
@@ -17,11 +19,13 @@ import java.util.concurrent.Semaphore;
*/
@Mixin(PalettedContainer.class)
public class MixinPalettedContainer {
@Mutable
private Semaphore lock;
@Inject(method = "<init>", at = @At("RETURN"))
private void setSemaphore(CallbackInfo ci) {
this.lock = new Semaphore(2);
@Inject(method = "acquire", at = @At("HEAD"), cancellable = true)
private void acquire_skip(CallbackInfo ci) {
ci.cancel();
}
@Inject(method = "release", at = @At("HEAD"), cancellable = true)
private void release_skip(CallbackInfo ci) {
ci.cancel();
}
}
@@ -1,7 +1,10 @@
package com.seibel.lod.fabric.wrappers;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.handlers.dependencyInjection.DependencyHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.lod.fabric.wrappers.modAccessor.ModChecker;
import com.seibel.lod.common.wrappers.config.LodConfigWrapperSingleton;
/**
@@ -14,10 +17,16 @@ import com.seibel.lod.common.wrappers.config.LodConfigWrapperSingleton;
* @author Ran
* @version 12-1-2021
*/
public class DependencySetup
public class FabricDependencySetup
{
public static void createInitialBindings()
{
SingletonHandler.bind(ILodConfigWrapperSingleton.class, LodConfigWrapperSingleton.INSTANCE);
SingletonHandler.bind(ILodConfigWrapperSingleton.class, LodConfigWrapperSingleton.INSTANCE);;
SingletonHandler.bind(IModChecker.class, ModChecker.INSTANCE);
}
public static void finishBinding()
{
SingletonHandler.finishBinding();
}
}
@@ -6,6 +6,9 @@ import com.terraformersmc.modmenu.api.ModMenuApi;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.HashMap;
import java.util.Map;
/**
* For making the config show up in modmenu
*/
@@ -1,4 +1,3 @@
package com.seibel.lod.fabric.wrappers.modAccessor;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
@@ -1,3 +1,4 @@
package com.seibel.lod.fabric.wrappers.modAccessor;
import java.util.HashSet;
@@ -21,4 +22,4 @@ public class OptifineAccessor implements IOptifineAccessor
return null;
}
}
}
@@ -3,34 +3,65 @@ package com.seibel.lod.fabric.wrappers.modAccessor;
import java.util.HashSet;
import java.util.stream.Collectors;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
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;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.phys.AABB;
public class SodiumAccessor implements ISodiumAccessor {
private final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class);
@Override
public String getModName() {
return "Sodium-Fabric-1.17.1";
}
return "Sodium-Fabric-1.16.5";
}
@Override
public HashSet<AbstractChunkPosWrapper> getNormalRenderedChunks() {
SodiumWorldRenderer renderer = SodiumWorldRenderer.instance();
LevelHeightAccessor height = Minecraft.getInstance().level;
SodiumWorldRenderer renderer = SodiumWorldRenderer.getInstance();
LevelAccessor height = Minecraft.getInstance().level;
// TODO: Maybe use a mixin to make this more efficient
return MC_RENDER.getMaximumRenderedChunks().stream().filter((AbstractChunkPosWrapper chunk) -> {
return (renderer.isBoxVisible(
chunk.getMinBlockX()+1, height.getMinBuildHeight()+1, chunk.getMinBlockZ()+1,
chunk.getMinBlockX()+15, height.getMaxBuildHeight()-1, chunk.getMinBlockZ()+15));
FakeChunkEntity AABB = new FakeChunkEntity(chunk.getX(), chunk.getZ(), height.getMaxBuildHeight());
return (renderer.isEntityVisible(AABB));
}).collect(Collectors.toCollection(HashSet::new));
}
private static class FakeChunkEntity extends Entity {
public int cx;
public int cz;
public int my;
public FakeChunkEntity(int chunkX, int chunkZ, int maxHeight) {
super(EntityType.AREA_EFFECT_CLOUD, null);
cx = chunkX;
cz = chunkZ;
my = maxHeight;
}
@Override
public AABB getBoundingBoxForCulling() {
return new AABB(cx*16+1, 1, cz*16+1,
cx*16+15, my-1, cz*16+15);
}
@Override
protected void defineSynchedData() {}
@Override
protected void readAdditionalSaveData(CompoundTag paramCompoundTag) {}
@Override
protected void addAdditionalSaveData(CompoundTag paramCompoundTag) {}
@Override
public Packet<?> getAddEntityPacket() {
throw new UnsupportedOperationException("This is a FAKE CHUNK ENTITY... For tricking the Sodium to check a AABB.");
}}
}
@@ -2,17 +2,17 @@
"required": true,
"minVersion": "0.8",
"package": "com.seibel.lod.fabric.mixins",
"compatibilityLevel": "JAVA_16",
"compatibilityLevel": "JAVA_8",
"mixins": [
"events.MixinServerLevel",
"unsafe.MixinPalettedContainer"
"unsafe.MixinPalettedContainer",
"MixinChunkGenerator"
],
"client": [
"MixinMinecraft",
"MixinOptionsScreen",
"MixinWorldRenderer",
"MixinFogRenderer",
"MixinChunkGenerator",
"events.MixinClientLevel",
"events.MixinMinecraft",
"events.MixinBlockUpdate"
+5 -5
View File
@@ -8,9 +8,9 @@
"authors": ["${authors}"],
"contact": {
"homepage": "https://www.curseforge.com/minecraft/mc-mods/distant-horizons",
"sources": "https://gitlab.com/jeseibel/minecraft-lod-mod/",
"issues": "https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues"
"homepage": "${homepage}",
"sources": "${source}",
"issues": "${issues}"
},
"license": "CC0-1.0",
@@ -34,8 +34,8 @@
"depends": {
"fabricloader": "*",
"fabric": "*",
"minecraft": "1.17.x",
"java": ">=16"
"minecraft": ["1.16.5", "1.16.4", "1.16.3", "1.16.2"],
"java": ">=8"
},
"suggests": {
"another-mod": "*"
+10 -31
View File
@@ -25,16 +25,22 @@ configurations {
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}"
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowMe(project(path: ":common", configuration: "transformProductionForge")) { transitive = false }
// Starlight
// modImplementation("curse.maven:starlight-forge-526854:${rootProject.starlight_version_forge}")
// forgeDependencies(project(":core")) { transitive false }
@@ -57,36 +63,9 @@ task copyCommonResources(type: Copy) {
into file("build/resources/main")
}
// Put stuff from gradle.properties into the mod info stuff
def resourceTargets = ["META-INF/mods.toml"]
def intoTargets = ["$buildDir/resources/main/"]
def replaceProperties = [
version: mod_version,
mod_name: mod_name,
authors: mod_authors,
description: mod_description
]
processResources {
dependsOn(copyCoreResources)
dependsOn(copyCommonResources)
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
}
}
}
}
shadowJar {
@@ -97,7 +76,7 @@ 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' // This is already included with forge
relocate 'com.electronwill.nightconfig', 'shaded.electronwill.nightconfig'
relocate 'com.seibel.lod.common', 'forge.com.seibel.lod.common'
@@ -111,4 +111,6 @@ public class ForgeClientProxy
clientApi.keyPressedEvent(event.getKey());
}
}
@@ -22,12 +22,13 @@ 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.MinecraftWrapper;
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.api.ClientApi;
import com.seibel.lod.core.api.ModAccessorApi;
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
import com.seibel.lod.core.handlers.ReflectionHandler;
import com.seibel.lod.core.util.SingletonHandler;
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.forge.wrappers.ForgeDependencySetup;
@@ -35,19 +36,18 @@ import com.seibel.lod.forge.wrappers.ForgeDependencySetup;
import com.seibel.lod.forge.wrappers.modAccessor.ModChecker;
import com.seibel.lod.forge.wrappers.modAccessor.OptifineAccessor;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
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.common.MinecraftForge;
import net.minecraftforge.fml.ExtensionPoint;
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 net.minecraftforge.fmlclient.ConfigGuiHandler;
import java.util.List;
import java.util.Random;
@@ -67,16 +67,21 @@ public class ForgeMain implements LodForgeMethodCaller
private void init(final FMLCommonSetupEvent event)
{
// make sure the dependencies are set up before the mod needs them
ApiShared.LOGGER.info("Distant Horizons initializing...");
LodCommonMain.initConfig();
LodCommonMain.startup(this, !FMLLoader.getDist().isClient());
// make sure the dependencies are set up before the mod needs them
ForgeDependencySetup.createInitialBindings();
ClientApi.LOGGER.info("Distant Horizons initializing...");
SingletonHandler.bind(IModChecker.class, ModChecker.INSTANCE);
ForgeDependencySetup.finishBinding();
// mod dependencies
if (ReflectionHandler.instance.optifinePresent()) {
ModAccessorApi.bind(IOptifineAccessor.class, new OptifineAccessor());
ModAccessorHandler.bind(IOptifineAccessor.class, new OptifineAccessor());
}
ModAccessorHandler.finishBinding();
}
@@ -92,21 +97,15 @@ public class ForgeMain implements LodForgeMethodCaller
private void onClientStart(final FMLClientSetupEvent event)
{
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> ConfigGui.getScreen(parent, "")));
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
() -> (client, parent) -> ConfigGui.getScreen(parent, ""));
forgeClientProxy = new ForgeClientProxy();
MinecraftForge.EVENT_BUS.register(forgeClientProxy);
}
private ModelDataMap dataMap = new ModelDataMap.Builder().build();
@Override
public List<BakedQuad> getQuads(MinecraftWrapper mc, Block block, BlockState blockState, Direction direction, Random random) {
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);
}
@Override
public int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y) {
return sprite.getPixelRGBA(frameIndex, x, y);
}
}
@@ -6,7 +6,8 @@ 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.util.SingletonHandler;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import net.minecraft.client.Camera;
@@ -19,28 +20,32 @@ import net.minecraft.world.level.material.FogType;
@Mixin(FogRenderer.class)
public class MixinFogRenderer {
// Using this instead of Float.MAX_VALUE because Sodium don't like it. (And just in case it's here also for forge)
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
// Using this instead of Float.MAX_VALUE because Sodium don't like it. (And keeping it for forge just in case)
private static final float A_REALLY_REALLY_BIG_VALUE = 4206942069.F;
private static final float A_EVEN_LARGER_VALUE = 420694206942069.F;
@Inject(at = @At("RETURN"),
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
remap = false) // Due to this being a forge added method
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float tick, CallbackInfo callback) {
ILodConfigWrapperSingleton CONFIG;
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V")
private static final void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float ticks, CallbackInfo callback) {
ILodConfigWrapperSingleton CONFIG;
try {
CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
} catch (NullPointerException e) {
return; // Happens on forge not loading the mod before this.
return; // Can happen due to forge calling this before setting up the mod
}
FogType fogTypes = camera.getFluidInCamera();
ApiShared.LOGGER.debug("LOD: MixinSetupFog called!");
FogType fogType = camera.getFluidInCamera();
Entity entity = camera.getEntity();
boolean isUnderWater = (entity instanceof LivingEntity) && ((LivingEntity)entity).hasEffect(MobEffects.BLINDNESS);
isUnderWater |= fogType.equals(FogType.WATER);
isUnderWater |= fogType.equals(FogType.LAVA);
if (!isUnderWater) {
if (fogMode == FogMode.FOG_TERRAIN && fogTypes == FogType.NONE && CONFIG.client().graphics().fogQuality().getDisableVanillaFog()) {
if (fogMode == FogMode.FOG_TERRAIN && CONFIG.client().graphics().fogQuality().getDisableVanillaFog()) {
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
}
}
}
}
}
@@ -3,7 +3,7 @@ package com.seibel.lod.forge.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.util.SingletonHandler;
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;
@@ -34,7 +34,7 @@ public class MixinOptionsScreen extends Screen {
@Inject(at = @At("HEAD"),method = "init")
private void lodconfig$init(CallbackInfo ci) {
if (SingletonHandler.get(ILodConfigWrapperSingleton.class).client().getOptionsButton())
this.addRenderableWidget(new TexturedButtonWidget(
this.addButton(new TexturedButtonWidget(
// Where the button is on the screen
this.width / 2 - 180, this.height / 6 - 12,
// Width and height of the button
@@ -0,0 +1,49 @@
package com.seibel.lod.forge.mixins;
import java.util.Random;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
//import com.seibel.lod.core.api.ClientApi;
import com.terraforged.mod.chunk.generator.FeatureGenerator;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
@Mixin(FeatureGenerator.class)
public class MixinTFChunkGenerator {
@Redirect(method = "decorate("
+ "Lnet/minecraft/world/level/StructureFeatureManager;"
+ "Lnet/minecraft/world/level/WorldGenLevel;"
+ "Lnet/minecraft/world/level/chunk/ChunkAccess;"
+ "Lnet/minecraft/world/level/biome/Biome;"
+ "Lnet/minecraft/core/BlockPos;"
+ "Lcom/terraforged/mod/profiler/watchdog/WatchdogContext;)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/levelgen/feature/ConfiguredFeature;place("
+ "Lnet/minecraft/world/level/WorldGenLevel;"
+ "Lnet/minecraft/world/level/chunk/ChunkGenerator;"
+ "Ljava/util/Random;Lnet/minecraft/core/BlockPos;)Z"
))
private boolean wrapDecorate$FeaturePlace(ConfiguredFeature<?, ?> feature, WorldGenLevel arg,
ChunkGenerator arg2, Random random, BlockPos arg3) {
synchronized((FeatureGenerator)(Object)this) {
//ClientApi.LOGGER.info("wrapDecorate FeaturePlace triggered");
return feature.place(arg, arg2, random, arg3);
}
}
//METHOD: com.terraforged.mod.chunk.generator.FeatureGenerator.decorate(StructureFeatureManager manager,
// WorldGenLevel region, ChunkAccess chunk, Biome biome, BlockPos pos, WatchdogContext context)
//TARGET: boolean net.minecraft.world.level.levelgen.feature.ConfiguredFeature.place
// (WorldGenLevel arg, ChunkGenerator arg2, Random random, BlockPos arg3)
}
@@ -20,17 +20,19 @@
package com.seibel.lod.forge.mixins;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
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.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
import org.lwjgl.opengl.GL15;
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.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.objects.math.Mat4f;
import net.minecraft.client.renderer.RenderType;
/**
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
@@ -47,28 +49,35 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LevelRenderer.class)
public class MixinWorldRenderer
{
// TODO: Fix clouds
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
@Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/vertex/PoseStack;F)V")
private void renderSky(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback)
{
// get the partial ticks since renderBlockLayer doesn't
// have access to them
previousPartialTicks = tickDelta;
previousPartialTicks = partialTicks;
}
// HEAD or RETURN
@Inject(at = @At("HEAD"), method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V")
private void renderChunkLayer(RenderType renderType, PoseStack modelViewMatrixStack, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, Matrix4f projectionMatrix, CallbackInfo callback)
@Inject(at = @At("HEAD"), method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V")
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
{
// only render before solid blocks
if (renderType.equals(RenderType.solid()))
{
Mat4f mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrixStack.last().pose());
Mat4f mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
// get MC's current projection matrix
float[] mcProjMatrixRaw = new float[16];
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
// OpenGl outputs their matrices in col,row form instead of row,col
// (or maybe vice versa I have no idea :P)
mcProjectionMatrix.transpose();
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}
@@ -1,23 +1,31 @@
package com.seibel.lod.forge.wrappers;
import com.seibel.lod.common.wrappers.config.LodConfigWrapperSingleton;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.lod.forge.wrappers.modAccessor.ModChecker;
/**
* Binds all necessary dependencies, so we
* 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
* @version 3-5-2022
*/
public class ForgeDependencySetup
{
public static void createInitialBindings()
{
SingletonHandler.bind(ILodConfigWrapperSingleton.class, LodConfigWrapperSingleton.INSTANCE);
SingletonHandler.bind(IModChecker.class, ModChecker.INSTANCE);
}
public static void finishBinding()
{
SingletonHandler.finishBinding();
}
}
@@ -10,4 +10,4 @@ public class ModChecker implements IModChecker {
public boolean isModLoaded(String modid) {
return ModList.get().isLoaded(modid);
}
}
}
@@ -1,3 +1,4 @@
package com.seibel.lod.forge.wrappers.modAccessor;
import java.util.HashSet;
@@ -21,4 +22,4 @@ public class OptifineAccessor implements IOptifineAccessor
return null;
}
}
}
+2 -2
View File
@@ -2,7 +2,7 @@
modLoader="javafml" #//mandatory
loaderVersion="[36,)" # // mandatory. This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
license="GNU GPLv3"
issueTrackerURL="https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues"
issueTrackerURL="${issues}"
[[mods]] #//mandatory
@@ -10,7 +10,7 @@ issueTrackerURL="https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues"
version= "${version}" #//mandatory, gets the version number from jar populated by the build.gradle script
displayName="${mod_name}" #//mandatory
#//updateJSONURL="https://change.me.example.invalid/updates.json" # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
displayURL="https://www.curseforge.com/minecraft/mc-mods/distant-horizons"
displayURL="${homepage}"
logoFile="logo.png"
catalogueImageIcon="icon.png"
credits="Massive thanks to: Leonardo, Cola, Ran, and CoolGi. For their hard work to bring Distant Horizons to where it is today. - James"
+4 -3
View File
@@ -2,9 +2,10 @@
"required": true,
"minVersion": "0.8",
"package": "com.seibel.lod.forge.mixins",
"compatibilityLevel": "JAVA_16",
"compatibilityLevel": "JAVA_8",
"mixins": [
"MixinChunkGenerator"
"MixinChunkGenerator",
"MixinTFChunkGenerator"
],
"client": [
"MixinOptionsScreen",
@@ -12,4 +13,4 @@
"MixinFogRenderer"
],
"server": []
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"pack": {
"description": "",
"pack_format": 7
"pack_format": 6
}
}
+30 -14
View File
@@ -1,9 +1,9 @@
org.gradle.jvmargs=-Xmx2048M
minecraft_version=1.17.1
minecraft_version=1.16.5
archives_base_name=DistantHorizons
mod_version=1.6.0a
mod_version=1.6.2a
maven_group=com.seibel.lod
toml_version=3.6.4
@@ -12,19 +12,35 @@ mod_name=Distant Horizons
mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow.
mod_authors=James Seibel, Leonardo Amato, Cola, coolGi2007, Ran, Leetom
mod_homepage=https://www.curseforge.com/minecraft/mc-mods/distant-horizons
mod_source=https://gitlab.com/jeseibel/minecraft-lod-mod/
mod_issues=https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues
# Fabric loader
fabric_loader_version=0.12.6
fabric_api_version=0.37.1+1.17
# Fabric mods
modmenu_version=2.0.14
starlight_version_fabric=3442770
lithium_version=mc1.17.1-0.7.5
sodium_version=3605275
iris_version=1.17.x-v1.1.4
immersive_portals_version = 0.14-1.17
fabric_loader_version=0.13.2
fabric_api_version=0.42.0+1.16
# Fabric mod versions
modmenu_version=1.16.22
lithium_version=mc1.16.5-0.6.6
sodium_version=3488820
iris_version=1.16.x-v1.1.4
# Fabric mod run
# 0 = Dont enable and dont run
# 1 = Can be refranced in code but dosnt run
# 2 = Can be refranced in code and runs in client
enable_lithium=0
enable_sodium=1
enable_iris=0
# Forge loader
forge_version=37.1.1
# Forge mods
starlight_version_forge=3457784
forge_version=36.2.28
# Forge mod versions
terraforged_version=3285909
# Forge mod run
# 0 = Dont enable and dont run
# 1 = Can be refranced in code but dosnt run
# 2 = Can be refranced in code and runs in client
enable_terraforged=1
Binary file not shown.