diff --git a/.github/workflows/azure.yml b/.github/workflows/azure.yml new file mode 100644 index 0000000000..96a95373e1 --- /dev/null +++ b/.github/workflows/azure.yml @@ -0,0 +1,23 @@ +name: Azure security for Pull Requests + +on: + pull_request: + branches: + - '*' + +jobs: + validate: + runs-on: ubuntu-latest + + permissions: + pull-requests: read + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Prevent file change + uses: xalvarez/prevent-file-change-action@v1 + with: + githubToken: ${{ secrets.GITHUB_TOKEN }} + pattern: .*\azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6d25f6d5ca..40faca0e96 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -161,6 +161,11 @@ steps: [$(DiscordMessage)] condition: and(eq(variables.SKIP_BUILD, 'false'), eq(variables['CreateArtifacts'], 'True')) + - powershell: | + Write-Host "##vso[task.setvariable variable=RunMavenPublishTask]True" + displayName: Allow Maven Publish tasks + condition: and(and(succeeded(), eq(variables['CreateArtifacts'], 'True')), eq(variables.SKIP_BUILD, 'false')) + - task: Gradle@2 displayName: Publish to Maven inputs: @@ -174,7 +179,7 @@ steps: publishJUnitResults: false testResultsFiles: '**/TEST-*.xml' tasks: 'publish' - condition: and(and(succeeded(), eq(variables['CreateArtifacts'], 'True')), eq(variables.SKIP_BUILD, 'false')) + condition: and(and(succeeded(), eq(variables['RunMavenPublishTask'], 'True')), eq(variables.SKIP_BUILD, 'false')) env: ARTIFACTORY_USER: $(Artifactory.User) ARTIFACTORY_PASS: $(Artifactory.Password) @@ -187,7 +192,7 @@ steps: messageType: 'embeds' embeds: | [$(DiscordMessageMavenFailed)] - condition: failed() + condition: and(and(failed(), eq(variables['RunMavenPublishTask'], 'True')), eq(variables.SKIP_BUILD, 'false')) - script: | # stop the Gradle daemon to ensure no files are left open (impacting the save cache operation later) diff --git a/build.gradle b/build.gradle index 7630908ad1..26680a8fe4 100644 --- a/build.gradle +++ b/build.gradle @@ -109,7 +109,7 @@ afterEvaluate { // DO NOT ASK... it fixes the runClient and family tasks :harold } jar { - exclude 'data/twilightforest/functions/**' + exclude 'data/twilightforest/function/**' if (hasProperty("CIRevision")) exclude 'data/twilightforest/structure/lich_tower' } diff --git a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 index ac6f3ef5dc..e5bc79638c 100644 --- a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 +++ b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 @@ -1,4 +1,4 @@ -// 1.21.1 2024-09-15T21:52:34.189045622 Registries +// 1.21.1 2024-10-15T02:33:32.127678962 Registries 9089ada9ce06fd30adf8b10e50f02233c7d5a76e data/minecraft/twilight/wood_palettes/acacia.json dca1ef01d0df4e956fd414782de57c25dfddd290 data/minecraft/twilight/wood_palettes/birch.json 01becb45438b7f2bfdc77baba72bc986341510c8 data/minecraft/twilight/wood_palettes/crimson.json @@ -118,7 +118,7 @@ cd3724ced610878eed7614232aa3df1c1d501f72 data/twilightforest/worldgen/biome/clea 17c5d64992834cfb5edd94617a56698fbd5328d7 data/twilightforest/worldgen/biome/dark_forest_center.json afbd0904fbe5fdf5e5dcf4a6657138a379e2ad76 data/twilightforest/worldgen/biome/dense_forest.json 6554f2be9d0faeabfa8a652ddb059fc61367f177 data/twilightforest/worldgen/biome/dense_mushroom_forest.json -36c0bc6ee39058dcb350f4a807151a7612f1b007 data/twilightforest/worldgen/biome/enchanted_forest.json +455c74918cb6c93ac993806592dee6381a17f0d7 data/twilightforest/worldgen/biome/enchanted_forest.json 0f7add8c82f0867894000c6f3a5db4bc48b9027f data/twilightforest/worldgen/biome/final_plateau.json 16a6c39507c7bfda243d44efebf67c427688aa24 data/twilightforest/worldgen/biome/fire_swamp.json 73e266bb4fc8eaad4094adc4133efc6bf25f6e58 data/twilightforest/worldgen/biome/firefly_forest.json @@ -148,7 +148,10 @@ fc967db45aba7ff6345e2b3474a33e812d4340dc data/twilightforest/worldgen/configured ab75ab20d3277ecf1272d3feed8028c122e12769 data/twilightforest/worldgen/configured_feature/dark_pumpkins.json 1a0558d6d59585ab34a471dd18acf173abf9a2ef data/twilightforest/worldgen/configured_feature/dark_red_mushrooms.json 571fb66edc9ad540d5d783e3bc1d268ae5f1b6bf data/twilightforest/worldgen/configured_feature/default_fallen_logs.json +b440bd1dac981632071cf8fb6e1a340562eb7a2b data/twilightforest/worldgen/configured_feature/dense_ferns.json +ab76c025e8ae4ec52230793dd2609a34cfec97dc data/twilightforest/worldgen/configured_feature/dense_large_ferns.json 6f97a684e664e5f261e2ada0ba9f818d8556c149 data/twilightforest/worldgen/configured_feature/druid_hut.json +9032ca20c46420ee68c1f3412ff705ef53c5b5ab data/twilightforest/worldgen/configured_feature/enchanted_forest_vines.json 3afb7351561a98f14065cff830300735f3985625 data/twilightforest/worldgen/configured_feature/fallen_leaves.json 8cec51f8c8ef53061114075cca36e703dd7a0617 data/twilightforest/worldgen/configured_feature/fancy_well.json 244b31e5e86c79c1637e2d89902eddf50c2cb4d8 data/twilightforest/worldgen/configured_feature/fiddlehead.json @@ -222,7 +225,7 @@ c923cb36a4a7190f2bec1ad3ce6be81fb012e755 data/twilightforest/worldgen/configured 486cff87aee3cd06a82a7d75d8b9bf509102d7f5 data/twilightforest/worldgen/configured_feature/tree/selector/canopy_trees.json 8d7b406fda16d82162f4851b28b52155853613c5 data/twilightforest/worldgen/configured_feature/tree/selector/dark_forest_trees.json 96861e6a3bb90f63112617abf3f2ac8f4f8421c3 data/twilightforest/worldgen/configured_feature/tree/selector/dense_canopy_trees.json -7f621cf20a68d70764e47a1365e26f948ac9445d data/twilightforest/worldgen/configured_feature/tree/selector/enchanted_forest_trees.json +f57dede3ce3fd8ab45b79f9ed494d49cbeb5c4c6 data/twilightforest/worldgen/configured_feature/tree/selector/enchanted_forest_trees.json 9c42c640892024958f9171d185ba4a18a5cca734 data/twilightforest/worldgen/configured_feature/tree/selector/firefly_forest_trees.json 77679e79279a34d2afb4f0590862298960f8dd89 data/twilightforest/worldgen/configured_feature/tree/selector/highlands_trees.json 636310ed05f9ba187f75a0492914d76034b706d0 data/twilightforest/worldgen/configured_feature/tree/selector/snowy_forest_trees.json @@ -266,7 +269,11 @@ c1cdd1abaa4f2a0a7ed4654dc1990477411d9dee data/twilightforest/worldgen/placed_fea ed07f065cfb7a5086353305b5c8dc01c4e35e82e data/twilightforest/worldgen/placed_feature/dark_pumpkins.json 4c01547375217b1f29972e9f383f39447c23718b data/twilightforest/worldgen/placed_feature/dark_red_mushrooms.json 53e9eb90d244012f3ccbfba21ee44aa346f2d7a1 data/twilightforest/worldgen/placed_feature/default_fallen_logs.json +8380d1e76bf8dbee27ab7e28c3525d43f3e1ac20 data/twilightforest/worldgen/placed_feature/dense_ferns.json +bb9784d9ccca1f1a47065c00c53e64cd92c26d82 data/twilightforest/worldgen/placed_feature/dense_large_ferns.json +7cee9c2996dac31b077e6479bef3524817b91011 data/twilightforest/worldgen/placed_feature/dense_water_lake.json 77bc97d3a7c316f9a7cef0fc3c687b0a5cf0e14a data/twilightforest/worldgen/placed_feature/druid_hut.json +558fc6fc1afda17c9b52e9864b67dd03a4e6af4c data/twilightforest/worldgen/placed_feature/enchanted_forest_vines.json 0648665b104dc44bac69861cd8d240c941ebc50d data/twilightforest/worldgen/placed_feature/fallen_leaves.json 575df3da21e8b7a4fdbd4a1bc6f89495f8447a45 data/twilightforest/worldgen/placed_feature/fiddlehead.json 4450866e7c5041ea9e6fceafb690cb5445f5300b data/twilightforest/worldgen/placed_feature/fire_jet.json @@ -303,7 +310,7 @@ c3fc67e79de094ff946f1ec84d4fd4ab92f5ec67 data/twilightforest/worldgen/placed_fea 217561cafb8d2b0f498b72a07463ed85b50bf6cb data/twilightforest/worldgen/placed_feature/small_diorite.json 55de6f980fe917425a411568dbae60ca2ea2caa2 data/twilightforest/worldgen/placed_feature/small_granite.json 38028922ed95c74e215e3d73b03aba6f35d7bcf5 data/twilightforest/worldgen/placed_feature/smoker.json -d0914a5b0f3a2ee56393aee240d07ef50d8cd0c0 data/twilightforest/worldgen/placed_feature/snow_under_trees.json +ae12871905d6b984a4b742b87fe7973645c15a9d data/twilightforest/worldgen/placed_feature/snow_under_trees.json 94c65233419c08cfb5f77cf4ca20233527ef30c7 data/twilightforest/worldgen/placed_feature/sparse_mushglooms.json ec487e589c0848f71eb9af87b55c15591514501e data/twilightforest/worldgen/placed_feature/spruce_fallen_log.json 4208c165f5a2f75a47dffd8e133234648997c161 data/twilightforest/worldgen/placed_feature/stone_circle.json @@ -353,7 +360,7 @@ ab9ab413230504cd9f9bb3c899d29183f7a544c3 data/twilightforest/worldgen/structure/ 981f279d63889e26d2d3a41f1dd5d82684797006 data/twilightforest/worldgen/structure/medium_hollow_hill.json aa4567b8171a3bb0d739364aa9e8bb5a5fead921 data/twilightforest/worldgen/structure/mushroom_tower.json 2a51406fdc1088d7de4914189d81c69bf788d77c data/twilightforest/worldgen/structure/naga_courtyard.json -4ff0066540dbb64483260da0b4d60d6e622304b2 data/twilightforest/worldgen/structure/quest_grove.json +ebef5750d9a6a7409d072acc8681ed504a05d160 data/twilightforest/worldgen/structure/quest_grove.json da563625a31738c46356e6c58c35824f5d98c2c4 data/twilightforest/worldgen/structure/small_hollow_hill.json 2db553ab8a6b2ca93ce23fe0738645cff99e2520 data/twilightforest/worldgen/structure/swamp_hollow_tree.json c80eb035dafc0e1686ca2cffc235606e90cc189b data/twilightforest/worldgen/structure/troll_cave.json diff --git a/src/generated/resources/data/twilightforest/worldgen/biome/enchanted_forest.json b/src/generated/resources/data/twilightforest/worldgen/biome/enchanted_forest.json index e5579aae40..3f5fd1ad42 100644 --- a/src/generated/resources/data/twilightforest/worldgen/biome/enchanted_forest.json +++ b/src/generated/resources/data/twilightforest/worldgen/biome/enchanted_forest.json @@ -33,7 +33,9 @@ }, "features": [ [], - [], + [ + "twilightforest:dense_water_lake" + ], [], [], [ @@ -64,13 +66,10 @@ ], [], [ - "minecraft:patch_tall_grass", "minecraft:patch_grass_badlands", - "minecraft:patch_grass_savanna", "minecraft:patch_sugar_cane", - "minecraft:patch_grass_jungle", - "minecraft:patch_large_fern", - "twilightforest:mayapple", + "twilightforest:dense_ferns", + "twilightforest:dense_large_ferns", "twilightforest:flower_placer", "twilightforest:grove_ruins", "twilightforest:stone_circle", @@ -79,13 +78,14 @@ "twilightforest:hollow_stump", "twilightforest:hollow_log", "twilightforest:tree/selector/enchanted_forest_trees", + "twilightforest:tree/selector/dense_canopy_trees", "twilightforest:fiddlehead", - "minecraft:vines", "twilightforest:tree/selector/canopy_trees", "twilightforest:default_fallen_logs" ], [ - "minecraft:freeze_top_layer" + "minecraft:freeze_top_layer", + "twilightforest:enchanted_forest_vines" ] ], "has_precipitation": false, diff --git a/src/generated/resources/data/twilightforest/worldgen/configured_feature/dense_ferns.json b/src/generated/resources/data/twilightforest/worldgen/configured_feature/dense_ferns.json new file mode 100644 index 0000000000..f476c36d4b --- /dev/null +++ b/src/generated/resources/data/twilightforest/worldgen/configured_feature/dense_ferns.json @@ -0,0 +1,44 @@ +{ + "type": "minecraft:random_patch", + "config": { + "feature": { + "feature": { + "type": "minecraft:simple_block", + "config": { + "to_place": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:fern" + } + } + } + }, + "placement": [ + { + "type": "minecraft:block_predicate_filter", + "predicate": { + "type": "minecraft:all_of", + "predicates": [ + { + "type": "minecraft:matching_blocks", + "blocks": "minecraft:air" + }, + { + "type": "minecraft:matching_block_tag", + "offset": [ + 0, + -1, + 0 + ], + "tag": "minecraft:dirt" + } + ] + } + } + ] + }, + "tries": 64, + "xz_spread": 7, + "y_spread": 3 + } +} \ No newline at end of file diff --git a/src/generated/resources/data/twilightforest/worldgen/configured_feature/dense_large_ferns.json b/src/generated/resources/data/twilightforest/worldgen/configured_feature/dense_large_ferns.json new file mode 100644 index 0000000000..6287605756 --- /dev/null +++ b/src/generated/resources/data/twilightforest/worldgen/configured_feature/dense_large_ferns.json @@ -0,0 +1,47 @@ +{ + "type": "minecraft:random_patch", + "config": { + "feature": { + "feature": { + "type": "minecraft:simple_block", + "config": { + "to_place": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:large_fern", + "Properties": { + "half": "lower" + } + } + } + } + }, + "placement": [ + { + "type": "minecraft:block_predicate_filter", + "predicate": { + "type": "minecraft:all_of", + "predicates": [ + { + "type": "minecraft:matching_blocks", + "blocks": "minecraft:air" + }, + { + "type": "minecraft:matching_block_tag", + "offset": [ + 0, + -1, + 0 + ], + "tag": "minecraft:dirt" + } + ] + } + } + ] + }, + "tries": 64, + "xz_spread": 7, + "y_spread": 3 + } +} \ No newline at end of file diff --git a/src/generated/resources/data/twilightforest/worldgen/configured_feature/enchanted_forest_vines.json b/src/generated/resources/data/twilightforest/worldgen/configured_feature/enchanted_forest_vines.json new file mode 100644 index 0000000000..7cb272f231 --- /dev/null +++ b/src/generated/resources/data/twilightforest/worldgen/configured_feature/enchanted_forest_vines.json @@ -0,0 +1,4 @@ +{ + "type": "twilightforest:enchanted_forest_vines", + "config": {} +} \ No newline at end of file diff --git a/src/generated/resources/data/twilightforest/worldgen/configured_feature/tree/selector/enchanted_forest_trees.json b/src/generated/resources/data/twilightforest/worldgen/configured_feature/tree/selector/enchanted_forest_trees.json index ad3d97d430..6ebd7c8429 100644 --- a/src/generated/resources/data/twilightforest/worldgen/configured_feature/tree/selector/enchanted_forest_trees.json +++ b/src/generated/resources/data/twilightforest/worldgen/configured_feature/tree/selector/enchanted_forest_trees.json @@ -21,7 +21,7 @@ } }, { - "chance": 0.1, + "chance": 0.15, "feature": { "feature": "twilightforest:tree/large_rainbow_oak", "placement": [] diff --git a/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_ferns.json b/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_ferns.json new file mode 100644 index 0000000000..07963be975 --- /dev/null +++ b/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_ferns.json @@ -0,0 +1,31 @@ +{ + "feature": "twilightforest:dense_ferns", + "placement": [ + { + "type": "minecraft:count", + "count": { + "type": "minecraft:weighted_list", + "distribution": [ + { + "data": 3, + "weight": 1 + }, + { + "data": 4, + "weight": 1 + } + ] + } + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "WORLD_SURFACE_WG" + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_large_ferns.json b/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_large_ferns.json new file mode 100644 index 0000000000..b7a6ffd4a3 --- /dev/null +++ b/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_large_ferns.json @@ -0,0 +1,19 @@ +{ + "feature": "twilightforest:dense_large_ferns", + "placement": [ + { + "type": "minecraft:count", + "count": 2 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "WORLD_SURFACE_WG" + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_water_lake.json b/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_water_lake.json new file mode 100644 index 0000000000..e08c5bd5f2 --- /dev/null +++ b/src/generated/resources/data/twilightforest/worldgen/placed_feature/dense_water_lake.json @@ -0,0 +1,25 @@ +{ + "feature": "twilightforest:water_lake", + "placement": [ + { + "type": "minecraft:rarity_filter", + "chance": 4 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "OCEAN_FLOOR" + }, + { + "type": "twilightforest:no_structure", + "additional_clearance": 0, + "occupies_surface": true, + "occupies_underground": true + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/twilightforest/worldgen/placed_feature/enchanted_forest_vines.json b/src/generated/resources/data/twilightforest/worldgen/placed_feature/enchanted_forest_vines.json new file mode 100644 index 0000000000..0cd63fbf7a --- /dev/null +++ b/src/generated/resources/data/twilightforest/worldgen/placed_feature/enchanted_forest_vines.json @@ -0,0 +1,9 @@ +{ + "feature": "twilightforest:enchanted_forest_vines", + "placement": [ + { + "type": "minecraft:heightmap", + "heightmap": "MOTION_BLOCKING" + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/twilightforest/worldgen/placed_feature/snow_under_trees.json b/src/generated/resources/data/twilightforest/worldgen/placed_feature/snow_under_trees.json index 75713120ea..ed964343a6 100644 --- a/src/generated/resources/data/twilightforest/worldgen/placed_feature/snow_under_trees.json +++ b/src/generated/resources/data/twilightforest/worldgen/placed_feature/snow_under_trees.json @@ -1,6 +1,10 @@ { "feature": "twilightforest:snow_under_trees", "placement": [ + { + "type": "minecraft:heightmap", + "heightmap": "WORLD_SURFACE_WG" + }, { "type": "minecraft:biome" } diff --git a/src/generated/resources/data/twilightforest/worldgen/structure/quest_grove.json b/src/generated/resources/data/twilightforest/worldgen/structure/quest_grove.json index a90e5dde6b..4d945f9e69 100644 --- a/src/generated/resources/data/twilightforest/worldgen/structure/quest_grove.json +++ b/src/generated/resources/data/twilightforest/worldgen/structure/quest_grove.json @@ -4,7 +4,7 @@ "allow_biome_surface_decorations": false, "allow_biome_underground_decorations": true, "biomes": "#twilightforest:valid_quest_grove_biomes", - "chunk_clearance_radius": 1, + "chunk_clearance_radius": 2, "spawn_overrides": { "ambient": { "bounding_box": "full", diff --git a/src/main/java/twilightforest/block/WroughtIronFenceBlock.java b/src/main/java/twilightforest/block/WroughtIronFenceBlock.java index 3accc0128f..6b7098c324 100644 --- a/src/main/java/twilightforest/block/WroughtIronFenceBlock.java +++ b/src/main/java/twilightforest/block/WroughtIronFenceBlock.java @@ -167,7 +167,7 @@ private PostState makePost(LevelReader level, BlockState state, BlockPos pos) { BlockState above = level.getBlockState(pos.above()); boolean shouldAnyBePost = shouldAnyBePost(level, pos); - if (state.getValue(POST) == PostState.CAPPED && above.isAir()) return PostState.CAPPED; + if (state.getValue(POST) == PostState.CAPPED && !above.isSolid()) return PostState.CAPPED; if (shouldAnyBePost) return PostState.POST; else return shouldBePost(state) ? PostState.POST : PostState.NONE; } @@ -202,7 +202,7 @@ private boolean shouldBePost(BlockState state) { boolean east = eSide == FenceSide.NONE; boolean west = wSide == FenceSide.NONE; - return north && south && east && west || north != south || east != west; + return north && south && east && west || north != south || east != west || !north && !south && !east && !west; } @Override diff --git a/src/main/java/twilightforest/client/ISTER.java b/src/main/java/twilightforest/client/ISTER.java index 6e4d54d039..d704324bc3 100644 --- a/src/main/java/twilightforest/client/ISTER.java +++ b/src/main/java/twilightforest/client/ISTER.java @@ -224,7 +224,7 @@ public void renderByItem(ItemStack stack, ItemDisplayContext camera, PoseStack p VertexConsumer vertexconsumer = material.sprite().wrap(ItemRenderer.getFoilBufferDirect(buffers, this.shield.renderType(material.atlasLocation()), true, stack.hasFoil())); this.shield.renderToBuffer(pose, vertexconsumer, light, overlay); pose.popPose(); - } else if (item instanceof WearableLichCrown && this.trophies.get(BossVariant.LICH) instanceof LichModel lichModel) { + } else if (item instanceof WearableLichCrown && this.trophies.get(BossVariant.LICH) instanceof LichModel lichModel) { pose.pushPose(); pose.scale(1.0F, -1.0F, -1.0F); if (camera == ItemDisplayContext.GUI) { diff --git a/src/main/java/twilightforest/client/event/RegistrationEvents.java b/src/main/java/twilightforest/client/event/RegistrationEvents.java index 0071aa0ced..f774255958 100644 --- a/src/main/java/twilightforest/client/event/RegistrationEvents.java +++ b/src/main/java/twilightforest/client/event/RegistrationEvents.java @@ -61,6 +61,8 @@ import twilightforest.client.renderer.TFSkyRenderer; import twilightforest.client.renderer.entity.*; import twilightforest.client.renderer.block.*; +import twilightforest.client.renderer.entity.layers.IceLayer; +import twilightforest.client.renderer.entity.layers.ShieldLayer; import twilightforest.client.renderer.map.ConqueredMapIconRenderer; import twilightforest.client.renderer.map.MagicMapPlayerIconRenderer; import twilightforest.components.item.PotionFlaskComponent; @@ -322,7 +324,7 @@ private static void registerEntityRenderers(EntityRenderersEvent.RegisterRendere event.registerEntityRenderer(TFEntities.HOSTILE_WOLF.get(), HostileWolfRenderer::new); event.registerEntityRenderer(TFEntities.WRAITH.get(), m -> new WraithRenderer(m, new WraithModel(m.bakeLayer(TFModelLayers.WRAITH)), 0.5F)); event.registerEntityRenderer(TFEntities.HYDRA.get(), m -> new HydraRenderer<>(m, new HydraModel(m.bakeLayer(TFModelLayers.HYDRA)), 4.0F)); - event.registerEntityRenderer(TFEntities.LICH.get(), m -> new LichRenderer(m, new LichModel(m.bakeLayer(TFModelLayers.LICH)), 0.6F)); + event.registerEntityRenderer(TFEntities.LICH.get(), m -> new LichRenderer<>(m, new LichModel<>(m.bakeLayer(TFModelLayers.LICH)), 0.6F)); event.registerEntityRenderer(TFEntities.PENGUIN.get(), m -> new BirdRenderer<>(m, new PenguinModel(m.bakeLayer(TFModelLayers.PENGUIN)), 0.375F, "penguin.png")); event.registerEntityRenderer(TFEntities.LICH_MINION.get(), m -> new TFBipedRenderer<>(m, new LichMinionModel(m.bakeLayer(TFModelLayers.LICH_MINION)), new LichMinionModel(m.bakeLayer(ModelLayers.ZOMBIE_INNER_ARMOR)), new LichMinionModel(m.bakeLayer(ModelLayers.ZOMBIE_OUTER_ARMOR)), 0.5F, "textures/entity/zombie/zombie.png")); event.registerEntityRenderer(TFEntities.LOYAL_ZOMBIE.get(), m -> new TFBipedRenderer<>(m, new LoyalZombieModel(m.bakeLayer(TFModelLayers.LOYAL_ZOMBIE)), new LoyalZombieModel(m.bakeLayer(ModelLayers.ZOMBIE_INNER_ARMOR)), new LoyalZombieModel(m.bakeLayer(ModelLayers.ZOMBIE_OUTER_ARMOR)), 0.5F, "textures/entity/zombie/zombie.png")); diff --git a/src/main/java/twilightforest/client/model/entity/LichModel.java b/src/main/java/twilightforest/client/model/entity/LichModel.java index 6a8797e1cf..e2250fbcbb 100644 --- a/src/main/java/twilightforest/client/model/entity/LichModel.java +++ b/src/main/java/twilightforest/client/model/entity/LichModel.java @@ -18,7 +18,7 @@ import java.util.Arrays; -public class LichModel extends HumanoidModel implements TrophyBlockModel { +public class LichModel extends HumanoidModel implements TrophyBlockModel { private boolean shadowClone; private final ModelPart collar; @@ -83,7 +83,7 @@ public void renderToBuffer(PoseStack stack, VertexConsumer builder, int light, i if (!this.shadowClone) { super.renderToBuffer(stack, builder, light, overlay, color); } else { - super.renderToBuffer(stack, builder, light, overlay, FastColor.ARGB32.color((int) (FastColor.ARGB32.alpha(color) * 0.75F), (int) (FastColor.ARGB32.red(color) * 0.25F), (int) (FastColor.ARGB32.green(color) * 0.25F), (int) (FastColor.ARGB32.blue(color) * 0.25F))); + super.renderToBuffer(stack, builder, light, overlay, FastColor.ARGB32.color((int) (FastColor.ARGB32.alpha(color) * 0.5F), (int) (FastColor.ARGB32.red(color) * 0.333F), (int) (FastColor.ARGB32.green(color) * 0.333F), (int) (FastColor.ARGB32.blue(color) * 0.333F))); } } @@ -97,7 +97,7 @@ protected Iterable bodyParts() { } @Override - public void setupAnim(Lich entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + public void setupAnim(T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { this.shadowClone = entity.isShadowClone(); super.setupAnim(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); diff --git a/src/main/java/twilightforest/client/renderer/TFRenderTypes.java b/src/main/java/twilightforest/client/renderer/TFRenderTypes.java index 81f0483626..40a51fb72f 100644 --- a/src/main/java/twilightforest/client/renderer/TFRenderTypes.java +++ b/src/main/java/twilightforest/client/renderer/TFRenderTypes.java @@ -1,5 +1,6 @@ package twilightforest.client.renderer; +import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; @@ -8,6 +9,7 @@ import net.minecraft.client.renderer.RenderType; import org.joml.Matrix4f; import twilightforest.TwilightForestMod; +import twilightforest.client.renderer.entity.LichRenderer; public class TFRenderTypes extends RenderType { public TFRenderTypes(String name, VertexFormat vertexFormat, VertexFormat.Mode mode, int bufferSize, boolean crumbling, boolean sort, Runnable setup, Runnable clear) { @@ -15,13 +17,34 @@ public TFRenderTypes(String name, VertexFormat vertexFormat, VertexFormat.Mode m } public static final RenderType PROTECTION_BOX = create("protection_box", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, false, true, - RenderType.CompositeState.builder().setShaderState(RENDERTYPE_ENERGY_SWIRL_SHADER) + RenderType.CompositeState.builder() + .setShaderState(RENDERTYPE_ENERGY_SWIRL_SHADER) .setTextureState(new RenderStateShard.TextureStateShard(TwilightForestMod.getModelTexture("protectionbox.png"), false, false)) .setTexturingState(new ProtectionBoxTexturingStateShard()) - .setTransparencyState(TRANSLUCENT_TRANSPARENCY).setCullState(NO_CULL) - .setLightmapState(LIGHTMAP).setOverlayState(OVERLAY) + .setTransparencyState(TRANSLUCENT_TRANSPARENCY) + .setCullState(NO_CULL) + .setLightmapState(LIGHTMAP) + .setOverlayState(OVERLAY) .createCompositeState(false)); + public static final TransparencyStateShard TRANSPARENCY_STATE_SHARD = new TransparencyStateShard("shadow_clone", () -> { + RenderSystem.enableBlend(); + RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + }, () -> { + RenderSystem.disableBlend(); + RenderSystem.defaultBlendFunc(); + }); + + public static final RenderType SHADOW_CLONE = create("shadow_clone", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 1536, true, true, + RenderType.CompositeState.builder() + .setShaderState(RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER) + .setTextureState(new RenderStateShard.TextureStateShard(LichRenderer.TEXTURE, false, false)) + .setTransparencyState(TRANSPARENCY_STATE_SHARD) + .setCullState(NO_CULL) + .setLightmapState(LIGHTMAP) + .setOverlayState(OVERLAY) + .createCompositeState(true)); + public static final class ProtectionBoxTexturingStateShard extends RenderStateShard.TexturingStateShard { public ProtectionBoxTexturingStateShard() { super("protection_offset_texturing", () -> { diff --git a/src/main/java/twilightforest/client/renderer/block/TrophyRenderer.java b/src/main/java/twilightforest/client/renderer/block/TrophyRenderer.java index c161e32759..6aadb2fa0e 100644 --- a/src/main/java/twilightforest/client/renderer/block/TrophyRenderer.java +++ b/src/main/java/twilightforest/client/renderer/block/TrophyRenderer.java @@ -34,7 +34,7 @@ public TrophyRenderer(BlockEntityRendererProvider.Context context) { public static Map createTrophyRenderers(EntityModelSet set) { ImmutableMap.Builder trophyList = ImmutableMap.builder(); trophyList.put(BossVariant.NAGA, new NagaModel<>(set.bakeLayer(TFModelLayers.NAGA_TROPHY))); - trophyList.put(BossVariant.LICH, new LichModel(set.bakeLayer(TFModelLayers.LICH_TROPHY))); + trophyList.put(BossVariant.LICH, new LichModel<>(set.bakeLayer(TFModelLayers.LICH_TROPHY))); trophyList.put(BossVariant.MINOSHROOM, new MinoshroomModel<>(set.bakeLayer(TFModelLayers.MINOSHROOM_TROPHY))); trophyList.put(BossVariant.HYDRA, new HydraHeadModel<>(set.bakeLayer(TFModelLayers.HYDRA_TROPHY))); trophyList.put(BossVariant.KNIGHT_PHANTOM, new KnightPhantomModel(set.bakeLayer(TFModelLayers.KNIGHT_PHANTOM_TROPHY))); diff --git a/src/main/java/twilightforest/client/renderer/entity/LichRenderer.java b/src/main/java/twilightforest/client/renderer/entity/LichRenderer.java index a4d9b26040..f4f011d12a 100644 --- a/src/main/java/twilightforest/client/renderer/entity/LichRenderer.java +++ b/src/main/java/twilightforest/client/renderer/entity/LichRenderer.java @@ -9,31 +9,33 @@ import org.jetbrains.annotations.Nullable; import twilightforest.TwilightForestMod; import twilightforest.client.model.entity.LichModel; +import twilightforest.client.renderer.TFRenderTypes; +import twilightforest.client.renderer.entity.layers.ShieldLayer; import twilightforest.entity.boss.Lich; -public class LichRenderer extends HumanoidMobRenderer { +public class LichRenderer> extends HumanoidMobRenderer { public static final ResourceLocation TEXTURE = TwilightForestMod.getModelTexture("twilightlich64.png"); - public LichRenderer(EntityRendererProvider.Context context, LichModel model, float shadowSize) { + public LichRenderer(EntityRendererProvider.Context context, M model, float shadowSize) { super(context, model, shadowSize); this.addLayer(new ShieldLayer<>(this)); } @Nullable @Override - protected RenderType getRenderType(Lich entity, boolean bodyVisible, boolean translucent, boolean glowing) { - if (entity.isShadowClone()) return RenderType.entityTranslucent(this.getTextureLocation(entity)); + protected RenderType getRenderType(T entity, boolean bodyVisible, boolean translucent, boolean glowing) { + if (entity.isShadowClone()) return TFRenderTypes.SHADOW_CLONE; else return super.getRenderType(entity, bodyVisible, translucent, glowing); } @Override - protected boolean isShaking(Lich entity) { + protected boolean isShaking(T entity) { return super.isShaking(entity) || (entity.isDeadOrDying() && entity.deathTime <= Lich.DEATH_ANIMATION_POINT_A); } @Override - public void render(Lich entity, float entityYaw, float partialTicks, PoseStack stack, MultiBufferSource buffer, int packedLight) { + public void render(T entity, float entityYaw, float partialTicks, PoseStack stack, MultiBufferSource buffer, int packedLight) { if (entity.deathTime > 0) { stack.pushPose(); if (entity.deathTime > Lich.DEATH_ANIMATION_POINT_A) { @@ -48,7 +50,7 @@ public void render(Lich entity, float entityYaw, float partialTicks, PoseStack s } @Override - protected float getFlipDegrees(Lich entity) { //Prevent the body from keeling over + protected float getFlipDegrees(T entity) { //Prevent the body from keeling over return entity.isDeadOrDying() ? 0.0F : super.getFlipDegrees(entity); } diff --git a/src/main/java/twilightforest/client/renderer/entity/IceLayer.java b/src/main/java/twilightforest/client/renderer/entity/layers/IceLayer.java similarity index 98% rename from src/main/java/twilightforest/client/renderer/entity/IceLayer.java rename to src/main/java/twilightforest/client/renderer/entity/layers/IceLayer.java index 9002a36fcc..658bc3de9b 100644 --- a/src/main/java/twilightforest/client/renderer/entity/IceLayer.java +++ b/src/main/java/twilightforest/client/renderer/entity/layers/IceLayer.java @@ -1,4 +1,4 @@ -package twilightforest.client.renderer.entity; +package twilightforest.client.renderer.entity.layers; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; diff --git a/src/main/java/twilightforest/client/renderer/entity/ShieldLayer.java b/src/main/java/twilightforest/client/renderer/entity/layers/ShieldLayer.java similarity index 98% rename from src/main/java/twilightforest/client/renderer/entity/ShieldLayer.java rename to src/main/java/twilightforest/client/renderer/entity/layers/ShieldLayer.java index 5527e8b95e..3d62eeb7e1 100644 --- a/src/main/java/twilightforest/client/renderer/entity/ShieldLayer.java +++ b/src/main/java/twilightforest/client/renderer/entity/layers/ShieldLayer.java @@ -1,4 +1,4 @@ -package twilightforest.client.renderer.entity; +package twilightforest.client.renderer.entity.layers; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; diff --git a/src/main/java/twilightforest/client/renderer/entity/layers/package-info.java b/src/main/java/twilightforest/client/renderer/entity/layers/package-info.java new file mode 100644 index 0000000000..6250d0b75d --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/entity/layers/package-info.java @@ -0,0 +1,9 @@ +@FieldsAreNonnullByDefault +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.client.renderer.entity.layers; + +import net.minecraft.FieldsAreNonnullByDefault; +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/init/TFBlocks.java b/src/main/java/twilightforest/init/TFBlocks.java index e0d4c44e50..067bf6c26d 100644 --- a/src/main/java/twilightforest/init/TFBlocks.java +++ b/src/main/java/twilightforest/init/TFBlocks.java @@ -51,7 +51,7 @@ public class TFBlocks { public static final DeferredBlock SMOKER = register("smoker", () -> new TFSmokerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.GRASS).sound(SoundType.WOOD).strength(1.5F, 6.0F))); public static final DeferredBlock ENCASED_SMOKER = register("encased_smoker", () -> new EncasedSmokerBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.SAND).requiresCorrectToolForDrops().sound(SoundType.WOOD).strength(1.5F, 6.0F))); public static final DeferredBlock FIRE_JET = register("fire_jet", () -> new FireJetBlock(BlockBehaviour.Properties.of().lightLevel((state) -> state.getValue(FireJetBlock.STATE) != FireJetVariant.FLAME ? 0 : 15).mapColor(MapColor.GRASS).randomTicks().sound(SoundType.WOOD).strength(1.5F, 6.0F))); - public static final DeferredBlock ENCASED_FIRE_JET = register("encased_fire_jet", () -> new EncasedFireJetBlock(BlockBehaviour.Properties.of().ignitedByLava().lightLevel((state) -> 15).mapColor(MapColor.SAND).requiresCorrectToolForDrops().sound(SoundType.WOOD).strength(1.5F, 6.0F))); + public static final DeferredBlock ENCASED_FIRE_JET = register("encased_fire_jet", () -> new EncasedFireJetBlock(BlockBehaviour.Properties.of().ignitedByLava().lightLevel((state) -> state.getValue(FireJetBlock.STATE) != FireJetVariant.FLAME ? 0 : 15).mapColor(MapColor.SAND).requiresCorrectToolForDrops().sound(SoundType.WOOD).strength(1.5F, 6.0F))); public static final DeferredBlock FIREFLY = register("firefly", () -> new FireflyBlock(BlockBehaviour.Properties.of().instabreak().lightLevel((state) -> 15).noCollission().noTerrainParticles().pushReaction(PushReaction.DESTROY).sound(SoundType.SLIME_BLOCK))); public static final DeferredBlock CICADA = register("cicada", () -> new CicadaBlock(BlockBehaviour.Properties.of().instabreak().noCollission().noTerrainParticles().pushReaction(PushReaction.DESTROY).sound(SoundType.SLIME_BLOCK))); public static final DeferredBlock MOONWORM = register("moonworm", () -> new MoonwormBlock(BlockBehaviour.Properties.of().instabreak().lightLevel((state) -> 14).noCollission().noTerrainParticles().pushReaction(PushReaction.DESTROY).sound(SoundType.SLIME_BLOCK))); diff --git a/src/main/java/twilightforest/init/TFConfiguredFeatures.java b/src/main/java/twilightforest/init/TFConfiguredFeatures.java index f22f2b3cf6..775f109984 100644 --- a/src/main/java/twilightforest/init/TFConfiguredFeatures.java +++ b/src/main/java/twilightforest/init/TFConfiguredFeatures.java @@ -57,6 +57,8 @@ public final class TFConfiguredFeatures { //all the fun little things you find around the dimension public static final ResourceKey> BIG_MUSHGLOOM = registerKey("mushroom/big_mushgloom"); + public static final ResourceKey> DENSE_FERNS = registerKey("dense_ferns"); + public static final ResourceKey> DENSE_LARGE_FERNS = registerKey("dense_large_ferns"); public static final ResourceKey> FALLEN_LEAVES = registerKey("fallen_leaves"); public static final ResourceKey> MAYAPPLE = registerKey("mayapple"); public static final ResourceKey> FIDDLEHEAD = registerKey("fiddlehead"); @@ -88,6 +90,7 @@ public final class TFConfiguredFeatures { public static final ResourceKey> WEBS = registerKey("webs"); public static final ResourceKey> WOOD_ROOTS_SPREAD = registerKey("ore/wood_roots_spread"); public static final ResourceKey> SNOW_UNDER_TREES = registerKey("snow_under_trees"); + public static final ResourceKey> ENCHANTED_FOREST_VINES = registerKey("enchanted_forest_vines"); //fallen logs! public static final ResourceKey> TF_OAK_FALLEN_LOG = registerKey("tf_oak_fallen_log"); @@ -234,6 +237,8 @@ public static void bootstrap(BootstrapContext> context) registerTemplateFeatures(context); context.register(BIG_MUSHGLOOM, new ConfiguredFeature<>(TFFeatures.BIG_MUSHGLOOM.get(), new HugeMushroomFeatureConfiguration(BlockStateProvider.simple(TFBlocks.HUGE_MUSHGLOOM.get().defaultBlockState().setValue(HugeMushroomBlock.UP, Boolean.TRUE).setValue(HugeMushroomBlock.DOWN, Boolean.FALSE)), BlockStateProvider.simple(TFBlocks.HUGE_MUSHGLOOM_STEM.get().defaultBlockState().setValue(HugeMushroomBlock.UP, Boolean.FALSE).setValue(HugeMushroomBlock.DOWN, Boolean.FALSE)), 1))); + context.register(DENSE_FERNS, new ConfiguredFeature<>(Feature.RANDOM_PATCH, new RandomPatchConfiguration(64, 7, 3, PlacementUtils.filtered(Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(BlockStateProvider.simple(Blocks.FERN)), BlockPredicate.allOf(BlockPredicate.ONLY_IN_AIR_PREDICATE, BlockPredicate.matchesTag(Direction.DOWN.getNormal(), BlockTags.DIRT)))))); + context.register(DENSE_LARGE_FERNS, new ConfiguredFeature<>(Feature.RANDOM_PATCH, new RandomPatchConfiguration(64, 7, 3, PlacementUtils.filtered(Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(BlockStateProvider.simple(Blocks.LARGE_FERN)), BlockPredicate.allOf(BlockPredicate.ONLY_IN_AIR_PREDICATE, BlockPredicate.matchesTag(Direction.DOWN.getNormal(), BlockTags.DIRT)))))); context.register(FALLEN_LEAVES, new ConfiguredFeature<>(TFFeatures.FALLEN_LEAVES.get(), FeatureConfiguration.NONE)); context.register(MAYAPPLE, new ConfiguredFeature<>(Feature.RANDOM_PATCH, FeatureUtils.simplePatchConfiguration(Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(BlockStateProvider.simple(TFBlocks.MAYAPPLE.get()))))); context.register(FIDDLEHEAD, new ConfiguredFeature<>(Feature.RANDOM_PATCH, FeatureUtils.simplePatchConfiguration(Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(BlockStateProvider.simple(TFBlocks.FIDDLEHEAD.get()))))); @@ -265,6 +270,7 @@ public static void bootstrap(BootstrapContext> context) context.register(WEBS, new ConfiguredFeature<>(TFFeatures.WEBS.get(), NoneFeatureConfiguration.NONE)); context.register(WOOD_ROOTS_SPREAD, new ConfiguredFeature<>(TFFeatures.WOOD_ROOTS.get(), new RootConfig(TreeDecorators.ROOT_BLEND_PROVIDER, BlockStateProvider.simple(TFBlocks.LIVEROOT_BLOCK.get())))); context.register(SNOW_UNDER_TREES, new ConfiguredFeature<>(TFFeatures.SNOW_UNDER_TREES.get(), NoneFeatureConfiguration.NONE)); + context.register(ENCHANTED_FOREST_VINES, new ConfiguredFeature<>(TFFeatures.ENCHANTED_FOREST_VINES.get(), NoneFeatureConfiguration.NONE)); context.register(OAK_BUSH, new ConfiguredFeature<>(Feature.TREE, TreeConfigurations.OAK_BUSH)); context.register(TF_OAK_FALLEN_LOG, new ConfiguredFeature<>(TFFeatures.FALLEN_SMALL_LOG.get(), new HollowLogConfig(TFBlocks.TWILIGHT_OAK_LOG.get().defaultBlockState(), TFBlocks.HOLLOW_TWILIGHT_OAK_LOG_HORIZONTAL.get().defaultBlockState()))); @@ -340,7 +346,7 @@ public static void bootstrap(BootstrapContext> context) context.register(FIREFLY_FOREST_TREES, new ConfiguredFeature<>(Feature.RANDOM_SELECTOR, new RandomFeatureConfiguration(ImmutableList.of(new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(CANOPY_TREE)), 0.33F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(FIREFLY_CANOPY_TREE)), 0.45F)), PlacementUtils.inlinePlaced(features.getOrThrow(TWILIGHT_OAK_TREE))))); context.register(DARK_FOREST_TREES, new ConfiguredFeature<>(Feature.RANDOM_SELECTOR, new RandomFeatureConfiguration(ImmutableList.of(new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(DARK_FOREST_BIRCH_TREE)), 0.2F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(DARK_FOREST_OAK_TREE)), 0.2F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(DARK_OAK_BUSH)), 0.4F)), PlacementUtils.inlinePlaced(features.getOrThrow(DARKWOOD_TREE))))); context.register(HIGHLANDS_TREES, new ConfiguredFeature<>(Feature.RANDOM_SELECTOR, new RandomFeatureConfiguration(ImmutableList.of(new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(VANILLA_BIRCH_TREE)), 0.25F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(TreeFeatures.SPRUCE)), 0.25F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(TreeFeatures.PINE)), 0.1F)), PlacementUtils.inlinePlaced(features.getOrThrow(MEGA_SPRUCE_TREE))))); - context.register(ENCHANTED_FOREST_TREES, new ConfiguredFeature<>(Feature.RANDOM_SELECTOR, new RandomFeatureConfiguration(ImmutableList.of(new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(VANILLA_OAK_TREE)), 0.15F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(VANILLA_BIRCH_TREE)), 0.15F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(LARGE_RAINBOW_OAK_TREE)), 0.1F)), PlacementUtils.inlinePlaced(features.getOrThrow(RAINBOW_OAK_TREE))))); + context.register(ENCHANTED_FOREST_TREES, new ConfiguredFeature<>(Feature.RANDOM_SELECTOR, new RandomFeatureConfiguration(ImmutableList.of(new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(VANILLA_OAK_TREE)), 0.15F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(VANILLA_BIRCH_TREE)), 0.15F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(LARGE_RAINBOW_OAK_TREE)), 0.15F)), PlacementUtils.inlinePlaced(features.getOrThrow(RAINBOW_OAK_TREE))))); context.register(SNOWY_FOREST_TREES, new ConfiguredFeature<>(Feature.RANDOM_SELECTOR, new RandomFeatureConfiguration(ImmutableList.of(new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(MEGA_SPRUCE_TREE)), 0.33F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(LARGE_WINTER_TREE)), 0.125F)), PlacementUtils.inlinePlaced(features.getOrThrow(SNOWY_SPRUCE_TREE))))); context.register(VANILLA_TF_TREES, new ConfiguredFeature<>(Feature.RANDOM_SELECTOR, new RandomFeatureConfiguration(ImmutableList.of(new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(VANILLA_BIRCH_TREE)), 0.25F), new WeightedPlacedFeature(PlacementUtils.inlinePlaced(features.getOrThrow(VANILLA_OAK_TREE)), 0.25F)), PlacementUtils.inlinePlaced(features.getOrThrow(TWILIGHT_OAK_TREE))))); context.register(VANILLA_TF_BIG_MUSH, new ConfiguredFeature<>(Feature.RANDOM_BOOLEAN_SELECTOR, new RandomBooleanFeatureConfiguration(PlacementUtils.inlinePlaced(features.getOrThrow(TreeFeatures.HUGE_RED_MUSHROOM)), PlacementUtils.inlinePlaced(features.getOrThrow(TreeFeatures.HUGE_BROWN_MUSHROOM))))); diff --git a/src/main/java/twilightforest/init/TFFeatures.java b/src/main/java/twilightforest/init/TFFeatures.java index a69306b53c..a4c3a13dee 100644 --- a/src/main/java/twilightforest/init/TFFeatures.java +++ b/src/main/java/twilightforest/init/TFFeatures.java @@ -56,5 +56,6 @@ public class TFFeatures { public static final DeferredHolder, Feature> WOOD_ROOTS = FEATURES.register("wood_roots", () -> new WoodRootFeature(RootConfig.CODEC)); public static final DeferredHolder, Feature> SNOW_UNDER_TREES = FEATURES.register("snow_under_trees", () -> new SnowUnderTreeFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, Feature> SNOW_TREE = FEATURES.register("anywhere_tree", () -> new SnowTreeFeature(TreeConfiguration.CODEC)); + public static final DeferredHolder, Feature> ENCHANTED_FOREST_VINES = FEATURES.register("enchanted_forest_vines", () -> new EnchantedForestVinesFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, Feature> DARK_FOREST_PLACER = FEATURES.register("dark_forest_placer", () -> new DarkForestFeature(RandomPatchConfiguration.CODEC)); } diff --git a/src/main/java/twilightforest/init/TFPlacedFeatures.java b/src/main/java/twilightforest/init/TFPlacedFeatures.java index 13b16e25c0..5e4179365f 100644 --- a/src/main/java/twilightforest/init/TFPlacedFeatures.java +++ b/src/main/java/twilightforest/init/TFPlacedFeatures.java @@ -6,6 +6,7 @@ import net.minecraft.core.HolderSet; import net.minecraft.core.registries.Registries; import net.minecraft.data.worldgen.BootstrapContext; +import net.minecraft.data.worldgen.features.VegetationFeatures; import net.minecraft.data.worldgen.placement.PlacementUtils; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.Biome; @@ -28,6 +29,9 @@ public class TFPlacedFeatures { public static final ResourceKey PLACED_LAKE_WATER = registerKey("water_lake"); public static final ResourceKey PLACED_LAKE_FROZEN = registerKey("frozen_lake"); public static final ResourceKey PLACED_DRUID_HUT = registerKey("druid_hut"); + public static final ResourceKey PLACED_DENSE_FERNS = registerKey("dense_ferns"); + public static final ResourceKey PLACED_DENSE_LARGE_FERNS = registerKey("dense_large_ferns"); + public static final ResourceKey PLACED_DENSE_LAKE_WATER = registerKey("dense_water_lake"); public static final ResourceKey PLACED_GRAVEYARD = registerKey("graveyard"); public static final ResourceKey PLACED_BIG_MUSHGLOOM = registerKey("big_mushgloom"); public static final ResourceKey PLACED_FALLEN_LEAVES = registerKey("fallen_leaves"); @@ -57,6 +61,7 @@ public class TFPlacedFeatures { public static final ResourceKey PLACED_WEBS = registerKey("webs"); public static final ResourceKey PLACED_WOOD_ROOTS_SPREAD = registerKey("wood_roots"); public static final ResourceKey PLACED_SNOW_UNDER_TREES = registerKey("snow_under_trees"); + public static final ResourceKey PLACED_ENCHANTED_FOREST_VINES = registerKey("enchanted_forest_vines"); public static final ResourceKey PLACED_TF_OAK_FALLEN_LOG = registerKey("tf_oak_fallen_log"); public static final ResourceKey PLACED_CANOPY_FALLEN_LOG = registerKey("canopy_fallen_log"); public static final ResourceKey PLACED_MANGROVE_FALLEN_LOG = registerKey("mangrove_fallen_log"); @@ -152,6 +157,9 @@ public static void bootstrap(BootstrapContext context) { context.register(PLACED_LAKE_WATER, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.LAKE_WATER), tfFeatureCheckArea(AvoidLandmarkModifier.checkBoth(), 32).build())); context.register(PLACED_LAKE_FROZEN, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.LAKE_FROZEN), tfFeatureCheckArea(AvoidLandmarkModifier.checkBoth(), 4).build())); context.register(PLACED_DRUID_HUT, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.DRUID_HUT), tfFeatureCheckArea(AvoidLandmarkModifier.checkBoth(), 105).build())); + context.register(PLACED_DENSE_FERNS, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.DENSE_FERNS), ImmutableList.builder().add(PlacementUtils.countExtra(3, 0.5F, 1), InSquarePlacement.spread(), PlacementUtils.HEIGHTMAP_WORLD_SURFACE, BiomeFilter.biome()).build())); + context.register(PLACED_DENSE_LARGE_FERNS, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.DENSE_LARGE_FERNS), ImmutableList.builder().add(CountPlacement.of(2), InSquarePlacement.spread(), PlacementUtils.HEIGHTMAP_WORLD_SURFACE, BiomeFilter.biome()).build())); + context.register(PLACED_DENSE_LAKE_WATER, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.LAKE_WATER), tfFeatureCheckArea(AvoidLandmarkModifier.checkBoth(), 4).build())); context.register(PLACED_GRAVEYARD, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.GRAVEYARD), tfFeatureCheckArea(AvoidLandmarkModifier.checkSurface(), 70).build())); context.register(PLACED_BIG_MUSHGLOOM, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.BIG_MUSHGLOOM), tfFeatureCheckArea(AvoidLandmarkModifier.checkSurface(), 1).build())); context.register(PLACED_FALLEN_LEAVES, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.FALLEN_LEAVES), tfFeatureCheckArea(AvoidLandmarkModifier.checkSurface(), 1).build())); @@ -181,7 +189,7 @@ public static void bootstrap(BootstrapContext context) { context.register(PLACED_WEBS, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.WEBS), ImmutableList.builder().add(PlacementUtils.HEIGHTMAP_WORLD_SURFACE, CountPlacement.of(60), InSquarePlacement.spread(), BiomeFilter.biome()).build())); context.register(PLACED_WOOD_ROOTS_SPREAD, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.WOOD_ROOTS_SPREAD), tfFeatureCheckArea(AvoidLandmarkModifier.checkUnderground(), 40, HeightRangePlacement.uniform(VerticalAnchor.bottom(), VerticalAnchor.absolute(0))).build())); - context.register(PLACED_SNOW_UNDER_TREES, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.SNOW_UNDER_TREES), ImmutableList.builder().add(BiomeFilter.biome()).build())); + context.register(PLACED_SNOW_UNDER_TREES, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.SNOW_UNDER_TREES), ImmutableList.builder().add(PlacementUtils.HEIGHTMAP_WORLD_SURFACE, BiomeFilter.biome()).build())); context.register(PLACED_TF_OAK_FALLEN_LOG, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.TF_OAK_FALLEN_LOG), hollowLog(AvoidLandmarkModifier.checkSurface()).build())); context.register(PLACED_CANOPY_FALLEN_LOG, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.CANOPY_FALLEN_LOG), hollowLog(AvoidLandmarkModifier.checkSurface()).build())); context.register(PLACED_MANGROVE_FALLEN_LOG, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.MANGROVE_FALLEN_LOG), hollowLog(AvoidLandmarkModifier.checkSurface()).build())); @@ -198,6 +206,8 @@ public static void bootstrap(BootstrapContext context) { context.register(PLACED_DARK_RED_MUSHROOMS, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.DARK_RED_MUSHROOMS), ImmutableList.builder().add(RarityFilter.onAverageOnceEvery(3), InSquarePlacement.spread(), PlacementUtils.HEIGHTMAP_WORLD_SURFACE, BiomeFilter.biome()).build())); context.register(PLACED_DARK_DEAD_BUSHES, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.DARK_DEAD_BUSHES), ImmutableList.builder().add(RarityFilter.onAverageOnceEvery(3), InSquarePlacement.spread(), PlacementUtils.HEIGHTMAP_WORLD_SURFACE, BiomeFilter.biome()).build())); + context.register(PLACED_ENCHANTED_FOREST_VINES, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.ENCHANTED_FOREST_VINES), ImmutableList.builder().add(PlacementUtils.HEIGHTMAP).build())); + context.register(PLACED_LEGACY_COAL_ORE, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.LEGACY_COAL_ORE), ImmutableList.builder().add(HeightRangePlacement.uniform(VerticalAnchor.bottom(), VerticalAnchor.absolute(127)), InSquarePlacement.spread(), CountPlacement.of(20), BiomeFilter.biome()).build())); context.register(PLACED_LEGACY_IRON_ORE, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.LEGACY_IRON_ORE), ImmutableList.builder().add(HeightRangePlacement.uniform(VerticalAnchor.bottom(), VerticalAnchor.absolute(63)), InSquarePlacement.spread(), CountPlacement.of(20), BiomeFilter.biome()).build())); context.register(PLACED_LEGACY_GOLD_ORE, new PlacedFeature(features.getOrThrow(TFConfiguredFeatures.LEGACY_GOLD_ORE), ImmutableList.builder().add(HeightRangePlacement.uniform(VerticalAnchor.bottom(), VerticalAnchor.absolute(31)), InSquarePlacement.spread(), CountPlacement.of(2), BiomeFilter.biome()).build())); diff --git a/src/main/java/twilightforest/world/components/BiomeColorAlgorithms.java b/src/main/java/twilightforest/world/components/BiomeColorAlgorithms.java index c2b27b9a00..82b94dac04 100644 --- a/src/main/java/twilightforest/world/components/BiomeColorAlgorithms.java +++ b/src/main/java/twilightforest/world/components/BiomeColorAlgorithms.java @@ -1,22 +1,25 @@ package twilightforest.world.components; +import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; import net.minecraft.world.level.FoliageColor; import net.minecraft.world.level.GrassColor; import net.minecraft.world.level.biome.Biome; import twilightforest.beans.Component; import twilightforest.util.ColorUtil; +import twilightforest.util.landmarks.LegacyLandmarkPlacements; +import twilightforest.world.components.structures.type.QuestGroveStructure; @Component public class BiomeColorAlgorithms { public int enchanted(int originalColor, int x, int z) { // TODO - // center of the biome is at % 256 - 8 - int cx = 256 * Math.round((x - 8) / 256F) + 8; - int cz = 256 * Math.round((z - 8) / 256F) - 8; + BlockPos center = LegacyLandmarkPlacements.getNearestCenterXZ(x / 16, z / 16); // Center is quest grove + int cx = center.getX(); + int cz = center.getZ(); int dist = (int) Mth.sqrt((cx - x) * (cx - x) + (cz - z) * (cz - z)); - int color = dist * 64; + int color = dist * 16; color %= 512; if (color > 255) { diff --git a/src/main/java/twilightforest/world/components/feature/EnchantedForestVinesFeature.java b/src/main/java/twilightforest/world/components/feature/EnchantedForestVinesFeature.java new file mode 100644 index 0000000000..63aa8e87a3 --- /dev/null +++ b/src/main/java/twilightforest/world/components/feature/EnchantedForestVinesFeature.java @@ -0,0 +1,106 @@ +package twilightforest.world.components.feature; + +import com.llamalad7.mixinextras.lib.apache.commons.tuple.Pair; +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.VineBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import twilightforest.init.TFBlocks; + +import java.util.*; + +public class EnchantedForestVinesFeature extends Feature { + private static final int rarity = 7; + private static final int extraRarityOnTrees = 8; + + public EnchantedForestVinesFeature(Codec codec) {super(codec);} + + @Override + public boolean place(FeaturePlaceContext context) { + WorldGenLevel world = context.level(); + setAllPossibleStates(world, context.random(), context.origin()); + return true; + } + + private void setAllPossibleStates(WorldGenLevel world, RandomSource random, BlockPos pos) { + Map, Pair> columnsY = getAllColumnsY(world, pos.getX(), pos.getZ()); + for (Map.Entry, Pair> entry : columnsY.entrySet()) { + Pair horizontalCoordinates = entry.getKey(); + int x = horizontalCoordinates.getLeft(); + int z = horizontalCoordinates.getRight(); + int minY = entry.getValue().getLeft(); + int maxY = entry.getValue().getRight(); + + setColumn(world, random, x, minY, maxY, z); + } + } + + private Map, Pair> getAllColumnsY(WorldGenLevel world, int originX, int originZ) { + Map, Pair> columns = new HashMap<>(); + for (int x = originX; x < originX + 16; x++) { + for (int z = originZ; z < originZ + 16; z++) { + columns.put(Pair.of(x, z), getColumnY(world, x, z)); + } + } + return columns; + } + + private Pair getColumnY(WorldGenLevel world, int x, int z) { + int height1 = world.getHeight(Heightmap.Types.MOTION_BLOCKING, x - 1, z); + int height2 = world.getHeight(Heightmap.Types.MOTION_BLOCKING, x + 1, z); + int height3 = world.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z - 1); + int height4 = world.getHeight(Heightmap.Types.MOTION_BLOCKING, x, z + 1); + + return Pair.of(-10, Math.max(Math.max(height1, height2), Math.max(height3, height4))); + } + + private void setColumn(WorldGenLevel world, RandomSource random, int x, int minY, int maxY, int z) { + for (int y = minY; y <= maxY; y++) { + BlockPos pos = new BlockPos(x, y, z); + setVine(world, random, pos); + } + } + + private void setVine(WorldGenLevel world, RandomSource random, BlockPos pos) { + if (random.nextInt(rarity) > 0 || !world.getBlockState(pos).isEmpty() || !isSuitableBiome(world, pos)) + return; + + BlockState state = Blocks.VINE.defaultBlockState(); + boolean empty = true; + boolean isTree = true; + + for (Direction dir : Direction.values()) { + BlockPos relativePos = pos.relative(dir); + if (dir != Direction.DOWN && VineBlock.isAcceptableNeighbour(world, relativePos, dir) && !world.getBlockState(relativePos).is(TFBlocks.RAINBOW_OAK_LEAVES.get())) { + if (!isTree(world.getBlockState(relativePos))) + isTree = false; + + state = state.setValue(VineBlock.getPropertyForFace(dir), true); + if (dir.getAxis() != Direction.Axis.Y) + empty = false; + } + } + if (isTree && random.nextInt(extraRarityOnTrees) > 0) + return; + + if (!empty) + setBlock(world, pos, state); + } + + private boolean isSuitableBiome(WorldGenLevel world, BlockPos pos) { + return Objects.requireNonNull(world.getBiome(pos).getKey()).location().getPath().equals("enchanted_forest"); + } + + private boolean isTree(BlockState state) { + return state.is(BlockTags.LOGS) || state.is(BlockTags.LEAVES); + } +} diff --git a/src/main/java/twilightforest/world/components/structures/type/QuestGroveStructure.java b/src/main/java/twilightforest/world/components/structures/type/QuestGroveStructure.java index 5598bd3343..07d3d0382a 100644 --- a/src/main/java/twilightforest/world/components/structures/type/QuestGroveStructure.java +++ b/src/main/java/twilightforest/world/components/structures/type/QuestGroveStructure.java @@ -25,6 +25,7 @@ public class QuestGroveStructure extends ConquerableStructure { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> landmarkCodec(instance).apply(instance, QuestGroveStructure::new)); + public static final int LENGTH = 27; public QuestGroveStructure(DecorationConfig decorationConfig, boolean centerInChunk, Optional> structureIcon, StructureSettings structureSettings) { super(decorationConfig, centerInChunk, structureIcon, structureSettings); @@ -32,7 +33,7 @@ public QuestGroveStructure(DecorationConfig decorationConfig, boolean centerInCh @Override protected StructurePiece getFirstPiece(GenerationContext context, RandomSource random, ChunkPos chunkPos, int x, int y, int z) { - return new QuestGrove(context.structureTemplateManager(), new BlockPos(x - 12, y + 2, z - 12)); + return new QuestGrove(context.structureTemplateManager(), new BlockPos(x - LENGTH / 2 + 1, y + 2, z - LENGTH / 2 + 1)); // + 1 offsets to center the structure } @Override @@ -42,7 +43,7 @@ public StructureType type() { public static QuestGroveStructure buildStructureConfig(BootstrapContext context) { return new QuestGroveStructure( - new DecorationConfig(1, false, true, true), + new DecorationConfig(2, false, true, true), true, Optional.of(TFMapDecorations.QUEST_GROVE), new StructureSettings( context.lookup(Registries.BIOME).getOrThrow(BiomeTagGenerator.VALID_QUEST_GROVE_BIOMES), diff --git a/src/main/java/twilightforest/world/registration/biomes/BiomeHelper.java b/src/main/java/twilightforest/world/registration/biomes/BiomeHelper.java index fcf60298d5..48f3698838 100644 --- a/src/main/java/twilightforest/world/registration/biomes/BiomeHelper.java +++ b/src/main/java/twilightforest/world/registration/biomes/BiomeHelper.java @@ -108,18 +108,27 @@ public static BiomeGenerationSettings.Builder oakSavannaGen(HolderGetter featureGetter, HolderGetter> carverGetter) { - BiomeGenerationSettings.Builder biome = defaultGenSettingBuilder(featureGetter, carverGetter); + BiomeGenerationSettings.Builder biome = new BiomeGenerationSettings.Builder(featureGetter, carverGetter); + BiomeDefaultFeatures.addDefaultSoftDisks(biome); + BiomeDefaultFeatures.addDefaultGrass(biome); + biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_SUGAR_CANE); + BiomeDefaultFeatures.addSurfaceFreezing(biome); + withWoodRoots(biome); + addCaves(biome); + addSmallStoneClusters(biome); - biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_JUNGLE); - biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_LARGE_FERN); + biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, TFPlacedFeatures.PLACED_DENSE_FERNS); + biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, TFPlacedFeatures.PLACED_DENSE_LARGE_FERNS); + biome.addFeature(GenerationStep.Decoration.LAKES, TFPlacedFeatures.PLACED_DENSE_LAKE_WATER); - addForestVegetation(biome); + biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, TFPlacedFeatures.PLACED_FLOWER_PLACER); commonFeatures(biome); biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, TFPlacedFeatures.PLACED_ENCHANTED_FOREST_TREES); + biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, TFPlacedFeatures.PLACED_DENSE_CANOPY_TREES); biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, TFPlacedFeatures.PLACED_FIDDLEHEAD); - biome.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.VINES); + biome.addFeature(GenerationStep.Decoration.TOP_LAYER_MODIFICATION, TFPlacedFeatures.PLACED_ENCHANTED_FOREST_VINES); addCanopyTrees(biome); diff --git a/src/main/resources/assets/twilightforest/lang/vi_vn.json b/src/main/resources/assets/twilightforest/lang/vi_vn.json index 89d89c0a5e..dd235f2909 100644 --- a/src/main/resources/assets/twilightforest/lang/vi_vn.json +++ b/src/main/resources/assets/twilightforest/lang/vi_vn.json @@ -1790,4 +1790,4 @@ "twilightforest.tips.worldgen_features": "Khu rừng đầy những tàn tích. Một số thậm chí có thể chứa các vật phẩm độc đáo.", "twilightforest.tips.yeti": "Yetis thích ném mọi thứ.", "twilightforest.tips.zombie_healing": "Zombie được triệu hồi bằng Zombie Scepter có thể được chữa khỏi bằng Thịt Thối." -} \ No newline at end of file +} diff --git a/src/main/resources/assets/twilightforest/textures/block/mining_leaves.png b/src/main/resources/assets/twilightforest/textures/block/mining_leaves.png index 08a3749256..083ec43cff 100644 Binary files a/src/main/resources/assets/twilightforest/textures/block/mining_leaves.png and b/src/main/resources/assets/twilightforest/textures/block/mining_leaves.png differ diff --git a/src/main/resources/assets/twilightforest/textures/block/time_leaves.png b/src/main/resources/assets/twilightforest/textures/block/time_leaves.png index 08a3749256..af37397c1c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/block/time_leaves.png and b/src/main/resources/assets/twilightforest/textures/block/time_leaves.png differ diff --git a/src/main/resources/assets/twilightforest/textures/block/transformation_leaves.png b/src/main/resources/assets/twilightforest/textures/block/transformation_leaves.png index b23d3ade4f..2783b70b57 100644 Binary files a/src/main/resources/assets/twilightforest/textures/block/transformation_leaves.png and b/src/main/resources/assets/twilightforest/textures/block/transformation_leaves.png differ