Compare commits

...

578 Commits

Author SHA1 Message Date
dfsek 3f3ce89b1f update readme to reflect licensing change 2021-04-02 23:58:55 -07:00
dfsek 1bf95eee36 relicense API under LGPLv3 2021-04-02 23:57:11 -07:00
dfsek 8a933609ee Merge pull request #107 from PolyhedralDev/ver/5.1.2
5.1.2 LootPopulateEvent patch
2021-04-01 15:14:14 -07:00
dfsek ba4a50e234 add getStructureScript method to LootPopulateEvent 2021-04-01 15:03:48 -07:00
dfsek f8e8ce8bc2 Bump version 2021-03-31 20:50:17 -07:00
dfsek 0013d4e682 Merge pull request #106 from PolyhedralDev/ver/5.1.2
Add LootPopulateEvent and EntitySpawnEvent
2021-03-31 20:49:44 -07:00
dfsek 9a97f1178d release modrinth to beta channel 2021-03-31 08:34:17 -07:00
dfsek e6a551d84d add getter/setter for loot table in LootPopulateEvent 2021-03-30 09:23:21 -07:00
dfsek 92921430d8 add EntitySpawnEvent 2021-03-30 00:27:16 -07:00
dfsek 20c905aae4 add LootPopulateEvent 2021-03-30 00:19:32 -07:00
dfsek ec0730ef73 test commit so version is different B) 2021-03-29 21:14:34 -07:00
dfsek e4576b3405 Add modrinth publish task 2021-03-29 21:09:36 -07:00
dfsek c5800970a8 i totally didnt forget to bump version 2021-03-29 16:39:10 -07:00
dfsek 8f88b1c156 Merge pull request #101 from PolyhedralDev/ver/5.1.1
API to add populators, Buildscript improvements
2021-03-29 16:26:59 -07:00
dfsek 1360994a67 Add options to disable default populators 2021-03-29 11:56:16 -07:00
dfsek e00b28d27e remove sysout 2021-03-29 10:07:25 -07:00
dfsek c5ff5c101d custom biome color configuration 2021-03-29 09:52:54 -07:00
dfsek b1a1001c49 clean up buildscripts 2021-03-26 08:50:58 -07:00
dfsek 77d5162e73 add API for addons to register populators 2021-03-23 11:40:22 -07:00
dfsek 2e8cd54ac2 Merge pull request #96 from PolyhedralDev/ver/5.1.0
Address several issues
2021-03-17 10:53:32 -07:00
dfsek 28222c074e bump version 2021-03-16 22:29:13 -07:00
dfsek 1b70766a17 remove legacy fractal trees (will be available in an addon) 2021-03-16 21:49:08 -07:00
dfsek cda2d4688c implement DynamicBlockFunction 2021-03-16 21:20:02 -07:00
dfsek 5028582198 add smart waterlog 2021-03-16 21:04:56 -07:00
dfsek 5458564cfa fix CommandTest issues 2021-03-16 11:06:58 -07:00
dfsek 7f11373f75 Merge pull request #80 from PolyhedralDev/ver/5.0.0
Addon loader, fleshed out addon API, and Fabric finalization
2021-03-16 10:45:42 -07:00
dfsek f9ca8d139b fix ExpressionFunction issue 2021-03-16 09:09:30 -07:00
dfsek 6f287a1894 use LinkedHashMap for loading functions to preserve order 2021-03-15 23:24:49 -07:00
dfsek 6f4251796e optimize ores and sampling 2021-03-15 21:15:53 -07:00
dfsek 5ad349e350 document event API 2021-03-14 23:54:10 -07:00
dfsek ec4e0694a4 add structure locate command 2021-03-14 16:45:32 -07:00
dfsek 6ab8cd5b5b fix mushrooms on fabric 2021-03-14 16:30:27 -07:00
dfsek b3868bd750 allow paralithic expressions to be defined in expression samplers 2021-03-13 15:18:25 -07:00
dfsek ff8181bbfa fix function loading issues 2021-03-13 14:48:02 -07:00
dfsek 074ad44bca add Gabor noise 2021-03-11 19:03:57 -07:00
dfsek 9a6c34a2d5 fix fabric teleportation issues 2021-03-10 16:33:55 -07:00
dfsek ce3c0f105e more specific duplicate ID message 2021-03-10 16:26:15 -07:00
dfsek 58162027a9 specify problematic addon class 2021-03-10 16:21:04 -07:00
dfsek 39400cce0a Merge pull request #89 from PolyhedralDev/dev/commands
Platform-agnostic command API
2021-03-10 16:16:40 -07:00
dfsek 819d795c23 Fabric cleanup 2021-03-10 16:16:11 -07:00
dfsek d6b5f60b18 implement Bukkit-specific commands 2021-03-10 16:08:25 -07:00
dfsek 1f16a82a8d implement GeometryCommands 2021-03-10 16:02:25 -07:00
dfsek 51fa58b481 add command main-menu messages 2021-03-10 15:52:20 -07:00
dfsek bed8c561a4 add "usage" to all commands 2021-03-10 15:33:38 -07:00
dfsek fdb2441b1a export command 2021-03-10 15:28:50 -07:00
dfsek bf5be91868 clean up WorldHandle, add generic utility classes 2021-03-10 15:20:17 -07:00
dfsek 06956a7a2d fix command NPEs on invalid IDs 2021-03-10 03:20:34 -07:00
dfsek a584ac2401 Bukkit command cleanup/fixes 2021-03-10 03:03:04 -07:00
dfsek 513c6a647f Bukkit command cleanup 2021-03-10 02:54:03 -07:00
dfsek 5a85aced45 BiomeInfoCommand 2021-03-10 02:50:40 -07:00
dfsek 41933b84a0 implement entity teleportation and biome locate 2021-03-10 02:46:00 -07:00
dfsek 67aae87754 work on fabric commands 2021-03-10 01:57:01 -07:00
Daniil Z 13346daa6a Russian translation (#88)
* Russian translation

* Move file to commons
2021-03-09 23:30:14 -07:00
dfsek 5e9b841cac trigger block re-render on Fabric 2021-03-09 23:20:47 -07:00
dfsek 5820fe1db3 fix imageloader issue 2021-03-09 20:05:52 -07:00
dfsek f5c0174473 more command stuff 2021-03-09 20:05:42 -07:00
dfsek 31b583910e fabric command fixes 2021-03-09 03:48:26 -07:00
dfsek fac4cb43a8 cleanup fabric commands 2021-03-09 03:15:43 -07:00
dfsek 0f39d64d72 sort of working Fabric commands 2021-03-09 03:07:02 -07:00
dfsek 5fc012f7ba injection for argumentparser 2021-03-08 23:56:58 -07:00
dfsek f773ca2322 ArgumentTarget and SwitchTarget 2021-03-08 23:56:06 -07:00
dfsek 52c56af02c tab completion 2021-03-08 03:17:22 -07:00
dfsek 22d6fdf293 add tab completion 2021-03-08 02:27:35 -07:00
dfsek b1256427a2 basic bukkit implementation 2021-03-08 01:40:12 -07:00
dfsek 026a6066d3 implement switches 2021-03-08 00:52:57 -07:00
dfsek 0cd5898107 fix child command issues 2021-03-08 00:38:52 -07:00
dfsek a5d101ff61 fix child command issues 2021-03-08 00:38:52 -07:00
dfsek c1b04d1772 argument parsing 2021-03-08 00:14:19 -07:00
dfsek 0d58201e3f mock command API 2021-03-07 23:44:19 -07:00
dfsek 939121dea6 Merge pull request #87 from PolyhedralDev/dev/fabric
Fabric stuff
2021-03-07 23:42:01 -07:00
dfsek c44d26cc18 loom is pain 2021-03-07 21:41:13 -07:00
dfsek c047209b86 manually create terra-refmap.json because loom is dumb 2021-03-06 22:26:13 -07:00
dfsek f989e4dc89 fix fabric mixin stuff 2021-03-06 11:37:28 -07:00
dfsek c8c3ab312b separate generator and GeneratorWrapper 2021-03-06 10:05:11 -07:00
dfsek dc52dd635b update README.md 2021-03-03 15:59:26 -07:00
dfsek 4e97ba6da9 Merge remote-tracking branch 'origin/ver/5.0.0' into ver/5.0.0 2021-03-03 13:42:22 -07:00
dfsek c0d26256af fix typo 2021-03-03 13:42:15 -07:00
dfsek 7828de74aa work on loom stuff 2021-03-02 00:30:26 -07:00
dfsek 01396e739c Merge pull request #84 from PolyhedralDev/dev/world-maps
World specific config pack instances
2021-03-01 18:41:30 -07:00
dfsek e4c1a056ae fix server issues 2021-03-01 17:20:19 -07:00
dfsek 613e9c0c54 fabric ID fix 2021-03-01 16:54:56 -07:00
dfsek c5a174ba7a remove sys.out 2021-03-01 16:49:32 -07:00
dfsek 72296cf960 cleanup 2021-03-01 16:45:27 -07:00
dfsek 265449c5a7 fix ProbabilityCollection map issues 2021-03-01 16:43:14 -07:00
dfsek 1125b498ec remove unneeded generic from BiomeBuilder 2021-03-01 15:39:10 -07:00
dfsek a28f3fa660 working WorldConfig impl 2021-03-01 15:20:09 -07:00
dfsek 5a6b7ac4c1 begin work on WorldConfig stuff
This doesn't compile right now. A lot of work needs to be done.
2021-03-01 09:58:18 -07:00
dfsek 7f988dcf26 implement FabricDirectional 2021-02-25 01:43:01 -07:00
dfsek 7c177d568b implement FabricRotatable 2021-02-25 01:33:10 -07:00
dfsek 12af19edba fabric entities 2021-02-25 01:21:28 -07:00
dfsek 924bc6e469 Fabric Enchantments 2021-02-25 00:57:36 -07:00
dfsek 4569a9ed13 working damage 2021-02-25 00:45:25 -07:00
dfsek 4ca2f0c08d fabric inventory stuff 2021-02-24 23:46:43 -07:00
dfsek 4a47815be7 remove assumption that world starts at Y=0 2021-02-24 19:49:39 -07:00
dfsek dd446b3034 add HPROF to ignored files 2021-02-24 14:12:30 -07:00
dfsek 0fcc0f798c fabric cleanup, move lang and config to common 2021-02-24 13:59:25 -07:00
dfsek 1637644bdd accesswideners B) 2021-02-24 13:14:21 -07:00
dfsek 2b114f225e bump version 2021-02-24 09:54:20 -07:00
dfsek 32746e8dd9 target 1.16.5 for Fabric 2021-02-24 09:40:56 -07:00
dfsek d29c1e572e basic Fabric pack selection 2021-02-24 09:17:44 -07:00
dfsek bb6dcb3880 fix structure buffer weirdness 2021-02-24 08:51:42 -07:00
dfsek 3c56813d6b cursed #equals 2021-02-24 02:00:47 -07:00
dfsek 5c0482e972 more fabric stuff 2021-02-24 01:33:19 -07:00
dfsek 83f981111a remove debug stuff 2021-02-23 22:36:29 -07:00
dfsek 4171768cc9 semi working fabric inventories 2021-02-23 22:33:08 -07:00
dfsek df2acfaa40 FabricMobSpawner 2021-02-23 20:44:40 -07:00
dfsek 533380107b working FabricSign 2021-02-23 17:29:39 -07:00
dfsek 9c2b844290 preparations for Sponge API8 2021-02-23 15:57:27 -07:00
dfsek 98c1fea7fd more fabric stuff 2021-02-22 22:23:57 -07:00
dfsek 415df211ed fabric cleanup 2021-02-22 21:41:15 -07:00
dfsek ac09e059fc caves on fabric actually work now 2021-02-22 21:02:59 -07:00
dfsek 268cc7c48b fabric stuff 2021-02-22 20:47:06 -07:00
dfsek 358bd350b5 MaterialData is gone 2021-02-22 19:47:15 -07:00
dfsek a328ff2f2a refactor API 2021-02-22 16:13:53 -07:00
dfsek 46a08e49f5 registry stuff 2021-02-22 10:32:38 -07:00
dfsek 05cd0b625c notnull annotations 2021-02-21 23:08:51 -07:00
dfsek 5e940187d9 documentation 2021-02-21 22:25:00 -07:00
dfsek 8b196716a4 CheckedRegistry API 2021-02-21 22:04:29 -07:00
dfsek 6025e0f557 cleanup 2021-02-21 17:49:07 -07:00
dfsek e00209c99c rework chunkgenerator API to allow easier extension 2021-02-21 14:19:42 -07:00
dfsek 03e9f6b882 more cleanup 2021-02-20 23:59:17 -07:00
dfsek fab8c90e92 clean up ChunkGenerator API 2021-02-20 23:49:47 -07:00
dfsek 3b719d0880 add dependency injection API 2021-02-20 23:23:17 -07:00
dfsek 45dbe45fb4 set up dependency stuff 2021-02-20 22:31:13 -07:00
dfsek 76f2a3fbc4 fleshed out addon loading 2021-02-19 22:49:11 -07:00
dfsek 5e761c3e29 basic addon loading 2021-02-19 20:36:35 -07:00
dfsek 6d51da3118 Merge pull request #77 from PolyhedralDev/ver/4.3.0
Noise Changes
2021-02-18 20:39:49 -07:00
dfsek 839f429806 documentation 2021-02-18 20:34:36 -07:00
dfsek e533180dab add GaussianNoiseSampler 2021-02-18 19:51:25 -07:00
dfsek 40b9c6c08c Add KernelSampler 2021-02-18 16:04:22 -07:00
dfsek c8c9247dfe cleanup 2021-02-17 22:14:03 -07:00
dfsek 7f8749239f add ConstantNoiseTemplate, bump version 2021-02-17 18:35:49 -07:00
dfsek 2b84967e05 fix freq issues 2021-02-17 17:39:14 -07:00
dfsek 6446f9b4a7 Merge remote-tracking branch 'origin/ver/4.3.0' into ver/4.3.0 2021-02-17 17:13:36 -07:00
dfsek 5933f97f93 add ExpressionFunction 2021-02-17 17:13:28 -07:00
dfsek d670fc904f Merge branch 'master' into ver/4.3.0 2021-02-17 10:37:14 -07:00
dfsek 33371675e1 add event priorities 2021-02-17 10:35:38 -07:00
dfsek bd91506069 remove unneeded setSeed call 2021-02-17 01:50:13 -07:00
dfsek 393a92730f fix frequency issues 2021-02-17 01:40:31 -07:00
dfsek 5ff016ea1f finish new noise options, remove FastNoise 2021-02-17 01:30:52 -07:00
dfsek 84b8df6d96 calculate bounding in fractal types. 2021-02-17 00:16:54 -07:00
dfsek 353999aa45 cleanup 2021-02-17 00:15:49 -07:00
dfsek 4a4e7e42cc split up FastNoise 2021-02-16 15:35:13 -07:00
dfsek 06cd1dc562 use event API for registration of Bukkit trees 2021-02-16 12:57:35 -07:00
dfsek 48296fb14a Add separate publishing for Bukkit impl 2021-02-16 10:43:13 -07:00
dfsek b3a4c3af19 Merge pull request #76 from PolyhedralDev/functionregistry
Function Registry and Event System
2021-02-16 10:12:48 -07:00
dfsek c0773be780 add getters for all registries to ConfigPack 2021-02-15 22:38:57 -07:00
dfsek 79df7eed21 cleanup 2021-02-15 21:12:18 -07:00
dfsek 14ce12f08e Finish event system 2021-02-15 21:11:10 -07:00
dfsek 7cfa96f925 implement Event API 2021-02-15 19:56:55 -07:00
dfsek 4131b45c6f Merge pull request #72 from PolyhedralDev/asmparser
Implement Paralithic expression parser
2021-02-15 18:01:00 -07:00
dfsek 4bf31d863e bump paralithic version 2021-02-15 15:53:59 -07:00
dfsek 92db30e181 move expressions to registry 2021-02-14 23:08:43 -07:00
dfsek 0f152f9281 remove tstructure yelling 2021-02-14 22:15:26 -07:00
dfsek 7ca779f845 improve logging 2021-02-14 22:15:09 -07:00
dfsek 76a2d08906 remove debug logging 2021-02-14 21:45:15 -07:00
dfsek 161b047c39 cleanup 2021-02-14 16:27:45 -07:00
dfsek 8309ad665e refactor registries 2021-02-14 14:31:14 -07:00
dfsek b6e414f944 completely redo biome loading 2021-02-14 14:19:45 -07:00
dfsek 36db83b253 Merge remote-tracking branch 'origin/master' into asmparser
# Conflicts:
#	build.gradle.kts
2021-02-12 14:30:28 -07:00
dfsek c4e641069d Merge remote-tracking branch 'origin/asmparser' into asmparser 2021-02-12 14:29:50 -07:00
dfsek 5e40fbbf07 add image align options 2021-02-12 14:29:39 -07:00
dfsek 8a47a01dd8 bump listener to highest priority 2021-02-12 14:17:14 -07:00
dfsek e41587dbd9 fix user defined functions 2021-02-11 08:35:13 -07:00
dfsek d5de91a864 fix minor sapling issues 2021-02-07 22:15:42 -07:00
dfsek f8cf61e281 bump version for patch config update 2021-02-07 18:00:51 -07:00
dfsek 7323b051db remove debug logging 2021-02-07 16:30:33 -07:00
dfsek 72f86e68e8 Merge remote-tracking branch 'origin/master' into asmparser 2021-02-07 16:18:02 -07:00
dfsek 5f9b21ea09 apparently this got removed somehow 2021-02-07 15:49:33 -07:00
dfsek dd44839bd3 Merge pull request #57 from PolyhedralDev/biome
Biome Stuff
2021-02-07 15:40:45 -07:00
dfsek b8cec40317 cleanup again 2021-02-07 13:58:17 -07:00
dfsek 19f781af31 fix Directional rotations 2021-02-07 00:52:18 -07:00
dfsek af825761c7 update to latest Paralithic 2021-02-06 22:41:42 -07:00
dfsek 490fed8c2c Merge branch 'biome' into asmparser
# Conflicts:
#	platforms/bukkit/build.gradle.kts
2021-02-06 22:28:53 -07:00
dfsek 85efa44673 cleanup 2021-02-06 22:03:46 -07:00
dfsek 985443e228 remove unneeded config file 2021-02-06 20:14:39 -07:00
dfsek 213182e2ab re-implement noise carvers 2021-02-06 19:14:07 -07:00
dfsek 76eb0f3fe0 respect function loading order 2021-02-05 23:30:46 -07:00
M3RGeo a2f3752c31 Update afr_sa.yml (#73) 2021-02-05 13:21:54 -07:00
dfsek 4aebb83b0c improve biome mutation noise functions 2021-02-05 11:07:12 -07:00
dfsek 7418d67b09 update to latest paralithic 2021-02-04 00:03:57 -07:00
dfsek 565266992f paralithic implementation 2021-02-03 23:15:36 -07:00
dfsek 1863ba29fc implement UserDefinedFunction 2021-01-31 01:41:05 -07:00
dfsek e600b50a11 refactor biome templates 2021-01-30 21:34:55 -07:00
dfsek 762c3064d9 use fancy new tectonic stuff for biome stage loading 2021-01-30 15:23:29 -07:00
dfsek b99fabcf1d redo noise config loading with new tectonic object goodies 2021-01-30 12:02:06 -07:00
dfsek af248ee14a begin refactoring with Tectonic Object Templates 2021-01-30 03:22:13 -07:00
dfsek c834d80206 refactor NoiseSampler 2021-01-30 00:16:16 -07:00
dfsek 66fb481ac2 cleanup 2021-01-29 10:54:04 -07:00
dfsek 7858cc34c2 add DomainWarpedSampler 2021-01-29 10:30:03 -07:00
dfsek e306a0fd09 ImageSampler implementation 2021-01-29 10:09:19 -07:00
dfsek 02d61d0764 completely redo noise config loading (mostly keeps parity with old configs) 2021-01-29 01:52:12 -07:00
dfsek dddf644c34 Remove 2d base eq options. Closes #70. 2021-01-29 00:46:55 -07:00
dfsek a8266f99b1 implement NormalNormalizer 2021-01-28 15:26:17 -07:00
dfsek 2fb30322ff actually register overridden vars 2021-01-27 20:06:40 -07:00
snake d05fdeb94c Update ja_jp (#64) 2021-01-27 16:39:42 -07:00
dfsek dfec463765 add biome specific vars 2021-01-27 00:37:30 -07:00
dfsek f6967be95f biome cleanup 2021-01-26 21:50:56 -07:00
dfsek 82fa9abe15 more refactoring 2021-01-25 23:29:15 -07:00
dfsek 1d6cdf9eaa refactor 2021-01-25 19:34:29 -07:00
dfsek 89f52a22c8 fix domain warp frequency issue 2021-01-25 11:12:20 -07:00
dfsek dca0891e00 basic noise carver implementation 2021-01-24 21:14:21 -07:00
dfsek bd4812ef2b clean up noise eqs 2021-01-24 02:56:50 -07:00
dfsek ce62f1d7ac implement ChunkAccess 2021-01-24 01:58:51 -07:00
dfsek da5d3fe0ce refactor API 2021-01-24 01:46:01 -07:00
dfsek 3318161c44 cleanup biome config loading 2021-01-21 22:20:40 -07:00
dfsek 25acda4410 add rotation and rotationDegrees functions 2021-01-21 20:35:52 -07:00
dfsek 115bb414c0 configurable blend weight 2021-01-21 20:29:25 -07:00
dfsek 708ef16a1c reduce pipeline boilerplate 2021-01-21 20:00:51 -07:00
dfsek 8b501ddcde redo biome blending 2021-01-21 18:18:43 -07:00
dfsek 5b8beebaa3 fix fabric stuff 2021-01-20 18:49:45 -07:00
dfsek 7b6d195615 fix BiomeTest 2021-01-19 23:38:23 -07:00
dfsek 9e830abb90 image to biome stuff 2021-01-18 23:56:46 -07:00
dfsek 01d0d4c00a Merge pull request #59 from PolyhedralDev/structurelocate
StructureLocateEvent implementation
2021-01-18 14:53:15 -07:00
dfsek 4b21fcd80a add elevation weight, add "self" biome opt 2021-01-17 21:55:08 -07:00
dfsek af5b316326 fix minor biome issues 2021-01-17 04:05:30 -07:00
dfsek beb18c6e2c Merge branch 'structurelocate' into biome
# Conflicts:
#	build.gradle.kts
2021-01-17 01:25:28 -07:00
dfsek 09c1957ab6 StructureLocateEvent implementation 2021-01-16 17:30:11 -07:00
dfsek b2c3498a32 create DistributionTest 2021-01-16 14:37:00 -07:00
dfsek 20de531c8f custom noise functions per palette layer 2021-01-15 15:08:59 -07:00
dfsek 6d1dd3acbf terrascript should be thread safe now 2021-01-15 00:59:04 -07:00
dfsek 346a8826aa add domain warp controls to FastNoiseLite 2021-01-15 00:03:01 -07:00
dfsek 25f6f3dbe1 debug log structure exception 2021-01-14 21:26:05 -07:00
dfsek 87f7af1e1b fix tree determinism issues 2021-01-14 20:48:07 -07:00
dfsek 764344b4ef synchronize maps 2021-01-14 20:40:57 -07:00
dfsek d327909389 implement multiple vanilla biomes per custom biome 2021-01-14 20:28:52 -07:00
dfsek c1fdfa94f1 improve elevation interp (TEMP DISABLE CARVING) 2021-01-14 18:40:03 -07:00
LeoDog896 d65c700bb9 [ImgBot] Optimize images (#53)
/platforms/fabric/src/main/resources/assets/terra/icon.png -- 142.09kb -> 126.82kb (10.75%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>

Co-authored-by: ImgBotApp <ImgBotHelp@gmail.com>
2021-01-14 11:24:13 -07:00
dfsek cbc2885c16 replace dumb caches with guava caches 2021-01-14 00:34:23 -07:00
dfsek 8fd3530653 configurable cache sizes 2021-01-13 23:51:23 -07:00
dfsek 244f0fba11 protect against biome cell overflow 2021-01-13 22:12:18 -07:00
dfsek 56a0d5d15b Revert "use getUngeneratedBlock for trees"
This reverts commit ca8cc8bc
2021-01-13 20:03:01 -07:00
dfsek ca8cc8bc66 use getUngeneratedBlock for trees 2021-01-13 20:02:34 -07:00
dfsek 627f1b75d6 add BorderMutator to config 2021-01-13 19:02:51 -07:00
dfsek 18731a5aa0 remove unused biome opts 2021-01-13 19:02:38 -07:00
dfsek 4bd943ae7b implement getUngeneratedBlock 2021-01-13 17:48:30 -07:00
dfsek e04d363123 fix minor issues 2021-01-13 17:10:29 -07:00
dfsek d1c018690d minor perf improvements 2021-01-13 14:03:52 -07:00
dfsek 54f732176d implement biome pipeline config loader 2021-01-13 10:48:45 -07:00
dfsek fb32531584 implementation of BiomePipeline 2021-01-13 00:19:57 -07:00
dfsek 5c9a9c7dfa implement BiomePipeline 2021-01-12 22:36:16 -07:00
dfsek fc46c8bd4d fix border issues 2021-01-12 21:10:46 -07:00
dfsek f28759d07a add BorderMutator 2021-01-12 19:25:01 -07:00
dfsek 93c33ca455 refactor TerraBiome 2021-01-12 17:39:26 -07:00
dfsek 9c50dc2ef9 smoothing stuff 2021-01-12 17:22:49 -07:00
dfsek 883124d8ab basic framework 2021-01-12 16:32:21 -07:00
dfsek 1ee2b180d4 bump version 2021-01-12 11:10:17 -07:00
dfsek e6e2c62474 Merge pull request #50 from PolyhedralDev/palette
Noise config additions
2021-01-12 10:34:42 -07:00
dfsek 5df511a940 white noise micro opt 2021-01-11 22:00:10 -07:00
dfsek 462b0af225 normalization options 2021-01-11 20:23:41 -07:00
dfsek 5c469ed378 noise function flora and tree dist 2021-01-11 17:07:25 -07:00
dfsek c59ab5d917 fix lookup issue 2021-01-11 16:28:53 -07:00
dfsek 8a10a9807d allow configuration of 2d/3d noise in palettes 2021-01-11 14:37:56 -07:00
dfsek 623a4dea4f allow configuration of cellular lookup function 2021-01-11 13:34:53 -07:00
dfsek 18d7408f53 customizable palette noise 2021-01-11 13:31:19 -07:00
dfsek 462b6f4198 add publishing stuff 2021-01-10 20:44:56 -07:00
dfsek 1049bb901d complain about tstructure files 2021-01-10 18:08:41 -07:00
dfsek 999c9b565d fix biomegrid wackiness 2021-01-10 17:20:21 -07:00
dfsek 27aeb73157 fix minor version issues 2021-01-10 16:55:49 -07:00
dfsek 12ff9cc146 give gradle more memory 2021-01-10 16:19:16 -07:00
dfsek f114baebd6 better tab completion, fix testWithPaper task 2021-01-10 14:37:44 -07:00
dfsek 11a6546064 oops 2021-01-10 00:01:53 -07:00
dfsek 771e42d1a8 Add Terra name classifier to Jars 2021-01-09 23:58:46 -07:00
dfsek 5e3c12298b oops forgot nether trees 2021-01-09 23:14:16 -07:00
dfsek a5dd4a63d1 minor fixes/improvements 2021-01-09 22:26:39 -07:00
dfsek 9fbe117f78 fix fabric stuff 2021-01-09 12:00:18 -07:00
dfsek 3429165aca Merge pull request #43 from PolyhedralDev/agnostic
Platform-agnostic engine & TerraScript structures
2021-01-09 11:30:34 -07:00
dfsek 9310114c0e cleanup 2021-01-09 02:58:02 -07:00
dfsek 141b4f86ae cleanup 2021-01-09 02:25:48 -07:00
dfsek 67ffd91641 add enchantment to loot tables 2021-01-09 02:25:36 -07:00
dfsek 9a94485c91 add white noise to FastNoiseLite 2021-01-08 11:51:07 -07:00
dfsek 28b6fe49bb rework image stuff 2021-01-07 22:04:35 -07:00
dfsek 308ba887a3 add getOrigin functions 2021-01-07 17:18:38 -07:00
dfsek d2a1901f44 add max structure recursion depth 2021-01-07 16:38:07 -07:00
dfsek 64391f3abc remove unused random parameter from populators 2021-01-07 10:33:23 -07:00
dfsek e47b3f0397 add message to export command, more cleanup 2021-01-07 09:45:40 -07:00
dfsek c6ff808cce fix //regen and cleanup 2021-01-06 21:07:57 -07:00
dfsek e9d0c14eee cleanup biomegrids 2021-01-06 13:32:46 -07:00
dfsek 23d8a0aeeb skip over buffer when pasting trees 2021-01-06 11:56:17 -07:00
dfsek 512edae9c6 Multi-version support for 1.13-1.16 2021-01-06 10:57:34 -07:00
dfsek 25ae2b3c9b drastically increase script loading speed via optimised token pipeline 2021-01-06 01:11:13 -07:00
dfsek 44176f7ee6 fix Marks 2021-01-05 22:19:11 -07:00
dfsek 47cad8a30b refactor, cleanup, and perf improvements 2021-01-05 19:21:42 -07:00
dfsek 4ad2db3ca8 improve state function IDs 2021-01-05 14:51:49 -07:00
Roan-V 24a5a9425e Added dutch translation (#45) 2021-01-05 11:20:13 -07:00
DeltaRays 1cdf4478b8 Italian translation (#44)
* Created italian translation

* Revert "Created italian translation"

This reverts commit 74fe8ffe13.

* Created the italian translation file

(and translated everything in it to italian)
2021-01-05 10:15:52 -07:00
dfsek b67814d68a update to latest tectonic 2021-01-05 02:25:06 -07:00
dfsek 5a64424b16 reimplement ender eye redirection 2021-01-05 02:04:05 -07:00
dfsek 32b3b4cd3f fix StructureScript return issues 2021-01-05 02:00:01 -07:00
dfsek d0a24f7041 add spawner state info 2021-01-05 01:23:54 -07:00
dfsek aa406d9b8b properly handle BufferedStateManipulator application exception 2021-01-05 01:07:58 -07:00
dfsek a38eba2916 implement StateFunction 2021-01-05 01:04:15 -07:00
dfsek aec1d671fa fix StructureScript#test 2021-01-04 21:59:29 -07:00
dfsek 26504d6d83 revert some stuff 2021-01-04 10:52:51 -07:00
dfsek 87a1b0bf5a multithreaded jankiness 2021-01-04 09:39:39 -07:00
dfsek bd0726db37 implement properties in janky pregen 2021-01-04 01:58:25 -07:00
dfsek 75fbda5a9f continue work on janky pregenerator 2021-01-04 01:29:51 -07:00
dfsek ee093397d3 begin work on janky pregenerator 2021-01-04 00:21:49 -07:00
dfsek 3c12a98ef3 update .gitignore 2021-01-03 21:52:11 -07:00
dfsek fff918e0ee Add CheckBlockFunction, which mustn't be discussed without mentioning that it shall be covered with disclaimers. 2021-01-03 20:29:10 -07:00
dfsek 1536a13d3c fix minor issues & cleanup 2021-01-03 20:16:59 -07:00
dfsek b26847f250 implement BiomeFunction 2021-01-03 19:49:15 -07:00
dfsek c7d3e5294a fix mem leak 2021-01-03 19:43:26 -07:00
dfsek 86d42a03a0 decrease default cache size 2021-01-03 13:57:47 -07:00
dfsek bf4a831781 fix GridSpawn salt 2021-01-03 13:33:03 -07:00
dfsek 90cc88f05f set min heap size in testWithPaper 2021-01-03 13:28:10 -07:00
dfsek 315230af27 implement SamplerCache for drastically increased structure perf 2021-01-03 13:24:17 -07:00
dfsek fed24920f8 Add error message to BiomeGridFactory 2021-01-02 20:19:18 -07:00
dfsek a785d7b892 add 2d biomes support 2021-01-02 20:19:08 -07:00
dfsek de9eb26ebc fix check fail for search 2021-01-02 18:33:28 -07:00
dfsek a5105f9f9d implement precedence matrix and NegationOperation 2021-01-02 03:40:51 -07:00
dfsek 0fef1619d2 implement ModuloOperation 2021-01-02 01:08:45 -07:00
dfsek b209c49877 BukkitRail 2021-01-02 00:50:07 -07:00
dfsek ddc218c4d4 Add more math functions 2021-01-02 00:44:26 -07:00
dfsek 77f348912f completely redo internal TerraScript args 2021-01-02 00:44:16 -07:00
dfsek 6bac82da25 fix terrascript loading logging 2021-01-01 19:55:33 -07:00
dfsek a51727b636 fix exporting weirdness 2021-01-01 18:09:58 -07:00
dfsek ec722014e6 finalize commands 2021-01-01 17:45:06 -07:00
dfsek 256761eb5b fix version command 2021-01-01 17:43:10 -07:00
dfsek 07731c06c0 implement biome commands 2021-01-01 17:36:53 -07:00
dfsek 556584f9f5 improve BukkitAdapter, fix LocateCommand 2021-01-01 16:05:42 -07:00
dfsek 61c93b47ca implement EntityFunction 2021-01-01 03:28:06 -07:00
dfsek 044aa738a3 cleanup & add entity support 2021-01-01 01:50:01 -07:00
dfsek 8da2b63f31 refactor 2021-01-01 00:27:36 -07:00
dfsek ce033b0956 implement LootFunction 2021-01-01 00:08:03 -07:00
dfsek a9df684b80 reimplement loot tables 2020-12-31 23:20:16 -07:00
dfsek 356771bcea work on inventory stuff 2020-12-31 20:37:14 -07:00
dfsek 166c0f7dfb reimplement structure spawn command 2020-12-31 16:10:45 -07:00
dfsek aa41cc4d3d only allow loop flow control in loop 2020-12-31 02:49:48 -07:00
dfsek 0c3e3f2bc6 fix flow keyword issues 2020-12-31 02:44:33 -07:00
dfsek 792b6efd12 allow data to be returned 2020-12-31 02:30:41 -07:00
dfsek 122fbd841c correct scope wackiness in for loops 2020-12-31 02:06:53 -07:00
dfsek ad5823055d do precedence better 2020-12-31 02:03:47 -07:00
dfsek 92afe1c9ab refactor blockdata 2020-12-31 01:50:47 -07:00
dfsek 1826adf1c2 remove more logging 2020-12-30 21:38:23 -07:00
dfsek 97f6cda4ad remove debug logging 2020-12-30 21:10:52 -07:00
dfsek bccfcdf9a1 implement check cache 2020-12-30 21:03:28 -07:00
dfsek 8049824170 improve Transformer st handling 2020-12-30 20:32:55 -07:00
dfsek 99acadaf59 fix tscript comment issues 2020-12-30 18:05:32 -07:00
dfsek 2be4b36d1a configurable blending distance 2020-12-30 17:57:16 -07:00
dfsek c283f37390 fix spawn checks at biome edge 2020-12-30 13:55:15 -07:00
Haurum d21d448947 Create da.yml (#42) 2020-12-30 13:33:31 -07:00
dfsek d16c28aebd cleanup generation code 2020-12-30 03:19:39 -07:00
dfsek ce45bacc6f better biome blending 2020-12-30 01:45:20 -07:00
dfsek a68b85c522 elevation tweaks & general cleanup 2020-12-30 00:03:02 -07:00
dfsek 7d0149b59d brain moment 2020-12-29 19:23:37 -07:00
dfsek 447c82f74a StructureFunction returns boolean based on pass/fail 2020-12-27 21:08:48 -07:00
dfsek 8db263e19b fix EOF issues 2020-12-27 20:55:01 -07:00
dfsek 7cf34dbd8a allow single statement loops 2020-12-27 20:52:35 -07:00
dfsek 283495832f Add else if and else 2020-12-27 20:42:42 -07:00
dfsek f6312a01d7 reimplement locate command 2020-12-27 00:27:58 -07:00
dfsek c7d43142f2 remove structure bound 2020-12-26 22:43:51 -07:00
dfsek c4da858095 reimplement structure probability collections 2020-12-26 22:22:17 -07:00
dfsek 5ff47bad18 improve cache configs 2020-12-26 21:36:15 -07:00
dfsek 18819ae53d fabric implementations 2020-12-26 03:06:25 -07:00
dfsek ddc2cea427 implement all Bukkit block data 2020-12-26 01:38:54 -07:00
dfsek bc17597923 Implement structure caching mechanism 2020-12-25 22:39:52 -07:00
dfsek 49f3c16a38 Implement BukkitOrientable 2020-12-25 21:47:56 -07:00
dfsek 5db1494341 implement script structures with chunkification(tm) 2020-12-25 20:43:41 -07:00
dfsek cccb706ad5 pass random to structure gen 2020-12-25 20:22:19 -07:00
dfsek c6d7d1a947 implement PullFunction 2020-12-25 17:46:29 -07:00
dfsek 9685dbbb9d Fix IntermediateBuffer 2020-12-25 17:46:22 -07:00
dfsek a18d459343 implement BukkitDirectional and BukkitRotatable 2020-12-25 17:06:23 -07:00
dfsek 4b5013231c implement Marks 2020-12-25 15:26:58 -07:00
dfsek a04bcf5b23 fix bukkit slab implementation 2020-12-25 13:06:15 -07:00
dfsek 1c579e8e5b improve ParseException 2020-12-25 12:08:22 -07:00
dfsek bbab6e39ff enforce scope definitions in for loop declarations 2020-12-25 02:51:52 -07:00
dfsek 2e68a0db5d parser cleanup 2020-12-25 02:40:29 -07:00
dfsek abc59901c1 Add for loops 2020-12-25 00:12:28 -07:00
dfsek aaa0c99524 Add FailKeyword 2020-12-24 23:10:14 -07:00
dfsek 0780539326 reimplement sapling override 2020-12-24 14:58:53 -07:00
dfsek c8434e73ef implement robust equals and hashcode in Vector3 2020-12-24 02:49:27 -07:00
dfsek 058ec9f24d store structures in Buffer 2020-12-24 02:40:28 -07:00
dfsek 7127943298 remove chunk apply method 2020-12-24 02:17:46 -07:00
dfsek 9adc03d56b Reimplement structure trees with TerraScripts 2020-12-24 02:06:19 -07:00
dfsek 5d6b060dee Add math functions 2020-12-24 02:06:05 -07:00
dfsek fc82eff93b add remapShadedJar task to Fabric 2020-12-23 23:03:42 -07:00
dfsek 1c316e52a9 Exporting 2020-12-23 23:02:58 -07:00
dfsek 76afd54d3c use epsilon for numeric equals 2020-12-23 15:19:33 -07:00
dfsek 7fe7dac57a implement RecursionsFunction 2020-12-23 15:09:42 -07:00
dfsek 63e59692e2 Implement StructureFunction and temp RandomFunction 2020-12-23 03:08:31 -07:00
dfsek 405a96034c Load structure scripts into registry 2020-12-23 02:35:07 -07:00
dfsek e9dc7428b8 document new tokens 2020-12-23 01:43:53 -07:00
dfsek b4342a36aa implement break, return, and continue 2020-12-23 01:37:51 -07:00
dfsek 1158ae958a refactor rotations, reimplement RotationUtil 2020-12-22 22:48:31 -07:00
dfsek 062c9b5efb Pass rotation to Item#apply 2020-12-22 22:41:51 -07:00
dfsek 66e8647517 rework loaders to allow traversing filenames 2020-12-22 20:11:01 -07:00
dfsek f47b975fe7 implement block & check functions 2020-12-22 17:32:17 -07:00
dfsek e5d9ae62fa more cleanup 2020-12-22 15:13:01 -07:00
dfsek 9c1eab04b9 Cleanup & fix grouping related operator precedence issues 2020-12-22 14:49:58 -07:00
dfsek 72d4370878 fix various tokenizer issues 2020-12-22 02:58:42 -07:00
dfsek 88da796923 Implement variable reassignment and while loops 2020-12-22 02:39:53 -07:00
dfsek 2ab4ed871c check if var/function is already defined in scope. 2020-12-22 02:20:46 -07:00
dfsek 0ecd275c56 Fix comment whitespace tokenizer issues 2020-12-22 02:13:35 -07:00
dfsek 4f40bcbe5e Implement variables 2020-12-22 02:00:40 -07:00
dfsek cb7b3de48c better type checking for function args 2020-12-21 22:30:02 -07:00
dfsek 13fbb9bf54 Implement boolean binary operations AND and OR 2020-12-21 21:08:43 -07:00
dfsek be8ed913e5 allow grouping binary operations 2020-12-21 20:55:51 -07:00
dfsek fe17683d27 cleanup, refactor, remove logging 2020-12-21 20:36:48 -07:00
dfsek 7d72a91bb7 implement comparison operators 2020-12-21 20:31:57 -07:00
dfsek 7a75f20a2c implement operator precedence 2020-12-21 16:22:08 -07:00
dfsek 8a7499d874 binary operations work now 2020-12-21 02:01:42 -07:00
dfsek adc5f0becc more parsing reworks 2020-12-21 01:28:40 -07:00
dfsek 6d710ca442 set up framework for binary operations 2020-12-20 16:46:44 -07:00
dfsek 7cbf8dffbe parse things in a less dumb way 2020-12-20 14:04:33 -07:00
dfsek e1cb46c8fd basic structure implementation 2020-12-20 02:21:29 -07:00
dfsek 8b97d74e0a allow constant expressions in if statements 2020-12-20 01:50:41 -07:00
dfsek c4f927e72c account for dangling opening/closing brace 2020-12-20 01:43:50 -07:00
dfsek 2880c29f8c if statements with code blocks 2020-12-20 01:08:37 -07:00
dfsek 474962db39 add escape character to parser string literals 2020-12-19 21:03:14 -07:00
dfsek f970838ecf Working parser/tokenizer 2020-12-19 20:04:58 -07:00
dfsek 29e2746e72 working tokenizer 2020-12-19 01:50:56 -07:00
dfsek 1ce884d1c7 Merge branch 'structure-rewrite' into agnostic
# Conflicts:
#	common/src/test/java/structure/LookaheadTest.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/Function.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/Parser.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/tokenizer/Char.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/tokenizer/Lookahead.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/tokenizer/Position.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/tokenizer/Token.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/tokenizer/Tokenizer.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/tokenizer/Tokens.java
#	platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/structure/v2/tokenizer/exceptions/TokenizerException.java
2020-12-18 20:50:41 -07:00
dfsek 24697ae60f Refactor API 2020-12-18 19:57:42 -07:00
dfsek 53c554f25c Gaea is gone 2020-12-18 19:46:19 -07:00
dfsek d1af8c1224 Begin absorbing Gaea into Terra 2020-12-18 19:36:27 -07:00
dfsek 9ac098f1ca Fix fractal trees 2020-12-18 16:55:36 -07:00
dfsek 300fe10da5 Cleanup 2020-12-18 15:44:16 -07:00
dfsek b33c8d6b77 fix population order 2020-12-18 15:35:09 -07:00
dfsek b06a755154 Trees work on Fabric now 2020-12-18 15:31:12 -07:00
dfsek 817b962c4a Move all pops to feature 2020-12-18 15:13:59 -07:00
dfsek 56c52e860d Version bump (releasing minor config update to fix config issues) 2020-12-18 02:27:19 -07:00
dfsek fd89c1128a fix order of population in FabricChunkGeneratorWrapper 2020-12-18 02:07:20 -07:00
dfsek beec1a97d4 Implement flora as a Feature on Fabric 2020-12-16 02:38:48 -07:00
dfsek b955e3d9b9 Register Fabric biomes as actual modded biomes. 2020-12-16 01:07:04 -07:00
dfsek b12079694c Add Validator API & cleanup Fabric 2020-12-16 00:26:05 -07:00
dfsek 7a83584317 Fix minor build issues 2020-12-15 11:02:14 -07:00
dfsek 1c4cc090af Merge remote-tracking branch 'origin/agnostic' into agnostic 2020-12-15 02:37:46 -07:00
solonovamax a614d7dddd Completely redo how gradle works (#40)
* make getWorldEdit() never null.

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* Locate commands work like vanilla

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* Completely rework all the gradle stuff for the subprojects

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* Update gradle version

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* make :common an api in the bukkit build.gradle

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* Move git clone function to CommonConfig.kt + make processResources depend on downloadDefaultPacks

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* clean up common build.gradle.kts

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* remove sponge

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* rename fabric group from com.dfsek.terra.bukkit to com.dfsek.terra.fabric

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* idk why this was removed some how?

It shows it's still in the main repo, but it was removed for me /shrug

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* Fix shading issues.

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* Fix issues with fabric-loom being stupid and requiring the plugin on the root project.

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
2020-12-15 02:37:38 -07:00
dfsek ae21b8305a Begin work on not jank world implementation 2020-12-15 02:37:21 -07:00
dfsek 6f6767ab86 Trees no longer crash fabric. they are incredibly dumb on fabric so i will do them later 2020-12-15 02:03:54 -07:00
dfsek ee35c371ec Trees on Bukkit 2020-12-14 23:53:01 -07:00
dfsek 4d59c27a13 Reimplement fractal trees 2020-12-14 22:51:45 -07:00
dfsek 0dc0742e81 Implement Transformer API 2020-12-14 22:51:25 -07:00
dfsek 3b0abb7a20 Add access widener to mod.json 2020-12-14 18:19:34 -07:00
dfsek 42231cf319 fabric slabs & MultipleFacing 2020-12-14 17:09:47 -07:00
dfsek 11c8025ef4 Fix Fabric carver cache flushing 2020-12-14 16:33:19 -07:00
dfsek eda976bb5d Fix Fabric main config loading 2020-12-14 16:33:08 -07:00
dfsek 49c445d0f7 Implement some BlockData stuff on Fabric, make stuff less jank 2020-12-14 15:38:40 -07:00
dfsek 875e1feafe population order/invocation is now per-platform 2020-12-14 12:44:16 -07:00
dfsek 5f5504100b Codec stuff 2020-12-14 12:28:57 -07:00
dfsek 2215c8a98c fix mem leak & increase perf 2020-12-14 02:19:18 -07:00
dfsek ebe887def0 Remove unused constructor param from FabricBlock 2020-12-14 02:00:42 -07:00
dfsek 1dded41311 Flora and ores on Fabric 2020-12-14 01:27:28 -07:00
dfsek 6db4755109 Fix biome gen 2020-12-13 23:13:02 -07:00
dfsek a01dee9a27 Custom carving implemented in Fabric 2020-12-13 22:40:57 -07:00
dfsek 582bde8d0e register features 2020-12-13 21:16:33 -07:00
dfsek f609727afb Vanilla biome setting (sort of) works on Fabric now 2020-12-13 17:18:19 -07:00
dfsek a058f1c58b BiomeGrid no longer needs World object. 2020-12-13 15:21:55 -07:00
dfsek 70abf69dc7 Terra on Fabric 2020-12-13 03:52:10 -07:00
dfsek 269ec257b5 fabric stuff 2020-12-13 03:44:49 -07:00
dfsek 2c15a9fc0c Successful default config load in Fabric 2020-12-13 02:00:15 -07:00
SkytAsul 0826246cbe Created and completed fr_fr.yml (#39) 2020-12-12 20:13:01 -07:00
dfsek a3add9b20f Begin Sponge implementation 2020-12-12 19:23:28 -07:00
dfsek 6c20b5911f Sponge 2020-12-12 16:54:39 -07:00
dfsek d779b3ea27 testWithPaper task moved to Bukkit subproject 2020-12-12 16:24:01 -07:00
dfsek 618e7ed12e Fabric stuff still doesnt work, but eh 2020-12-12 15:31:00 -07:00
dfsek d84dd3a526 Super basic Fabric stuff 2020-12-12 01:44:56 -07:00
dfsek 27dbd494bd Rotation & tree stuff 2020-12-11 19:31:25 -07:00
dfsek 15100caf32 Ocean 2020-12-11 17:51:09 -07:00
dfsek 4e9c7e0b91 Carving 2020-12-11 17:45:49 -07:00
dfsek 0261ecdcbb for some reason these werent in the changelist 2020-12-11 17:31:06 -07:00
dfsek 5bf699cba9 Look ma, no Bukkit API in the core package 2020-12-11 17:30:17 -07:00
dfsek 7ee1d2c391 Predefined Flora 2020-12-11 00:11:37 -07:00
dfsek 5c9c47d078 Fix Location clone issue 2020-12-10 23:13:35 -07:00
dfsek af5309ff21 Populators work now 2020-12-10 23:09:53 -07:00
dfsek c7539dc5dd haha yes it works sort of 2020-12-10 22:47:53 -07:00
dfsek 4b2c2d8ba2 Actually register loaders 2020-12-10 21:46:09 -07:00
dfsek ee529a5973 refactor 2020-12-10 21:39:31 -07:00
dfsek 3e04dc6b46 it compiles now B) 2020-12-10 21:35:14 -07:00
dfsek dbf4b4dd3b Implementation go brrrr 2020-12-10 20:39:55 -07:00
dfsek 560fdf17fa Implement a whole bunch of stuff 2020-12-10 18:13:54 -07:00
dfsek 7a61a2548b Implement more stuff 2020-12-10 15:23:43 -07:00
solonovamax 31361286b5 Slight change to how world edit is loaded + make locate commands like vanilla (#38)
* make getWorldEdit() never null.

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* Locate commands work like vanilla

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
2020-12-10 14:57:05 -07:00
dfsek abd29c1cb4 Do a whole bunch of stuff [DOES NOT COMPILE] 2020-12-10 14:15:02 -07:00
dfsek 9f4e120283 Implement Block interface 2020-12-10 12:28:59 -07:00
dfsek d9f585e4b2 make Handle separate interface 2020-12-10 11:51:30 -07:00
dfsek f4456f46a7 API stuff 2020-12-10 11:42:17 -07:00
dfsek 3dc27f2b0a Fix minor Gaea related issues 2020-12-10 10:52:02 -07:00
dfsek 95e39324c7 Dump Gaea into Terra. 2020-12-10 10:46:56 -07:00
dfsek 392ba59741 Begin reimplementing agnostic versions of Bukkit classes with delegate implementations 2020-12-10 10:19:16 -07:00
dfsek 26228d2c71 Tokenizer stuff 2020-12-10 09:49:46 -07:00
dfsek 8f58ba17a8 Begin work on tokenizer 2020-12-10 01:26:39 -07:00
dfsek 75f39640b0 Allow registering custom WorldHandle 2020-12-10 00:25:15 -07:00
dfsek 42dcc159e9 Implement WorldHandle 2020-12-09 22:13:10 -07:00
dfsek 791faa6dfd Apparently Walls have a separate rotation thing too 2020-12-09 17:18:04 -07:00
dfsek aea2b23fc3 Flora rotation options 2020-12-09 14:07:33 -07:00
dfsek 47438b7db9 Fix reloading issues 2020-12-09 01:36:21 -07:00
dfsek df3d3c6398 Fix profiler 2020-12-08 21:26:42 -07:00
dfsek 1457a10b0b hold PluginConfig instance in Terra plugin instance 2020-12-08 20:59:23 -07:00
dfsek 2b6e8eb67c Dependency injection moment 2020-12-08 20:35:18 -07:00
dfsek 11cb11bc2b Merge remote-tracking branch 'origin/master'
# Conflicts:
#	build.gradle.kts
2020-12-08 20:12:09 -07:00
dfsek bb5552c8bc Fix build issue causing lang to not be bundled 2020-12-08 20:10:55 -07:00
dfsek 8f5a9b7b8e Hold ConfigRegistry in Terra instance 2020-12-08 19:48:46 -07:00
dfsek 7e365c351d Ceiling ocean slabs 2020-12-08 19:36:06 -07:00
dfsek a0f0206ed8 Add GridSpawn seed option 2020-12-08 19:10:56 -07:00
dfsek 554628c486 Slabs can generate on ceiling in ocean 2020-12-08 19:10:46 -07:00
dfsek 37c2d945ec Bump version 2020-12-08 12:32:51 -07:00
Glare 59a24ef37f Implemented alternative ProcessResources (#36) 2020-12-08 09:26:16 -07:00
dfsek ad58a1efeb Fix raw loading issue 2020-12-07 18:51:34 -07:00
dfsek 682b155deb Fix structure features 2020-12-07 18:21:59 -07:00
dfsek 0e0d84fea7 Fix structure pull infinite loop 2020-12-07 00:59:27 -07:00
dfsek 4ceb4e22d4 make TerraBiomeGrid abstract, add TerraRadialBiomeGrid implementation & config options
Also adds lots of BiomeGrid validation stuff
2020-12-07 00:24:40 -07:00
solonovamax 2ae2801058 Remove editor specific files (#34)
* removed Terra.iml

* removed .idea directory
2020-12-06 16:58:24 -07:00
dfsek 5189aa5003 Use CodeMC for dependencies 2020-12-06 16:57:24 -07:00
dfsek 87cc2d01cb Don't do events in non-Terra worlds 2020-12-06 15:22:35 -07:00
dfsek f86fe4db32 Fix carving shift blocks 2020-12-06 02:52:21 -07:00
dfsek 1940309954 Remove singleton getter 2020-12-06 02:47:14 -07:00
dfsek d946ea9b15 Refactor Debug class, set up framework for Paper-specific events. 2020-12-06 02:25:15 -07:00
dfsek 0f8ce8966a Use Tectonic for world configs 2020-12-06 02:15:34 -07:00
dfsek c9b2c83dc4 Fix structure location issue. 2020-12-06 01:45:43 -07:00
dfsek 2d24a7bf00 Add more info to biome info command 2020-12-05 17:53:35 -07:00
dfsek 4c80a71bca Fix carving issues 2020-12-05 17:53:16 -07:00
dfsek 264f1df172 Update profiler target times 2020-12-05 16:13:17 -07:00
dfsek 5b17d87a97 Carving is now very much optimized 2020-12-05 16:11:56 -07:00
dfsek 0e4df43ddb carvers go brrrrrrr 2020-12-05 15:59:48 -07:00
dfsek 3d7796d8c3 carver speedup finalization 2020-12-05 03:19:39 -07:00
dfsek 4e647620f0 speed up carving even more 2020-12-05 02:56:58 -07:00
dfsek a38fcef6f1 Don't extract ZIPs, just bundle them 2020-12-04 22:30:30 -07:00
dfsek b5fdeef535 Re-add gradle wrapper because for some reason it was deleted 2020-12-04 21:46:12 -07:00
dfsek 5d3ae11374 Merge pull request #31 from PolyhedralDev/tectonic
Tectonic Implementation
2020-12-04 21:35:42 -07:00
dfsek 7db75ab21b Fix minor loading issue 2020-12-04 21:34:48 -07:00
dfsek 3d12af6b21 Add version key to config pack. 2020-12-04 21:09:35 -07:00
dfsek 601eb3e7ff Remove unneeded logging 2020-12-04 21:05:09 -07:00
dfsek 5754a95f48 Add seed variable to carver 2020-12-04 13:54:14 -07:00
dfsek b3e76f6485 Add packs list command. 2020-12-04 00:34:09 -07:00
dfsek 47b3278f96 Fix erosion NPE, add missing config 2020-12-03 22:31:03 -07:00
dfsek 27e31fef9f Improve flora placement algorithm 2020-12-03 01:13:25 -07:00
dfsek 3807b8c277 slabs and stairs generate on ceiling 2020-12-02 21:34:45 -07:00
dfsek 7db83c1dee Bump tectonic version 2020-12-02 15:29:07 -07:00
dfsek 496cd486b1 Carver go brrrr 2020-12-02 01:57:52 -07:00
dfsek 034f1072bf Carvers stop upon entering biome they arent present in. 2020-12-02 00:21:53 -07:00
dfsek b5c99c87e1 Structure features 2020-12-01 23:59:57 -07:00
dfsek c5fe86272e Loot tables 2020-12-01 23:45:09 -07:00
dfsek 15840302e0 Sapling growing and structure location 2020-12-01 23:38:30 -07:00
dfsek 0f526ca616 Cleanup and fix minor issues 2020-12-01 19:36:23 -07:00
dfsek bc3d694f7f Update to latest Tectonic 2020-12-01 01:57:04 -07:00
dfsek 7f880c23b8 Ore fixes 2020-12-01 01:56:51 -07:00
dfsek 7c6aa3a425 fix wacky biome location issue 2020-12-01 00:55:36 -07:00
dfsek 9636c808fe Structures! 2020-12-01 00:43:53 -07:00
dfsek f49ba88cb4 Add author option to config pack 2020-11-30 19:59:28 -07:00
dfsek 0cbc225408 Refactoring n stuff 2020-11-30 17:36:32 -07:00
dfsek f85d047ee6 Fix various issues 2020-11-30 17:23:57 -07:00
dfsek f033b8219c More flora controls 2020-11-30 14:37:28 -07:00
dfsek 1357e7f84e custom trees 2020-11-30 12:29:15 -07:00
dfsek 3eaab219f1 trees 2020-11-30 12:26:46 -07:00
dfsek ce97732da7 Use Tectonic validation API to validate Biome noise equations 2020-11-29 23:57:03 -07:00
dfsek 7fe2fa493e Prevent carvers crossing biomes 2020-11-29 20:08:04 -07:00
dfsek 78acf59f98 Working ZIP file loading 2020-11-29 18:17:29 -07:00
dfsek 1c0954d0cf Extra fancy loading 2020-11-29 15:24:33 -07:00
dfsek fe6ea9511b ZIP file loading should(tm) work now 2020-11-29 14:49:11 -07:00
dfsek 1c9c183d66 more sensitive derivative stuff 2020-11-29 14:12:01 -07:00
dfsek 67ff426894 Calculate derivative for slant palettes 2020-11-29 00:01:21 -07:00
dfsek 6eb5c0e0ec Equation-defined cave radii 2020-11-28 18:56:02 -07:00
dfsek 4e11d5c1cf implement ores, sort of 2020-11-28 18:05:19 -07:00
dfsek 155b293b61 new loading system, begin ZIP loading implementation 2020-11-28 16:45:35 -07:00
dfsek 282bfe9c5d begin work on ores 2020-11-28 02:34:43 -07:00
dfsek 4ddace2a92 Flora 2020-11-28 02:03:05 -07:00
dfsek 4b7b0ee7e9 live reloading 2020-11-27 15:53:52 -07:00
dfsek af6ba33921 carvers 2020-11-27 15:40:14 -07:00
dfsek 622e65e7a5 slab 2020-11-27 15:17:16 -07:00
dfsek 2f9f89042c probably a good idea to actually register variables 2020-11-27 14:32:31 -07:00
dfsek 538000ed32 Merge remote-tracking branch 'origin/tectonic' into tectonic 2020-11-27 14:17:12 -07:00
solonovamax fe676db0ce Vanilla ore (#28)
* Vanilla ore

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>

* Fast math

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
2020-11-27 14:17:01 -07:00
dfsek 30e89a0b69 fix typo 2020-11-27 13:29:57 -07:00
dfsek 8e49f7ec26 Add BIOME: identifier to BiomeGridRegistry 2020-11-27 13:06:20 -07:00
dfsek 86088d1dcd Ocean 2020-11-27 02:30:31 -07:00
dfsek 5c6ea59d30 make perf not suck 2020-11-27 02:17:41 -07:00
dfsek f364420007 Actually gets to world gen now B) 2020-11-27 02:08:25 -07:00
dfsek 96ff875d2b More loading stuff 2020-11-27 01:17:32 -07:00
dfsek 717ece9d1f More loaders 'n stuff 2020-11-27 00:59:15 -07:00
dfsek 013216ad8c Registries are pretty cool, I guess 2020-11-26 22:05:18 -07:00
dfsek 16d8d56832 Add a bunch of type loaders 2020-11-26 21:26:01 -07:00
dfsek 06d9fa1d98 Actually load configs on startup 2020-11-26 20:51:06 -07:00
dfsek 59141f99bd That's quite the commit you got there 2020-11-26 19:07:43 -07:00
dfsek dbbe7dbd0d Implement Tectonic for master config. 2020-11-25 01:57:02 -07:00
dfsek c46161fc87 Include latest parsii 2020-11-24 17:08:02 -07:00
solonovamax 70ec483581 Action (should work) (#25)
Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
2020-11-24 17:03:04 -07:00
823 changed files with 32926 additions and 9262 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = false
max_line_length = 120
max_line_length = 140
tab_width = 4
ij_continuation_indent_size = 8
ij_formatter_off_tag = @formatter:off
+40
View File
@@ -0,0 +1,40 @@
# This workflow will build a Java project with Gradle
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Java CI with Gradle
on:
push:
tags:
- "v*" # Push events to matching v*, i.e. v1.0, v20.15.10
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build Terra
run: gradle shadowJar
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: Package
path: build/libs
- name: Publish release
uses: marvinpinto/action-automatic-releases@latest
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
prerelease: false
files: |
build/libs/Terra-*.jar
LICENSE
+7
View File
@@ -52,6 +52,7 @@ gradle-app.setting
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*.hprof
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
@@ -137,3 +138,9 @@ build
!lib/*.jar
.idea/Terra.iml
/run/
.idea/**.iml
/lang/
/packs/
/config.yml
/region/
-8
View File
@@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
</component>
</project>
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="/usr/share/java/gradle" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
-23
View File
@@ -1,23 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="54" name="Java" />
</Languages>
</inspection_tool>
<inspection_tool class="NonSerializableObjectPassedToObjectStream" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SerialVersionUIDNotStaticFinal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SerializableHasSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreAnonymousInnerClasses" value="false" />
<option name="superClassString" value="java.awt.Component" />
</inspection_tool>
<inspection_tool class="SerializableInnerClassHasSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreAnonymousInnerClasses" value="false" />
<option name="superClassString" value="java.awt.Component" />
</inspection_tool>
<inspection_tool class="SerializableStoresNonSerializable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TransientFieldInNonSerializableClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TransientFieldNotInitialized" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
-85
View File
@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="papermc" />
<option name="name" value="papermc" />
<option name="url" value="https://papermc.io/repo/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="parsii.local" />
<option name="name" value="parsii" />
<option name="url" value="file:$PROJECT_DIR$/../parsii/repo" />
</remote-repository>
<remote-repository>
<option name="id" value="local" />
<option name="name" value="local" />
<option name="url" value="file:lib" />
</remote-repository>
<remote-repository>
<option name="id" value="aikar" />
<option name="name" value="aikar" />
<option name="url" value="https://repo.aikar.co/content/groups/aikar/" />
</remote-repository>
<remote-repository>
<option name="id" value="enginehub-maven" />
<option name="name" value="enginehub-maven" />
<option name="url" value="http://maven.enginehub.org/repo/" />
</remote-repository>
<remote-repository>
<option name="id" value="spigotmc-repo" />
<option name="name" value="spigotmc-repo" />
<option name="url" value="https://hub.spigotmc.org/nexus/content/repositories/snapshots/" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="enginehub" />
<option name="name" value="enginehub" />
<option name="url" value="https://maven.enginehub.org/repo/" />
</remote-repository>
<remote-repository>
<option name="id" value="minecraft-repo" />
<option name="name" value="minecraft-repo" />
<option name="url" value="https://libraries.minecraft.net/" />
</remote-repository>
<remote-repository>
<option name="id" value="gaea.local" />
<option name="name" value="gaea" />
<option name="url" value="file:$PROJECT_DIR$/../Gaea/repo" />
</remote-repository>
<remote-repository>
<option name="id" value="gaea.local" />
<option name="name" value="gaea-local" />
<option name="url" value="file:$PROJECT_DIR$/../Gaea/repo" />
</remote-repository>
<remote-repository>
<option name="id" value="CodeMC" />
<option name="name" value="CodeMC" />
<option name="url" value="https://repo.codemc.org/repository/maven-public" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:$MAVEN_REPOSITORY$/" />
</remote-repository>
</component>
</project>
-25
View File
@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0">
<entry_point TYPE="field" FQNAME="com.dfsek.terra.util.StructureTypeEnum NETHER_FORTRESS" />
</entry_points>
<list size="1">
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
-124
View File
@@ -1,124 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
Generated
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+21 -11
View File
@@ -1,20 +1,30 @@
# Terra
Terra is a data-driven world generator based on [Gaea](https://github.com/PolyhedralDev/Gaea). Find out more on our
[Spigot page](https://www.spigotmc.org/resources/85151/)!
Terra is an incredibly powerful free & open-source data-driven, platform-agnostic world generator. It allows you to create a world exactly
to your specifications, with no knowledge of Java required.
## Downloads:
* Paper+ servers (Paper, Tuinity, Purpur, etc): [SpigotMC](https://www.spigotmc.org/resources/85151/)
* Fabric: [Modrinth](https://modrinth.com/mod/terra) / [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
## Licensing
Terra as a whole is licensed under the GNU General Public License, version 3.0. Terra's API is licensed under the GNU Lesser General Public
License, version 3.0, in order to allow linking to the API without GPL infection.
## Building and running Terra
To build, simply run `./gradlew build` on Linux/MacOS, or `gradlew.bat build` on Windows.
This will produce a jar in `build/libs` called `Terra-[CURRENT VERSION].jar`.
You can put this right into your plugins dir, along with the correct Gaea version.
To build, simply run `./gradlew build` (`gradlew.bat build` on Windows). This will produce a jar in `build/libs`
called `Terra-[CURRENT VERSION].jar`. You can put this right into your plugins dir, along with the correct Gaea version.
If you would like to test it with a default server config, just run `./gradlew setupServer` or
`./gradlew.bat setupServer` to set up the server, then `./gradlew testWithPaper` or `gradlew.bat testWithPaper` to run
the server. If you want a clean installation of the server, re-run the `setupServer` task.
This will download a default server config from [here](https://github.com/PolyhedralDev/WorldGenTestServer)
`./gradlew.bat setupServer` to set up the server, then `./gradlew testWithPaper` or `gradlew.bat testWithPaper` to run the server. If you
want a clean installation of the server, re-run the `setupServer` task. This will download a default server config
from [here](https://github.com/PolyhedralDev/WorldGenTestServer)
and install the server in the `target/server` directory, along with all the needed plugins.
**Note: You will need to adjust the `NAME` variable `bukkit.yml` of the test server if you are not using the default
Terra config.**
**Note: You will need to adjust the `NAME` variable `bukkit.yml` of the test server if you are not using the default Terra config.**
## Contributing
Contributions are welcome! If you want to see a feature in Terra, please, open an issue, or implement it yourself and
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="CheckStyle-IDEA-Module">
<option name="configuration">
<map />
</option>
</component>
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>SPIGOT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
</module>
+6 -226
View File
@@ -1,200 +1,11 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import java.io.ByteArrayOutputStream
import java.net.URL
import java.nio.channels.Channels
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardCopyOption
//import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
import com.dfsek.terra.getGitHash
plugins {
java
maven
id("com.github.johnrengelman.shadow").version("6.1.0")
val versionObj = Version("5", "1", "2", true)
allprojects {
version = versionObj
group = "com.dfsek.terra"
}
repositories {
flatDir {
dirs("lib")
}
maven { url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") }
maven { url = uri("http://maven.enginehub.org/repo/") }
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
// maven { url = uri("https://maven.pkg.github.com/solonovamax/Gaea") }
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
val versionObj = Version("1", "5", "0", true)
version = versionObj
dependencies {
val gaeaVersion = "1.14.3"
compileOnly(name = "Gaea-${gaeaVersion}", group = "")
testImplementation(name = "Gaea-${gaeaVersion}", group = "")
compileOnly("org.jetbrains:annotations:20.1.0")
implementation("commons-io:commons-io:2.4")
implementation("org.apache.commons:commons-imaging:1.0-alpha2")
compileOnly("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT")
implementation("org.bstats:bstats-bukkit:1.7")
compileOnly("com.googlecode.json-simple:json-simple:1.1")
implementation(name = "parsii-1.2.1", group = "")
compileOnly("org.spigotmc:spigot-api:1.16.2-R0.1-SNAPSHOT")
implementation("io.papermc:paperlib:1.0.5")
implementation("net.jafama:jafama:2.3.2")
// JUnit.
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0")
}
val compileJava: JavaCompile by tasks
val mainSourceSet: SourceSet = sourceSets["main"]
val tokenizeJavaSources = task<Copy>(name = "tokenizeJavaSources") {
from(mainSourceSet.allSource) {
include("**/plugin.yml")
println("version: $versionObj")
val tokens = mapOf("VERSION" to versionObj.toString())
filter(org.apache.tools.ant.filters.ReplaceTokens::class, "tokens" to tokens)
}
into("build/tokenizedSources")
includeEmptyDirs = false
}
compileJava.apply {
dependsOn(tokenizeJavaSources)
options.encoding = "UTF-8"
doFirst {
options.compilerArgs = mutableListOf("-Xlint:all")
}
}
tasks.test {
useJUnitPlatform()
maxHeapSize = "4G"
ignoreFailures = false
failFast = true
maxParallelForks = 12
}
tasks.named<ShadowJar>("shadowJar") {
from(tokenizeJavaSources.destinationDir)
archiveClassifier.set("")
archiveBaseName.set("Terra")
setVersion(project.version)
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
relocate("org.bstats.bukkit", "com.dfsek.terra.lib.bstats")
relocate("parsii", "com.dfsek.terra.lib.parsii")
relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib")
relocate("net.jafama", "com.dfsek.terra.lib.jafama")
minimize()
}
tasks.build {
dependsOn(tasks.shadowJar)
// dependsOn(testWithPaper)
// testWithPaper.mustRunAfter(tasks.shadowJar)
}
val testDir = "target/server/"
val setupServer = tasks.create("setupServer") {
dependsOn(tasks.shadowJar)
doFirst {
// clean
file("${testDir}/").deleteRecursively()
file("${testDir}/plugins").mkdirs()
// Downloading latest paper jar.
val paperUrl = URL("https://papermc.io/api/v1/paper/1.16.4/latest/download")
val paperReadableByteChannel = Channels.newChannel(paperUrl.openStream())
val paperFile = file("${testDir}/paper.jar")
val paperFileOutputStream = paperFile.outputStream()
val paperFileChannel = paperFileOutputStream.channel
paperFileChannel.transferFrom(paperReadableByteChannel, 0, Long.MAX_VALUE)
// Cloning test setup.
gitClone("https://github.com/PolyhedralDev/WorldGenTestServer")
// Copying plugins
Files.move(Paths.get("WorldGenTestServer/plugins"),
Paths.get("$testDir/plugins"),
StandardCopyOption.REPLACE_EXISTING)
// Copying config
val serverText = URL("https://raw.githubusercontent.com/PolyhedralDev/WorldGenTestServer/master/server.properties").readText()
file("${testDir}/server.properties").writeText(serverText)
val bukkitText = URL("https://raw.githubusercontent.com/PolyhedralDev/WorldGenTestServer/master/bukkit.yml").readText()
file("${testDir}/bukkit.yml").writeText(bukkitText.replace("\${world}", "world").replace("\${gen}", "Terra:DEFAULT"))
File("${testDir}/eula.txt").writeText("eula=true")
// clean up
file("WorldGenTestServer").deleteRecursively()
}
}
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
doFirst {
// Downloading latest paper jar.
// if (file("${buildDir}/resources/main/packs/default").exists() && file("${buildDir}/resources/main/packs/nether").exists())
// return@doFirst
// else
file("${buildDir}/resources/main/packs/").deleteRecursively()
val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/default.zip")
downloadAndUnzipPack(defaultPackUrl)
val netherPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/nether.zip")
downloadAndUnzipPack(netherPackUrl)
}
}
tasks.processResources.get().dependsOn(downloadDefaultPacks)
val testWithPaper = task<JavaExec>(name = "testWithPaper") {
standardInput = System.`in`
dependsOn(tasks.shadowJar)
// Copy Terra into dir
doFirst {
copy {
from("${buildDir}/libs/Terra-${versionObj}.jar")
into("${testDir}/plugins/")
}
}
main = "io.papermc.paperclip.Paperclip"
jvmArgs = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200",
"-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch",
"-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M",
"-XX:G1ReservePercent=20", "-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4",
"-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90",
"-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem",
"-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs",
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear")
maxHeapSize = "2G"
args = listOf("nogui")
workingDir = file("${testDir}/")
classpath = files("${testDir}/paper.jar")
}
/**
* Version class that does version stuff.
*/
@@ -208,34 +19,3 @@ class Version(val major: String, val minor: String, val revision: String, val pr
"$major.$minor.$revision-BETA+${getGitHash()}"
}
}
fun getGitHash(): String {
val stdout = ByteArrayOutputStream()
exec {
commandLine = mutableListOf("git", "rev-parse", "--short", "HEAD")
standardOutput = stdout
}
return stdout.toString().trim()
}
fun gitClone(name: String) {
val stdout = ByteArrayOutputStream()
exec {
commandLine = mutableListOf("git", "clone", name)
standardOutput = stdout
}
}
fun downloadAndUnzipPack(packUrl: URL) {
ZipInputStream(packUrl.openStream()).use { zip ->
while (true) {
val entry = zip.nextEntry ?: break
if (entry.isDirectory)
file("${buildDir}/resources/main/packs/${entry.name}").mkdirs()
else
file("${buildDir}/resources/main/packs/${entry.name}").outputStream().use { output ->
output.write(zip.readBytes())
}
}
}
}
+13
View File
@@ -0,0 +1,13 @@
plugins {
`kotlin-dsl`
kotlin("jvm") version embeddedKotlinVersion
}
repositories {
mavenCentral()
gradlePluginPortal()
}
dependencies {
"implementation"("com.github.jengelman.gradle.plugins:shadow:+")
}
@@ -0,0 +1,47 @@
package com.dfsek.terra
import org.gradle.api.Project
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.withType
import java.io.ByteArrayOutputStream
fun Project.configureCommon() {
apply(plugin = "java-library")
apply(plugin = "maven-publish")
apply(plugin = "idea")
configureDependencies()
configureCompilation()
configureDistribution()
version = rootProject.version
tasks.withType<Test>().configureEach {
useJUnitPlatform()
maxHeapSize = "2G"
ignoreFailures = false
failFast = true
maxParallelForks = 12
}
}
fun Project.getGitHash(): String {
val stdout = ByteArrayOutputStream()
exec {
commandLine = mutableListOf("git", "rev-parse", "--short", "HEAD")
standardOutput = stdout
}
return stdout.toString().trim()
}
fun Project.gitClone(name: String) {
val stdout = ByteArrayOutputStream()
exec {
commandLine = mutableListOf("git", "clone", name)
standardOutput = stdout
}
}
@@ -0,0 +1,38 @@
package com.dfsek.terra
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.filter
import org.gradle.kotlin.dsl.withType
import org.gradle.language.jvm.tasks.ProcessResources
fun Project.configureCompilation() {
configure<JavaPluginConvention> {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
doFirst {
options.compilerArgs = mutableListOf("-Xlint:all")
}
}
tasks.withType<ProcessResources> {
include("**/*.*")
filter<org.apache.tools.ant.filters.ReplaceTokens>(
"tokens" to mapOf(
"VERSION" to project.version.toString()
)
)
}
tasks.withType<Javadoc> {
options.encoding = "UTF-8"
}
}
@@ -0,0 +1,26 @@
package com.dfsek.terra
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.repositories
fun Project.configureDependencies() {
repositories {
maven { url = uri("http://maven.enginehub.org/repo/") }
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
maven { url = uri("https://maven.fabricmc.net/") }
gradlePluginPortal()
jcenter()
mavenCentral()
}
dependencies {
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
"testImplementation"("org.yaml:snakeyaml:1.27")
"testImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
"compileOnly"("org.jetbrains:annotations:20.1.0")
}
}
@@ -0,0 +1,81 @@
package com.dfsek.terra
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.plugins.BasePluginConvention
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.kotlin.dsl.*
import java.io.File
import java.net.URL
fun Project.configureDistribution() {
apply(plugin = "java-library")
apply(plugin = "com.github.johnrengelman.shadow")
configurations {
val shaded = create("shaded")
getByName("compile").extendsFrom(shaded)
val shadedApi = create("shadedApi")
shaded.extendsFrom(shadedApi)
getByName("api").extendsFrom(shadedApi)
val shadedImplementation = create("shadedImplementation")
shaded.extendsFrom(shadedImplementation)
getByName("implementation").extendsFrom(shadedImplementation)
}
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
group = "terra"
doFirst {
file("${buildDir}/resources/main/packs/").deleteRecursively()
val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/default.zip")
downloadPack(defaultPackUrl, project)
val netherPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/nether.zip")
downloadPack(netherPackUrl, project)
}
}
tasks["processResources"].dependsOn(downloadDefaultPacks)
tasks.withType<Jar> {
archiveBaseName.set("Terra-${archiveBaseName.get()}")
from("../LICENSE", "../../LICENSE")
}
tasks.register<Jar>("sourcesJar") {
archiveClassifier.set("sources")
}
tasks.register<Jar>("javadocJar") {
dependsOn("javadoc")
archiveClassifier.set("javadoc")
from(tasks.getByName<Javadoc>("javadoc").destinationDir)
}
tasks.named<ShadowJar>("shadowJar") {
// Tell shadow to download the packs
dependsOn(downloadDefaultPacks)
configurations = listOf(project.configurations["shaded"])
archiveClassifier.set("shaded")
setVersion(project.version)
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
relocate("parsii", "com.dfsek.terra.lib.parsii")
relocate("net.jafama", "com.dfsek.terra.lib.jafama")
minimize()
}
convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name
tasks.named<DefaultTask>("build") {
dependsOn(tasks["shadowJar"])
}
}
fun downloadPack(packUrl: URL, project: Project) {
val fileName = packUrl.file.substring(packUrl.file.lastIndexOf("/"))
val file = File("${project.buildDir}/resources/main/packs/${fileName}")
file.parentFile.mkdirs()
file.outputStream().write(packUrl.readBytes())
}
+53
View File
@@ -0,0 +1,53 @@
import com.dfsek.terra.configureCommon
plugins {
`java-library`
`maven-publish`
}
configureCommon()
group = "com.dfsek.terra.common"
dependencies {
"shadedApi"("org.apache.commons:commons-rng-core:1.3")
"shadedApi"("commons-io:commons-io:2.4")
"shadedApi"("com.dfsek:Paralithic:0.3.2")
"shadedApi"("com.dfsek:Tectonic:1.2.3")
"shadedApi"("net.jafama:jafama:2.3.2")
"shadedApi"("org.yaml:snakeyaml:1.27")
"shadedApi"("org.ow2.asm:asm:9.0")
"shadedApi"("commons-io:commons-io:2.6")
"compileOnly"("com.googlecode.json-simple:json-simple:1.1")
"compileOnly"("com.google.guava:guava:30.0-jre")
"testImplementation"("com.google.guava:guava:30.0-jre")
}
publishing {
publications {
create<MavenPublication>("mavenJava") {
artifact(tasks["sourcesJar"])
artifact(tasks["jar"])
}
}
repositories {
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
maven(mavenUrl) {
val mavenUsername: String? by project
val mavenPassword: String? by project
if (mavenUsername != null && mavenPassword != null) {
credentials {
username = mavenUsername
password = mavenPassword
}
}
}
}
}
@@ -0,0 +1,61 @@
package com.dfsek.terra.addon;
import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.addons.annotations.Addon;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class AddonClassLoader extends URLClassLoader {
static {
ClassLoader.registerAsParallelCapable();
}
public AddonClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
public AddonClassLoader(URL[] urls) {
super(urls);
}
@SuppressWarnings("unchecked")
public static Set<Class<? extends TerraAddon>> fetchAddonClasses(File file) throws IOException {
JarFile jarFile = new JarFile(file);
Enumeration<JarEntry> entries = jarFile.entries();
AddonClassLoader loader = new AddonClassLoader(new URL[] {file.toURI().toURL()}, AddonClassLoader.class.getClassLoader());
Set<Class<? extends TerraAddon>> set = new HashSet<>();
while(entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if(entry.isDirectory() || !entry.getName().endsWith(".class")) continue;
String className = entry.getName().substring(0, entry.getName().length() - 6).replace('/', '.');
try {
Class<?> clazz = loader.loadClass(className);
Addon addon = clazz.getAnnotation(Addon.class);
if(addon == null) continue;
if(!TerraAddon.class.isAssignableFrom(clazz))
throw new IllegalArgumentException("Addon class \"" + clazz + "\" must extend TerraAddon.");
set.add((Class<? extends TerraAddon>) clazz);
} catch(ClassNotFoundException e) {
throw new IllegalStateException(e); // this should literally never happen, if it does something is very wrong
}
}
return set;
}
}
@@ -0,0 +1,42 @@
package com.dfsek.terra.addon;
import com.dfsek.terra.addon.exception.AddonLoadException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class AddonPool {
private final Map<String, PreLoadAddon> pool = new HashMap<>();
public void add(PreLoadAddon addon) throws AddonLoadException {
if(pool.containsKey(addon.getId())) {
String message = "Duplicate addon ID: " +
addon.getId() + "; original ID from file: " +
pool.get(addon.getId()).getFile().getAbsolutePath() +
", class: " +
pool.get(addon.getId()).getAddonClass().getCanonicalName() +
"Duplicate ID from file: " +
addon.getFile().getAbsolutePath() +
", class: " +
addon.getAddonClass().getCanonicalName();
throw new AddonLoadException(message);
}
pool.put(addon.getId(), addon);
}
public PreLoadAddon get(String id) {
return pool.get(id);
}
public void buildAll() throws AddonLoadException {
for(PreLoadAddon value : pool.values()) {
value.rebuildDependencies(this, value, true);
}
}
public Set<PreLoadAddon> getAddons() {
return new HashSet<>(pool.values());
}
}
@@ -0,0 +1,58 @@
package com.dfsek.terra.addon;
import com.dfsek.terra.addon.exception.AddonLoadException;
import com.dfsek.terra.addon.exception.CircularDependencyException;
import com.dfsek.terra.addon.exception.DependencyMissingException;
import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.addons.annotations.Addon;
import com.dfsek.terra.api.addons.annotations.Depends;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PreLoadAddon {
private final List<PreLoadAddon> depends = new ArrayList<>();
private final Class<? extends TerraAddon> addonClass;
private final String id;
private final String[] dependencies;
private final File file;
public PreLoadAddon(Class<? extends TerraAddon> addonClass, File file) {
this.addonClass = addonClass;
this.id = addonClass.getAnnotation(Addon.class).value();
this.file = file;
Depends depends = addonClass.getAnnotation(Depends.class);
this.dependencies = depends == null ? new String[] {} : depends.value();
}
public List<PreLoadAddon> getDepends() {
return depends;
}
public void rebuildDependencies(AddonPool pool, PreLoadAddon origin, boolean levelG1) throws AddonLoadException {
if(this.equals(origin) && !levelG1)
throw new CircularDependencyException("Detected circular dependency in addon \"" + id + "\", dependencies: " + Arrays.toString(dependencies));
for(String dependency : dependencies) {
PreLoadAddon preLoadAddon = pool.get(dependency);
if(preLoadAddon == null)
throw new DependencyMissingException("Dependency " + dependency + " was not found. Please install " + dependency + " to use " + id + ".");
depends.add(preLoadAddon);
preLoadAddon.rebuildDependencies(pool, origin, false);
}
}
public String getId() {
return id;
}
public Class<? extends TerraAddon> getAddonClass() {
return addonClass;
}
public File getFile() {
return file;
}
}
@@ -0,0 +1,13 @@
package com.dfsek.terra.addon.exception;
public class AddonLoadException extends Exception {
private static final long serialVersionUID = -4949084729296580176L;
public AddonLoadException(String message) {
super(message);
}
public AddonLoadException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,13 @@
package com.dfsek.terra.addon.exception;
public class CircularDependencyException extends AddonLoadException {
private static final long serialVersionUID = 7398510879124125121L;
public CircularDependencyException(String message) {
super(message);
}
public CircularDependencyException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,13 @@
package com.dfsek.terra.addon.exception;
public class DependencyMissingException extends AddonLoadException {
private static final long serialVersionUID = -8419489102208521583L;
public DependencyMissingException(String message) {
super(message);
}
public DependencyMissingException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
@@ -0,0 +1,7 @@
package com.dfsek.terra.api;
import com.dfsek.tectonic.loading.TypeRegistry;
public interface LoaderRegistrar {
void register(TypeRegistry registry);
}
@@ -0,0 +1,67 @@
package com.dfsek.terra.api;
import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.event.EventManager;
import com.dfsek.terra.api.platform.handle.ItemHandle;
import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.LockedRegistry;
import com.dfsek.terra.api.util.logging.DebugLogger;
import com.dfsek.terra.api.util.logging.Logger;
import com.dfsek.terra.config.PluginConfig;
import com.dfsek.terra.config.lang.Language;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.world.TerraWorld;
import java.io.File;
/**
* Represents a Terra mod/plugin instance.
*/
public interface TerraPlugin extends LoaderRegistrar {
WorldHandle getWorldHandle();
TerraWorld getWorld(World world);
Logger logger();
PluginConfig getTerraConfig();
File getDataFolder();
boolean isDebug();
Language getLanguage();
CheckedRegistry<ConfigPack> getConfigRegistry();
LockedRegistry<TerraAddon> getAddons();
boolean reload();
ItemHandle getItemHandle();
void saveDefaultConfig();
String platformName();
DebugLogger getDebugLogger();
EventManager getEventManager();
default String getVersion() {
return "@VERSION@";
}
/**
* Runs a task that may or may not be thread safe, depending on platform.
* <p>
* Allows platforms to define what code is safe to be run asynchronously.
*
* @param task Task to be run.
*/
default void runPossiblyUnsafeTask(Runnable task) {
task.run();
}
}
@@ -0,0 +1,49 @@
package com.dfsek.terra.api.addons;
import com.dfsek.terra.api.addons.annotations.Addon;
import com.dfsek.terra.api.addons.annotations.Author;
import com.dfsek.terra.api.addons.annotations.Version;
import org.jetbrains.annotations.NotNull;
/**
* Represents an entry point for an addon. Implementations must be annotated with {@link Addon}.
*/
public abstract class TerraAddon {
/**
* Gets the version of this addon.
*
* @return Addon version.
*/
public final @NotNull String getVersion() {
Version version = getClass().getAnnotation(Version.class);
return version == null ? "0.1.0" : version.value();
}
/**
* Gets the author of this addon.
*
* @return Addon author.
*/
public final @NotNull String getAuthor() {
Author author = getClass().getAnnotation(Author.class);
return author == null ? "Anon Y. Mous" : author.value();
}
/**
* Gets the name (ID) of this addon.
*
* @return Addon ID.
*/
public final @NotNull String getName() {
Addon addon = getClass().getAnnotation(Addon.class);
if(addon == null)
throw new IllegalStateException("Addon annotation not present"); // This should never happen; the presence of this annotation is checked by the addon loader.
return addon.value();
}
/**
* Invoked immediately after an addon is loaded.
*/
public abstract void initialize();
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.api.addons.annotations;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies that the annotated class is an entry point for a Terra addon.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Addon {
/**
* @return The ID of the addon.
*/
@NotNull String value();
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.api.addons.annotations;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Optional annotation that specifies the author of an addon.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Author {
/**
* @return Name of the addon author.
*/
@NotNull String value();
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.api.addons.annotations;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Optional annotation that specifies dependencies of an addon.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Depends {
/**
* @return All addons this addon is dependent upon.
*/
@NotNull String[] value();
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.api.addons.annotations;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Optional annotation that specifies the version of an addon.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Version {
/**
* @return Version of the addon.
*/
@NotNull String value();
}
@@ -0,0 +1,17 @@
package com.dfsek.terra.api.command;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.List;
public interface CommandManager {
void execute(String command, CommandSender sender, List<String> args) throws CommandException;
void register(String name, Class<? extends CommandTemplate> clazz) throws MalformedCommandException;
List<String> tabComplete(String command, CommandSender sender, List<String> args) throws CommandException;
int getMaxArgumentDepth();
}
@@ -0,0 +1,7 @@
package com.dfsek.terra.api.command;
import com.dfsek.terra.api.platform.CommandSender;
public interface CommandTemplate {
void execute(CommandSender sender);
}
@@ -0,0 +1,38 @@
package com.dfsek.terra.api.command;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public final class ExecutionState {
private final Set<String> switches = new HashSet<>();
private final Map<String, String> args = new HashMap<>();
private final CommandSender sender;
protected ExecutionState(CommandSender sender) {
this.sender = sender;
}
protected void addSwitch(String flag) {
switches.add(flag);
}
protected void addArgument(String arg, String value) {
args.put(arg, value);
}
public String getArgument(String argument) {
return args.get(argument);
}
public boolean hasSwitch(String flag) {
return switches.contains(flag);
}
public CommandSender getSender() {
return sender;
}
}
@@ -0,0 +1,283 @@
package com.dfsek.terra.api.command;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.Switch;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.inject.SwitchTarget;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.command.arg.ArgumentParser;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.command.exception.ExecutionException;
import com.dfsek.terra.api.command.exception.InvalidArgumentsException;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.command.exception.SwitchFormatException;
import com.dfsek.terra.api.command.tab.TabCompleter;
import com.dfsek.terra.api.injection.Injector;
import com.dfsek.terra.api.injection.exception.InjectionException;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.util.ReflectionUtil;
import com.dfsek.terra.world.TerraWorld;
import net.jafama.FastMath;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TerraCommandManager implements CommandManager {
private final Map<String, CommandHolder> commands = new HashMap<>();
private final Injector<TerraPlugin> pluginInjector;
private final TerraPlugin main;
public TerraCommandManager(TerraPlugin main) {
this.main = main;
this.pluginInjector = new Injector<>(main);
pluginInjector.addExplicitTarget(TerraPlugin.class);
}
@Override
public void execute(String commandName, CommandSender sender, List<String> argsIn) throws CommandException {
if(!commands.containsKey(commandName)) throw new InvalidArgumentsException("No such command \"" + commandName + "\"");
execute(commands.get(commandName), sender, new ArrayList<>(argsIn));
}
private void execute(CommandHolder commandHolder, CommandSender sender, List<String> args) throws CommandException {
Class<? extends CommandTemplate> commandClass = commandHolder.clazz;
if(commandClass.isAnnotationPresent(DebugCommand.class) && !main.isDebug()) {
sender.sendMessage("Command must be executed with debug mode enabled.");
return;
}
if(commandClass.isAnnotationPresent(PlayerCommand.class) && !(sender instanceof Player)) {
sender.sendMessage("Command must be executed by player.");
return;
}
if(commandClass.isAnnotationPresent(WorldCommand.class) && (!(sender instanceof Player) || !TerraWorld.isTerraWorld(((Player) sender).getWorld()))) {
sender.sendMessage("Command must be executed in a Terra world.");
return;
}
List<String> ogArgs = new ArrayList<>(args);
ExecutionState state = new ExecutionState(sender);
if(!commandClass.isAnnotationPresent(Command.class)) {
invoke(commandClass, state, commandHolder);
return;
}
Command command = commandClass.getAnnotation(Command.class);
if(command.arguments().length == 0 && command.subcommands().length == 0) {
if(args.isEmpty()) {
invoke(commandClass, state, commandHolder);
return;
} else throw new InvalidArgumentsException("Expected 0 arguments, found " + args.size());
}
if(!args.isEmpty() && commandHolder.subcommands.containsKey(args.get(0))) {
String c = args.get(0);
args.remove(0);
execute(commandHolder.subcommands.get(c), sender, args);
return;
}
boolean req = true;
for(Argument argument : command.arguments()) {
if(!req && argument.required()) {
throw new MalformedCommandException("Required arguments must come first! Arguments: " + Arrays.toString(command.arguments()));
}
req = argument.required();
if(args.isEmpty()) {
if(req) throw new InvalidArgumentsException("Invalid arguments: " + ogArgs + ", usage: " + command.usage());
break;
}
String arg = args.get(0);
if(arg.startsWith("-")) { // switches have started.
if(req) throw new InvalidArgumentsException("Switches must come after arguments.");
break;
}
state.addArgument(argument.value(), args.remove(0));
}
while(!args.isEmpty()) {
String aSwitch = args.remove(0);
if(!aSwitch.startsWith("-")) throw new SwitchFormatException("Invalid switch \"" + aSwitch + "\"");
String val = aSwitch.substring(1); // remove dash
if(!commandHolder.switches.containsKey(val)) throw new SwitchFormatException("No such switch \"" + aSwitch + "\"");
state.addSwitch(commandHolder.switches.get(val));
}
invoke(commandClass, state, commandHolder);
}
private void invoke(Class<? extends CommandTemplate> clazz, ExecutionState state, CommandHolder holder) throws CommandException {
try {
CommandTemplate template = clazz.getConstructor().newInstance();
pluginInjector.inject(template);
for(Field field : ReflectionUtil.getFields(clazz)) {
if(field.isAnnotationPresent(ArgumentTarget.class)) {
ArgumentTarget argumentTarget = field.getAnnotation(ArgumentTarget.class);
if(!holder.argumentMap.containsKey(argumentTarget.value())) {
throw new MalformedCommandException("Argument Target specifies nonexistent argument \"" + argumentTarget.value() + "\"");
}
String argument = argumentTarget.value();
ArgumentParser<?> argumentParser = holder.argumentMap.get(argumentTarget.value()).argumentParser().getConstructor().newInstance();
pluginInjector.inject(argumentParser);
field.setAccessible(true);
String value = state.getArgument(argument);
if(value == null) value = holder.argumentMap.get(argumentTarget.value()).defaultValue();
field.set(template, argumentParser.parse(state.getSender(), value));
}
if(field.isAnnotationPresent(SwitchTarget.class)) {
SwitchTarget switchTarget = field.getAnnotation(SwitchTarget.class);
if(!holder.switches.containsValue(switchTarget.value())) {
throw new MalformedCommandException("Switch Target specifies nonexistent switch \"" + switchTarget.value() + "\"");
}
if(!(field.getType() == boolean.class)) {
throw new MalformedCommandException("Switch Target must be of type boolean.");
}
field.setAccessible(true);
field.setBoolean(template, state.hasSwitch(switchTarget.value()));
}
}
try {
template.execute(state.getSender());
} catch(Throwable e) {
throw new ExecutionException("Failed to execute command: " + e.getMessage(), e);
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
throw new MalformedCommandException("Unable to reflectively instantiate command: ", e);
}
}
@Override
public void register(String name, Class<? extends CommandTemplate> clazz) throws MalformedCommandException {
commands.put(name, new CommandHolder(clazz));
}
@Override
public List<String> tabComplete(String command, CommandSender sender, List<String> args) throws CommandException {
if(args.isEmpty()) return new ArrayList<>(commands.keySet()).stream().sorted(String::compareTo).collect(Collectors.toList());
if(!commands.containsKey(command)) return Collections.emptyList();
return tabComplete(commands.get(command), sender, new ArrayList<>(args)).stream().filter(s -> s.toLowerCase().startsWith(args.get(args.size() - 1).toLowerCase())).sorted(String::compareTo).collect(Collectors.toList());
}
@Override
public int getMaxArgumentDepth() {
int max = 0;
for(CommandHolder value : commands.values()) {
max = FastMath.max(getMaxArgumentDepth(value), max);
}
return max;
}
private int getMaxArgumentDepth(CommandHolder holder) {
int max = 0;
max = FastMath.max(holder.arguments.size() + holder.switchList.size(), max);
for(CommandHolder value : holder.subcommands.values()) {
max = FastMath.max(max, getMaxArgumentDepth(value) + 1);
}
return max;
}
private List<String> tabComplete(CommandHolder holder, CommandSender sender, List<String> args) throws CommandException {
if(args.isEmpty()) return Collections.emptyList();
List<String> completions = new ArrayList<>();
if(args.size() == 1) {
completions.addAll(holder.subcommands.keySet());
}
if(holder.subcommands.containsKey(args.get(0))) {
List<String> newArgs = new ArrayList<>(args);
newArgs.remove(0);
completions.addAll(tabComplete(holder.subcommands.get(args.get(0)), sender, newArgs));
}
try {
if(args.size() <= holder.arguments.size()) {
TabCompleter completer = holder.arguments.get(args.size() - 1).tabCompleter().getConstructor().newInstance();
pluginInjector.inject(completer);
completions.addAll(completer.complete(sender));
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
throw new MalformedCommandException("Unable to reflectively instantiate tab-completer: ", e);
}
return completions;
}
/**
* Pre-processes command metadata.
*/
private static final class CommandHolder {
private final Class<? extends CommandTemplate> clazz;
private final Map<String, CommandHolder> subcommands = new HashMap<>();
private final Map<String, String> switches = new HashMap<>();
private final List<Argument> arguments;
private final List<Switch> switchList;
private final Map<String, Argument> argumentMap = new HashMap<>();
private CommandHolder(Class<? extends CommandTemplate> clazz) throws MalformedCommandException {
this.clazz = clazz;
if(clazz.isAnnotationPresent(Command.class)) {
Command command = clazz.getAnnotation(Command.class);
for(Subcommand subcommand : command.subcommands()) {
if(subcommands.containsKey(subcommand.value()))
throw new MalformedCommandException("Duplicate subcommand: " + subcommand);
CommandHolder holder = new CommandHolder(subcommand.clazz());
subcommands.put(subcommand.value(), holder);
for(String alias : subcommand.aliases()) {
subcommands.put(alias, holder);
}
}
for(Switch aSwitch : command.switches()) {
if(switches.containsKey(aSwitch.value())) throw new MalformedCommandException("Duplicate switch: " + aSwitch);
switches.put(aSwitch.value(), aSwitch.value());
for(String alias : aSwitch.aliases()) {
switches.put(alias, aSwitch.value());
}
}
for(Argument argument : command.arguments()) {
if(argumentMap.containsKey(argument.value())) throw new MalformedCommandException("Duplicate argument: " + argument);
argumentMap.put(argument.value(), argument);
}
arguments = Arrays.asList(command.arguments());
switchList = Arrays.asList(command.switches());
} else {
arguments = Collections.emptyList();
switchList = Collections.emptyList();
}
}
}
}
@@ -0,0 +1,25 @@
package com.dfsek.terra.api.command.annotation;
import com.dfsek.terra.api.command.arg.ArgumentParser;
import com.dfsek.terra.api.command.arg.StringArgumentParser;
import com.dfsek.terra.api.command.tab.NothingCompleter;
import com.dfsek.terra.api.command.tab.TabCompleter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Argument {
String value();
boolean required() default true;
Class<? extends TabCompleter> tabCompleter() default NothingCompleter.class;
Class<? extends ArgumentParser<?>> argumentParser() default StringArgumentParser.class;
String defaultValue() default "";
}
@@ -0,0 +1,18 @@
package com.dfsek.terra.api.command.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Command {
Argument[] arguments() default {};
Switch[] switches() default {};
Subcommand[] subcommands() default {};
String usage() default "";
}
@@ -0,0 +1,18 @@
package com.dfsek.terra.api.command.annotation;
import com.dfsek.terra.api.command.CommandTemplate;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Subcommand {
String value();
String[] aliases() default {};
Class<? extends CommandTemplate> clazz();
}
@@ -0,0 +1,14 @@
package com.dfsek.terra.api.command.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Switch {
String value();
String[] aliases() default {};
}
@@ -0,0 +1,12 @@
package com.dfsek.terra.api.command.annotation.inject;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ArgumentTarget {
String value();
}
@@ -0,0 +1,12 @@
package com.dfsek.terra.api.command.annotation.inject;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SwitchTarget {
String value();
}
@@ -0,0 +1,14 @@
package com.dfsek.terra.api.command.annotation.type;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Command may only be executed with debug mode enabled.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DebugCommand {
}
@@ -0,0 +1,14 @@
package com.dfsek.terra.api.command.annotation.type;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks command as player-only
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PlayerCommand {
}
@@ -0,0 +1,14 @@
package com.dfsek.terra.api.command.annotation.type;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Command may only be executed in a Terra world.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WorldCommand {
}
@@ -0,0 +1,7 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.platform.CommandSender;
public interface ArgumentParser<T> {
T parse(CommandSender sender, String arg);
}
@@ -0,0 +1,10 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.platform.CommandSender;
public class DoubleArgumentParser implements ArgumentParser<Double> {
@Override
public Double parse(CommandSender sender, String arg) {
return arg == null ? null : Double.parseDouble(arg);
}
}
@@ -0,0 +1,10 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.platform.CommandSender;
public class IntegerArgumentParser implements ArgumentParser<Integer> {
@Override
public Integer parse(CommandSender sender, String arg) {
return arg == null ? null : Integer.parseInt(arg);
}
}
@@ -0,0 +1,10 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.platform.CommandSender;
public class StringArgumentParser implements ArgumentParser<String> {
@Override
public String parse(CommandSender sender, String arg) {
return arg;
}
}
@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.exception;
public abstract class CommandException extends Exception {
private static final long serialVersionUID = -2955328495045879822L;
public CommandException(String message) {
super(message);
}
public CommandException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.exception;
public class ExecutionException extends CommandException {
private static final long serialVersionUID = -6345523475880607959L;
public ExecutionException(String message) {
super(message);
}
public ExecutionException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.exception;
public class InvalidArgumentsException extends CommandException {
private static final long serialVersionUID = 7563619667472569824L;
public InvalidArgumentsException(String message) {
super(message);
}
public InvalidArgumentsException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,16 @@
package com.dfsek.terra.api.command.exception;
/**
* Thrown when command is incorrectly defined.
*/
public class MalformedCommandException extends CommandException {
private static final long serialVersionUID = -5417760860407895496L;
public MalformedCommandException(String message) {
super(message);
}
public MalformedCommandException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.exception;
public class SwitchFormatException extends CommandException {
private static final long serialVersionUID = -965858989317844628L;
public SwitchFormatException(String message) {
super(message);
}
public SwitchFormatException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.tab;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.Collections;
import java.util.List;
public class NothingCompleter implements TabCompleter {
@Override
public List<String> complete(CommandSender sender) {
return Collections.emptyList();
}
}
@@ -0,0 +1,9 @@
package com.dfsek.terra.api.command.tab;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.List;
public interface TabCompleter {
List<String> complete(CommandSender sender);
}
@@ -0,0 +1,12 @@
package com.dfsek.terra.api.event;
import com.dfsek.terra.api.event.events.Event;
/**
* Marker interface for a class that contains event listener methods.
*
* @see Event
* @see EventManager
*/
public interface EventListener {
}
@@ -0,0 +1,25 @@
package com.dfsek.terra.api.event;
import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.event.events.Event;
/**
* Manages event registration and triggering.
*/
public interface EventManager {
/**
* Call an event, and return the execution status.
*
* @param event Event to pass to all registered EventListeners.
* @return False if the event is cancellable and has been cancelled, otherwise true.
*/
boolean callEvent(Event event);
/**
* Register an {@link EventListener} under an {@link TerraAddon}.
*
* @param addon Addon to register listener for.
* @param listener Listener to register.
*/
void registerListener(TerraAddon addon, EventListener listener);
}
@@ -0,0 +1,110 @@
package com.dfsek.terra.api.event;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.event.annotations.Global;
import com.dfsek.terra.api.event.annotations.Priority;
import com.dfsek.terra.api.event.events.Cancellable;
import com.dfsek.terra.api.event.events.Event;
import com.dfsek.terra.api.event.events.PackEvent;
import com.dfsek.terra.api.util.ReflectionUtil;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TerraEventManager implements EventManager {
private final Map<Class<? extends Event>, List<ListenerHolder>> listeners = new HashMap<>();
private final TerraPlugin main;
public TerraEventManager(TerraPlugin main) {
this.main = main;
}
@Override
public boolean callEvent(Event event) {
listeners.getOrDefault(event.getClass(), Collections.emptyList()).forEach(listenerHolder -> {
try {
if(event instanceof PackEvent && !listenerHolder.global) {
PackEvent packEvent = (PackEvent) event;
if(packEvent
.getPack()
.getTemplate()
.getAddons()
.contains(listenerHolder.addon)) {
listenerHolder.method.invoke(listenerHolder.listener, event);
}
} else {
listenerHolder.method.invoke(listenerHolder.listener, event);
}
} catch(InvocationTargetException e) {
StringWriter writer = new StringWriter();
e.getTargetException().printStackTrace(new PrintWriter(writer));
main.logger().warning("Exception occurred during event handling:");
main.logger().warning(writer.toString());
main.logger().warning("Report this to the maintainers of " + listenerHolder.method.getName());
} catch(Exception e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
main.logger().warning("Exception occurred during event handling:");
main.logger().warning(writer.toString());
main.logger().warning("Report this to the maintainers of " + listenerHolder.method.getName());
}
}
);
if(event instanceof Cancellable) return !((Cancellable) event).isCancelled();
return true;
}
@SuppressWarnings("unchecked")
@Override
public void registerListener(TerraAddon addon, EventListener listener) {
Class<? extends EventListener> listenerClass = listener.getClass();
Method[] methods = ReflectionUtil.getMethods(listenerClass);
for(Method method : methods) {
if(method.getParameterCount() != 1) continue; // Check that parameter count is only 1.
Class<?> eventParam = method.getParameterTypes()[0];
if(!Event.class.isAssignableFrom(eventParam)) continue; // Check that parameter is an Event.
Priority p = method.getAnnotation(Priority.class);
int priority = p == null ? 0 : p.value();
method.setAccessible(true);
List<ListenerHolder> holders = listeners.computeIfAbsent((Class<? extends Event>) eventParam, e -> new ArrayList<>());
holders.add(new ListenerHolder(method, listener, priority, addon, method.getAnnotation(Global.class) != null));
holders.sort(Comparator.comparingInt(ListenerHolder::getPriority)); // Sort priorities.
}
}
private static final class ListenerHolder {
private final Method method;
private final EventListener listener;
private final int priority;
private final TerraAddon addon;
private final boolean global;
private ListenerHolder(Method method, EventListener listener, int priority, TerraAddon addon, boolean global) {
this.method = method;
this.listener = listener;
this.priority = priority;
this.addon = addon;
this.global = global;
}
public int getPriority() {
return priority;
}
}
}
@@ -0,0 +1,17 @@
package com.dfsek.terra.api.event.annotations;
import com.dfsek.terra.api.event.events.PackEvent;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies that an event handler is to handle all {@link PackEvent}s, regardless of whether the pack
* depends on the addon's listener.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Global {
}
@@ -0,0 +1,38 @@
package com.dfsek.terra.api.event.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotated listener methods will have a specific priority set.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Priority {
/**
* Highest possible priority. Listeners with this priority will always be invoked last.
*/
int HIGHEST = Integer.MAX_VALUE;
/**
* Lowest possible priority. Listeners with this priority will always be invoked first.
*/
int LOWEST = Integer.MIN_VALUE;
/**
* Default priority.
*/
int NORMAL = 0;
/**
* High priority.
*/
int HIGH = 1;
/**
* Low Priority.
*/
int LOW = -1;
/**
* @return Priority of this event. Events are executed from lowest to highest priorities.
*/
int value();
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.api.event.events;
import com.dfsek.terra.api.util.mutable.MutableBoolean;
/**
* Abstract class containing basic {@link Cancellable} implementation.
*/
public abstract class AbstractCancellable implements Cancellable {
private final MutableBoolean cancelled = new MutableBoolean(false);
@Override
public boolean isCancelled() {
return cancelled.get();
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled.set(cancelled);
}
}
@@ -0,0 +1,22 @@
package com.dfsek.terra.api.event.events;
/**
* Events that implement this interface may be cancelled.
* <p>
* Cancelling an event is assumed to stop the execution of whatever action triggered the event.
*/
public interface Cancellable extends Event {
/**
* Get the cancellation status of the event.
*
* @return Whether event is cancelled.
*/
boolean isCancelled();
/**
* Set the cancellation status of the event.
*
* @param cancelled Whether event is cancelled.
*/
void setCancelled(boolean cancelled);
}
@@ -0,0 +1,7 @@
package com.dfsek.terra.api.event.events;
/**
* An event that addons may listen to.
*/
public interface Event {
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.api.event.events;
import com.dfsek.terra.api.event.annotations.Global;
import com.dfsek.terra.config.pack.ConfigPack;
/**
* An event with functionality directly linked to a {@link ConfigPack}.
* <p>
* PackEvents are only invoked when the pack specifies the addon in its
* {@code addon} key (or when the listener is annotated {@link Global}).
*/
@SuppressWarnings("InterfaceMayBeAnnotatedFunctional")
public interface PackEvent extends Event {
/**
* Get the {@link ConfigPack} associated with this event.
*
* @return ConfigPack associated with the event.
*/
ConfigPack getPack();
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.api.event.events.config;
import com.dfsek.terra.api.event.events.PackEvent;
import com.dfsek.terra.config.pack.ConfigPack;
/**
* An event related to the loading process of config packs.
*/
public abstract class ConfigPackLoadEvent implements PackEvent {
private final ConfigPack pack;
public ConfigPackLoadEvent(ConfigPack pack) {
this.pack = pack;
}
@Override
public ConfigPack getPack() {
return pack;
}
}
@@ -0,0 +1,12 @@
package com.dfsek.terra.api.event.events.config;
import com.dfsek.terra.config.pack.ConfigPack;
/**
* Called when a config pack has finished loading.
*/
public class ConfigPackPostLoadEvent extends ConfigPackLoadEvent {
public ConfigPackPostLoadEvent(ConfigPack pack) {
super(pack);
}
}
@@ -0,0 +1,12 @@
package com.dfsek.terra.api.event.events.config;
import com.dfsek.terra.config.pack.ConfigPack;
/**
* Called before a config pack's registries are filled. At this point, the pack manifest has been loaded, and all registries are empty.
*/
public class ConfigPackPreLoadEvent extends ConfigPackLoadEvent {
public ConfigPackPreLoadEvent(ConfigPack pack) {
super(pack);
}
}
@@ -0,0 +1,31 @@
package com.dfsek.terra.api.event.events.world;
import com.dfsek.terra.api.event.events.PackEvent;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.WorldConfig;
import com.dfsek.terra.world.TerraWorld;
/**
* Called upon initialization of a TerraWorld.
*/
public class TerraWorldLoadEvent implements PackEvent {
private final TerraWorld world;
private final ConfigPack pack;
public TerraWorldLoadEvent(TerraWorld world, ConfigPack pack) {
this.world = world;
this.pack = pack;
}
public TerraWorld getWorld() {
return world;
}
public ConfigPack getPack() {
return pack;
}
public WorldConfig getWorldConfig() {
return world.getConfig();
}
}
@@ -0,0 +1,45 @@
package com.dfsek.terra.api.event.events.world.generation;
import com.dfsek.terra.api.event.events.PackEvent;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.entity.Entity;
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedEntity;
import com.dfsek.terra.config.pack.ConfigPack;
/**
* Called when an entity is spawned via {@link BufferedEntity}.
*/
public class EntitySpawnEvent implements PackEvent {
private final ConfigPack pack;
private final Entity entity;
private final Location location;
public EntitySpawnEvent(ConfigPack pack, Entity entity, Location location) {
this.pack = pack;
this.entity = entity;
this.location = location;
}
@Override
public ConfigPack getPack() {
return pack;
}
/**
* Get the entity that triggered the event.
*
* @return The entity.
*/
public Entity getEntity() {
return entity;
}
/**
* Get the location of the entity.
*
* @return Location of the entity.
*/
public Location getLocation() {
return location;
}
}
@@ -0,0 +1,80 @@
package com.dfsek.terra.api.event.events.world.generation;
import com.dfsek.terra.api.event.events.AbstractCancellable;
import com.dfsek.terra.api.event.events.Cancellable;
import com.dfsek.terra.api.event.events.PackEvent;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.state.Container;
import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
import com.dfsek.terra.config.pack.ConfigPack;
import org.jetbrains.annotations.NotNull;
/**
* Called when loot is populated via {@link BufferedLootApplication}.
*/
public class LootPopulateEvent extends AbstractCancellable implements PackEvent, Cancellable {
private final Block block;
private final Container container;
private LootTable table;
private final ConfigPack pack;
private final StructureScript script;
public LootPopulateEvent(Block block, Container container, LootTable table, ConfigPack pack, StructureScript script) {
this.block = block;
this.container = container;
this.table = table;
this.pack = pack;
this.script = script;
}
@Override
public ConfigPack getPack() {
return pack;
}
/**
* Get the block containing the tile entity loot is applied to.
*
* @return Block at which loot is applied.
*/
public Block getBlock() {
return block;
}
/**
* Get the {@link Container} representing the inventory.
*
* @return Inventory recieving loot.
*/
public Container getContainer() {
return container;
}
/**
* Get the loot table to be populated.
* @return Loot table.
*/
public LootTable getTable() {
return table;
}
/**
* Set the loot table to be populated.
*
* @param table New loot table.
*/
public void setTable(@NotNull LootTable table) {
this.table = table;
}
/**
* Get the script used to generate the structure.
*
* @return Structure script.
*/
public StructureScript getStructureScript() {
return script;
}
}
@@ -0,0 +1,78 @@
package com.dfsek.terra.api.injection;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.injection.exception.InjectionException;
import com.dfsek.terra.api.util.ReflectionUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;
/**
* Dynamic dependency injector.
* <p>
* Stores an object to inject, and injects it into objects passed to {@link #inject(Object)}.
*
* @param <T> Type of object to inject.
*/
public class Injector<T> {
private final T value;
private final Set<Class<? extends T>> targets = new HashSet<>();
/**
* Instantiate an Injector with a value to inject
*
* @param value Value to inject
*/
public Injector(T value) {
this.value = value;
}
/**
* Add an explicit class as a target. Useful for applications where subclasses may cause issues with DI.
*
* @param target Target class type.
*/
public void addExplicitTarget(Class<? extends T> target) {
targets.add(target);
}
/**
* Inject the stored object into an object.
* <p>
* Injects the stored object into any non-static, non-final fields
* annotated with {@link Inject},
* with type matching the stored object or any explicit targets
* ({@link #addExplicitTarget(Class)}.
*
* @param object Object to inject into
* @throws InjectionException If:
* <ul>
* <li>Matching field annotated with {@link Inject} is final</li>
* <li>Matching field annotated with {@link Inject} is static</li>
* <li>A reflective access exception occurs</li>
* </ul>
*/
public void inject(Object object) throws InjectionException {
for(Field field : ReflectionUtil.getFields(object.getClass())) {
Inject inject = field.getAnnotation(Inject.class);
if(inject == null) continue;
if(value.getClass().equals(field.getType()) || targets.contains(field.getType())) {
int mod = field.getModifiers();
if(Modifier.isFinal(mod)) {
throw new InjectionException("Attempted to inject final field: " + field);
}
if(Modifier.isStatic(mod)) {
throw new InjectionException("Attempted to inject static field: " + field);
}
field.setAccessible(true);
try {
field.set(object, value);
} catch(IllegalAccessException e) {
throw new InjectionException("Failed to inject field: " + field, e);
}
}
}
}
}
@@ -0,0 +1,14 @@
package com.dfsek.terra.api.injection.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies that a field is a target for dependency injection.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Inject {
}
@@ -0,0 +1,18 @@
package com.dfsek.terra.api.injection.exception;
import com.dfsek.terra.api.injection.Injector;
/**
* Thrown when dynamic dependency injection cannot be completed by an {@link Injector}.
*/
public class InjectionException extends Exception {
private static final long serialVersionUID = -6929631447064215387L;
public InjectionException(String message) {
super(message);
}
public InjectionException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -1,9 +1,8 @@
package com.dfsek.terra.procgen;
package com.dfsek.terra.api.math;
import org.bukkit.util.Vector;
import org.polydev.gaea.math.MathUtil;
import org.polydev.gaea.util.FastRandom;
import org.polydev.gaea.util.GlueList;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.util.FastRandom;
import com.dfsek.terra.api.util.GlueList;
import java.util.List;
import java.util.Random;
@@ -14,10 +13,12 @@ import java.util.Random;
public class GridSpawn {
private final int separation;
private final int width;
private final int salt;
public GridSpawn(int width, int separation) {
public GridSpawn(int width, int separation, int salt) {
this.separation = separation;
this.width = width;
this.salt = salt;
}
/**
@@ -28,18 +29,18 @@ public class GridSpawn {
* @param seed Seed for RNG
* @return Vector representing nearest spawnpoint
*/
public Vector getNearestSpawn(int x, int z, long seed) {
public Vector3 getNearestSpawn(int x, int z, long seed) {
int structureChunkX = x / (width + 2 * separation);
int structureChunkZ = z / (width + 2 * separation);
List<Vector> zones = new GlueList<>();
List<Vector3> zones = new GlueList<>();
for(int xi = structureChunkX - 1; xi <= structureChunkX + 1; xi++) {
for(int zi = structureChunkZ - 1; zi <= structureChunkZ + 1; zi++) {
zones.add(getChunkSpawn(xi, zi, seed));
}
}
Vector shortest = zones.get(0);
Vector compare = new Vector(x, 0, z);
for(Vector v : zones) {
Vector3 shortest = zones.get(0);
Vector3 compare = new Vector3(x, 0, z);
for(Vector3 v : zones) {
if(compare.distanceSquared(shortest) > compare.distanceSquared(v)) shortest = v.clone();
}
return shortest;
@@ -53,13 +54,13 @@ public class GridSpawn {
* @param seed Seed for RNG
* @return Vector representing spawnpoint
*/
public Vector getChunkSpawn(int structureChunkX, int structureChunkZ, long seed) {
Random r = new FastRandom(MathUtil.getCarverChunkSeed(structureChunkX, structureChunkZ, seed));
public Vector3 getChunkSpawn(int structureChunkX, int structureChunkZ, long seed) {
Random r = new FastRandom(MathUtil.getCarverChunkSeed(structureChunkX, structureChunkZ, seed + salt));
int offsetX = r.nextInt(width);
int offsetZ = r.nextInt(width);
int sx = structureChunkX * (width + 2 * separation) + offsetX;
int sz = structureChunkZ * (width + 2 * separation) + offsetZ;
return new Vector(sx, 0, sz);
return new Vector3(sx, 0, sz);
}
public int getWidth() {
@@ -0,0 +1,193 @@
package com.dfsek.terra.api.math;
import com.dfsek.terra.api.util.FastRandom;
import com.dfsek.terra.world.generation.math.samplers.Sampler;
import net.jafama.FastMath;
import java.util.List;
import java.util.Random;
/**
* Utility class for mathematical functions.
*/
public final class MathUtil {
/**
* Epsilon for fuzzy floating point comparisons.
*/
public static final double EPSILON = 1.0E-5;
/**
* Derivative constant.
*/
private static final double DERIVATIVE_DIST = 0.55;
/**
* Gets the standard deviation of an array of doubles.
*
* @param numArray The array of numbers to calculate the standard deviation of.
* @return double - The standard deviation.
*/
public static double standardDeviation(List<Number> numArray) {
double sum = 0.0, standardDeviation = 0.0;
int length = numArray.size();
for(Number num : numArray) {
sum += num.doubleValue();
}
double mean = sum / length;
for(Number num : numArray) {
standardDeviation += FastMath.pow2(num.doubleValue() - mean);
}
return FastMath.sqrt(standardDeviation / length);
}
/**
* Gets the carver seed for a chunk.
*
* @param chunkX Chunk's X coordinate
* @param chunkZ Chunk's Z coordinate
* @param seed World seed
* @return long - The carver seed.
*/
public static long getCarverChunkSeed(int chunkX, int chunkZ, long seed) {
Random r = new FastRandom(seed);
return chunkX * r.nextLong() ^ chunkZ * r.nextLong() ^ seed;
}
public static long hashToLong(String s) {
if(s == null) {
return 0;
}
long hash = 0;
for(char c : s.toCharArray()) {
hash = 31L * hash + c;
}
return hash;
}
/**
* Compare 2 floating-point values with epsilon to account for rounding errors
*
* @param a Value 1
* @param b Value 2
* @return Whether these values are equal
*/
public static boolean equals(double a, double b) {
return a == b || FastMath.abs(a - b) < EPSILON;
}
public static double derivative(Sampler sampler, double x, double y, double z) {
double baseSample = sampler.sample(x, y, z);
double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
return Math.sqrt(((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
}
public static int normalizeIndex(double val, int size) {
return FastMath.max(FastMath.min(FastMath.floorToInt(((val + 1D) / 2D) * size), size - 1), 0);
}
public static long squash(int first, int last) {
return (((long) first) << 32) | (last & 0xffffffffL);
}
/**
* Clamp value to range of [-1, 1]
*
* @param in Value to clamp
* @return Clamped value
*/
public static double clamp(double in) {
return FastMath.min(FastMath.max(in, -1), 1);
}
/**
* Compute the value in a normally distributed data set that has probability p.
*
* @param p Probability of value
* @param mu Mean of data
* @param sigma Standard deviation of data
* @return Value corresponding to input probability
*/
public static double normalInverse(double p, double mu, double sigma) {
if(p < 0 || p > 1)
throw new IllegalArgumentException("Probability must be in range [0, 1]");
if(sigma < 0)
throw new IllegalArgumentException("Standard deviation must be positive.");
if(p == 0)
return Double.NEGATIVE_INFINITY;
if(p == 1)
return Double.POSITIVE_INFINITY;
if(sigma == 0)
return mu;
double q, r, val;
q = p - 0.5;
if(FastMath.abs(q) <= .425) {
r = .180625 - q * q;
val =
q * (((((((r * 2509.0809287301226727 +
33430.575583588128105) * r + 67265.770927008700853) * r +
45921.953931549871457) * r + 13731.693765509461125) * r +
1971.5909503065514427) * r + 133.14166789178437745) * r +
3.387132872796366608)
/ (((((((r * 5226.495278852854561 +
28729.085735721942674) * r + 39307.89580009271061) * r +
21213.794301586595867) * r + 5394.1960214247511077) * r +
687.1870074920579083) * r + 42.313330701600911252) * r + 1);
} else {
if(q > 0) {
r = 1 - p;
} else {
r = p;
}
r = FastMath.sqrt(-FastMath.log(r));
if(r <= 5) {
r += -1.6;
val = (((((((r * 7.7454501427834140764e-4 +
.0227238449892691845833) * r + .24178072517745061177) *
r + 1.27045825245236838258) * r +
3.64784832476320460504) * r + 5.7694972214606914055) *
r + 4.6303378461565452959) * r +
1.42343711074968357734)
/ (((((((r *
1.05075007164441684324e-9 + 5.475938084995344946e-4) *
r + .0151986665636164571966) * r +
.14810397642748007459) * r + .68976733498510000455) *
r + 1.6763848301838038494) * r +
2.05319162663775882187) * r + 1);
} else {
r += -5;
val = (((((((r * 2.01033439929228813265e-7 +
2.71155556874348757815e-5) * r +
.0012426609473880784386) * r + .026532189526576123093) *
r + .29656057182850489123) * r +
1.7848265399172913358) * r + 5.4637849111641143699) *
r + 6.6579046435011037772)
/ (((((((r *
2.04426310338993978564e-15 + 1.4215117583164458887e-7) *
r + 1.8463183175100546818e-5) * r +
7.868691311456132591e-4) * r + .0148753612908506148525)
* r + .13692988092273580531) * r +
.59983220655588793769) * r + 1);
}
if(q < 0.0) {
val = -val;
}
}
return mu + sigma * val;
}
}
@@ -0,0 +1,123 @@
package com.dfsek.terra.api.math;
import net.jafama.FastMath;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
import java.util.Random;
public class Range implements Iterable<Integer> {
private int min;
private int max;
public Range(int min, int max) {
if(min > max) throw new IllegalArgumentException("Minimum must not be grater than maximum!");
this.max = max;
this.min = min;
}
public boolean isInRange(int test) {
return test >= min && test < max;
}
public int getMax() {
return max;
}
public Range setMax(int max) {
this.max = max;
return this;
}
public int getMin() {
return min;
}
public Range setMin(int min) {
this.min = min;
return this;
}
public int getRange() {
return max - min;
}
public Range multiply(int mult) {
min *= mult;
max *= mult;
return this;
}
public Range reflect(int pt) {
return new Range(2 * pt - this.getMax(), 2 * pt - this.getMin());
}
public int get(Random r) {
return r.nextInt((max - min) + 1) + min;
}
public Range intersects(com.dfsek.terra.api.math.Range other) {
try {
return new Range(FastMath.max(this.getMin(), other.getMin()), FastMath.min(this.getMax(), other.getMax()));
} catch(IllegalArgumentException e) {
return null;
}
}
public Range add(int add) {
this.min += add;
this.max += add;
return this;
}
public Range sub(int sub) {
this.min -= sub;
this.max -= sub;
return this;
}
@Override
public String toString() {
return "Min: " + getMin() + ", Max:" + getMax();
}
@Override
public int hashCode() {
return min * 31 + max;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof com.dfsek.terra.api.math.Range)) return false;
Range other = (com.dfsek.terra.api.math.Range) obj;
return other.getMin() == this.getMin() && other.getMax() == this.getMax();
}
@NotNull
@Override
public Iterator<Integer> iterator() {
return new RangeIterator(this);
}
private static class RangeIterator implements Iterator<Integer> {
private final Range m;
private Integer current;
public RangeIterator(Range m) {
this.m = m;
current = m.getMin();
}
@Override
public boolean hasNext() {
return current < m.getMax();
}
@Override
public Integer next() {
current++;
return current - 1;
}
}
}
@@ -0,0 +1,32 @@
package com.dfsek.terra.api.math.noise;
import com.dfsek.terra.api.math.vector.Vector2;
import com.dfsek.terra.api.math.vector.Vector3;
public interface NoiseSampler {
/**
* 2D noise at given position using current settings
* <p>
* Noise output bounded between -1...1
*/
double getNoise(double x, double y);
/**
* 3D noise at given position using current settings
* <p>
* Noise output bounded between -1...1
*/
double getNoise(double x, double y, double z);
default double getNoise(Vector3 vector3) {
return getNoise(vector3.getX(), vector3.getY(), vector3.getZ());
}
default double getNoise(Vector2 vector2) {
return getNoise(vector2.getX(), vector2.getZ());
}
double getNoiseSeeded(int seed, double x, double y);
double getNoiseSeeded(int seed, double x, double y, double z);
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.api.math.noise.normalizer;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import net.jafama.FastMath;
public class ClampNormalizer extends Normalizer {
private final double min;
private final double max;
public ClampNormalizer(NoiseSampler sampler, double min, double max) {
super(sampler);
this.min = min;
this.max = max;
}
@Override
public double normalize(double in) {
return FastMath.max(FastMath.min(in, max), min);
}
}
@@ -0,0 +1,22 @@
package com.dfsek.terra.api.math.noise.normalizer;
import com.dfsek.terra.api.math.noise.NoiseSampler;
/**
* Normalizer to linearly scale data's range.
*/
public class LinearNormalizer extends Normalizer {
private final double min;
private final double max;
public LinearNormalizer(NoiseSampler sampler, double min, double max) {
super(sampler);
this.min = min;
this.max = max;
}
@Override
public double normalize(double in) {
return (in - min) * (2 / (max - min)) - 1;
}
}
@@ -0,0 +1,45 @@
package com.dfsek.terra.api.math.noise.normalizer;
import com.dfsek.terra.api.math.MathUtil;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import net.jafama.FastMath;
/**
* Normalizer to redistribute normally distributed data to a continuous distribution via an automatically generated lookup table.
*/
public class NormalNormalizer extends Normalizer {
private final double[] lookup;
public NormalNormalizer(NoiseSampler sampler, int buckets, double mean, double standardDeviation) {
super(sampler);
this.lookup = new double[buckets];
for(int i = 0; i < buckets; i++) {
lookup[i] = MathUtil.normalInverse((double) i / buckets, mean, standardDeviation);
}
}
@Override
public double normalize(double in) {
int start = 0;
int end = lookup.length - 1;
while(start + 1 < end) {
int mid = start + (end - start) / 2;
if(lookup[mid] <= in) {
start = mid;
} else {
end = mid;
}
}
double left = FastMath.abs(lookup[start] - in);
double right = FastMath.abs(lookup[end] - in);
double fin;
if(left <= right) {
fin = (double) start / (lookup.length);
} else fin = (double) end / (lookup.length);
return (fin - 0.5) * 2;
}
}
@@ -0,0 +1,33 @@
package com.dfsek.terra.api.math.noise.normalizer;
import com.dfsek.terra.api.math.noise.NoiseSampler;
public abstract class Normalizer implements NoiseSampler {
private final NoiseSampler sampler;
public Normalizer(NoiseSampler sampler) {
this.sampler = sampler;
}
public abstract double normalize(double in);
@Override
public double getNoise(double x, double y) {
return normalize(sampler.getNoise(x, y));
}
@Override
public double getNoise(double x, double y, double z) {
return normalize(sampler.getNoise(x, y, z));
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return normalize(sampler.getNoiseSeeded(seed, x, y));
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
return normalize(sampler.getNoiseSeeded(seed, x, y, z));
}
}
@@ -0,0 +1,44 @@
package com.dfsek.terra.api.math.noise.samplers;
import com.dfsek.terra.api.math.noise.NoiseSampler;
public class DomainWarpedSampler implements NoiseSampler {
private final NoiseSampler function;
private final NoiseSampler warp;
private final int seed;
private final double amplitude;
public DomainWarpedSampler(NoiseSampler function, NoiseSampler warp, int seed, double amplitude) {
this.function = function;
this.warp = warp;
this.seed = seed;
this.amplitude = amplitude;
}
@Override
public double getNoise(double x, double y) {
return getNoiseSeeded(seed, x, y);
}
@Override
public double getNoise(double x, double y, double z) {
return getNoiseSeeded(seed, x, y, z);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return function.getNoise(
x + warp.getNoiseSeeded(seed, x, y) * amplitude,
y + warp.getNoiseSeeded(seed + 1, x, y) * amplitude
);
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
return function.getNoise(
x + warp.getNoiseSeeded(seed, x, y, z) * amplitude,
y + warp.getNoiseSeeded(seed + 1, x, y, z) * amplitude,
z + warp.getNoiseSeeded(seed + 2, x, y, z) * amplitude
);
}
}
@@ -0,0 +1,67 @@
package com.dfsek.terra.api.math.noise.samplers;
import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction;
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction2;
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction3;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
import java.util.Map;
/**
* Sampler3D implementation using Paralithic expression
*/
public class ExpressionSampler implements NoiseSampler {
private final Expression expression;
public ExpressionSampler(String equation, Scope parent, long seed, Map<String, NoiseSeeded> functions, Map<String, FunctionTemplate> definedFunctions) throws ParseException {
Parser parser = new Parser();
Scope scope = new Scope().withParent(parent);
scope.addInvocationVariable("x");
scope.addInvocationVariable("y");
scope.addInvocationVariable("z");
functions.forEach((id, noise) -> {
switch(noise.getDimensions()) {
case 2:
parser.registerFunction(id, new NoiseFunction2(noise.apply(seed)));
break;
case 3:
parser.registerFunction(id, new NoiseFunction3(noise.apply(seed)));
break;
}
});
for(Map.Entry<String, FunctionTemplate> entry : definedFunctions.entrySet()) {
parser.registerFunction(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), parser, parent));
}
this.expression = parser.parse(equation, scope);
}
@Override
public double getNoise(double x, double y) {
return getNoise(x, 0, y);
}
@Override
public double getNoise(double x, double y, double z) {
return expression.evaluate(x, y, z);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return getNoise(x, y);
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
return getNoise(x, y, z);
}
}
@@ -0,0 +1,70 @@
package com.dfsek.terra.api.math.noise.samplers;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import net.jafama.FastMath;
import java.awt.image.BufferedImage;
public class ImageSampler implements NoiseSampler {
private final BufferedImage image;
private final Channel channel;
private final double frequency;
public ImageSampler(BufferedImage image, Channel channel, double frequency) {
this.image = image;
this.channel = channel;
this.frequency = frequency;
}
@Override
public double getNoise(double x, double y) {
return ((channel.getChannel(image.getRGB(FastMath.floorMod(FastMath.floorToInt(x * frequency), image.getWidth()), FastMath.floorMod(FastMath.floorToInt(y * frequency), image.getHeight()))) / 255D) - 0.5) * 2;
}
@Override
public double getNoise(double x, double y, double z) {
return getNoise(x, y);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return getNoise(x, y);
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
return getNoise(x, y, z);
}
public enum Channel {
RED {
@Override
public int getChannel(int mashed) {
return (mashed >> 16) & 0xff;
}
}, GREEN {
@Override
public int getChannel(int mashed) {
return (mashed >> 8) & 0xff;
}
}, BLUE {
@Override
public int getChannel(int mashed) {
return mashed & 0xff;
}
}, GRAYSCALE {
@Override
public int getChannel(int mashed) {
return (RED.getChannel(mashed) + GREEN.getChannel(mashed) + BLUE.getChannel(mashed)) / 3;
}
}, ALPHA {
@Override
public int getChannel(int mashed) {
return (mashed >> 24) & 0xff;
}
};
public abstract int getChannel(int mashed);
}
}
@@ -0,0 +1,59 @@
package com.dfsek.terra.api.math.noise.samplers;
import com.dfsek.terra.api.math.noise.NoiseSampler;
public class KernelSampler implements NoiseSampler {
private final double[][] kernel;
private final NoiseSampler in;
private double frequency = 1;
public KernelSampler(double[][] kernel, NoiseSampler in) {
this.kernel = kernel;
this.in = in;
}
@Override
public double getNoise(double x, double y) {
return getNoiseSeeded(0, x, y);
}
@Override
public double getNoise(double x, double y, double z) {
return getNoiseSeeded(0, x, y, z);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
x *= frequency;
y *= frequency;
double accumulator = 0;
for(int kx = 0; kx < kernel.length; kx++) {
for(int ky = 0; ky < kernel[kx].length; ky++) {
accumulator += in.getNoise(x + kx, y + ky) * kernel[kx][ky];
}
}
return accumulator;
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
x *= frequency;
y *= frequency;
z *= frequency;
double accumulator = 0;
for(int kx = 0; kx < kernel.length; kx++) {
for(int ky = 0; ky < kernel[kx].length; ky++) {
accumulator += in.getNoise(x + kx, y, z + ky) * kernel[kx][ky];
}
}
return accumulator;
}
public void setFrequency(double frequency) {
this.frequency = frequency;
}
}
@@ -0,0 +1,565 @@
package com.dfsek.terra.api.math.noise.samplers.noise;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.math.vector.Vector2;
import com.dfsek.terra.api.math.vector.Vector3;
/**
* NoiseSampler implementation for Cellular (Voronoi/Worley) Noise.
*/
public class CellularSampler extends NoiseFunction {
private static final double[] RAND_VECS_3D = {
-0.7292736885d, -0.6618439697d, 0.1735581948d, 0, 0.790292081d, -0.5480887466d, -0.2739291014d, 0, 0.7217578935d, 0.6226212466d,
-0.3023380997d, 0, 0.565683137d, -0.8208298145d, -0.0790000257d, 0, 0.760049034d, -0.5555979497d, -0.3370999617d, 0,
0.3713945616d, 0.5011264475d, 0.7816254623d, 0, -0.1277062463d, -0.4254438999d, -0.8959289049d, 0, -0.2881560924d,
-0.5815838982d, 0.7607405838d, 0, 0.5849561111d, -0.662820239d, -0.4674352136d, 0, 0.3307171178d, 0.0391653737d, 0.94291689d, 0,
0.8712121778d, -0.4113374369d, -0.2679381538d, 0, 0.580981015d, 0.7021915846d, 0.4115677815d, 0, 0.503756873d, 0.6330056931d,
-0.5878203852d, 0, 0.4493712205d, 0.601390195d, 0.6606022552d, 0, -0.6878403724d, 0.09018890807d, -0.7202371714d, 0,
-0.5958956522d, -0.6469350577d, 0.475797649d, 0, -0.5127052122d, 0.1946921978d, -0.8361987284d, 0, -0.9911507142d,
-0.05410276466d, -0.1212153153d, 0, -0.2149721042d, 0.9720882117d, -0.09397607749d, 0, -0.7518650936d, -0.5428057603d,
0.3742469607d, 0, 0.5237068895d, 0.8516377189d, -0.02107817834d, 0, 0.6333504779d, 0.1926167129d, -0.7495104896d, 0,
-0.06788241606d, 0.3998305789d, 0.9140719259d, 0, -0.5538628599d, -0.4729896695d, -0.6852128902d, 0, -0.7261455366d,
-0.5911990757d, 0.3509933228d, 0, -0.9229274737d, -0.1782808786d, 0.3412049336d, 0, -0.6968815002d, 0.6511274338d,
0.3006480328d, 0, 0.9608044783d, -0.2098363234d, -0.1811724921d, 0, 0.06817146062d, -0.9743405129d, 0.2145069156d, 0,
-0.3577285196d, -0.6697087264d, -0.6507845481d, 0, -0.1868621131d, 0.7648617052d, -0.6164974636d, 0, -0.6541697588d,
0.3967914832d, 0.6439087246d, 0, 0.6993340405d, -0.6164538506d, 0.3618239211d, 0, -0.1546665739d, 0.6291283928d, 0.7617583057d,
0, -0.6841612949d, -0.2580482182d, -0.6821542638d, 0, 0.5383980957d, 0.4258654885d, 0.7271630328d, 0, -0.5026987823d,
-0.7939832935d, -0.3418836993d, 0, 0.3202971715d, 0.2834415347d, 0.9039195862d, 0, 0.8683227101d, -0.0003762656404d,
-0.4959995258d, 0, 0.791120031d, -0.08511045745d, 0.6057105799d, 0, -0.04011016052d, -0.4397248749d, 0.8972364289d, 0,
0.9145119872d, 0.3579346169d, -0.1885487608d, 0, -0.9612039066d, -0.2756484276d, 0.01024666929d, 0, 0.6510361721d,
-0.2877799159d, -0.7023778346d, 0, -0.2041786351d, 0.7365237271d, 0.644859585d, 0, -0.7718263711d, 0.3790626912d, 0.5104855816d,
0, -0.3060082741d, -0.7692987727d, 0.5608371729d, 0, 0.454007341d, -0.5024843065d, 0.7357899537d, 0, 0.4816795475d,
0.6021208291d, -0.6367380315d, 0, 0.6961980369d, -0.3222197429d, 0.641469197d, 0, -0.6532160499d, -0.6781148932d, 0.3368515753d,
0, 0.5089301236d, -0.6154662304d, -0.6018234363d, 0, -0.1635919754d, -0.9133604627d, -0.372840892d, 0, 0.52408019d,
-0.8437664109d, 0.1157505864d, 0, 0.5902587356d, 0.4983817807d, -0.6349883666d, 0, 0.5863227872d, 0.494764745d, 0.6414307729d,
0, 0.6779335087d, 0.2341345225d, 0.6968408593d, 0, 0.7177054546d, -0.6858979348d, 0.120178631d, 0, -0.5328819713d,
-0.5205125012d, 0.6671608058d, 0, -0.8654874251d, -0.0700727088d, -0.4960053754d, 0, -0.2861810166d, 0.7952089234d,
0.5345495242d, 0, -0.04849529634d, 0.9810836427d, -0.1874115585d, 0, -0.6358521667d, 0.6058348682d, 0.4781800233d, 0,
0.6254794696d, -0.2861619734d, 0.7258696564d, 0, -0.2585259868d, 0.5061949264d, -0.8227581726d, 0, 0.02136306781d,
0.5064016808d, -0.8620330371d, 0, 0.200111773d, 0.8599263484d, 0.4695550591d, 0, 0.4743561372d, 0.6014985084d, -0.6427953014d,
0, 0.6622993731d, -0.5202474575d, -0.5391679918d, 0, 0.08084972818d, -0.6532720452d, 0.7527940996d, 0, -0.6893687501d,
0.0592860349d, 0.7219805347d, 0, -0.1121887082d, -0.9673185067d, 0.2273952515d, 0, 0.7344116094d, 0.5979668656d, -0.3210532909d,
0, 0.5789393465d, -0.2488849713d, 0.7764570201d, 0, 0.6988182827d, 0.3557169806d, -0.6205791146d, 0, -0.8636845529d,
-0.2748771249d, -0.4224826141d, 0, -0.4247027957d, -0.4640880967d, 0.777335046d, 0, 0.5257722489d, -0.8427017621d,
0.1158329937d, 0, 0.9343830603d, 0.316302472d, -0.1639543925d, 0, -0.1016836419d, -0.8057303073d, -0.5834887393d, 0,
-0.6529238969d, 0.50602126d, -0.5635892736d, 0, -0.2465286165d, -0.9668205684d, -0.06694497494d, 0, -0.9776897119d,
-0.2099250524d, -0.007368825344d, 0, 0.7736893337d, 0.5734244712d, 0.2694238123d, 0, -0.6095087895d, 0.4995678998d,
0.6155736747d, 0, 0.5794535482d, 0.7434546771d, 0.3339292269d, 0, -0.8226211154d, 0.08142581855d, 0.5627293636d, 0,
-0.510385483d, 0.4703667658d, 0.7199039967d, 0, -0.5764971849d, -0.07231656274d, -0.8138926898d, 0, 0.7250628871d,
0.3949971505d, -0.5641463116d, 0, -0.1525424005d, 0.4860840828d, -0.8604958341d, 0, -0.5550976208d, -0.4957820792d,
0.667882296d, 0, -0.1883614327d, 0.9145869398d, 0.357841725d, 0, 0.7625556724d, -0.5414408243d, -0.3540489801d, 0,
-0.5870231946d, -0.3226498013d, -0.7424963803d, 0, 0.3051124198d, 0.2262544068d, -0.9250488391d, 0, 0.6379576059d, 0.577242424d,
-0.5097070502d, 0, -0.5966775796d, 0.1454852398d, -0.7891830656d, 0, -0.658330573d, 0.6555487542d, -0.3699414651d, 0,
0.7434892426d, 0.2351084581d, 0.6260573129d, 0, 0.5562114096d, 0.8264360377d, -0.0873632843d, 0, -0.3028940016d, -0.8251527185d,
0.4768419182d, 0, 0.1129343818d, -0.985888439d, -0.1235710781d, 0, 0.5937652891d, -0.5896813806d, 0.5474656618d, 0,
0.6757964092d, -0.5835758614d, -0.4502648413d, 0, 0.7242302609d, -0.1152719764d, 0.6798550586d, 0, -0.9511914166d,
0.0753623979d, -0.2992580792d, 0, 0.2539470961d, -0.1886339355d, 0.9486454084d, 0, 0.571433621d, -0.1679450851d, -0.8032795685d,
0, -0.06778234979d, 0.3978269256d, 0.9149531629d, 0, 0.6074972649d, 0.733060024d, -0.3058922593d, 0, -0.5435478392d,
0.1675822484d, 0.8224791405d, 0, -0.5876678086d, -0.3380045064d, -0.7351186982d, 0, -0.7967562402d, 0.04097822706d,
-0.6029098428d, 0, -0.1996350917d, 0.8706294745d, 0.4496111079d, 0, -0.02787660336d, -0.9106232682d, -0.4122962022d, 0,
-0.7797625996d, -0.6257634692d, 0.01975775581d, 0, -0.5211232846d, 0.7401644346d, -0.4249554471d, 0, 0.8575424857d,
0.4053272873d, -0.3167501783d, 0, 0.1045223322d, 0.8390195772d, -0.5339674439d, 0, 0.3501822831d, 0.9242524096d, -0.1520850155d,
0, 0.1987849858d, 0.07647613266d, 0.9770547224d, 0, 0.7845996363d, 0.6066256811d, -0.1280964233d, 0, 0.09006737436d,
-0.9750989929d, -0.2026569073d, 0, -0.8274343547d, -0.542299559d, 0.1458203587d, 0, -0.3485797732d, -0.415802277d, 0.840000362d,
0, -0.2471778936d, -0.7304819962d, -0.6366310879d, 0, -0.3700154943d, 0.8577948156d, 0.3567584454d, 0, 0.5913394901d,
-0.548311967d, -0.5913303597d, 0, 0.1204873514d, -0.7626472379d, -0.6354935001d, 0, 0.616959265d, 0.03079647928d, 0.7863922953d,
0, 0.1258156836d, -0.6640829889d, -0.7369967419d, 0, -0.6477565124d, -0.1740147258d, -0.7417077429d, 0, 0.6217889313d,
-0.7804430448d, -0.06547655076d, 0, 0.6589943422d, -0.6096987708d, 0.4404473475d, 0, -0.2689837504d, -0.6732403169d,
-0.6887635427d, 0, -0.3849775103d, 0.5676542638d, 0.7277093879d, 0, 0.5754444408d, 0.8110471154d, -0.1051963504d, 0,
0.9141593684d, 0.3832947817d, 0.131900567d, 0, -0.107925319d, 0.9245493968d, 0.3654593525d, 0, 0.377977089d, 0.3043148782d,
0.8743716458d, 0, -0.2142885215d, -0.8259286236d, 0.5214617324d, 0, 0.5802544474d, 0.4148098596d, -0.7008834116d, 0,
-0.1982660881d, 0.8567161266d, -0.4761596756d, 0, -0.03381553704d, 0.3773180787d, -0.9254661404d, 0, -0.6867922841d,
-0.6656597827d, 0.2919133642d, 0, 0.7731742607d, -0.2875793547d, -0.5652430251d, 0, -0.09655941928d, 0.9193708367d,
-0.3813575004d, 0, 0.2715702457d, -0.9577909544d, -0.09426605581d, 0, 0.2451015704d, -0.6917998565d, -0.6792188003d, 0,
0.977700782d, -0.1753855374d, 0.1155036542d, 0, -0.5224739938d, 0.8521606816d, 0.02903615945d, 0, -0.7734880599d,
-0.5261292347d, 0.3534179531d, 0, -0.7134492443d, -0.269547243d, 0.6467878011d, 0, 0.1644037271d, 0.5105846203d, -0.8439637196d,
0, 0.6494635788d, 0.05585611296d, 0.7583384168d, 0, -0.4711970882d, 0.5017280509d, -0.7254255765d, 0, -0.6335764307d,
-0.2381686273d, -0.7361091029d, 0, -0.9021533097d, -0.270947803d, -0.3357181763d, 0, -0.3793711033d, 0.872258117d,
0.3086152025d, 0, -0.6855598966d, -0.3250143309d, 0.6514394162d, 0, 0.2900942212d, -0.7799057743d, -0.5546100667d, 0,
-0.2098319339d, 0.85037073d, 0.4825351604d, 0, -0.4592603758d, 0.6598504336d, -0.5947077538d, 0, 0.8715945488d, 0.09616365406d,
-0.4807031248d, 0, -0.6776666319d, 0.7118504878d, -0.1844907016d, 0, 0.7044377633d, 0.312427597d, 0.637304036d, 0,
-0.7052318886d, -0.2401093292d, -0.6670798253d, 0, 0.081921007d, -0.7207336136d, -0.6883545647d, 0, -0.6993680906d,
-0.5875763221d, -0.4069869034d, 0, -0.1281454481d, 0.6419895885d, 0.7559286424d, 0, -0.6337388239d, -0.6785471501d,
-0.3714146849d, 0, 0.5565051903d, -0.2168887573d, -0.8020356851d, 0, -0.5791554484d, 0.7244372011d, -0.3738578718d, 0,
0.1175779076d, -0.7096451073d, 0.6946792478d, 0, -0.6134619607d, 0.1323631078d, 0.7785527795d, 0, 0.6984635305d,
-0.02980516237d, -0.715024719d, 0, 0.8318082963d, -0.3930171956d, 0.3919597455d, 0, 0.1469576422d, 0.05541651717d,
-0.9875892167d, 0, 0.708868575d, -0.2690503865d, 0.6520101478d, 0, 0.2726053183d, 0.67369766d, -0.68688995d, 0, -0.6591295371d,
0.3035458599d, -0.6880466294d, 0, 0.4815131379d, -0.7528270071d, 0.4487723203d, 0, 0.9430009463d, 0.1675647412d, -0.2875261255d,
0, 0.434802957d, 0.7695304522d, -0.4677277752d, 0, 0.3931996188d, 0.594473625d, 0.7014236729d, 0, 0.7254336655d, -0.603925654d,
0.3301814672d, 0, 0.7590235227d, -0.6506083235d, 0.02433313207d, 0, -0.8552768592d, -0.3430042733d, 0.3883935666d, 0,
-0.6139746835d, 0.6981725247d, 0.3682257648d, 0, -0.7465905486d, -0.5752009504d, 0.3342849376d, 0, 0.5730065677d, 0.810555537d,
-0.1210916791d, 0, -0.9225877367d, -0.3475211012d, -0.167514036d, 0, -0.7105816789d, -0.4719692027d, -0.5218416899d, 0,
-0.08564609717d, 0.3583001386d, 0.929669703d, 0, -0.8279697606d, -0.2043157126d, 0.5222271202d, 0, 0.427944023d, 0.278165994d,
0.8599346446d, 0, 0.5399079671d, -0.7857120652d, -0.3019204161d, 0, 0.5678404253d, -0.5495413974d, -0.6128307303d, 0,
-0.9896071041d, 0.1365639107d, -0.04503418428d, 0, -0.6154342638d, -0.6440875597d, 0.4543037336d, 0, 0.1074204368d,
-0.7946340692d, 0.5975094525d, 0, -0.3595449969d, -0.8885529948d, 0.28495784d, 0, -0.2180405296d, 0.1529888965d, 0.9638738118d,
0, -0.7277432317d, -0.6164050508d, -0.3007234646d, 0, 0.7249729114d, -0.00669719484d, 0.6887448187d, 0, -0.5553659455d,
-0.5336586252d, 0.6377908264d, 0, 0.5137558015d, 0.7976208196d, -0.3160000073d, 0, -0.3794024848d, 0.9245608561d,
-0.03522751494d, 0, 0.8229248658d, 0.2745365933d, -0.4974176556d, 0, -0.5404114394d, 0.6091141441d, 0.5804613989d, 0,
0.8036581901d, -0.2703029469d, 0.5301601931d, 0, 0.6044318879d, 0.6832968393d, 0.4095943388d, 0, 0.06389988817d, 0.9658208605d,
-0.2512108074d, 0, 0.1087113286d, 0.7402471173d, -0.6634877936d, 0, -0.713427712d, -0.6926784018d, 0.1059128479d, 0,
0.6458897819d, -0.5724548511d, -0.5050958653d, 0, -0.6553931414d, 0.7381471625d, 0.159995615d, 0, 0.3910961323d, 0.9188871375d,
-0.05186755998d, 0, -0.4879022471d, -0.5904376907d, 0.6429111375d, 0, 0.6014790094d, 0.7707441366d, -0.2101820095d, 0,
-0.5677173047d, 0.7511360995d, 0.3368851762d, 0, 0.7858573506d, 0.226674665d, 0.5753666838d, 0, -0.4520345543d, -0.604222686d,
-0.6561857263d, 0, 0.002272116345d, 0.4132844051d, -0.9105991643d, 0, -0.5815751419d, -0.5162925989d, 0.6286591339d, 0,
-0.03703704785d, 0.8273785755d, 0.5604221175d, 0, -0.5119692504d, 0.7953543429d, -0.3244980058d, 0, -0.2682417366d,
-0.9572290247d, -0.1084387619d, 0, -0.2322482736d, -0.9679131102d, -0.09594243324d, 0, 0.3554328906d, -0.8881505545d,
0.2913006227d, 0, 0.7346520519d, -0.4371373164d, 0.5188422971d, 0, 0.9985120116d, 0.04659011161d, -0.02833944577d, 0,
-0.3727687496d, -0.9082481361d, 0.1900757285d, 0, 0.91737377d, -0.3483642108d, 0.1925298489d, 0, 0.2714911074d, 0.4147529736d,
-0.8684886582d, 0, 0.5131763485d, -0.7116334161d, 0.4798207128d, 0, -0.8737353606d, 0.18886992d, -0.4482350644d, 0,
0.8460043821d, -0.3725217914d, 0.3814499973d, 0, 0.8978727456d, -0.1780209141d, -0.4026575304d, 0, 0.2178065647d,
-0.9698322841d, -0.1094789531d, 0, -0.1518031304d, -0.7788918132d, -0.6085091231d, 0, -0.2600384876d, -0.4755398075d,
-0.8403819825d, 0, 0.572313509d, -0.7474340931d, -0.3373418503d, 0, -0.7174141009d, 0.1699017182d, -0.6756111411d, 0,
-0.684180784d, 0.02145707593d, -0.7289967412d, 0, -0.2007447902d, 0.06555605789d, -0.9774476623d, 0, -0.1148803697d,
-0.8044887315d, 0.5827524187d, 0, -0.7870349638d, 0.03447489231d, 0.6159443543d, 0, -0.2015596421d, 0.6859872284d,
0.6991389226d, 0, -0.08581082512d, -0.10920836d, -0.9903080513d, 0, 0.5532693395d, 0.7325250401d, -0.396610771d, 0,
-0.1842489331d, -0.9777375055d, -0.1004076743d, 0, 0.0775473789d, -0.9111505856d, 0.4047110257d, 0, 0.1399838409d,
0.7601631212d, -0.6344734459d, 0, 0.4484419361d, -0.845289248d, 0.2904925424d, 0
};
private static final double[] RAND_VECS_2D = {
-0.2700222198d, -0.9628540911d, 0.3863092627d, -0.9223693152d, 0.04444859006d, -0.999011673d, -0.5992523158d, -0.8005602176d,
-0.7819280288d, 0.6233687174d, 0.9464672271d, 0.3227999196d, -0.6514146797d, -0.7587218957d, 0.9378472289d, 0.347048376d,
-0.8497875957d, -0.5271252623d, -0.879042592d, 0.4767432447d, -0.892300288d, -0.4514423508d, -0.379844434d, -0.9250503802d,
-0.9951650832d, 0.0982163789d, 0.7724397808d, -0.6350880136d, 0.7573283322d, -0.6530343002d, -0.9928004525d, -0.119780055d,
-0.0532665713d, 0.9985803285d, 0.9754253726d, -0.2203300762d, -0.7665018163d, 0.6422421394d, 0.991636706d, 0.1290606184d,
-0.994696838d, 0.1028503788d, -0.5379205513d, -0.84299554d, 0.5022815471d, -0.8647041387d, 0.4559821461d, -0.8899889226d,
-0.8659131224d, -0.5001944266d, 0.0879458407d, -0.9961252577d, -0.5051684983d, 0.8630207346d, 0.7753185226d, -0.6315704146d,
-0.6921944612d, 0.7217110418d, -0.5191659449d, -0.8546734591d, 0.8978622882d, -0.4402764035d, -0.1706774107d, 0.9853269617d,
-0.9353430106d, -0.3537420705d, -0.9992404798d, 0.03896746794d, -0.2882064021d, -0.9575683108d, -0.9663811329d, 0.2571137995d,
-0.8759714238d, -0.4823630009d, -0.8303123018d, -0.5572983775d, 0.05110133755d, -0.9986934731d, -0.8558373281d, -0.5172450752d,
0.09887025282d, 0.9951003332d, 0.9189016087d, 0.3944867976d, -0.2439375892d, -0.9697909324d, -0.8121409387d, -0.5834613061d,
-0.9910431363d, 0.1335421355d, 0.8492423985d, -0.5280031709d, -0.9717838994d, -0.2358729591d, 0.9949457207d, 0.1004142068d,
0.6241065508d, -0.7813392434d, 0.662910307d, 0.7486988212d, -0.7197418176d, 0.6942418282d, -0.8143370775d, -0.5803922158d,
0.104521054d, -0.9945226741d, -0.1065926113d, -0.9943027784d, 0.445799684d, -0.8951327509d, 0.105547406d, 0.9944142724d,
-0.992790267d, 0.1198644477d, -0.8334366408d, 0.552615025d, 0.9115561563d, -0.4111755999d, 0.8285544909d, -0.5599084351d,
0.7217097654d, -0.6921957921d, 0.4940492677d, -0.8694339084d, -0.3652321272d, -0.9309164803d, -0.9696606758d, 0.2444548501d,
0.08925509731d, -0.996008799d, 0.5354071276d, -0.8445941083d, -0.1053576186d, 0.9944343981d, -0.9890284586d, 0.1477251101d,
0.004856104961d, 0.9999882091d, 0.9885598478d, 0.1508291331d, 0.9286129562d, -0.3710498316d, -0.5832393863d, -0.8123003252d,
0.3015207509d, 0.9534596146d, -0.9575110528d, 0.2883965738d, 0.9715802154d, -0.2367105511d, 0.229981792d, 0.9731949318d,
0.955763816d, -0.2941352207d, 0.740956116d, 0.6715534485d, -0.9971513787d, -0.07542630764d, 0.6905710663d, -0.7232645452d,
-0.290713703d, -0.9568100872d, 0.5912777791d, -0.8064679708d, -0.9454592212d, -0.325740481d, 0.6664455681d, 0.74555369d,
0.6236134912d, 0.7817328275d, 0.9126993851d, -0.4086316587d, -0.8191762011d, 0.5735419353d, -0.8812745759d, -0.4726046147d,
0.9953313627d, 0.09651672651d, 0.9855650846d, -0.1692969699d, -0.8495980887d, 0.5274306472d, 0.6174853946d, -0.7865823463d,
0.8508156371d, 0.52546432d, 0.9985032451d, -0.05469249926d, 0.1971371563d, -0.9803759185d, 0.6607855748d, -0.7505747292d,
-0.03097494063d, 0.9995201614d, -0.6731660801d, 0.739491331d, -0.7195018362d, -0.6944905383d, 0.9727511689d, 0.2318515979d,
0.9997059088d, -0.0242506907d, 0.4421787429d, -0.8969269532d, 0.9981350961d, -0.061043673d, -0.9173660799d, -0.3980445648d,
-0.8150056635d, -0.5794529907d, -0.8789331304d, 0.4769450202d, 0.0158605829d, 0.999874213d, -0.8095464474d, 0.5870558317d,
-0.9165898907d, -0.3998286786d, -0.8023542565d, 0.5968480938d, -0.5176737917d, 0.8555780767d, -0.8154407307d, -0.5788405779d,
0.4022010347d, -0.9155513791d, -0.9052556868d, -0.4248672045d, 0.7317445619d, 0.6815789728d, -0.5647632201d, -0.8252529947d,
-0.8403276335d, -0.5420788397d, -0.9314281527d, 0.363925262d, 0.5238198472d, 0.8518290719d, 0.7432803869d, -0.6689800195d,
-0.985371561d, -0.1704197369d, 0.4601468731d, 0.88784281d, 0.825855404d, 0.5638819483d, 0.6182366099d, 0.7859920446d,
0.8331502863d, -0.553046653d, 0.1500307506d, 0.9886813308d, -0.662330369d, -0.7492119075d, -0.668598664d, 0.743623444d,
0.7025606278d, 0.7116238924d, -0.5419389763d, -0.8404178401d, -0.3388616456d, 0.9408362159d, 0.8331530315d, 0.5530425174d,
-0.2989720662d, -0.9542618632d, 0.2638522993d, 0.9645630949d, 0.124108739d, -0.9922686234d, -0.7282649308d, -0.6852956957d,
0.6962500149d, 0.7177993569d, -0.9183535368d, 0.3957610156d, -0.6326102274d, -0.7744703352d, -0.9331891859d, -0.359385508d,
-0.1153779357d, -0.9933216659d, 0.9514974788d, -0.3076565421d, -0.08987977445d, -0.9959526224d, 0.6678496916d, 0.7442961705d,
0.7952400393d, -0.6062947138d, -0.6462007402d, -0.7631674805d, -0.2733598753d, 0.9619118351d, 0.9669590226d, -0.254931851d,
-0.9792894595d, 0.2024651934d, -0.5369502995d, -0.8436138784d, -0.270036471d, -0.9628500944d, -0.6400277131d, 0.7683518247d,
-0.7854537493d, -0.6189203566d, 0.06005905383d, -0.9981948257d, -0.02455770378d, 0.9996984141d, -0.65983623d, 0.751409442d,
-0.6253894466d, -0.7803127835d, -0.6210408851d, -0.7837781695d, 0.8348888491d, 0.5504185768d, -0.1592275245d, 0.9872419133d,
0.8367622488d, 0.5475663786d, -0.8675753916d, -0.4973056806d, -0.2022662628d, -0.9793305667d, 0.9399189937d, 0.3413975472d,
0.9877404807d, -0.1561049093d, -0.9034455656d, 0.4287028224d, 0.1269804218d, -0.9919052235d, -0.3819600854d, 0.924178821d,
0.9754625894d, 0.2201652486d, -0.3204015856d, -0.9472818081d, -0.9874760884d, 0.1577687387d, 0.02535348474d, -0.9996785487d,
0.4835130794d, -0.8753371362d, -0.2850799925d, -0.9585037287d, -0.06805516006d, -0.99768156d, -0.7885244045d, -0.6150034663d,
0.3185392127d, -0.9479096845d, 0.8880043089d, 0.4598351306d, 0.6476921488d, -0.7619021462d, 0.9820241299d, 0.1887554194d,
0.9357275128d, -0.3527237187d, -0.8894895414d, 0.4569555293d, 0.7922791302d, 0.6101588153d, 0.7483818261d, 0.6632681526d,
-0.7288929755d, -0.6846276581d, 0.8729032783d, -0.4878932944d, 0.8288345784d, 0.5594937369d, 0.08074567077d, 0.9967347374d,
0.9799148216d, -0.1994165048d, -0.580730673d, -0.8140957471d, -0.4700049791d, -0.8826637636d, 0.2409492979d, 0.9705377045d,
0.9437816757d, -0.3305694308d, -0.8927998638d, -0.4504535528d, -0.8069622304d, 0.5906030467d, 0.06258973166d, 0.9980393407d,
-0.9312597469d, 0.3643559849d, 0.5777449785d, 0.8162173362d, -0.3360095855d, -0.941858566d, 0.697932075d, -0.7161639607d,
-0.002008157227d, -0.9999979837d, -0.1827294312d, -0.9831632392d, -0.6523911722d, 0.7578824173d, -0.4302626911d, -0.9027037258d,
-0.9985126289d, -0.05452091251d, -0.01028102172d, -0.9999471489d, -0.4946071129d, 0.8691166802d, -0.2999350194d, 0.9539596344d,
0.8165471961d, 0.5772786819d, 0.2697460475d, 0.962931498d, -0.7306287391d, -0.6827749597d, -0.7590952064d, -0.6509796216d,
-0.907053853d, 0.4210146171d, -0.5104861064d, -0.8598860013d, 0.8613350597d, 0.5080373165d, 0.5007881595d, -0.8655698812d,
-0.654158152d, 0.7563577938d, -0.8382755311d, -0.545246856d, 0.6940070834d, 0.7199681717d, 0.06950936031d, 0.9975812994d,
0.1702942185d, -0.9853932612d, 0.2695973274d, 0.9629731466d, 0.5519612192d, -0.8338697815d, 0.225657487d, -0.9742067022d,
0.4215262855d, -0.9068161835d, 0.4881873305d, -0.8727388672d, -0.3683854996d, -0.9296731273d, -0.9825390578d, 0.1860564427d,
0.81256471d, 0.5828709909d, 0.3196460933d, -0.9475370046d, 0.9570913859d, 0.2897862643d, -0.6876655497d, -0.7260276109d,
-0.9988770922d, -0.047376731d, -0.1250179027d, 0.992154486d, -0.8280133617d, 0.560708367d, 0.9324863769d, -0.3612051451d,
0.6394653183d, 0.7688199442d, -0.01623847064d, -0.9998681473d, -0.9955014666d, -0.09474613458d, -0.81453315d, 0.580117012d,
0.4037327978d, -0.9148769469d, 0.9944263371d, 0.1054336766d, -0.1624711654d, 0.9867132919d, -0.9949487814d, -0.100383875d,
-0.6995302564d, 0.7146029809d, 0.5263414922d, -0.85027327d, -0.5395221479d, 0.841971408d, 0.6579370318d, 0.7530729462d,
0.01426758847d, -0.9998982128d, -0.6734383991d, 0.7392433447d, 0.639412098d, -0.7688642071d, 0.9211571421d, 0.3891908523d,
-0.146637214d, -0.9891903394d, -0.782318098d, 0.6228791163d, -0.5039610839d, -0.8637263605d, -0.7743120191d, -0.6328039957d,
};
private DistanceFunction distanceFunction = DistanceFunction.EuclideanSq;
private ReturnType returnType = ReturnType.Distance;
private double jitterModifier = 1.0;
private NoiseSampler noiseLookup;
public CellularSampler(int seed) {
super(seed);
noiseLookup = new OpenSimplex2Sampler(seed);
}
public void setDistanceFunction(DistanceFunction distanceFunction) {
this.distanceFunction = distanceFunction;
}
public void setJitterModifier(double jitterModifier) {
this.jitterModifier = jitterModifier;
}
public void setNoiseLookup(NoiseSampler noiseLookup) {
this.noiseLookup = noiseLookup;
}
public void setReturnType(ReturnType returnType) {
this.returnType = returnType;
}
@Override
public double getNoiseRaw(int seed, double x, double y) {
int xr = fastRound(x);
int yr = fastRound(y);
double distance0 = Double.MAX_VALUE;
double distance1 = Double.MAX_VALUE;
double distance2 = Double.MAX_VALUE;
int closestHash = 0;
double cellularJitter = 0.43701595 * jitterModifier;
int xPrimed = (xr - 1) * PRIME_X;
int yPrimedBase = (yr - 1) * PRIME_Y;
Vector2 center = new Vector2(x, y);
switch(distanceFunction) {
default:
case Euclidean:
case EuclideanSq:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int hash = hash(seed, xPrimed, yPrimed);
int idx = hash & (255 << 1);
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
double newDistance = vecX * vecX + vecY * vecY;
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
center.setZ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
case Manhattan:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int hash = hash(seed, xPrimed, yPrimed);
int idx = hash & (255 << 1);
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
double newDistance = fastAbs(vecX) + fastAbs(vecY);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
center.setZ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
case Hybrid:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int hash = hash(seed, xPrimed, yPrimed);
int idx = hash & (255 << 1);
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
double newDistance = (fastAbs(vecX) + fastAbs(vecY)) + (vecX * vecX + vecY * vecY);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
center.setZ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
}
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
distance0 = fastSqrt(distance0);
if(returnType != ReturnType.CellValue) {
distance1 = fastSqrt(distance1);
}
}
switch(returnType) {
case CellValue:
return closestHash * (1 / 2147483648.0);
case Distance:
return distance0 - 1;
case Distance2:
return distance1 - 1;
case Distance2Add:
return (distance1 + distance0) * 0.5 - 1;
case Distance2Sub:
return distance1 - distance0 - 1;
case Distance2Mul:
return distance1 * distance0 * 0.5 - 1;
case Distance2Div:
return distance0 / distance1 - 1;
case NoiseLookup:
return noiseLookup.getNoise(center.getX(), center.getZ());
case Distance3:
return distance2 - 1;
case Distance3Add:
return (distance2 + distance0) * 0.5 - 1;
case Distance3Sub:
return distance2 - distance0 - 1;
case Distance3Mul:
return distance2 * distance0 - 1;
case Distance3Div:
return distance0 / distance2 - 1;
default:
return 0;
}
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
int xr = fastRound(x);
int yr = fastRound(y);
int zr = fastRound(z);
double distance0 = Double.MAX_VALUE;
double distance1 = Double.MAX_VALUE;
double distance2 = Double.MAX_VALUE;
int closestHash = 0;
double cellularJitter = 0.39614353 * jitterModifier;
int xPrimed = (xr - 1) * PRIME_X;
int yPrimedBase = (yr - 1) * PRIME_Y;
int zPrimedBase = (zr - 1) * PRIME_Z;
Vector3 center = new Vector3(x, y, z);
switch(distanceFunction) {
case Euclidean:
case EuclideanSq:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int zPrimed = zPrimedBase;
for(int zi = zr - 1; zi <= zr + 1; zi++) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
int idx = hash & (255 << 2);
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
double newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
center.setZ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
zPrimed += PRIME_Z;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
case Manhattan:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int zPrimed = zPrimedBase;
for(int zi = zr - 1; zi <= zr + 1; zi++) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
int idx = hash & (255 << 2);
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
double newDistance = fastAbs(vecX) + fastAbs(vecY) + fastAbs(vecZ);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
center.setZ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
zPrimed += PRIME_Z;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
case Hybrid:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int zPrimed = zPrimedBase;
for(int zi = zr - 1; zi <= zr + 1; zi++) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
int idx = hash & (255 << 2);
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
double newDistance = (fastAbs(vecX) + fastAbs(vecY) + fastAbs(vecZ)) +
(vecX * vecX + vecY * vecY + vecZ * vecZ);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
center.setZ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
zPrimed += PRIME_Z;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
default:
break;
}
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
distance0 = fastSqrt(distance0);
if(returnType != ReturnType.CellValue) {
distance1 = fastSqrt(distance1);
}
}
switch(returnType) {
case CellValue:
return closestHash * (1 / 2147483648.0);
case Distance:
return distance0 - 1;
case Distance2:
return distance1 - 1;
case Distance2Add:
return (distance1 + distance0) * 0.5 - 1;
case Distance2Sub:
return distance1 - distance0 - 1;
case Distance2Mul:
return distance1 * distance0 * 0.5 - 1;
case Distance2Div:
return distance0 / distance1 - 1;
case NoiseLookup:
return noiseLookup.getNoise(center.getX(), center.getY(), center.getZ());
case Distance3:
return distance2 - 1;
case Distance3Add:
return (distance2 + distance0) * 0.5 - 1;
case Distance3Sub:
return distance2 - distance0 - 1;
case Distance3Mul:
return distance2 * distance0 - 1;
case Distance3Div:
return distance0 / distance2 - 1;
default:
return 0;
}
}
public enum DistanceFunction {
Euclidean,
EuclideanSq,
Manhattan,
Hybrid
}
public enum ReturnType {
CellValue,
Distance,
Distance2,
Distance2Add,
Distance2Sub,
Distance2Mul,
Distance2Div,
NoiseLookup,
Distance3,
Distance3Add,
Distance3Sub,
Distance3Mul,
Distance3Div
}
}
@@ -0,0 +1,23 @@
package com.dfsek.terra.api.math.noise.samplers.noise;
/**
* Sampler3D implementation that returns a constant.
*/
public class ConstantSampler extends NoiseFunction {
private final double constant;
public ConstantSampler(double constant) {
super(0);
this.constant = constant;
}
@Override
public double getNoiseRaw(int seed, double x, double y) {
return constant;
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
return constant;
}
}
@@ -0,0 +1,43 @@
package com.dfsek.terra.api.math.noise.samplers.noise;
import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.Function;
import java.util.Map;
/**
* NoiseSampler implementation using a Paralithic expression.
*/
public class ExpressionFunction extends NoiseFunction {
private final Expression expression;
public ExpressionFunction(Map<String, Function> functions, String eq, Map<String, Double> vars) throws ParseException {
super(0);
Parser p = new Parser();
Scope scope = new Scope();
scope.addInvocationVariable("x");
scope.addInvocationVariable("y");
scope.addInvocationVariable("z");
vars.forEach(scope::create);
functions.forEach(p::registerFunction);
expression = p.parse(eq, scope);
frequency = 1;
}
@Override
public double getNoiseRaw(int seed, double x, double y) {
return expression.evaluate(x, 0, y);
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
return expression.evaluate(x, y, z);
}
}
@@ -0,0 +1,105 @@
package com.dfsek.terra.api.math.noise.samplers.noise;
import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler;
import net.jafama.FastMath;
public class GaborNoiseSampler extends NoiseFunction {
private final WhiteNoiseSampler rand;
private double k = 1.0;
private double a = 0.1;
private double f0 = 0.625;
private double kernelRadius = (FastMath.sqrt(-FastMath.log(0.05) / Math.PI) / a);
private double omega0 = Math.PI * 0.25;
private boolean isotropic = true;
private double impulsesPerKernel = 64d;
private double impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
private double impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
private double g = FastMath.exp(-impulsesPerCell);
public GaborNoiseSampler(int seed) {
super(seed);
rand = new WhiteNoiseSampler(seed);
}
public void setIsotropic(boolean isotropic) {
this.isotropic = isotropic;
}
public void setImpulsesPerKernel(double impulsesPerKernel) {
this.impulsesPerKernel = impulsesPerKernel;
recalculateRadiusAndDensity();
}
public void setA(double a) {
this.a = a;
recalculateRadiusAndDensity();
}
public void setFrequency0(double f0) {
this.f0 = f0;
}
public void setRotation(double omega0) {
this.omega0 = Math.PI * omega0;
}
public void setDeviation(double k) {
this.k = k;
}
private void recalculateRadiusAndDensity() {
kernelRadius = (FastMath.sqrt(-FastMath.log(0.05) / Math.PI) / this.a);
impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
g = FastMath.exp(-impulsesPerCell);
}
@Override
public double getNoiseRaw(int seed, double x, double z) {
return gaborNoise(seed, x, z);
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
return gaborNoise(seed, x, z);
}
private double gaborNoise(int seed, double x, double y) {
x /= kernelRadius;
y /= kernelRadius;
int xi = fastFloor(x);
int yi = fastFloor(y);
double xf = x - xi;
double yf = y - yi;
double noise = 0;
for(int dx = -1; dx <= 1; dx++) {
for(int dz = -1; dz <= 1; dz++) {
noise += calculateCell(seed, xi + dx, yi + dz, xf - dx, yf - dz);
}
}
return noise;
}
private double calculateCell(int seed, int xi, int yi, double x, double y) {
long mashedSeed = murmur64(31L * xi + yi) + seed;
double gaussianSource = (rand.getNoiseRaw(mashedSeed++) + 1) / 2;
int impulses = 0;
while(gaussianSource > g) {
impulses++;
gaussianSource *= (rand.getNoiseRaw(mashedSeed++) + 1) / 2;
}
double noise = 0;
for(int i = 0; i < impulses; i++) {
noise += rand.getNoiseRaw(mashedSeed++) * gabor(isotropic ? (rand.getNoiseRaw(mashedSeed++) + 1) * Math.PI : omega0, x * kernelRadius, y * kernelRadius);
}
return noise;
}
private double gabor(double omega_0, double x, double y) {
return k * (FastMath.exp(-Math.PI * (a * a) * (x * x + y * y)) * fastCos(2 * Math.PI * f0 * (x * fastCos(omega_0) + y * fastSin(omega_0))));
}
}
@@ -0,0 +1,157 @@
package com.dfsek.terra.api.math.noise.samplers.noise;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import net.jafama.FastMath;
@SuppressWarnings("ManualMinMaxCalculation")
public abstract class NoiseFunction implements NoiseSampler {
// Hashing
protected static final int PRIME_X = 501125321;
protected static final int PRIME_Y = 1136930381;
protected static final int PRIME_Z = 1720413743;
protected double frequency = 0.02d;
protected int seed;
public NoiseFunction(int seed) {
this.seed = seed;
}
protected static int fastFloor(double f) {
return f >= 0 ? (int) f : (int) f - 1;
}
static final int precision = 100;
protected static int hash(int seed, int xPrimed, int yPrimed, int zPrimed) {
int hash = seed ^ xPrimed ^ yPrimed ^ zPrimed;
hash *= 0x27d4eb2d;
return hash;
}
protected static int hash(int seed, int xPrimed, int yPrimed) {
int hash = seed ^ xPrimed ^ yPrimed;
hash *= 0x27d4eb2d;
return hash;
}
static final int modulus = 360 * precision;
protected static int fastRound(double f) {
return f >= 0 ? (int) (f + 0.5f) : (int) (f - 0.5);
}
protected static double lerp(double a, double b, double t) {
return a + t * (b - a);
}
protected static double interpHermite(double t) {
return t * t * (3 - 2 * t);
}
protected static double interpQuintic(double t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
protected static double cubicLerp(double a, double b, double c, double d, double t) {
double p = (d - c) - (a - b);
return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b;
}
protected static double fastMin(double a, double b) {
return a < b ? a : b;
}
protected static double fastMax(double a, double b) {
return a > b ? a : b;
}
protected static double fastAbs(double f) {
return f < 0 ? -f : f;
}
protected static double fastSqrt(double f) {
return FastMath.sqrt(f);
}
static final double[] sin = new double[360 * 100]; // lookup table
static {
for(int i = 0; i < sin.length; i++) {
sin[i] = (float) Math.sin((double) (i) / (precision));
}
}
protected static int fastCeil(double f) {
int i = (int) f;
if(i < f) i++;
return i;
}
/**
* Murmur64 hashing function
*
* @param h Input value
* @return Hashed value
*/
protected static long murmur64(long h) {
h ^= h >>> 33;
h *= 0xff51afd7ed558ccdL;
h ^= h >>> 33;
h *= 0xc4ceb9fe1a85ec53L;
h ^= h >>> 33;
return h;
}
private static double sinLookup(int a) {
return a >= 0 ? sin[a % (modulus)] : -sin[-a % (modulus)];
}
protected static double fastSin(double a) {
return sinLookup((int) (a * precision + 0.5f));
}
protected static double fastCos(double a) {
return sinLookup((int) ((a + Math.PI / 2) * precision + 0.5f));
}
public void setSeed(int seed) {
this.seed = seed;
}
public double getFrequency() {
return frequency;
}
public void setFrequency(double frequency) {
this.frequency = frequency;
}
@Override
public double getNoise(double x, double y) {
return getNoiseSeeded(seed, x, y);
}
@Override
public double getNoise(double x, double y, double z) {
return getNoiseSeeded(seed, x, y, z);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return getNoiseRaw(seed, x * frequency, y * frequency);
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
return getNoiseRaw(seed, x * frequency, y * frequency, z * frequency);
}
public abstract double getNoiseRaw(int seed, double x, double y);
public abstract double getNoiseRaw(int seed, double x, double y, double z);
}
@@ -0,0 +1,46 @@
package com.dfsek.terra.api.math.noise.samplers.noise.fractal;
import com.dfsek.terra.api.math.noise.NoiseSampler;
public class BrownianMotionSampler extends FractalNoiseFunction {
public BrownianMotionSampler(int seed, NoiseSampler input) {
super(seed, input);
}
@Override
public double getNoiseRaw(int seed, double x, double y) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = input.getNoiseSeeded(seed++, x, y);
sum += noise * amp;
amp *= lerp(1.0, fastMin(noise + 1, 2) * 0.5, weightedStrength);
x *= lacunarity;
y *= lacunarity;
amp *= gain;
}
return sum;
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = input.getNoiseSeeded(seed++, x, y, z);
sum += noise * amp;
amp *= lerp(1.0, (noise + 1) * 0.5, weightedStrength);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}
@@ -0,0 +1,48 @@
package com.dfsek.terra.api.math.noise.samplers.noise.fractal;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
public abstract class FractalNoiseFunction extends NoiseFunction {
protected final NoiseSampler input;
protected double fractalBounding = 1 / 1.75;
protected int octaves = 3;
protected double gain = 0.5;
protected double lacunarity = 2.0d;
protected double weightedStrength = 0.0d;
public FractalNoiseFunction(int seed, NoiseSampler input) {
super(seed);
this.input = input;
frequency = 1;
}
public void setWeightedStrength(double weightedStrength) {
this.weightedStrength = weightedStrength;
}
protected void calculateFractalBounding() {
double gain = fastAbs(this.gain);
double amp = gain;
double ampFractal = 1.0;
for(int i = 1; i < octaves; i++) {
ampFractal += amp;
amp *= gain;
}
fractalBounding = 1 / ampFractal;
}
public void setOctaves(int octaves) {
this.octaves = octaves;
calculateFractalBounding();
}
public void setGain(double gain) {
this.gain = gain;
calculateFractalBounding();
}
public void setLacunarity(double lacunarity) {
this.lacunarity = lacunarity;
}
}
@@ -0,0 +1,58 @@
package com.dfsek.terra.api.math.noise.samplers.noise.fractal;
import com.dfsek.terra.api.math.noise.NoiseSampler;
public class PingPongSampler extends FractalNoiseFunction {
private double pingPongStrength = 2.0;
public PingPongSampler(int seed, NoiseSampler input) {
super(seed, input);
}
private static double pingPong(double t) {
t -= (int) (t * 0.5f) << 1;
return t < 1 ? t : 2 - t;
}
public void setPingPongStrength(double strength) {
this.pingPongStrength = strength;
}
@Override
public double getNoiseRaw(int seed, double x, double y) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = pingPong((input.getNoiseSeeded(seed++, x, y) + 1) * pingPongStrength);
sum += (noise - 0.5) * 2 * amp;
amp *= lerp(1.0, noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
amp *= gain;
}
return sum;
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = pingPong((input.getNoiseSeeded(seed++, x, y, z) + 1) * pingPongStrength);
sum += (noise - 0.5) * 2 * amp;
amp *= lerp(1.0, noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}
@@ -0,0 +1,47 @@
package com.dfsek.terra.api.math.noise.samplers.noise.fractal;
import com.dfsek.terra.api.math.noise.NoiseSampler;
public class RidgedFractalSampler extends FractalNoiseFunction {
public RidgedFractalSampler(int seed, NoiseSampler input) {
super(seed, input);
}
@Override
public double getNoiseRaw(int seed, double x, double y) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = fastAbs(input.getNoiseSeeded(seed++, x, y));
sum += (noise * -2 + 1) * amp;
amp *= lerp(1.0, 1 - noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
amp *= gain;
}
return sum;
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = fastAbs(input.getNoiseSeeded(seed++, x, y, z));
sum += (noise * -2 + 1) * amp;
amp *= lerp(1.0, 1 - noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}
@@ -0,0 +1,39 @@
package com.dfsek.terra.api.math.noise.samplers.noise.random;
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
/**
* NoiseSampler implementation to provide random, normally distributed (Gaussian) noise.
*/
public class GaussianNoiseSampler extends NoiseFunction {
private final WhiteNoiseSampler whiteNoiseSampler; // Back with a white noise sampler.
public GaussianNoiseSampler(int seed) {
super(seed);
whiteNoiseSampler = new WhiteNoiseSampler(seed);
}
@Override
public double getNoiseRaw(int seed, double x, double y) {
double v1, v2, s;
do {
v1 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y);
v2 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y);
s = v1 * v1 + v2 * v2;
} while(s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
return v1 * multiplier;
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
double v1, v2, s;
do {
v1 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y, z);
v2 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y, z);
s = v1 * v1 + v2 * v2;
} while(s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
return v1 * multiplier;
}
}
@@ -0,0 +1,52 @@
package com.dfsek.terra.api.math.noise.samplers.noise.random;
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
/**
* NoiseSampler implementation to produce random, uniformly distributed (white) noise.
*/
public class WhiteNoiseSampler extends NoiseFunction {
private static final long POSITIVE_POW1 = 0b01111111111L << 52; // Bits that when applied to the exponent/sign section of a double, produce a positive number with a power of 1.
public WhiteNoiseSampler(int seed) {
super(seed);
}
public double getNoiseRaw(long seed) {
return (Double.longBitsToDouble((murmur64(seed) & 0x000fffffffffffffL) | POSITIVE_POW1) - 1.5) * 2;
}
@Override
public double getNoiseRaw(int seed, double x, double y) {
return (getNoiseUnmapped(seed, x, y) - 1.5) * 2;
}
@Override
public double getNoiseRaw(int seed, double x, double y, double z) {
return (getNoiseUnmapped(seed, x, y, z) - 1.5) * 2;
}
public double getNoiseUnmapped(int seed, double x, double y, double z) {
long base = ((randomBits(seed, x, y, z)) & 0x000fffffffffffffL) | POSITIVE_POW1; // Sign and exponent
return Double.longBitsToDouble(base);
}
public double getNoiseUnmapped(int seed, double x, double y) {
long base = (randomBits(seed, x, y) & 0x000fffffffffffffL) | POSITIVE_POW1; // Sign and exponent
return Double.longBitsToDouble(base);
}
public long randomBits(int seed, double x, double y, double z) {
long hashX = Double.doubleToRawLongBits(x) ^ seed;
long hashZ = Double.doubleToRawLongBits(y) ^ seed;
long hash = (((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed) + Double.doubleToRawLongBits(z);
return murmur64(hash);
}
public long randomBits(int seed, double x, double y) {
long hashX = Double.doubleToRawLongBits(x) ^ seed;
long hashZ = Double.doubleToRawLongBits(y) ^ seed;
long hash = ((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed;
return murmur64(hash);
}
}

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