Skip to content

Commit b91128d

Browse files
Add CustomFreezeTopLayerFeature
1 parent db020cb commit b91128d

4 files changed

Lines changed: 204 additions & 5 deletions

File tree

src/main/java/com/mmodding/mmodding_lib/library/blocks/CustomInfluenceableBlock.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import net.minecraft.util.math.BlockPos;
1212
import net.minecraft.util.math.Direction;
1313
import net.minecraft.world.WorldAccess;
14+
import org.jetbrains.annotations.ApiStatus;
1415
import org.jetbrains.annotations.Nullable;
1516
import org.quiltmc.qsl.item.setting.api.QuiltItemSettings;
1617

@@ -20,7 +21,8 @@ public static <E extends Enum<E> & StringIdentifiable> EnumProperty<E> createInf
2021
return EnumProperty.of("influence", type);
2122
}
2223

23-
protected abstract EnumProperty<E> getInfluenceProperty();
24+
@ApiStatus.OverrideOnly
25+
public abstract EnumProperty<E> getInfluenceProperty();
2426

2527
public CustomInfluenceableBlock(Settings settings) {
2628
this(settings, false);

src/main/java/com/mmodding/mmodding_lib/library/worldgen/MModdingFeatures.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import com.mmodding.mmodding_lib.library.utils.MModdingIdentifier;
44
import com.mmodding.mmodding_lib.library.utils.RegistrationUtils;
55
import com.mmodding.mmodding_lib.library.worldgen.features.builtin.LayeredFeature;
6-
import com.mmodding.mmodding_lib.library.worldgen.features.builtin.differed.DifferedDripstoneClusterFeature;
7-
import com.mmodding.mmodding_lib.library.worldgen.features.builtin.differed.DifferedLargeDripstoneFeature;
8-
import com.mmodding.mmodding_lib.library.worldgen.features.builtin.differed.DifferedPointedDripstoneFeature;
9-
import com.mmodding.mmodding_lib.library.worldgen.features.builtin.differed.DifferedLiquidVegetationPatch;
6+
import com.mmodding.mmodding_lib.library.worldgen.features.builtin.differed.*;
107
import net.minecraft.world.gen.feature.Feature;
118
import net.minecraft.world.gen.feature.FeatureConfig;
129

@@ -16,6 +13,10 @@ public class MModdingFeatures {
1613
"layered", new LayeredFeature(LayeredFeature.Config.CODEC)
1714
);
1815

16+
public static final Feature<DifferedFreezeTopLayerFeature.Config> DIFFERED_FREEZE_TOP_LAYER = MModdingFeatures.register(
17+
"differed_freeze_top_layer", new DifferedFreezeTopLayerFeature(DifferedFreezeTopLayerFeature.Config.CODEC)
18+
);
19+
1920
public static final Feature<DifferedDripstoneClusterFeature.Config> DIFFERED_DRIPSTONE_CLUSTER = MModdingFeatures.register(
2021
"differed_dripstone_cluster", new DifferedDripstoneClusterFeature(DifferedDripstoneClusterFeature.Config.CODEC)
2122
);
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.mmodding.mmodding_lib.library.worldgen.features.builtin.differed;
2+
3+
import com.mmodding.mmodding_lib.library.blocks.CustomInfluenceableBlock;
4+
import com.mojang.serialization.Codec;
5+
import com.mojang.serialization.codecs.RecordCodecBuilder;
6+
import net.minecraft.block.Block;
7+
import net.minecraft.block.BlockState;
8+
import net.minecraft.block.SnowyBlock;
9+
import net.minecraft.util.StringIdentifiable;
10+
import net.minecraft.util.math.BlockPos;
11+
import net.minecraft.util.math.Direction;
12+
import net.minecraft.world.Heightmap;
13+
import net.minecraft.world.StructureWorldAccess;
14+
import net.minecraft.world.biome.Biome;
15+
import net.minecraft.world.gen.feature.Feature;
16+
import net.minecraft.world.gen.feature.FeatureConfig;
17+
import net.minecraft.world.gen.feature.util.FeatureContext;
18+
import net.minecraft.world.gen.stateprovider.BlockStateProvider;
19+
20+
public class DifferedFreezeTopLayerFeature extends Feature<DifferedFreezeTopLayerFeature.Config> {
21+
22+
public DifferedFreezeTopLayerFeature(Codec<DifferedFreezeTopLayerFeature.Config> codec) {
23+
super(codec);
24+
}
25+
26+
@Override
27+
public boolean place(FeatureContext<DifferedFreezeTopLayerFeature.Config> context) {
28+
StructureWorldAccess world = context.getWorld();
29+
BlockPos blockPos = context.getOrigin();
30+
BlockPos.Mutable snowLayerPos = new BlockPos.Mutable();
31+
BlockPos.Mutable iceBlockPos = new BlockPos.Mutable();
32+
33+
for (int xOffset = 0; xOffset < 16; xOffset++) {
34+
for (int zOffset = 0; zOffset < 16; zOffset++) {
35+
int x = blockPos.getX() + xOffset;
36+
int z = blockPos.getZ() + zOffset;
37+
int y = world.getTopY(Heightmap.Type.MOTION_BLOCKING, x, z);
38+
snowLayerPos.set(x, y, z);
39+
iceBlockPos.set(snowLayerPos).move(Direction.DOWN, 1);
40+
Biome biome = world.getBiome(snowLayerPos).value();
41+
if (biome.canSetIce(world, iceBlockPos, false)) {
42+
world.setBlockState(
43+
iceBlockPos,
44+
context.getConfig().iceBlock.getBlockState(context.getRandom(), iceBlockPos),
45+
Block.NOTIFY_LISTENERS
46+
);
47+
}
48+
49+
if (biome.canSetSnow(world, snowLayerPos)) {
50+
world.setBlockState(snowLayerPos, context.getConfig().snowLayer.getBlockState(context.getRandom(), snowLayerPos), Block.NOTIFY_LISTENERS);
51+
BlockState state = world.getBlockState(iceBlockPos);
52+
if (state.contains(SnowyBlock.SNOWY)) {
53+
world.setBlockState(iceBlockPos, state.with(SnowyBlock.SNOWY, Boolean.TRUE), Block.NOTIFY_LISTENERS);
54+
}
55+
this.updateInfluencableBlock(state, world, new BlockPos(iceBlockPos));
56+
}
57+
}
58+
}
59+
60+
return true;
61+
}
62+
63+
@SuppressWarnings("unchecked")
64+
private <E extends Enum<E> & StringIdentifiable> void updateInfluencableBlock(BlockState state, StructureWorldAccess world, BlockPos pos) {
65+
if (state.getBlock() instanceof CustomInfluenceableBlock<?>) {
66+
CustomInfluenceableBlock<E> influenceable = (CustomInfluenceableBlock<E>) state.getBlock();
67+
world.setBlockState(
68+
pos,
69+
state.with(
70+
influenceable.getInfluenceProperty(),
71+
influenceable.getInfluence(world.getBlockState(new BlockPos(pos).up()))
72+
),
73+
Block.NOTIFY_LISTENERS
74+
);
75+
}
76+
}
77+
78+
public static class Config implements FeatureConfig {
79+
80+
public static final Codec<Config> CODEC = RecordCodecBuilder.create(instance -> instance.group(
81+
BlockStateProvider.TYPE_CODEC.fieldOf("ice_block").forGetter(config -> config.iceBlock),
82+
BlockStateProvider.TYPE_CODEC.fieldOf("snow_layer").forGetter(config -> config.snowLayer)
83+
).apply(instance, Config::new));
84+
85+
private final BlockStateProvider iceBlock;
86+
private final BlockStateProvider snowLayer;
87+
88+
public Config(BlockStateProvider iceBlock, BlockStateProvider snowLayer) {
89+
this.iceBlock = iceBlock;
90+
this.snowLayer = snowLayer;
91+
}
92+
}
93+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.mmodding.mmodding_lib.library.worldgen.features.defaults;
2+
3+
import com.mmodding.mmodding_lib.library.utils.BiArrayList;
4+
import com.mmodding.mmodding_lib.library.utils.BiList;
5+
import com.mmodding.mmodding_lib.library.utils.IdentifierUtils;
6+
import com.mmodding.mmodding_lib.library.utils.ListUtils;
7+
import com.mmodding.mmodding_lib.library.worldgen.MModdingFeatures;
8+
import com.mmodding.mmodding_lib.library.worldgen.features.builtin.differed.DifferedFreezeTopLayerFeature;
9+
import net.minecraft.block.Block;
10+
import net.minecraft.util.Holder;
11+
import net.minecraft.util.Identifier;
12+
import net.minecraft.util.registry.Registry;
13+
import net.minecraft.util.registry.RegistryKey;
14+
import net.minecraft.world.gen.GenerationStep;
15+
import net.minecraft.world.gen.decorator.*;
16+
import net.minecraft.world.gen.feature.*;
17+
import net.minecraft.world.gen.stateprovider.BlockStateProvider;
18+
import org.quiltmc.qsl.worldgen.biome.api.BiomeModifications;
19+
import org.quiltmc.qsl.worldgen.biome.api.BiomeSelectionContext;
20+
21+
import java.util.concurrent.atomic.AtomicBoolean;
22+
import java.util.concurrent.atomic.AtomicReference;
23+
import java.util.function.Predicate;
24+
25+
public class CustomFreezeTopLayerFeature implements CustomFeature, FeatureRegistrable {
26+
27+
private final AtomicBoolean registered = new AtomicBoolean();
28+
private final AtomicReference<Identifier> identifier = new AtomicReference<>();
29+
private final BiList<PlacedFeature, String> additionalPlacedFeatures = new BiArrayList<>();
30+
31+
private final Block iceBlock;
32+
private final Block snowLayer;
33+
34+
public CustomFreezeTopLayerFeature(Block iceBlock, Block snowLayer) {
35+
this.iceBlock = iceBlock;
36+
this.snowLayer = snowLayer;
37+
}
38+
39+
@Override
40+
public Feature<DifferedFreezeTopLayerFeature.Config> getFeature() {
41+
return MModdingFeatures.DIFFERED_FREEZE_TOP_LAYER;
42+
}
43+
44+
@Override
45+
public ConfiguredFeature<?, ?> getConfiguredFeature() {
46+
return new ConfiguredFeature<>(this.getFeature(), new DifferedFreezeTopLayerFeature.Config(
47+
BlockStateProvider.of(this.iceBlock),
48+
BlockStateProvider.of(this.snowLayer)
49+
));
50+
}
51+
52+
public PlacedFeature createPlacedFeature() {
53+
return new PlacedFeature(
54+
Holder.createDirect(this.getConfiguredFeature()),
55+
ListUtils.builder(placementModifiers -> placementModifiers.add(BiomePlacementModifier.getInstance()))
56+
);
57+
}
58+
59+
@Override
60+
public PlacedFeature getDefaultPlacedFeature() {
61+
return this.createPlacedFeature();
62+
}
63+
64+
public CustomFreezeTopLayerFeature addPlacedFeature(String idExt) {
65+
this.additionalPlacedFeatures.add(this.createPlacedFeature(), idExt);
66+
return this;
67+
}
68+
69+
@Override
70+
public BiList<PlacedFeature, String> getAdditionalPlacedFeatures() {
71+
return this.additionalPlacedFeatures;
72+
}
73+
74+
@Override
75+
public void addDefaultToBiomes(Predicate<BiomeSelectionContext> ctx) {
76+
this.addAdditionalToBiomes(ctx, "");
77+
}
78+
79+
@Override
80+
public void addAdditionalToBiomes(Predicate<BiomeSelectionContext> ctx, String idExt) {
81+
if (this.registered.get()) {
82+
BiomeModifications.addFeature(
83+
ctx, GenerationStep.Feature.TOP_LAYER_MODIFICATION,
84+
RegistryKey.of(Registry.PLACED_FEATURE_KEY, IdentifierUtils.extend(this.identifier.get(), idExt))
85+
);
86+
}
87+
}
88+
89+
@Override
90+
public void setIdentifier(Identifier identifier) {
91+
this.identifier.set(identifier);
92+
}
93+
94+
@Override
95+
public boolean isNotRegistered() {
96+
return !this.registered.get();
97+
}
98+
99+
@Override
100+
public void setRegistered() {
101+
this.registered.set(true);
102+
}
103+
}

0 commit comments

Comments
 (0)