Skip to content

Commit

Permalink
add in-world oil sprouts (#1263)
Browse files Browse the repository at this point in the history
* start on oil sprouts

* add GUI overlay texture for in-world fluids

* tweak the rarity a bit
  • Loading branch information
screret committed May 23, 2024
1 parent 3d463ee commit 0d2648e
Show file tree
Hide file tree
Showing 8 changed files with 5,573 additions and 5,387 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.gregtechceu.gtceu.api.registry.registrate.forge;

import com.gregtechceu.gtceu.GTCEu;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;

public class GTClientFluidTypeExtensions implements IClientFluidTypeExtensions {
public static final ResourceLocation FLUID_SCREEN_OVERLAY = GTCEu.id("textures/misc/fluid_screen_overlay.png");

public GTClientFluidTypeExtensions(ResourceLocation stillTexture, ResourceLocation flowingTexture, int tintColor) {
this.stillTexture = stillTexture;
Expand All @@ -18,4 +21,8 @@ public GTClientFluidTypeExtensions(ResourceLocation stillTexture, ResourceLocati
@Getter @Setter
private int tintColor;

@Override
public ResourceLocation getRenderOverlayTexture(Minecraft mc) {
return FLUID_SCREEN_OVERLAY;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ public class GTConfiguredFeatures {
new StoneBlobConfiguration(OreConfiguration.target(new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), GTBlocks.RED_GRANITE.getDefaultState()), UniformInt.of(20, 30)));
public static final Holder<ConfiguredFeature<StoneBlobConfiguration, ?>> MARBLE_BLOB = FeatureUtils.register(GTCEu.MOD_ID + ":marble_blob", GTFeatures.STONE_BLOB.get(),
new StoneBlobConfiguration(OreConfiguration.target(new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), GTBlocks.MARBLE.getDefaultState()), UniformInt.of(20, 30)));
public static final Holder<ConfiguredFeature<StoneBlobConfiguration, ?>> FLUID_SPROUT = FeatureUtils.register(GTCEu.MOD_ID + ":raw_oil_sprout", GTFeatures.FLUID_SPROUT.get(),
new FluidSproutConfiguration(GTMaterials.RawOil.getFluid(), UniformInt.of(9, 13), UniformInt.of(6, 9), 0.4f));
}
23 changes: 23 additions & 0 deletions src/main/java/com/gregtechceu/gtceu/common/data/GTFeatures.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.gregtechceu.gtceu.api.data.worldgen.modifier.DimensionFilter;
import com.gregtechceu.gtceu.api.data.worldgen.modifier.FrequencyModifier;
import com.gregtechceu.gtceu.api.registry.GTRegistries;
import com.gregtechceu.gtceu.common.worldgen.feature.FluidSproutFeature;
import com.gregtechceu.gtceu.common.worldgen.feature.StoneBlobFeature;
import com.gregtechceu.gtceu.config.ConfigHolder;
import com.gregtechceu.gtceu.data.recipe.CustomTags;
Expand Down Expand Up @@ -53,6 +54,7 @@ public class GTFeatures {
public static final DeferredRegister<Feature<?>> FEATURE_REGISTER = DeferredRegister.create(Registry.FEATURE_REGISTRY, GTCEu.MOD_ID);

public static final RegistryObject<StoneBlobFeature> STONE_BLOB = FEATURE_REGISTER.register("stone_blob", StoneBlobFeature::new);
public static final RegistryObject<FluidSproutFeature> FLUID_SPROUT = FEATURE_REGISTER.register("fluid_sprout", FluidSproutFeature::new);

public static void init() {
Object inst = FrequencyModifier.FREQUENCY_MODIFIER; // seemingly useless access to init the class in time
Expand Down Expand Up @@ -133,6 +135,16 @@ public static void register() {
HeightRangePlacement.uniform(VerticalAnchor.absolute(-8), VerticalAnchor.top())
));
});
PLACED_FEATURE_REGISTER.register("raw_oil_sprout", () -> {
Registry<ConfiguredFeature<?, ?>> featureRegistry = BuiltinRegistries.ACCESS.registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY);
var holder = featureRegistry.getOrCreateHolderOrThrow(ResourceKey.create(Registry.CONFIGURED_FEATURE_REGISTRY, GTCEu.id("raw_oil_sprout")));
return new PlacedFeature(holder, List.of(
RarityFilter.onAverageOnceEvery(64),
InSquarePlacement.spread(),
BiomeFilter.biome(),
HeightRangePlacement.uniform(VerticalAnchor.absolute(10), VerticalAnchor.absolute(40))
));
});

