Biome generator
This commit is contained in:
parent
ce76ed9c7a
commit
8f08c310aa
14 changed files with 3173 additions and 44 deletions
|
@ -1,10 +1,15 @@
|
||||||
package ru.betterend;
|
package ru.betterend;
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import ru.betterend.registry.BiomeRegistry;
|
||||||
|
import ru.betterend.world.generator.BetterEndBiomeSource;
|
||||||
|
|
||||||
public class BetterEnd implements ModInitializer {
|
public class BetterEnd implements ModInitializer {
|
||||||
|
public static final String MOD_ID = "betterend";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
System.out.println("Hello Fabric world!");
|
BiomeRegistry.register();
|
||||||
|
BetterEndBiomeSource.register();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
104
src/main/java/ru/betterend/BlocksHelper.java
Normal file
104
src/main/java/ru/betterend/BlocksHelper.java
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
package ru.betterend;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.state.property.Property;
|
||||||
|
import net.minecraft.util.BlockMirror;
|
||||||
|
import net.minecraft.util.BlockRotation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3i;
|
||||||
|
import net.minecraft.world.WorldAccess;
|
||||||
|
|
||||||
|
public class BlocksHelper {
|
||||||
|
public static final int FLAG_UPDATE_BLOCK = 1;
|
||||||
|
public static final int FLAG_SEND_CLIENT_CHANGES = 2;
|
||||||
|
public static final int FLAG_NO_RERENDER = 4;
|
||||||
|
public static final int FORSE_RERENDER = 8;
|
||||||
|
public static final int FLAG_IGNORE_OBSERVERS = 16;
|
||||||
|
|
||||||
|
public static final int SET_SILENT = FLAG_UPDATE_BLOCK | FLAG_IGNORE_OBSERVERS | FLAG_SEND_CLIENT_CHANGES;
|
||||||
|
public static final Direction[] HORIZONTAL = new Direction[] { Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST };
|
||||||
|
|
||||||
|
private static final Vec3i[] OFFSETS = new Vec3i[] {
|
||||||
|
new Vec3i(-1, -1, -1), new Vec3i(-1, -1, 0), new Vec3i(-1, -1, 1),
|
||||||
|
new Vec3i(-1, 0, -1), new Vec3i(-1, 0, 0), new Vec3i(-1, 0, 1),
|
||||||
|
new Vec3i(-1, 1, -1), new Vec3i(-1, 1, 0), new Vec3i(-1, 1, 1),
|
||||||
|
|
||||||
|
new Vec3i(0, -1, -1), new Vec3i(0, -1, 0), new Vec3i(0, -1, 1),
|
||||||
|
new Vec3i(0, 0, -1), new Vec3i(0, 0, 0), new Vec3i(0, 0, 1),
|
||||||
|
new Vec3i(0, 1, -1), new Vec3i(0, 1, 0), new Vec3i(0, 1, 1),
|
||||||
|
|
||||||
|
new Vec3i(1, -1, -1), new Vec3i(1, -1, 0), new Vec3i(1, -1, 1),
|
||||||
|
new Vec3i(1, 0, -1), new Vec3i(1, 0, 0), new Vec3i(1, 0, 1),
|
||||||
|
new Vec3i(1, 1, -1), new Vec3i(1, 1, 0), new Vec3i(1, 1, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void setWithoutUpdate(WorldAccess world, BlockPos pos, BlockState state) {
|
||||||
|
world.setBlockState(pos, state, SET_SILENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int upRay(WorldAccess world, BlockPos pos, int maxDist) {
|
||||||
|
int length = 0;
|
||||||
|
for (int j = 1; j < maxDist && (world.isAir(pos.up(j))); j++)
|
||||||
|
length++;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int downRay(WorldAccess world, BlockPos pos, int maxDist) {
|
||||||
|
int length = 0;
|
||||||
|
for (int j = 1; j < maxDist && (world.isAir(pos.down(j))); j++)
|
||||||
|
length++;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlockState rotateHorizontal(BlockState state, BlockRotation rotation, Property<Direction> facing) {
|
||||||
|
return (BlockState) state.with(facing, rotation.rotate((Direction) state.get(facing)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlockState mirrorHorizontal(BlockState state, BlockMirror mirror, Property<Direction> facing) {
|
||||||
|
return state.rotate(mirror.getRotation((Direction) state.get(facing)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getLengthDown(ServerWorld world, BlockPos pos, Block block) {
|
||||||
|
int count = 1;
|
||||||
|
while (world.getBlockState(pos.down(count)).getBlock() == block)
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cover(WorldAccess world, BlockPos center, Block ground, BlockState cover, int radius, Random random) {
|
||||||
|
HashSet<BlockPos> points = new HashSet<BlockPos>();
|
||||||
|
HashSet<BlockPos> points2 = new HashSet<BlockPos>();
|
||||||
|
if (world.getBlockState(center).getBlock() == ground) {
|
||||||
|
points.add(center);
|
||||||
|
points2.add(center);
|
||||||
|
for (int i = 0; i < radius; i++) {
|
||||||
|
Iterator<BlockPos> iterator = points.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
BlockPos pos = iterator.next();
|
||||||
|
for (Vec3i offset : OFFSETS) {
|
||||||
|
if (random.nextBoolean()) {
|
||||||
|
BlockPos pos2 = pos.add(offset);
|
||||||
|
if (random.nextBoolean() && world.getBlockState(pos2).getBlock() == ground
|
||||||
|
&& !points.contains(pos2))
|
||||||
|
points2.add(pos2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
points.addAll(points2);
|
||||||
|
points2.clear();
|
||||||
|
}
|
||||||
|
Iterator<BlockPos> iterator = points.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
BlockPos pos = iterator.next();
|
||||||
|
BlocksHelper.setWithoutUpdate(world, pos, cover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
src/main/java/ru/betterend/MHelper.java
Normal file
51
src/main/java/ru/betterend/MHelper.java
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package ru.betterend;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class MHelper {
|
||||||
|
public static final float PI2 = (float) (Math.PI * 2);
|
||||||
|
private static final int ALPHA = 255 << 24;
|
||||||
|
public static final Random RANDOM = new Random();
|
||||||
|
|
||||||
|
public static int color(int r, int g, int b) {
|
||||||
|
return ALPHA | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int randRange(int min, int max, Random random) {
|
||||||
|
return min + random.nextInt(max - min + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float randRange(float min, float max, Random random) {
|
||||||
|
return min + random.nextFloat() * (max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte setBit(byte source, int pos, boolean value) {
|
||||||
|
return value ? setBitTrue(source, pos) : setBitFalse(source, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte setBitTrue(byte source, int pos) {
|
||||||
|
source |= 1 << pos;
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte setBitFalse(byte source, int pos) {
|
||||||
|
source &= ~(1 << pos);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean getBit(byte source, int pos) {
|
||||||
|
return ((source >> pos) & 1) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int floor(float x) {
|
||||||
|
return x < 0 ? (int) (x - 1) : (int) x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float wrap(float x, float side) {
|
||||||
|
return x - floor(x / side) * side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int floor(double x) {
|
||||||
|
return x < 0 ? (int) (x - 1) : (int) x;
|
||||||
|
}
|
||||||
|
}
|
27
src/main/java/ru/betterend/mixin/DimensionTypeMixin.java
Normal file
27
src/main/java/ru/betterend/mixin/DimensionTypeMixin.java
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package ru.betterend.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 net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
|
import net.minecraft.world.gen.chunk.NoiseChunkGenerator;
|
||||||
|
import ru.betterend.world.generator.BetterEndBiomeSource;
|
||||||
|
|
||||||
|
@Mixin(DimensionType.class)
|
||||||
|
public class DimensionTypeMixin
|
||||||
|
{
|
||||||
|
@Inject(method = "createEndGenerator", at = @At("HEAD"), cancellable = true)
|
||||||
|
private static void replaceGenerator(Registry<Biome> biomeRegistry, Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry, long seed, CallbackInfoReturnable<ChunkGenerator> info)
|
||||||
|
{
|
||||||
|
info.setReturnValue(new NoiseChunkGenerator(new BetterEndBiomeSource(biomeRegistry, seed), seed, () -> {
|
||||||
|
return (ChunkGeneratorSettings) chunkGeneratorSettingsRegistry.getOrThrow(ChunkGeneratorSettings.END);
|
||||||
|
}));
|
||||||
|
info.cancel();
|
||||||
|
}
|
||||||
|
}
|
2185
src/main/java/ru/betterend/noise/OpenSimplexNoise.java
Normal file
2185
src/main/java/ru/betterend/noise/OpenSimplexNoise.java
Normal file
File diff suppressed because it is too large
Load diff
54
src/main/java/ru/betterend/registry/BiomeRegistry.java
Normal file
54
src/main/java/ru/betterend/registry/BiomeRegistry.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package ru.betterend.registry;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import net.minecraft.util.registry.BuiltinRegistries;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.BuiltinBiomes;
|
||||||
|
import ru.betterend.world.biome.BiomeDefinition;
|
||||||
|
import ru.betterend.world.biome.EndBiome;
|
||||||
|
import ru.betterend.world.generator.BiomePicker;
|
||||||
|
|
||||||
|
public class BiomeRegistry {
|
||||||
|
private static final Map<EndBiome, RegistryKey<Biome>> KEYS = Maps.newHashMap();
|
||||||
|
public static final HashMap<Biome, EndBiome> MUTABLE = Maps.newHashMap();
|
||||||
|
|
||||||
|
public static final EndBiome END = registerBiome(BuiltinBiomes.PLAINS);
|
||||||
|
public static final EndBiome TEST = registerBiome(new EndBiome(new BiomeDefinition("test").setFogColor(255, 0, 0)));
|
||||||
|
|
||||||
|
public static void register() {}
|
||||||
|
|
||||||
|
private static EndBiome registerBiome(Biome biome) {
|
||||||
|
EndBiome endBiome = new EndBiome(biome);
|
||||||
|
BiomePicker.addBiome(endBiome);
|
||||||
|
makeLink(endBiome);
|
||||||
|
return endBiome;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EndBiome registerBiome(EndBiome biome) {
|
||||||
|
BiomePicker.addBiome(biome);
|
||||||
|
registerBiomeDirect(biome);
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void registerBiomeDirect(EndBiome biome) {
|
||||||
|
Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome());
|
||||||
|
makeLink(biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeLink(EndBiome biome) {
|
||||||
|
Optional<RegistryKey<Biome>> optional = BuiltinRegistries.BIOME.getKey(biome.getBiome());
|
||||||
|
RegistryKey<Biome> key = optional.isPresent() ? optional.get() : RegistryKey.of(Registry.BIOME_KEY, biome.getID());
|
||||||
|
KEYS.put(biome, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RegistryKey<Biome> getBiomeKey(EndBiome biome) {
|
||||||
|
return KEYS.get(biome);
|
||||||
|
}
|
||||||
|
}
|
312
src/main/java/ru/betterend/world/biome/BiomeDefinition.java
Normal file
312
src/main/java/ru/betterend/world/biome/BiomeDefinition.java
Normal file
|
@ -0,0 +1,312 @@
|
||||||
|
package ru.betterend.world.biome;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.client.sound.MusicType;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.SpawnGroup;
|
||||||
|
import net.minecraft.sound.BiomeAdditionsSound;
|
||||||
|
import net.minecraft.sound.BiomeMoodSound;
|
||||||
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.Biome.Category;
|
||||||
|
import net.minecraft.world.biome.Biome.Precipitation;
|
||||||
|
import net.minecraft.world.biome.BiomeEffects.Builder;
|
||||||
|
import net.minecraft.world.biome.BiomeParticleConfig;
|
||||||
|
import net.minecraft.world.biome.GenerationSettings;
|
||||||
|
import net.minecraft.world.biome.SpawnSettings;
|
||||||
|
import net.minecraft.world.gen.GenerationStep.Feature;
|
||||||
|
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||||
|
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||||
|
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilders;
|
||||||
|
import ru.betterend.BetterEnd;
|
||||||
|
import ru.betterend.MHelper;
|
||||||
|
|
||||||
|
public class BiomeDefinition
|
||||||
|
{
|
||||||
|
private final List<ConfiguredStructureFeature<?, ?>> structures = Lists.newArrayList();
|
||||||
|
private final List<FeatureInfo> features = Lists.newArrayList();
|
||||||
|
private final List<SpawnInfo> mobs = Lists.newArrayList();
|
||||||
|
|
||||||
|
private BiomeParticleConfig particleConfig;
|
||||||
|
private BiomeAdditionsSound additions;
|
||||||
|
private BiomeMoodSound mood;
|
||||||
|
private SoundEvent music;
|
||||||
|
private SoundEvent loop;
|
||||||
|
|
||||||
|
private int waterFogColor = 329011;
|
||||||
|
private int waterColor = 4159204;
|
||||||
|
private int fogColor = 3344392;
|
||||||
|
|
||||||
|
private boolean stalactites = true;
|
||||||
|
private boolean bnStructures = true;
|
||||||
|
|
||||||
|
private final Identifier id;
|
||||||
|
|
||||||
|
public BiomeDefinition(String name)
|
||||||
|
{
|
||||||
|
this.id = new Identifier(BetterEnd.MOD_ID, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeDefinition setStalactites(boolean value)
|
||||||
|
{
|
||||||
|
stalactites = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeDefinition setBNStructures(boolean value)
|
||||||
|
{
|
||||||
|
bnStructures = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set default ores generation
|
||||||
|
* @param value - if true (default) then default ores will be generated
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setDefaultOres(boolean value)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set default nether structure features to be added
|
||||||
|
* @param value - if true (default) then default structure features (nether fortresses, caves, etc.) will be added into biome
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setDefaultStructureFeatures(boolean value)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set default nether features to be added
|
||||||
|
* @param value - if true (default) then default features (small structures) will be added into biome
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setDefaultFeatures(boolean value)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set default Nether Wastes mobs to be added
|
||||||
|
* @param value - if true (default) then default mobs will be added into biome
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setDefaultMobs(boolean value)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeDefinition setParticleConfig(BiomeParticleConfig config)
|
||||||
|
{
|
||||||
|
this.particleConfig = config;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds mob into biome
|
||||||
|
* @param type - {@link EntityType}
|
||||||
|
* @param group - {@link SpawnGroup}
|
||||||
|
* @param weight - cumulative spawning weight
|
||||||
|
* @param minGroupSize - minimum count of mobs in the group
|
||||||
|
* @param maxGroupSize - maximum count of mobs in the group
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition addMobSpawn(EntityType<?> type, int weight, int minGroupSize, int maxGroupSize)
|
||||||
|
{
|
||||||
|
Identifier eID = Registry.ENTITY_TYPE.getId(type);
|
||||||
|
if (eID != Registry.ENTITY_TYPE.getDefaultId())
|
||||||
|
{
|
||||||
|
SpawnInfo info = new SpawnInfo();
|
||||||
|
info.type = type;
|
||||||
|
info.weight = weight;
|
||||||
|
info.minGroupSize = minGroupSize;
|
||||||
|
info.maxGroupSize = maxGroupSize;
|
||||||
|
mobs.add(info);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds feature (small structure) into biome - plants, ores, small buildings, etc.
|
||||||
|
* @param feature - {@link ConfiguredStructureFeature} to add
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition addStructureFeature(ConfiguredStructureFeature<?, ?> feature)
|
||||||
|
{
|
||||||
|
System.out.println("Structure " + feature);
|
||||||
|
structures.add(feature);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeDefinition addFeature(Feature featureStep, ConfiguredFeature<?, ?> feature)
|
||||||
|
{
|
||||||
|
FeatureInfo info = new FeatureInfo();
|
||||||
|
info.featureStep = featureStep;
|
||||||
|
info.feature = feature;
|
||||||
|
features.add(info);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets biome fog color
|
||||||
|
* @param r - Red [0 - 255]
|
||||||
|
* @param g - Green [0 - 255]
|
||||||
|
* @param b - Blue [0 - 255]
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setFogColor(int r, int g, int b)
|
||||||
|
{
|
||||||
|
r = MathHelper.clamp(r, 0, 255);
|
||||||
|
g = MathHelper.clamp(g, 0, 255);
|
||||||
|
b = MathHelper.clamp(b, 0, 255);
|
||||||
|
this.fogColor = MHelper.color(r, g, b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets biome water color
|
||||||
|
* @param r - Red [0 - 255]
|
||||||
|
* @param g - Green [0 - 255]
|
||||||
|
* @param b - Blue [0 - 255]
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setWaterColor(int r, int g, int b)
|
||||||
|
{
|
||||||
|
r = MathHelper.clamp(r, 0, 255);
|
||||||
|
g = MathHelper.clamp(g, 0, 255);
|
||||||
|
b = MathHelper.clamp(b, 0, 255);
|
||||||
|
this.waterColor = MHelper.color(r, g, b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets biome underwater fog color
|
||||||
|
* @param r - Red [0 - 255]
|
||||||
|
* @param g - Green [0 - 255]
|
||||||
|
* @param b - Blue [0 - 255]
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setWaterFogColor(int r, int g, int b)
|
||||||
|
{
|
||||||
|
r = MathHelper.clamp(r, 0, 255);
|
||||||
|
g = MathHelper.clamp(g, 0, 255);
|
||||||
|
b = MathHelper.clamp(b, 0, 255);
|
||||||
|
this.waterFogColor = MHelper.color(r, g, b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays in never-ending loop for as long as player is in the biome
|
||||||
|
* @param loop - SoundEvent
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setLoop(SoundEvent loop)
|
||||||
|
{
|
||||||
|
this.loop = loop;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays commonly while the player is in the biome
|
||||||
|
* @param mood - SoundEvent
|
||||||
|
* @return this {@link BiomeDefinition}
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setMood(SoundEvent mood)
|
||||||
|
{
|
||||||
|
this.mood = new BiomeMoodSound(mood, 6000, 8, 2.0D);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set additional sounds. They plays once every 6000-17999 ticks while the player is in the biome
|
||||||
|
* @param additions - SoundEvent
|
||||||
|
* @return this BiomeDefenition
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setAdditions(SoundEvent additions)
|
||||||
|
{
|
||||||
|
this.additions = new BiomeAdditionsSound(additions, 0.0111);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set background music for biome
|
||||||
|
* @param music
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public BiomeDefinition setMusic(SoundEvent music)
|
||||||
|
{
|
||||||
|
this.music = music;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Biome build()
|
||||||
|
{
|
||||||
|
SpawnSettings.Builder spawnSettings = new SpawnSettings.Builder();
|
||||||
|
GenerationSettings.Builder generationSettings = new GenerationSettings.Builder();
|
||||||
|
Builder effects = new Builder();
|
||||||
|
|
||||||
|
mobs.forEach((spawn) -> { spawnSettings.spawn(spawn.type.getSpawnGroup(), new SpawnSettings.SpawnEntry(spawn.type, spawn.weight, spawn.minGroupSize, spawn.maxGroupSize)); });
|
||||||
|
|
||||||
|
generationSettings.surfaceBuilder(ConfiguredSurfaceBuilders.END);
|
||||||
|
structures.forEach((structure) -> generationSettings.structureFeature(structure));
|
||||||
|
features.forEach((info) -> generationSettings.feature(info.featureStep, info.feature));
|
||||||
|
|
||||||
|
effects.skyColor(fogColor).waterColor(waterColor).waterFogColor(waterFogColor).fogColor(fogColor);
|
||||||
|
if (loop != null) effects.loopSound(loop);
|
||||||
|
if (mood != null) effects.moodSound(mood);
|
||||||
|
if (additions != null) effects.additionsSound(additions);
|
||||||
|
if (particleConfig != null) effects.particleConfig(particleConfig);
|
||||||
|
effects.music(MusicType.createIngameMusic(music != null ? music : SoundEvents.MUSIC_END));
|
||||||
|
|
||||||
|
return new Biome.Builder()
|
||||||
|
.precipitation(Precipitation.NONE)
|
||||||
|
.category(Category.THEEND)
|
||||||
|
.depth(0.1F)
|
||||||
|
.scale(0.2F)
|
||||||
|
.temperature(2.0F)
|
||||||
|
.downfall(0.0F)
|
||||||
|
.effects(effects.build())
|
||||||
|
.spawnSettings(spawnSettings.build())
|
||||||
|
.generationSettings(generationSettings.build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class SpawnInfo
|
||||||
|
{
|
||||||
|
EntityType<?> type;
|
||||||
|
int weight;
|
||||||
|
int minGroupSize;
|
||||||
|
int maxGroupSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class FeatureInfo
|
||||||
|
{
|
||||||
|
Feature featureStep;
|
||||||
|
ConfiguredFeature<?, ?> feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier getID()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasStalactites()
|
||||||
|
{
|
||||||
|
return stalactites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasBNStructures()
|
||||||
|
{
|
||||||
|
return bnStructures;
|
||||||
|
}
|
||||||
|
}
|
163
src/main/java/ru/betterend/world/biome/EndBiome.java
Normal file
163
src/main/java/ru/betterend/world/biome/EndBiome.java
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
package ru.betterend.world.biome;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.registry.BuiltinRegistries;
|
||||||
|
import net.minecraft.world.WorldAccess;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
|
||||||
|
public class EndBiome
|
||||||
|
{
|
||||||
|
protected List<Subbiome> subbiomes = Lists.newArrayList();
|
||||||
|
|
||||||
|
protected final Biome biome;
|
||||||
|
protected final Identifier mcID;
|
||||||
|
protected EndBiome edge;
|
||||||
|
protected int edgeSize;
|
||||||
|
|
||||||
|
protected EndBiome biomeParent;
|
||||||
|
protected float maxSubBiomeChance = 1;
|
||||||
|
protected float genChance = 1;
|
||||||
|
protected float noiseDensity = 0.3F;
|
||||||
|
protected float plantDensity = 1.0001F;
|
||||||
|
|
||||||
|
public EndBiome(BiomeDefinition definition)
|
||||||
|
{
|
||||||
|
biome = definition.build();
|
||||||
|
mcID = definition.getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EndBiome(Biome biome)
|
||||||
|
{
|
||||||
|
this.biome = biome;
|
||||||
|
mcID = BuiltinRegistries.BIOME.getId(biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlantDensity(float density)
|
||||||
|
{
|
||||||
|
this.plantDensity = density * 1.0001F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPlantDensity()
|
||||||
|
{
|
||||||
|
return plantDensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNoiseDensity(float density)
|
||||||
|
{
|
||||||
|
this.noiseDensity = 1 - density * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getNoiseDensity()
|
||||||
|
{
|
||||||
|
return (1F - this.noiseDensity) / 2F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void genSurfColumn(WorldAccess world, BlockPos pos, Random random) {}
|
||||||
|
|
||||||
|
public EndBiome getEdge()
|
||||||
|
{
|
||||||
|
return edge == null ? this : edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEdge(EndBiome edge)
|
||||||
|
{
|
||||||
|
this.edge = edge;
|
||||||
|
edge.biomeParent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEdgeSize()
|
||||||
|
{
|
||||||
|
return edgeSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEdgeSize(int size)
|
||||||
|
{
|
||||||
|
edgeSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSubBiome(EndBiome biome, float chance)
|
||||||
|
{
|
||||||
|
maxSubBiomeChance += chance;
|
||||||
|
biome.biomeParent = this;
|
||||||
|
subbiomes.add(new Subbiome(biome, maxSubBiomeChance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public EndBiome getSubBiome(Random random)
|
||||||
|
{
|
||||||
|
float chance = random.nextFloat() * maxSubBiomeChance;
|
||||||
|
for (Subbiome biome: subbiomes)
|
||||||
|
if (biome.canGenerate(chance))
|
||||||
|
return biome.biome;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EndBiome getParentBiome()
|
||||||
|
{
|
||||||
|
return this.biomeParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasEdge()
|
||||||
|
{
|
||||||
|
return edge != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasParentBiome()
|
||||||
|
{
|
||||||
|
return biomeParent != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSame(EndBiome biome)
|
||||||
|
{
|
||||||
|
return biome == this || (biome.hasParentBiome() && biome.getParentBiome() == this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final class Subbiome
|
||||||
|
{
|
||||||
|
EndBiome biome;
|
||||||
|
float chance;
|
||||||
|
|
||||||
|
Subbiome(EndBiome biome, float chance)
|
||||||
|
{
|
||||||
|
this.biome = biome;
|
||||||
|
this.chance = chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canGenerate(float chance)
|
||||||
|
{
|
||||||
|
return chance < this.chance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canGenerate(float chance)
|
||||||
|
{
|
||||||
|
return chance <= this.genChance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float setGenChance(float chance)
|
||||||
|
{
|
||||||
|
genChance += chance;
|
||||||
|
return genChance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Biome getBiome()
|
||||||
|
{
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return mcID.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier getID()
|
||||||
|
{
|
||||||
|
return mcID;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package ru.betterend.world.generator;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.util.registry.RegistryLookupCodec;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.source.BiomeSource;
|
||||||
|
import ru.betterend.BetterEnd;
|
||||||
|
import ru.betterend.registry.BiomeRegistry;
|
||||||
|
import ru.betterend.world.biome.EndBiome;
|
||||||
|
|
||||||
|
public class BetterEndBiomeSource extends BiomeSource {
|
||||||
|
public static final Codec<BetterEndBiomeSource> CODEC = RecordCodecBuilder.create((instance) -> {
|
||||||
|
return instance.group(RegistryLookupCodec.of(Registry.BIOME_KEY).forGetter((theEndBiomeSource) -> {
|
||||||
|
return theEndBiomeSource.biomeRegistry;
|
||||||
|
}), Codec.LONG.fieldOf("seed").stable().forGetter((theEndBiomeSource) -> {
|
||||||
|
return theEndBiomeSource.seed;
|
||||||
|
})).apply(instance, instance.stable(BetterEndBiomeSource::new));
|
||||||
|
});
|
||||||
|
private BiomeMap map;
|
||||||
|
private final long seed;
|
||||||
|
private final Registry<Biome> biomeRegistry;
|
||||||
|
|
||||||
|
public BetterEndBiomeSource(Registry<Biome> biomeRegistry, long seed) {
|
||||||
|
super(Collections.emptyList());
|
||||||
|
this.seed = seed;
|
||||||
|
this.map = new BiomeMap(seed, 50);
|
||||||
|
this.biomeRegistry = biomeRegistry;
|
||||||
|
|
||||||
|
BiomeRegistry.MUTABLE.clear();
|
||||||
|
for (EndBiome biome : BiomePicker.getBiomes())
|
||||||
|
BiomeRegistry.MUTABLE.put(biomeRegistry.getOrThrow(BiomeRegistry.getBiomeKey(biome)), biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
||||||
|
EndBiome netherBiome = map.getBiome(biomeX << 2, biomeZ << 2);
|
||||||
|
if (biomeX == 0 && biomeZ == 0) {
|
||||||
|
map.clearCache();
|
||||||
|
}
|
||||||
|
return biomeRegistry.getOrThrow(BiomeRegistry.getBiomeKey(netherBiome));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeSource withSeed(long seed) {
|
||||||
|
return new BetterEndBiomeSource(biomeRegistry, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Codec<? extends BiomeSource> getCodec() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
Registry.register(Registry.BIOME_SOURCE, new Identifier(BetterEnd.MOD_ID, "better_end_biome_source"), CODEC);
|
||||||
|
}
|
||||||
|
}
|
39
src/main/java/ru/betterend/world/generator/BiomeChunk.java
Normal file
39
src/main/java/ru/betterend/world/generator/BiomeChunk.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package ru.betterend.world.generator;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import ru.betterend.world.biome.EndBiome;
|
||||||
|
|
||||||
|
public class BiomeChunk
|
||||||
|
{
|
||||||
|
protected static final int WIDTH = 16;
|
||||||
|
private static final int SM_WIDTH = WIDTH >> 1;
|
||||||
|
private static final int MASK_A = SM_WIDTH - 1;
|
||||||
|
private static final int MASK_C = WIDTH - 1;
|
||||||
|
|
||||||
|
private final EndBiome[][] biomes;
|
||||||
|
|
||||||
|
public BiomeChunk(BiomeMap map, Random random)
|
||||||
|
{
|
||||||
|
EndBiome[][] PreBio = new EndBiome[SM_WIDTH][SM_WIDTH];
|
||||||
|
biomes = new EndBiome[WIDTH][WIDTH];
|
||||||
|
|
||||||
|
for (int x = 0; x < SM_WIDTH; x++)
|
||||||
|
for (int z = 0; z < SM_WIDTH; z++)
|
||||||
|
PreBio[x][z] = BiomePicker.getBiome(random);
|
||||||
|
|
||||||
|
for (int x = 0; x < WIDTH; x++)
|
||||||
|
for (int z = 0; z < WIDTH; z++)
|
||||||
|
biomes[x][z] = PreBio[offsetXZ(x, random)][offsetXZ(z, random)].getSubBiome(random);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EndBiome getBiome(int x, int z)
|
||||||
|
{
|
||||||
|
return biomes[x & MASK_C][z & MASK_C];
|
||||||
|
}
|
||||||
|
|
||||||
|
private int offsetXZ(int x, Random random)
|
||||||
|
{
|
||||||
|
return ((x + random.nextInt(2)) >> 1) & MASK_A;
|
||||||
|
}
|
||||||
|
}
|
100
src/main/java/ru/betterend/world/generator/BiomeMap.java
Normal file
100
src/main/java/ru/betterend/world/generator/BiomeMap.java
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
package ru.betterend.world.generator;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.ChunkPos;
|
||||||
|
import net.minecraft.world.gen.ChunkRandom;
|
||||||
|
import ru.betterend.MHelper;
|
||||||
|
import ru.betterend.noise.OpenSimplexNoise;
|
||||||
|
import ru.betterend.world.biome.EndBiome;
|
||||||
|
|
||||||
|
public class BiomeMap
|
||||||
|
{
|
||||||
|
private static final HashMap<ChunkPos, BiomeChunk> MAPS = new HashMap<ChunkPos, BiomeChunk>();
|
||||||
|
private static final ChunkRandom RANDOM = new ChunkRandom();
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
private final int sizeXZ;
|
||||||
|
private final int depth;
|
||||||
|
private final OpenSimplexNoise noiseX;;
|
||||||
|
private final OpenSimplexNoise noiseZ;
|
||||||
|
|
||||||
|
public BiomeMap(long seed, int size)
|
||||||
|
{
|
||||||
|
RANDOM.setSeed(seed);
|
||||||
|
noiseX = new OpenSimplexNoise(RANDOM.nextLong());
|
||||||
|
noiseZ = new OpenSimplexNoise(RANDOM.nextLong());
|
||||||
|
this.sizeXZ = size;
|
||||||
|
depth = (int) Math.ceil(Math.log(size) / Math.log(2)) - 2;
|
||||||
|
this.size = 1 << depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearCache()
|
||||||
|
{
|
||||||
|
if (MAPS.size() > 16)
|
||||||
|
MAPS.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private EndBiome getRawBiome(int bx, int bz)
|
||||||
|
{
|
||||||
|
double x = (double) bx * size / sizeXZ;
|
||||||
|
double z = (double) bz * size / sizeXZ;
|
||||||
|
double nx = x;
|
||||||
|
double nz = z;
|
||||||
|
|
||||||
|
double px = bx * 0.2;
|
||||||
|
double pz = bz * 0.2;
|
||||||
|
|
||||||
|
for (int i = 0; i < depth; i++)
|
||||||
|
{
|
||||||
|
nx = (x + noiseX.eval(px, pz)) / 2F;
|
||||||
|
nz = (z + noiseZ.eval(px, pz)) / 2F;
|
||||||
|
|
||||||
|
x = nx;
|
||||||
|
z = nz;
|
||||||
|
|
||||||
|
px = px / 2 + i;
|
||||||
|
pz = pz / 2 + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChunkPos cpos = new ChunkPos(MHelper.floor((double) x / BiomeChunk.WIDTH), MHelper.floor((double) z / BiomeChunk.WIDTH));
|
||||||
|
BiomeChunk chunk = MAPS.get(cpos);
|
||||||
|
if (chunk == null)
|
||||||
|
{
|
||||||
|
RANDOM.setTerrainSeed(cpos.x, cpos.z);
|
||||||
|
chunk = new BiomeChunk(this, RANDOM);
|
||||||
|
MAPS.put(cpos, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunk.getBiome(MHelper.floor(x), MHelper.floor(z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public EndBiome getBiome(int x, int z)
|
||||||
|
{
|
||||||
|
EndBiome biome = getRawBiome(x, z);
|
||||||
|
|
||||||
|
if (biome.hasEdge() || (biome.hasParentBiome() && biome.getParentBiome().hasEdge()))
|
||||||
|
{
|
||||||
|
EndBiome search = biome;
|
||||||
|
if (biome.hasParentBiome())
|
||||||
|
search = biome.getParentBiome();
|
||||||
|
int d = (int) Math.ceil(search.getEdgeSize() / 4F) << 2;
|
||||||
|
|
||||||
|
boolean edge = !search.isSame(getRawBiome(x + d, z));
|
||||||
|
edge = edge || !search.isSame(getRawBiome(x - d, z));
|
||||||
|
edge = edge || !search.isSame(getRawBiome(x, z + d));
|
||||||
|
edge = edge || !search.isSame(getRawBiome(x, z - d));
|
||||||
|
edge = edge || !search.isSame(getRawBiome(x - 1, z - 1));
|
||||||
|
edge = edge || !search.isSame(getRawBiome(x - 1, z + 1));
|
||||||
|
edge = edge || !search.isSame(getRawBiome(x + 1, z - 1));
|
||||||
|
edge = edge || !search.isSame(getRawBiome(x + 1, z + 1));
|
||||||
|
|
||||||
|
if (edge)
|
||||||
|
{
|
||||||
|
biome = search.getEdge();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
}
|
30
src/main/java/ru/betterend/world/generator/BiomePicker.java
Normal file
30
src/main/java/ru/betterend/world/generator/BiomePicker.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package ru.betterend.world.generator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import ru.betterend.world.biome.EndBiome;
|
||||||
|
|
||||||
|
public class BiomePicker {
|
||||||
|
private static final List<EndBiome> BIOMES = Lists.newArrayList();
|
||||||
|
private static float maxChance = 0;
|
||||||
|
|
||||||
|
public static void addBiome(EndBiome biome) {
|
||||||
|
BIOMES.add(biome);
|
||||||
|
maxChance = biome.setGenChance(maxChance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EndBiome getBiome(Random random) {
|
||||||
|
float chance = random.nextFloat() * maxChance;
|
||||||
|
for (EndBiome biome: BIOMES)
|
||||||
|
if (biome.canGenerate(chance))
|
||||||
|
return biome;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<EndBiome> getBiomes() {
|
||||||
|
return BIOMES;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "ru.betternd.mixin",
|
"package": "ru.betterend.mixin",
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
],
|
"DimensionTypeMixin"
|
||||||
"client": [
|
],
|
||||||
],
|
"client": [],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,35 @@
|
||||||
{
|
{
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "betterend",
|
"id": "betterend",
|
||||||
"version": "${version}",
|
"version": "${version}",
|
||||||
|
|
||||||
"name": "Better End",
|
"name": "Better End",
|
||||||
"description": "More content for The End",
|
"description": "More content for The End",
|
||||||
"authors": [
|
"authors": [
|
||||||
"paulevs",
|
"paulevs",
|
||||||
"Bulldog83"
|
"Bulldog83"
|
||||||
],
|
],
|
||||||
"contact": {
|
"contact": {
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
"sources": ""
|
"sources": ""
|
||||||
},
|
},
|
||||||
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/modid/icon.png",
|
"icon": "assets/modid/icon.png",
|
||||||
|
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": [
|
"main": [
|
||||||
"ru.betterend.BetterEnd"
|
"ru.betterend.BetterEnd"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"betterend.mixins.json"
|
"betterend.mixins.json"
|
||||||
],
|
],
|
||||||
|
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.7.4",
|
"fabricloader": ">=0.7.4",
|
||||||
"fabric": "*",
|
"fabric": "*",
|
||||||
"minecraft": "1.16.x"
|
"minecraft": "1.16.x"
|
||||||
},
|
}
|
||||||
"suggests": {
|
|
||||||
"flamingo": "*"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue