- Fixed clouds affecting lighting

- Clouds no longer affect the world heightmap (fixes certain structures generating on clouds)
- Added proper cloud gen beyond just structures
- Fixed mobs spawning on clouds when they shouldn't
This commit is contained in:
Sollace 2024-09-24 23:49:09 +01:00
parent 2565e199be
commit 991a2407bb
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
6 changed files with 215 additions and 1 deletions

View file

@ -12,6 +12,8 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.block.BedBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
@ -23,6 +25,7 @@ import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
public class NaturalCloudBlock extends PoreousCloudBlock {
@ -39,7 +42,9 @@ public class NaturalCloudBlock extends PoreousCloudBlock {
@Nullable Supplier<Soakable> soggyBlock,
Supplier<Block> compactedBlock,
Settings settings) {
super(meltable, soggyBlock, settings.nonOpaque());
super(meltable, soggyBlock, settings.nonOpaque().allowsSpawning((state, world, pos, type) -> {
return type == EntityType.PHANTOM || type == EntityType.PARROT || type.getSpawnGroup() == SpawnGroup.AMBIENT;
}));
this.compactedBlock = compactedBlock;
}
@ -48,6 +53,17 @@ public class NaturalCloudBlock extends PoreousCloudBlock {
return CODEC;
}
@Override
@Deprecated
public float getAmbientOcclusionLightLevel(BlockState state, BlockView world, BlockPos pos) {
return 0.9F;
}
@Override
public boolean isTransparent(BlockState state, BlockView world, BlockPos pos) {
return true;
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ItemStack stack = player.getStackInHand(hand);

View file

@ -0,0 +1,21 @@
package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.unicopia.block.cloud.CloudLike;
import net.minecraft.block.BlockState;
import net.minecraft.world.Heightmap;
@Mixin(Heightmap.class)
abstract class MixinHeightmap {
@Inject(method = "method_16682", at = @At("HEAD"), cancellable = true)
private static void excludeCloudsFromWorldSurfaceHeightMap(BlockState state, CallbackInfoReturnable<Boolean> info) {
if (state.getBlock() instanceof CloudLike) {
info.setReturnValue(false);
}
}
}

View file

@ -7,6 +7,7 @@ import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.block.ShellsBlock;
import com.minelittlepony.unicopia.block.UBlocks;
import com.minelittlepony.unicopia.server.world.gen.CaveCarvingStructureProcessor;
import com.minelittlepony.unicopia.server.world.gen.CloudCarver;
import com.minelittlepony.unicopia.server.world.gen.OverworldBiomeSelectionCallback;
import com.minelittlepony.unicopia.server.world.gen.SurfaceGrowthStructureProcessor;
import com.minelittlepony.unicopia.util.registry.DynamicRegistry;
@ -38,6 +39,9 @@ import net.minecraft.world.biome.OverworldBiomeCreator;
import net.minecraft.world.biome.SpawnSettings;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.blockpredicate.BlockPredicate;
import net.minecraft.world.gen.carver.Carver;
import net.minecraft.world.gen.carver.CaveCarverConfig;
import net.minecraft.world.gen.carver.ConfiguredCarver;
import net.minecraft.world.gen.feature.ConfiguredFeatures;
import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
import net.minecraft.world.gen.feature.Feature;
@ -126,6 +130,9 @@ public interface UWorldGen {
StructureProcessorType<SurfaceGrowthStructureProcessor> SURFACE_GROWTH_STRUCTURE_PROCESSOR = Registry.register(Registries.STRUCTURE_PROCESSOR, Unicopia.id("surface_growth"), () -> SurfaceGrowthStructureProcessor.CODEC);
StructureProcessorType<CaveCarvingStructureProcessor> CAVE_CARVING_STRUCTURE_PROCESSOR = Registry.register(Registries.STRUCTURE_PROCESSOR, Unicopia.id("cave_carving"), () -> CaveCarvingStructureProcessor.CODEC);
RegistryKey<ConfiguredCarver<?>> OVERWORLD_CLOUD_CARVER_CONFIG = RegistryKey.of(RegistryKeys.CONFIGURED_CARVER, Unicopia.id("overworld_cloud_carver"));
Carver<CaveCarverConfig> CLOUR_CARVER = Registry.register(Registries.CARVER, Unicopia.id("cloud"), new CloudCarver(CaveCarverConfig.CAVE_CODEC));
@SafeVarargs
static <T> T applyAll(T t, Consumer<T> ...consumers) {
for (Consumer<T> consumer : consumers) {
@ -142,6 +149,7 @@ public interface UWorldGen {
.or(BiomeSelectors.tag(BiomeTags.IS_RIVER))
.or(BiomeSelectors.includeByKey(BiomeKeys.STONY_SHORE))
), GenerationStep.Feature.VEGETAL_DECORATION, SHELLS_PLACED_FEATURE);
BiomeModifications.addCarver(BiomeSelectors.foundInOverworld(), GenerationStep.Carver.AIR, OVERWORLD_CLOUD_CARVER_CONFIG);
UTreeGen.bootstrap();
OverworldBiomeSelectionCallback.EVENT.register(context -> {

View file

@ -0,0 +1,142 @@
package com.minelittlepony.unicopia.server.world.gen;
import java.util.function.Function;
import com.minelittlepony.unicopia.block.UBlocks;
import com.mojang.serialization.Codec;
import net.minecraft.block.BlockState;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.carver.Carver;
import net.minecraft.world.gen.carver.CarverContext;
import net.minecraft.world.gen.carver.CarvingMask;
import net.minecraft.world.gen.carver.CaveCarver;
import net.minecraft.world.gen.carver.CaveCarverConfig;
import net.minecraft.world.gen.chunk.AquiferSampler;
import net.minecraft.world.gen.densityfunction.DensityFunction.NoisePos;
public class CloudCarver extends CaveCarver {
private Random random;
public CloudCarver(Codec<CaveCarverConfig> codec) {
super(codec);
}
@Override
protected int getMaxCaveCount() {
return 15;
}
@Override
protected float getTunnelSystemWidth(Random random) {
return (random.nextFloat() * 2.0F + random.nextFloat()) * 2.0F;
}
@Override
protected double getTunnelSystemHeightWidthRatio() {
return 0.5;
}
@Override
public boolean carve(
CarverContext context,
CaveCarverConfig config,
Chunk chunk,
Function<BlockPos, RegistryEntry<Biome>> function,
Random random,
AquiferSampler sampler,
ChunkPos chunkPos,
CarvingMask carvingMask
) {
this.random = random;
return super.carve(context, config, chunk, function, random, new AquiferSampler() {
@Override
public BlockState apply(NoisePos pos, double density) {
BlockState state = sampler.apply(pos, density);
return state != null && state.isAir() ? UBlocks.CLOUD.getDefaultState() : state;
}
@Override
public boolean needsFluidTick() {
return sampler.needsFluidTick();
}
}, chunkPos, carvingMask);
}
@Override
protected void carveCave(
CarverContext context,
CaveCarverConfig config,
Chunk chunk,
Function<BlockPos, RegistryEntry<Biome>> posToBiome,
AquiferSampler aquiferSampler,
double x,
double y,
double z,
float xScale,
double yScale,
CarvingMask mask,
Carver.SkipPredicate skipPredicate
) {
if (random == null) {
return;
}
int maxY = context.getMinY() + context.getHeight();
int bubbleCount = 10 + random.nextInt(12);
for (int i = 0; i < bubbleCount; i++) {
double width = 1.5 * xScale + random.nextTriangular(3, 2);
double height = Math.min(width * yScale * (1 + random.nextFloat() * 2) + MathHelper.sin((float) (Math.PI / 2)) * xScale, maxY - y);
double bubbleX = x + (random.nextFloat() * 2 - 1) * width;
double bubbleZ = z + (random.nextFloat() * 2 - 1) * width;
carveRegion(context, config, chunk, posToBiome, aquiferSampler, bubbleX + 1.0, y, bubbleZ, width, height, mask, skipPredicate);
}
}
@Override
protected void carveTunnels(
CarverContext context,
CaveCarverConfig config,
Chunk chunk,
Function<BlockPos, RegistryEntry<Biome>> posToBiome,
long seed,
AquiferSampler aquiferSampler,
double x,
double y,
double z,
double horizontalScale,
double verticalScale,
float w,
float yaw,
float pitch,
int branchStartIndex,
int branchCount,
double yawPitchRatio,
CarvingMask mask,
Carver.SkipPredicate skipPredicate
) {
if (random == null) {
return;
}
int maxY = context.getMinY() + context.getHeight();
int bubbleCount = 10 + random.nextInt(12);
for (int i = 0; i < bubbleCount; i++) {
double width = /*1.5 + MathHelper.sin((float) (Math.PI / 2)) * xScale +*/ 1.5 * horizontalScale + random.nextInt(3) + w;
double height = width * (1 + random.nextFloat() * 2) * verticalScale * 0.2;
double bubbleX = x + (random.nextFloat() * 2 - 1) * width * 1.5;
double bubbleZ = z + (random.nextFloat() * 2 - 1) * width * 1.5;
double bubbleY = y + random.nextFloat() * height * 0.5;
if (bubbleY + height < maxY) {
carveRegion(context, config, chunk, posToBiome, aquiferSampler, bubbleX, bubbleY, bubbleZ, width, height, mask, skipPredicate);
}
}
//super.carveTunnels(context, config, chunk, posToBiome, seed, aquiferSampler, x, y, z, horizontalScale, verticalScale, w, yaw, pitch, branchStartIndex, branchCount, yawPitchRatio, mask, skipPredicate);
}
}

View file

@ -0,0 +1,26 @@
{
"type": "unicopia:cloud",
"config": {
"probability": 0.05,
"y": {
"type": "minecraft:uniform",
"min_inclusive": {
"absolute": 240
},
"max_inclusive": {
"absolute": 600
}
},
"yScale": 0.15,
"lava_level": {
"above_bottom": 8
},
"replaceable": "minecraft:air",
"horizontal_radius_multiplier": 3.7,
"vertical_radius_multiplier": 2.8,
"floor_level": {
"type": "minecraft:constant",
"value": 0
}
}
}

View file

@ -28,6 +28,7 @@
"MixinFallingBlockEntity",
"MixinFlowableFluid",
"MixinGuardianTargetPredicate",
"MixinHeightmap",
"MixinItem",
"MixinItemEntity",
"MixinItemStack",