BIOME_MODIFIER_REGISTER.register(id.getPath(), () -> {
Registry<Biome> biomeRegistry = BuiltinRegistries.ACCESS.registryOrThrow(Registry.BIOME_REGISTRY);
Expand All @@ -157,5 +169,16 @@ public static void register() {
GenerationStep.Decoration.UNDERGROUND_ORES
);
});
BIOME_MODIFIER_REGISTER.register("raw_oil_sprout", () -> {
Registry<Biome> biomeRegistry = BuiltinRegistries.ACCESS.registryOrThrow(Registry.BIOME_REGISTRY);
Registry<PlacedFeature> featureRegistry = BuiltinRegistries.ACCESS.registryOrThrow(Registry.PLACED_FEATURE_REGISTRY);
HolderSet<Biome> biomes = new HolderSet.Named<>(biomeRegistry, BiomeTags.IS_OVERWORLD);
Holder<PlacedFeature> rawOilSprout = featureRegistry.getOrCreateHolderOrThrow(ResourceKey.create(Registry.PLACED_FEATURE_REGISTRY, GTCEu.id("raw_oil_sprout")));
return new ForgeBiomeModifiers.AddFeaturesBiomeModifier(
biomes,
HolderSet.direct(rawOilSprout),
GenerationStep.Decoration.FLUID_SPRINGS
);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.gregtechceu.gtceu.common.worldgen.feature;

import com.gregtechceu.gtceu.common.worldgen.feature.configurations.FluidSproutConfiguration;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.BulkSectionAccess;
import net.minecraft.world.level.chunk.LevelChunkSection;
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.structure.templatesystem.RuleTest;
import net.minecraft.world.level.material.Fluids;
import org.apache.commons.lang3.mutable.MutableInt;

import java.util.function.Function;

public class FluidSproutFeature extends Feature<FluidSproutConfiguration> {
public FluidSproutFeature() {
super(FluidSproutConfiguration.CODEC);
}

@Override
public boolean place(FeaturePlaceContext<FluidSproutConfiguration> context) {
RandomSource random = context.random();
BlockPos blockpos = context.origin();
WorldGenLevel level = context.level();
FluidSproutConfiguration config = context.config();

MutableInt placedAmount = new MutableInt(0);
int size = config.size().sample(random);
int radius = Mth.ceil(size / 2f);
int x0 = blockpos.getX() - radius;
int y0 = blockpos.getY() - radius;
int z0 = blockpos.getZ() - radius;
int width = size + 1;
int length = size + 1;
int height = size + 1;

if (config.fluid().isSame(Fluids.EMPTY)) {
return false;
}
int surfaceHeight = level.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, blockpos.getX(), blockpos.getZ());
if (blockpos.getY() >= surfaceHeight) {
return false;
}

BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
try (BulkSectionAccess bulkSectionAccess = new BulkSectionAccess(level)) {
for (int x = 0; x < width; x++) {
float dx = x * 2f / width - 1;
if (dx * dx > 1)
continue;

for (int y = 0; y < height; y++) {
float dy = y * 2f / height - 1;
if (dx * dx + dy * dy > 1)
continue;
if (level.isOutsideBuildHeight(y0 + y))
continue;

for (int z = 0; z < length; z++) {
float dz = z * 2f / length - 1;
if (dx * dx + dy * dy + dz * dz > 1)
continue;

final int currentX = x0 + x;
final int currentY = y0 + y;
final int currentZ = z0 + z;

setBlock(mutablePos, currentX, currentY, currentZ,
bulkSectionAccess, level,
config, placedAmount);
}
}
}

if (random.nextFloat() <= config.sproutChance()) {
int currentX = blockpos.getX();
int currentZ = blockpos.getZ();

int springHeight = surfaceHeight + config.surfaceOffset().sample(random);
for (int currentY = blockpos.getY(); currentY <= springHeight; ++currentY) {
setBlock(mutablePos, currentX, currentY, currentZ,
bulkSectionAccess, level,
config, placedAmount);
if (currentY <= surfaceHeight) {
setBlock(mutablePos, currentX + 1, currentY, currentZ,
bulkSectionAccess, level,
config, placedAmount);
setBlock(mutablePos, currentX - 1, currentY, currentZ,
bulkSectionAccess, level,
config, placedAmount);
setBlock(mutablePos, currentX, currentY, currentZ + 1,
bulkSectionAccess, level,
config, placedAmount);
setBlock(mutablePos, currentX, currentY, currentZ - 1,
bulkSectionAccess, level,
config, placedAmount);
}
}
}
}

return placedAmount.getValue() > 0;
}

public void setBlock(BlockPos.MutableBlockPos mutablePos, int currentX, int currentY, int currentZ,
BulkSectionAccess access, WorldGenLevel level,
FluidSproutConfiguration config, MutableInt placedAmount) {
mutablePos.set(currentX, currentY, currentZ);
if (!level.ensureCanWrite(mutablePos))
return;
LevelChunkSection levelchunksection = access.getSection(mutablePos);
if (levelchunksection == null)
return;

int sectionX = SectionPos.sectionRelative(currentX);
int sectionY = SectionPos.sectionRelative(currentY);
int sectionZ = SectionPos.sectionRelative(currentZ);
levelchunksection.setBlockState(sectionX, sectionY, sectionZ, config.fluid().defaultFluidState().createLegacyBlock(), false);
placedAmount.add(1);
}

public boolean canPlaceFluid(BlockState state, Function<BlockPos, BlockState> adjacentStateAccessor,
RandomSource random, RuleTest target,
BlockPos.MutableBlockPos mutablePos) {
if (!target.test(state, random))
return false;

return !isAdjacentToAir(adjacentStateAccessor, mutablePos);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.gregtechceu.gtceu.common.worldgen.feature.configurations;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.util.valueproviders.IntProvider;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.material.Fluid;

public record FluidSproutConfiguration(Fluid fluid, IntProvider size, IntProvider surfaceOffset, float sproutChance) implements FeatureConfiguration {
public static final Codec<FluidSproutConfiguration> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
BuiltInRegistries.FLUID.byNameCodec().fieldOf("fluid").forGetter(FluidSproutConfiguration::fluid),
IntProvider.codec(1, 64).fieldOf("size").forGetter(FluidSproutConfiguration::size),
IntProvider.codec(0, 24).fieldOf("surface_offset").forGetter(FluidSproutConfiguration::surfaceOffset),
Codec.FLOAT.fieldOf("sprout_chance").forGetter(FluidSproutConfiguration::sproutChance)
).apply(instance, FluidSproutConfiguration::new));
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ public static void gatherData(GatherDataEvent event) {
generator.addProvider(true, new BiomeTagsLoader(generator, event.getExistingFileHelper()));
}
}
}
}
Loading

0 comments on commit 0d2648e

Please sign in to comment.