commit
ff7eda1287
97 changed files with 1287 additions and 1138 deletions
|
@ -13,6 +13,7 @@ import ru.bclib.api.dataexchange.handler.autosync.RequestFiles;
|
|||
import ru.bclib.api.dataexchange.handler.autosync.SendFiles;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.recipes.AnvilRecipe;
|
||||
import ru.bclib.recipes.CraftingRecipes;
|
||||
import ru.bclib.registry.BaseBlockEntities;
|
||||
import ru.bclib.registry.BaseRegistry;
|
||||
|
@ -38,6 +39,7 @@ public class BCLib implements ModInitializer {
|
|||
CraftingRecipes.init();
|
||||
WorldDataAPI.registerModCache(MOD_ID);
|
||||
DataExchangeAPI.registerMod(MOD_ID);
|
||||
AnvilRecipe.register();
|
||||
|
||||
DataExchangeAPI.registerDescriptors(List.of(
|
||||
HelloClient.DESCRIPTOR,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ru.bclib.api;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
@ -49,7 +50,7 @@ public class LifeCycleAPI {
|
|||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
ServerLevelData serverLevelData,
|
||||
ResourceKey<Level> resourceKey,
|
||||
DimensionType dimensionType,
|
||||
Holder<DimensionType> dimensionType,
|
||||
ChunkProgressListener chunkProgressListener,
|
||||
ChunkGenerator chunkGenerator,
|
||||
boolean bl,
|
||||
|
@ -114,7 +115,7 @@ public class LifeCycleAPI {
|
|||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
ServerLevelData serverLevelData,
|
||||
ResourceKey<Level> resourceKey,
|
||||
DimensionType dimensionType,
|
||||
Holder<DimensionType> dimensionType,
|
||||
ChunkProgressListener chunkProgressListener,
|
||||
ChunkGenerator chunkGenerator,
|
||||
boolean bl,
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.world.item.Item;
|
|||
import net.minecraft.world.level.block.Block;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.biomes.BiomeAPI;
|
||||
import ru.bclib.api.tag.NamedMineableTags;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
import ru.bclib.api.tag.TagAPI.TagLocation;
|
||||
import ru.bclib.blocks.BaseBarrelBlock;
|
||||
|
@ -23,6 +24,7 @@ import ru.bclib.config.Configs;
|
|||
import ru.bclib.interfaces.PostInitable;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.interfaces.TagProvider;
|
||||
import ru.bclib.interfaces.tools.*;
|
||||
import ru.bclib.registry.BaseBlockEntities;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -111,6 +113,29 @@ public class PostInitAPI {
|
|||
else if (block instanceof BaseFurnaceBlock) {
|
||||
BaseBlockEntities.FURNACE.registerBlock(block);
|
||||
}
|
||||
if (!(block instanceof PreventMineableAdd)) {
|
||||
if (block instanceof AddMineableShears) {
|
||||
TagAPI.addBlockTags(block, NamedMineableTags.SHEARS);
|
||||
}
|
||||
if (block instanceof AddMineableAxe) {
|
||||
TagAPI.addBlockTags(block, NamedMineableTags.AXE);
|
||||
}
|
||||
if (block instanceof AddMineablePickaxe) {
|
||||
TagAPI.addBlockTags(block, NamedMineableTags.PICKAXE);
|
||||
}
|
||||
if (block instanceof AddMineableShovel) {
|
||||
TagAPI.addBlockTags(block, NamedMineableTags.SHOVEL);
|
||||
}
|
||||
if (block instanceof AddMineableHoe) {
|
||||
TagAPI.addBlockTags(block, NamedMineableTags.HOE);
|
||||
}
|
||||
if (block instanceof AddMineableSword) {
|
||||
TagAPI.addBlockTags(block, NamedMineableTags.SWORD);
|
||||
}
|
||||
if (block instanceof AddMineableHammer) {
|
||||
TagAPI.addBlockTags(block, NamedMineableTags.HAMMER);
|
||||
}
|
||||
}
|
||||
if (block instanceof TagProvider) {
|
||||
TagProvider.class.cast(block).addTags(blockTags, itemTags);
|
||||
blockTags.forEach(tag -> TagAPI.addBlockTag(tag, block));
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
package ru.bclib.api.biomes;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.data.worldgen.BiomeDefaultFeatures;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.Music;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.level.biome.AmbientAdditionsSettings;
|
||||
import net.minecraft.world.level.biome.AmbientMoodSettings;
|
||||
import net.minecraft.world.level.biome.AmbientParticleSettings;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.*;
|
||||
import net.minecraft.world.level.biome.Biome.BiomeBuilder;
|
||||
import net.minecraft.world.level.biome.Biome.BiomeCategory;
|
||||
import net.minecraft.world.level.biome.Biome.Precipitation;
|
||||
import net.minecraft.world.level.biome.BiomeGenerationSettings;
|
||||
import net.minecraft.world.level.biome.BiomeSpecialEffects;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -28,12 +27,13 @@ import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
|||
import net.minecraft.world.level.levelgen.Noises;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules;
|
||||
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import ru.bclib.api.surface.SurfaceRuleBuilder;
|
||||
import ru.bclib.entity.BCLEntityWrapper;
|
||||
import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor;
|
||||
import ru.bclib.util.CollectionsUtil;
|
||||
import ru.bclib.util.ColorUtil;
|
||||
import ru.bclib.util.Pair;
|
||||
import ru.bclib.util.TriFunction;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
import ru.bclib.world.biomes.BCLBiomeSettings;
|
||||
|
@ -41,12 +41,10 @@ import ru.bclib.world.features.BCLFeature;
|
|||
import ru.bclib.world.structures.BCLStructureFeature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BCLBiomeBuilder {
|
||||
|
@ -57,7 +55,8 @@ public class BCLBiomeBuilder {
|
|||
private static final BCLBiomeBuilder INSTANCE = new BCLBiomeBuilder();
|
||||
private static final SurfaceRules.ConditionSource SURFACE_NOISE = SurfaceRules.noiseCondition(Noises.SOUL_SAND_LAYER, -0.012);
|
||||
|
||||
private List<ConfiguredStructureFeature> structures = new ArrayList<>(16);
|
||||
private List<TagKey<Biome>> structureTags = new ArrayList<>(8);
|
||||
private List<Pair<GenerationStep.Carving, Holder<? extends ConfiguredWorldCarver<?>>>> carvers = new ArrayList<>(1);
|
||||
private BiomeGenerationSettings.Builder generationSettings;
|
||||
private BiomeSpecialEffects.Builder effectsBuilder;
|
||||
private MobSpawnSettings.Builder spawnSettings;
|
||||
|
@ -87,7 +86,7 @@ public class BCLBiomeBuilder {
|
|||
INSTANCE.generationSettings = null;
|
||||
INSTANCE.effectsBuilder = null;
|
||||
INSTANCE.spawnSettings = null;
|
||||
INSTANCE.structures.clear();
|
||||
INSTANCE.structureTags.clear();
|
||||
INSTANCE.temperature = 1.0F;
|
||||
INSTANCE.fogDensity = 1.0F;
|
||||
INSTANCE.edgeSize = 0;
|
||||
|
@ -96,6 +95,7 @@ public class BCLBiomeBuilder {
|
|||
INSTANCE.height = 0.1F;
|
||||
INSTANCE.vertical = false;
|
||||
INSTANCE.edge = null;
|
||||
INSTANCE.carvers.clear();
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
@ -500,7 +500,7 @@ public class BCLBiomeBuilder {
|
|||
* @param feature {@link PlacedFeature}.
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder feature(Decoration decoration, PlacedFeature feature) {
|
||||
public BCLBiomeBuilder feature(Decoration decoration, Holder<PlacedFeature> feature) {
|
||||
getGeneration().addFeature(decoration, feature);
|
||||
return this;
|
||||
}
|
||||
|
@ -542,11 +542,11 @@ public class BCLBiomeBuilder {
|
|||
|
||||
/**
|
||||
* Adds new structure feature into the biome.
|
||||
* @param structure {@link ConfiguredStructureFeature} to add.
|
||||
* @param structureTag {@link TagKey} to add.
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder structure(ConfiguredStructureFeature<?, ?> structure) {
|
||||
structures.add(structure);
|
||||
public BCLBiomeBuilder structure(TagKey<Biome> structureTag) {
|
||||
structureTags.add(structureTag);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ public class BCLBiomeBuilder {
|
|||
*/
|
||||
public BCLBiomeBuilder structure(BCLStructureFeature structure) {
|
||||
structure.addInternalBiome(biomeID);
|
||||
return structure(structure.getFeatureConfigured());
|
||||
return structure(structure.biomeTag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -565,11 +565,13 @@ public class BCLBiomeBuilder {
|
|||
* @param carver {@link ConfiguredWorldCarver} to add.
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder carver(GenerationStep.Carving step, ConfiguredWorldCarver<?> carver) {
|
||||
public BCLBiomeBuilder carver(GenerationStep.Carving step, Holder<? extends ConfiguredWorldCarver<?>> carver) {
|
||||
final ResourceLocation immutableID = biomeID;
|
||||
BuiltinRegistries.CONFIGURED_CARVER
|
||||
.getResourceKey(carver)
|
||||
.ifPresent(key -> BiomeModifications.addCarver(ctx -> ctx.getBiomeKey().location().equals(immutableID), step, key));
|
||||
var oKey = carver.unwrapKey();
|
||||
if (oKey.isPresent()) {
|
||||
BiomeModifications.addCarver(ctx -> ctx.getBiomeKey().location().equals(immutableID), step, (ResourceKey<ConfiguredWorldCarver<?>>) oKey.get());
|
||||
}
|
||||
//carvers.add(new Pair<>(step, carver));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -625,8 +627,8 @@ public class BCLBiomeBuilder {
|
|||
this.height = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Make this a vertical Biome
|
||||
|
@ -645,7 +647,7 @@ public class BCLBiomeBuilder {
|
|||
public BCLBiome build() {
|
||||
return build((BiomeSupplier<BCLBiome>)BCLBiome::new);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalize biome creation.
|
||||
* @param biomeConstructor {@link BiFunction} biome constructor.
|
||||
|
@ -655,7 +657,22 @@ public class BCLBiomeBuilder {
|
|||
public <T extends BCLBiome> T build(BiFunction<ResourceLocation, Biome, T> biomeConstructor) {
|
||||
return build((id, biome, settings)->biomeConstructor.apply(id, biome));
|
||||
}
|
||||
|
||||
|
||||
private static BiomeGenerationSettings fixGenerationSettings(BiomeGenerationSettings settings){
|
||||
//Fabric Biome Modification API can not handle an empty carver map, thus we will create one with
|
||||
//an empty HolderSet for every possible step:
|
||||
//https://github.com/FabricMC/fabric/issues/2079
|
||||
//TODO: Remove, once fabric gets fixed
|
||||
if (settings instanceof BiomeGenerationSettingsAccessor acc){
|
||||
Map<GenerationStep.Carving, HolderSet<ConfiguredWorldCarver<?>>> carvers = CollectionsUtil.getMutable(acc.bclib_getCarvers());
|
||||
for (GenerationStep.Carving step : GenerationStep.Carving.values()){
|
||||
carvers.computeIfAbsent(step, __->HolderSet.direct(Lists.newArrayList()));
|
||||
}
|
||||
acc.bclib_setCarvers(carvers);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize biome creation.
|
||||
* @param biomeConstructor {@link BiomeSupplier} biome constructor.
|
||||
|
@ -670,26 +687,8 @@ public class BCLBiomeBuilder {
|
|||
|
||||
builder.mobSpawnSettings(getSpawns().build());
|
||||
builder.specialEffects(getEffects().build());
|
||||
|
||||
Map<Decoration, List<Supplier<PlacedFeature>>> defferedFeatures = new HashMap<>();
|
||||
BiomeGenerationSettingsAccessor acc = BiomeGenerationSettingsAccessor.class.cast(getGeneration().build());
|
||||
if (acc != null) {
|
||||
builder.generationSettings(new BiomeGenerationSettings.Builder().build());
|
||||
var decorations = acc.bclib_getFeatures();
|
||||
for (Decoration d : Decoration.values()) {
|
||||
int i = d.ordinal();
|
||||
if (i >= 0 && i < decorations.size()) {
|
||||
var features = decorations.get(i);
|
||||
defferedFeatures.put(d, features.stream().collect(Collectors.toList()));
|
||||
}
|
||||
else {
|
||||
defferedFeatures.put(d, new ArrayList<>(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
builder.generationSettings(getGeneration().build());
|
||||
}
|
||||
|
||||
builder.generationSettings(fixGenerationSettings(getGeneration().build()));
|
||||
|
||||
BCLBiomeSettings settings = BCLBiomeSettings.createBCL()
|
||||
.setTerrainHeight(height)
|
||||
|
@ -699,11 +698,13 @@ public class BCLBiomeBuilder {
|
|||
.setEdge(edge)
|
||||
.setVertical(vertical)
|
||||
.build();
|
||||
|
||||
final T res = biomeConstructor.apply(biomeID, builder.build(), settings);
|
||||
res.attachStructures(structures);
|
||||
|
||||
final Biome biome = builder.build();
|
||||
final T res = biomeConstructor.apply(biomeID, biome, settings);
|
||||
res.attachStructures(structureTags);
|
||||
res.setSurface(surfaceRule);
|
||||
res.setFeatures(defferedFeatures);
|
||||
|
||||
//carvers.forEach(cfg -> BiomeAPI.addBiomeCarver(biome, cfg.second, cfg.first));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
package ru.bclib.api.biomes;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.impl.biome.NetherBiomeData;
|
||||
import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
|
||||
import net.fabricmc.fabric.impl.structure.FabricStructureImpl;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
@ -26,11 +25,7 @@ import net.minecraft.world.entity.MobCategory;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeGenerationSettings;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.biome.*;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -41,27 +36,21 @@ import net.minecraft.world.level.levelgen.GenerationStep.Carving;
|
|||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.StructureSettings;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
|
||||
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.StructureFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.entity.BCLEntityWrapper;
|
||||
import ru.bclib.interfaces.BiomeSourceAccessor;
|
||||
import ru.bclib.interfaces.NoiseGeneratorSettingsProvider;
|
||||
import ru.bclib.interfaces.SurfaceMaterialProvider;
|
||||
import ru.bclib.interfaces.SurfaceProvider;
|
||||
import ru.bclib.interfaces.SurfaceRuleProvider;
|
||||
import ru.bclib.interfaces.*;
|
||||
import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor;
|
||||
import ru.bclib.mixin.common.MobSpawnSettingsAccessor;
|
||||
import ru.bclib.mixin.common.StructureSettingsAccessor;
|
||||
import ru.bclib.util.CollectionsUtil;
|
||||
import ru.bclib.util.MHelper;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
|
@ -69,18 +58,9 @@ import ru.bclib.world.biomes.FabricBiomesData;
|
|||
import ru.bclib.world.biomes.VanillaBiomeSettings;
|
||||
import ru.bclib.world.features.BCLFeature;
|
||||
import ru.bclib.world.generator.BiomePicker;
|
||||
import ru.bclib.world.structures.BCLStructureFeature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -100,27 +80,26 @@ public class BiomeAPI {
|
|||
private static final Map<Biome, BCLBiome> CLIENT = Maps.newHashMap();
|
||||
private static Registry<Biome> biomeRegistry;
|
||||
|
||||
private static final Map<PlacedFeature, Integer> FEATURE_ORDER = Maps.newHashMap();
|
||||
private static final Map<Holder<PlacedFeature>, Integer> FEATURE_ORDER = Maps.newHashMap();
|
||||
private static final MutableInt FEATURE_ORDER_ID = new MutableInt(0);
|
||||
|
||||
private final static Map<StructureID, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>>> STRUCTURE_STARTS = new HashMap<>();
|
||||
private static final Map<ResourceKey, List<BiConsumer<ResourceLocation, Biome>>> MODIFICATIONS = Maps.newHashMap();
|
||||
|
||||
private static final Map<ResourceKey, List<BiConsumer<ResourceLocation, Holder<Biome>>>> MODIFICATIONS = Maps.newHashMap();
|
||||
private static final Map<ResourceLocation, SurfaceRules.RuleSource> SURFACE_RULES = Maps.newHashMap();
|
||||
private static final Set<SurfaceRuleProvider> MODIFIED_SURFACE_PROVIDERS = new HashSet<>(8);
|
||||
|
||||
public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES));
|
||||
public static final BCLBiome CRIMSON_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.CRIMSON_FOREST));
|
||||
public static final BCLBiome WARPED_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.WARPED_FOREST));
|
||||
public static final BCLBiome SOUL_SAND_VALLEY_BIOME = registerNetherBiome(getFromRegistry(Biomes.SOUL_SAND_VALLEY));
|
||||
public static final BCLBiome BASALT_DELTAS_BIOME = registerNetherBiome(getFromRegistry(Biomes.BASALT_DELTAS));
|
||||
public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES).value());
|
||||
public static final BCLBiome CRIMSON_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.CRIMSON_FOREST).value());
|
||||
public static final BCLBiome WARPED_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.WARPED_FOREST).value());
|
||||
public static final BCLBiome SOUL_SAND_VALLEY_BIOME = registerNetherBiome(getFromRegistry(Biomes.SOUL_SAND_VALLEY).value());
|
||||
public static final BCLBiome BASALT_DELTAS_BIOME = registerNetherBiome(getFromRegistry(Biomes.BASALT_DELTAS).value());
|
||||
|
||||
public static final BCLBiome THE_END = registerEndLandBiome(getFromRegistry(Biomes.THE_END));
|
||||
public static final BCLBiome END_MIDLANDS = registerSubBiome(THE_END, getFromRegistry(Biomes.END_MIDLANDS), 0.5F);
|
||||
public static final BCLBiome END_HIGHLANDS = registerSubBiome(THE_END, getFromRegistry(Biomes.END_HIGHLANDS), 0.5F);
|
||||
public static final BCLBiome END_MIDLANDS = registerSubBiome(THE_END, getFromRegistry(Biomes.END_MIDLANDS).value(), 0.5F);
|
||||
public static final BCLBiome END_HIGHLANDS = registerSubBiome(THE_END, getFromRegistry(Biomes.END_HIGHLANDS).value(), 0.5F);
|
||||
|
||||
public static final BCLBiome END_BARRENS = registerEndVoidBiome(getFromRegistry(new ResourceLocation("end_barrens")));
|
||||
public static final BCLBiome SMALL_END_ISLANDS = registerEndVoidBiome(getFromRegistry(new ResourceLocation("small_end_islands")));
|
||||
|
||||
|
||||
private static void initFeatureOrder() {
|
||||
if (!FEATURE_ORDER.isEmpty()) {
|
||||
return;
|
||||
|
@ -137,8 +116,7 @@ public class BiomeAPI {
|
|||
.map(Entry::getValue)
|
||||
.map(biome -> (BiomeGenerationSettingsAccessor) biome.getGenerationSettings())
|
||||
.map(BiomeGenerationSettingsAccessor::bclib_getFeatures)
|
||||
.forEach(stepFeatureSuppliers -> stepFeatureSuppliers.forEach(step -> step.forEach(featureSupplier -> {
|
||||
PlacedFeature feature = featureSupplier.get();
|
||||
.forEach(stepFeatureSuppliers -> stepFeatureSuppliers.forEach(step -> step.forEach(feature -> {
|
||||
FEATURE_ORDER.computeIfAbsent(feature, f -> FEATURE_ORDER_ID.getAndIncrement());
|
||||
})));
|
||||
}
|
||||
|
@ -161,23 +139,23 @@ public class BiomeAPI {
|
|||
* called from {@link ru.bclib.mixin.client.MinecraftMixin}
|
||||
*/
|
||||
public static void prepareNewLevel(){
|
||||
STRUCTURE_STARTS.clear();
|
||||
|
||||
MODIFIED_SURFACE_PROVIDERS.forEach(p->p.bclib_clearBiomeSources());
|
||||
MODIFIED_SURFACE_PROVIDERS.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
|
||||
* @param biome {@link BCLBiome}
|
||||
* @param bclbiome {@link BCLBiome}
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome registerBiome(BCLBiome biome) {
|
||||
if (BuiltinRegistries.BIOME.get(biome.getID()) == null) {
|
||||
Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome());
|
||||
public static BCLBiome registerBiome(BCLBiome bclbiome) {
|
||||
if (BuiltinRegistries.BIOME.get(bclbiome.getID()) == null) {
|
||||
final Biome biome = bclbiome.getBiome();
|
||||
ResourceLocation loc = bclbiome.getID();
|
||||
Registry.register(BuiltinRegistries.BIOME, loc, biome);
|
||||
}
|
||||
ID_MAP.put(biome.getID(), biome);
|
||||
return biome;
|
||||
ID_MAP.put(bclbiome.getID(), bclbiome);
|
||||
return bclbiome;
|
||||
}
|
||||
|
||||
public static BCLBiome registerSubBiome(BCLBiome parent, BCLBiome subBiome) {
|
||||
|
@ -212,7 +190,7 @@ public class BiomeAPI {
|
|||
MHelper.randRange(-1.5F, 1.5F, random),
|
||||
random.nextFloat()
|
||||
);
|
||||
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).orElseThrow();
|
||||
ResourceKey<Biome> key = BiomeAPI.getBiomeKeyOrThrow(biome.getBiomeHolder());
|
||||
NetherBiomeData.addNetherBiome(key, parameters);
|
||||
return biome;
|
||||
}
|
||||
|
@ -242,7 +220,7 @@ public class BiomeAPI {
|
|||
|
||||
END_LAND_BIOME_PICKER.addBiome(biome);
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).orElseThrow();
|
||||
ResourceKey<Biome> key = BiomeAPI.getBiomeKey(biome.getBiome());
|
||||
TheEndBiomeData.addEndBiomeReplacement(Biomes.END_HIGHLANDS, key, weight);
|
||||
TheEndBiomeData.addEndBiomeReplacement(Biomes.END_MIDLANDS, key, weight);
|
||||
return biome;
|
||||
|
@ -254,8 +232,8 @@ public class BiomeAPI {
|
|||
* @param biome {@link BCLBiome}
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome registerEndLandBiome(Biome biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome, null);
|
||||
public static BCLBiome registerEndLandBiome(Holder<Biome> biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
|
||||
|
||||
END_LAND_BIOME_PICKER.addBiome(bclBiome);
|
||||
registerBiome(bclBiome);
|
||||
|
@ -269,8 +247,8 @@ public class BiomeAPI {
|
|||
* @param genChance float generation chance.
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome registerEndLandBiome(Biome biome, float genChance) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome, VanillaBiomeSettings.createVanilla().setGenChance(genChance).build());
|
||||
public static BCLBiome registerEndLandBiome(Holder<Biome> biome, float genChance) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), VanillaBiomeSettings.createVanilla().setGenChance(genChance).build());
|
||||
|
||||
END_LAND_BIOME_PICKER.addBiome(bclBiome);
|
||||
registerBiome(bclBiome);
|
||||
|
@ -288,7 +266,7 @@ public class BiomeAPI {
|
|||
|
||||
END_VOID_BIOME_PICKER.addBiome(biome);
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).orElseThrow();
|
||||
ResourceKey<Biome> key = BiomeAPI.getBiomeKeyOrThrow(biome.getBiomeHolder());
|
||||
TheEndBiomeData.addEndBiomeReplacement(Biomes.SMALL_END_ISLANDS, key, weight);
|
||||
return biome;
|
||||
}
|
||||
|
@ -299,8 +277,8 @@ public class BiomeAPI {
|
|||
* @param biome {@link BCLBiome}
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome registerEndVoidBiome(Biome biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome, null);
|
||||
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
|
||||
|
||||
END_VOID_BIOME_PICKER.addBiome(bclBiome);
|
||||
registerBiome(bclBiome);
|
||||
|
@ -314,8 +292,8 @@ public class BiomeAPI {
|
|||
* @param genChance float generation chance.
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome registerEndVoidBiome(Biome biome, float genChance) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome, VanillaBiomeSettings.createVanilla().setGenChance(genChance).build());
|
||||
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome, float genChance) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), VanillaBiomeSettings.createVanilla().setGenChance(genChance).build());
|
||||
|
||||
END_VOID_BIOME_PICKER.addBiome(bclBiome);
|
||||
registerBiome(bclBiome);
|
||||
|
@ -324,14 +302,14 @@ public class BiomeAPI {
|
|||
|
||||
/**
|
||||
* Get {@link BCLBiome} from {@link Biome} instance on server. Used to convert world biomes to BCLBiomes.
|
||||
* @param biome - {@link Biome} from world.
|
||||
* @param biome - {@link Holder<Biome>} from world.
|
||||
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
|
||||
*/
|
||||
public static BCLBiome getFromBiome(Biome biome) {
|
||||
public static BCLBiome getFromBiome(Holder<Biome> biome) {
|
||||
if (biomeRegistry == null) {
|
||||
return EMPTY_BIOME;
|
||||
}
|
||||
return ID_MAP.getOrDefault(biomeRegistry.getKey(biome), EMPTY_BIOME);
|
||||
return ID_MAP.getOrDefault(biome.unwrapKey().orElseThrow().location(), EMPTY_BIOME);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -375,6 +353,27 @@ public class BiomeAPI {
|
|||
}
|
||||
return id == null ? EMPTY_BIOME.getID() : id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get biome {@link ResourceLocation} from given {@link Biome}.
|
||||
* @param biome - {@link Holder<Biome>} from server world.
|
||||
* @return biome {@link ResourceLocation}.
|
||||
*/
|
||||
public static ResourceLocation getBiomeID(Holder<Biome> biome) {
|
||||
var oKey = biome.unwrapKey();
|
||||
if (oKey.isPresent()){
|
||||
return oKey.get().location();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ResourceKey getBiomeKey(Holder<Biome> biome) {
|
||||
return biome.unwrapKey().orElse(null);
|
||||
}
|
||||
|
||||
public static ResourceKey getBiomeKeyOrThrow(Holder<Biome> biome) {
|
||||
return biome.unwrapKey().orElseThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link BCLBiome} from given {@link ResourceLocation}.
|
||||
|
@ -393,6 +392,15 @@ public class BiomeAPI {
|
|||
public static BCLBiome getBiome(Biome biome) {
|
||||
return getBiome(BiomeAPI.getBiomeID(biome));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link BCLBiome} from given {@link Biome}.
|
||||
* @param biome - biome {@link Biome}.
|
||||
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
|
||||
*/
|
||||
public static BCLBiome getBiome(Holder<Biome> biome) {
|
||||
return getBiome(BiomeAPI.getBiomeID(biome));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if biome with {@link ResourceLocation} exists in API registry.
|
||||
|
@ -409,31 +417,31 @@ public class BiomeAPI {
|
|||
public static void loadFabricAPIBiomes() {
|
||||
FabricBiomesData.NETHER_BIOMES.forEach((key) -> {
|
||||
if (!hasBiome(key.location())) {
|
||||
registerNetherBiome(BuiltinRegistries.BIOME.get(key.location()));
|
||||
registerNetherBiome(BuiltinRegistries.BIOME.get(key));
|
||||
}
|
||||
});
|
||||
|
||||
FabricBiomesData.END_LAND_BIOMES.forEach((key, weight) -> {
|
||||
if (!hasBiome(key.location())) {
|
||||
registerEndLandBiome(BuiltinRegistries.BIOME.get(key.location()), weight);
|
||||
registerEndLandBiome(BuiltinRegistries.BIOME.getHolder(key).orElseThrow(), weight);
|
||||
}
|
||||
});
|
||||
|
||||
FabricBiomesData.END_VOID_BIOMES.forEach((key, weight) -> {
|
||||
if (!hasBiome(key.location())) {
|
||||
registerEndVoidBiome(BuiltinRegistries.BIOME.get(key.location()), weight);
|
||||
registerEndVoidBiome(BuiltinRegistries.BIOME.getOrCreateHolder(key), weight);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Biome getFromRegistry(ResourceLocation key) {
|
||||
return BuiltinRegistries.BIOME.get(key);
|
||||
public static Holder<Biome> getFromRegistry(ResourceLocation key) {
|
||||
return BuiltinRegistries.BIOME.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, key)).orElseThrow();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Biome getFromRegistry(ResourceKey<Biome> key) {
|
||||
return BuiltinRegistries.BIOME.get(key);
|
||||
public static Holder<Biome> getFromRegistry(ResourceKey<Biome> key) {
|
||||
return BuiltinRegistries.BIOME.getOrCreateHolder(key);
|
||||
}
|
||||
|
||||
public static boolean isDatapackBiome(ResourceLocation biomeID) {
|
||||
|
@ -457,8 +465,8 @@ public class BiomeAPI {
|
|||
* @param dimensionID {@link ResourceLocation} dimension ID, example: Level.OVERWORLD or "minecraft:overworld".
|
||||
* @param modification {@link BiConsumer} with {@link ResourceKey} biome ID and {@link Biome} parameters.
|
||||
*/
|
||||
public static void registerBiomeModification(ResourceKey dimensionID, BiConsumer<ResourceLocation, Biome> modification) {
|
||||
List<BiConsumer<ResourceLocation, Biome>> modifications = MODIFICATIONS.computeIfAbsent(dimensionID, k -> Lists.newArrayList());
|
||||
public static void registerBiomeModification(ResourceKey dimensionID, BiConsumer<ResourceLocation, Holder<Biome>> modification) {
|
||||
List<BiConsumer<ResourceLocation, Holder<Biome>>> modifications = MODIFICATIONS.computeIfAbsent(dimensionID, k -> Lists.newArrayList());
|
||||
modifications.add(modification);
|
||||
}
|
||||
|
||||
|
@ -466,7 +474,7 @@ public class BiomeAPI {
|
|||
* Registers new biome modification for the Overworld. Will work both for mod and datapack biomes.
|
||||
* @param modification {@link BiConsumer} with {@link ResourceLocation} biome ID and {@link Biome} parameters.
|
||||
*/
|
||||
public static void registerOverworldBiomeModification(BiConsumer<ResourceLocation, Biome> modification) {
|
||||
public static void registerOverworldBiomeModification(BiConsumer<ResourceLocation, Holder<Biome>> modification) {
|
||||
registerBiomeModification(Level.OVERWORLD, modification);
|
||||
}
|
||||
|
||||
|
@ -474,7 +482,7 @@ public class BiomeAPI {
|
|||
* Registers new biome modification for the Nether. Will work both for mod and datapack biomes.
|
||||
* @param modification {@link BiConsumer} with {@link ResourceLocation} biome ID and {@link Biome} parameters.
|
||||
*/
|
||||
public static void registerNetherBiomeModification(BiConsumer<ResourceLocation, Biome> modification) {
|
||||
public static void registerNetherBiomeModification(BiConsumer<ResourceLocation, Holder<Biome>> modification) {
|
||||
registerBiomeModification(Level.NETHER, modification);
|
||||
}
|
||||
|
||||
|
@ -482,7 +490,7 @@ public class BiomeAPI {
|
|||
* Registers new biome modification for the End. Will work both for mod and datapack biomes.
|
||||
* @param modification {@link BiConsumer} with {@link ResourceLocation} biome ID and {@link Biome} parameters.
|
||||
*/
|
||||
public static void registerEndBiomeModification(BiConsumer<ResourceLocation, Biome> modification) {
|
||||
public static void registerEndBiomeModification(BiConsumer<ResourceLocation, Holder<Biome>> modification) {
|
||||
registerBiomeModification(Level.END, modification);
|
||||
}
|
||||
|
||||
|
@ -491,40 +499,54 @@ public class BiomeAPI {
|
|||
* @param level
|
||||
*/
|
||||
public static void applyModifications(ServerLevel level) {
|
||||
final BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource();
|
||||
final StructureSettings settings = level.getChunkSource().getGenerator().getSettings();
|
||||
final Set<Biome> biomes = source.possibleBiomes();
|
||||
NoiseGeneratorSettings noiseGeneratorSettings = null;
|
||||
final ChunkGenerator chunkGenerator = level.getChunkSource().getGenerator();
|
||||
final BiomeSource source = chunkGenerator.getBiomeSource();
|
||||
final Set<Holder<Biome>> biomes = source.possibleBiomes();
|
||||
|
||||
NoiseGeneratorSettings generator = level
|
||||
if (chunkGenerator instanceof NoiseGeneratorSettingsProvider gen)
|
||||
noiseGeneratorSettings = gen.bclib_getNoiseGeneratorSettings();
|
||||
/*final Registry<StructureSet> structureSetRegistry;
|
||||
if (chunkGenerator instanceof ChunkGeneratorAccessor acc) {
|
||||
structureSetRegistry = acc.bclib_getStructureSetsRegistry();
|
||||
} else {
|
||||
structureSetRegistry = null;
|
||||
}
|
||||
|
||||
|
||||
noiseGeneratorSettings = level
|
||||
.getServer()
|
||||
.getWorldData()
|
||||
.worldGenSettings()
|
||||
.dimensions()
|
||||
.stream()
|
||||
.map(dim->dim.generator())
|
||||
.filter(gen->(gen instanceof NoiseGeneratorSettingsProvider) && gen.getSettings()==settings)
|
||||
.filter(gen-> structureSetRegistry!=null && (gen instanceof NoiseGeneratorSettingsProvider) && (gen instanceof ChunkGeneratorAccessor) && ((ChunkGeneratorAccessor)gen).bclib_getStructureSetsRegistry()==structureSetRegistry)
|
||||
.map(gen->((NoiseGeneratorSettingsProvider)gen).bclib_getNoiseGeneratorSettings())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
.orElse(null);*/
|
||||
|
||||
|
||||
// Datapacks (like Amplified Nether)will change the GeneratorSettings upon load, so we will
|
||||
// only use the default Setting for Nether/End if we were unable to find a settings object
|
||||
if (generator==null){
|
||||
if (noiseGeneratorSettings==null){
|
||||
if (level.dimension() == Level.NETHER) {
|
||||
generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.NETHER);
|
||||
noiseGeneratorSettings = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.NETHER);
|
||||
} else if (level.dimension() == Level.END) {
|
||||
generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.END);
|
||||
noiseGeneratorSettings = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.END);
|
||||
}
|
||||
}
|
||||
|
||||
List<BiConsumer<ResourceLocation, Biome>> modifications = MODIFICATIONS.get(level.dimension());
|
||||
for (Biome biome : biomes) {
|
||||
applyModificationsAndUpdateFeatures(modifications, biome);
|
||||
List<BiConsumer<ResourceLocation, Holder<Biome>>> modifications = MODIFICATIONS.get(level.dimension());
|
||||
for (Holder<Biome> biomeHolder : biomes) {
|
||||
if (biomeHolder.isBound()) {
|
||||
applyModificationsAndUpdateFeatures(modifications, biomeHolder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (generator != null) {
|
||||
final SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator);
|
||||
if (noiseGeneratorSettings != null) {
|
||||
final SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(noiseGeneratorSettings);
|
||||
// Multiple Biomes can use the same generator. So we need to keep track of all Biomes that are
|
||||
// Provided by all the BiomeSources that use the same generator.
|
||||
// This happens for example when using the MiningDimensions, which reuses the generator for the
|
||||
|
@ -535,20 +557,10 @@ public class BiomeAPI {
|
|||
BCLib.LOGGER.warning("No generator for " + source);
|
||||
}
|
||||
|
||||
if (settings!=null){
|
||||
final StructureSettingsAccessor settingsAccessor = (StructureSettingsAccessor)settings;
|
||||
final Set<ResourceLocation> biomeIDs = biomes.stream().map(BiomeAPI::getBiomeID).collect(Collectors.toSet());
|
||||
for (Entry<StructureID, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>>> e : STRUCTURE_STARTS.entrySet()) {
|
||||
if (biomeIDs.contains(e.getKey().biomeID)) {
|
||||
applyStructureStarts(settingsAccessor, e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
((BiomeSourceAccessor) source).bclRebuildFeatures();
|
||||
}
|
||||
|
||||
private static void applyModificationsAndUpdateFeatures(List<BiConsumer<ResourceLocation, Biome>> modifications, Biome biome) {
|
||||
private static void applyModificationsAndUpdateFeatures(List<BiConsumer<ResourceLocation, Holder<Biome>>> modifications, Holder<Biome> biome) {
|
||||
ResourceLocation biomeID = getBiomeID(biome);
|
||||
if (modifications!=null) {
|
||||
modifications.forEach(consumer -> {
|
||||
|
@ -556,11 +568,6 @@ public class BiomeAPI {
|
|||
});
|
||||
}
|
||||
|
||||
final BCLBiome bclBiome = BiomeAPI.getBiome(biome);
|
||||
if (bclBiome != null) {
|
||||
addStepFeaturesToBiome(biome, bclBiome.getFeatures());
|
||||
}
|
||||
|
||||
sortBiomeFeatures(biome);
|
||||
}
|
||||
|
||||
|
@ -568,20 +575,20 @@ public class BiomeAPI {
|
|||
* Create a unique sort order for all Features of the Biome
|
||||
* @param biome The {@link Biome} to sort the features for
|
||||
*/
|
||||
public static void sortBiomeFeatures(Biome biome) {
|
||||
BiomeGenerationSettings settings = biome.getGenerationSettings();
|
||||
public static void sortBiomeFeatures(Holder<Biome> biome) {
|
||||
BiomeGenerationSettings settings = biome.value().getGenerationSettings();
|
||||
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings;
|
||||
List<List<Supplier<PlacedFeature>>> featureList = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
||||
List<HolderSet<PlacedFeature>> featureList = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
||||
final int size = featureList.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
List<Supplier<PlacedFeature>> features = CollectionsUtil.getMutable(featureList.get(i));
|
||||
List<Holder<PlacedFeature>> features = getFeaturesListCopy(featureList, i);
|
||||
sortFeatures(features);
|
||||
featureList.set(i, features);
|
||||
featureList.set(i, HolderSet.direct(features));
|
||||
}
|
||||
accessor.bclib_setFeatures(featureList);
|
||||
}
|
||||
|
||||
private static List<SurfaceRules.RuleSource> getRuleSourcesForBiomes(Set<Biome> biomes) {
|
||||
private static List<SurfaceRules.RuleSource> getRuleSourcesForBiomes(Set<Holder<Biome>> biomes) {
|
||||
Set<ResourceLocation> biomeIDs = biomes
|
||||
.stream()
|
||||
.map(biome -> getBiomeID(biome))
|
||||
|
@ -600,7 +607,7 @@ public class BiomeAPI {
|
|||
* @return A list of {@link RuleSource}-Objects that are needed to create those Biomes
|
||||
*/
|
||||
public static List<SurfaceRules.RuleSource> getRuleSources(Set<BiomeSource> sources) {
|
||||
final Set<Biome> biomes = new HashSet<>();
|
||||
final Set<Holder<Biome>> biomes = new HashSet<>();
|
||||
for (BiomeSource s : sources) {
|
||||
biomes.addAll(s.possibleBiomes());
|
||||
}
|
||||
|
@ -624,7 +631,7 @@ public class BiomeAPI {
|
|||
* @param feature {@link ConfiguredFeature} to add.
|
||||
*
|
||||
*/
|
||||
public static void addBiomeFeature(Biome biome, BCLFeature feature) {
|
||||
public static void addBiomeFeature(Holder<Biome> biome, BCLFeature feature) {
|
||||
addBiomeFeature(biome, feature.getDecoration(), feature.getPlacedFeature());
|
||||
}
|
||||
|
||||
|
@ -634,7 +641,7 @@ public class BiomeAPI {
|
|||
* @param step a {@link Decoration} step for the feature.
|
||||
* @param featureList {@link ConfiguredFeature} to add.
|
||||
*/
|
||||
public static void addBiomeFeature(Biome biome, Decoration step, PlacedFeature... featureList) {
|
||||
public static void addBiomeFeature(Holder<Biome> biome, Decoration step, Holder<PlacedFeature>... featureList) {
|
||||
addBiomeFeature(biome, step, List.of(featureList));
|
||||
}
|
||||
|
||||
|
@ -642,107 +649,25 @@ public class BiomeAPI {
|
|||
* Adds new features to existing biome.
|
||||
* @param biome {@link Biome} to add features in.
|
||||
* @param step a {@link Decoration} step for the feature.
|
||||
* @param featureList List of {@link ConfiguredFeature} to add.
|
||||
* @param additionalFeatures List of {@link ConfiguredFeature} to add.
|
||||
*/
|
||||
private static void addBiomeFeature(Biome biome, Decoration step, List<PlacedFeature> featureList) {
|
||||
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings();
|
||||
List<List<Supplier<PlacedFeature>>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
||||
Set<PlacedFeature> set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet());
|
||||
List<Supplier<PlacedFeature>> features = getFeaturesList(allFeatures, step);
|
||||
for (var feature : featureList) {
|
||||
features.add(() -> feature);
|
||||
set.add(feature);
|
||||
}
|
||||
accessor.bclib_setFeatures(allFeatures);
|
||||
accessor.bclib_setFeatureSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use only!
|
||||
*
|
||||
* Adds new features to existing biome. Called from {@link #applyModificationsAndUpdateFeatures(List, Biome)} when the Biome is
|
||||
* present in any {@link BiomeSource}
|
||||
* @param biome {@link Biome} to add features in.
|
||||
* @param featureMap Map of {@link ConfiguredFeature} to add.
|
||||
*/
|
||||
private static void addStepFeaturesToBiome(Biome biome, Map<Decoration, List<Supplier<PlacedFeature>>> featureMap) {
|
||||
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings();
|
||||
List<List<Supplier<PlacedFeature>>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
||||
Set<PlacedFeature> set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet());
|
||||
|
||||
for (Decoration step: featureMap.keySet()) {
|
||||
List<Supplier<PlacedFeature>> features = getFeaturesList(allFeatures, step);
|
||||
List<Supplier<PlacedFeature>> featureList = featureMap.get(step);
|
||||
|
||||
for (Supplier<PlacedFeature> feature : featureList) {
|
||||
private static void addBiomeFeature(Holder<Biome> biome, Decoration step, List<Holder<PlacedFeature>> additionalFeatures) {
|
||||
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.value().getGenerationSettings();
|
||||
List<HolderSet<PlacedFeature>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
||||
List<Holder<PlacedFeature>> features = getFeaturesListCopy(allFeatures, step);
|
||||
|
||||
for (var feature : additionalFeatures) {
|
||||
if (!features.contains(feature))
|
||||
features.add(feature);
|
||||
set.add(feature.get());
|
||||
}
|
||||
}
|
||||
|
||||
allFeatures.set(step.ordinal(), HolderSet.direct(features));
|
||||
final Supplier<List<ConfiguredFeature<?, ?>>> flowerFeatures = Suppliers.memoize(() -> allFeatures.stream().flatMap(HolderSet::stream).map(Holder::value).flatMap(PlacedFeature::getFeatures).filter(configuredFeature -> configuredFeature.feature() == Feature.FLOWER).collect(ImmutableList.toImmutableList()));
|
||||
final Supplier<Set<PlacedFeature>> featureSet = Suppliers.memoize(() -> allFeatures.stream().flatMap(HolderSet::stream).map(Holder::value).collect(Collectors.toSet()));
|
||||
|
||||
accessor.bclib_setFeatures(allFeatures);
|
||||
accessor.bclib_setFeatureSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new structure feature to existing biome.
|
||||
* @param biomeKey {@link ResourceKey} for the {@link Biome} to add structure feature in.
|
||||
* @param structure {@link ConfiguredStructureFeature} to add.
|
||||
*/
|
||||
public static void addBiomeStructure(ResourceKey biomeKey, ConfiguredStructureFeature structure) {
|
||||
if (biomeKey == null){
|
||||
BCLib.LOGGER.error("null is not a valid biomeKey for " + structure);
|
||||
return;
|
||||
}
|
||||
changeStructureStarts(biomeKey.location(), structure, (structureMap, configMap) -> {
|
||||
Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>> configuredMap = structureMap.computeIfAbsent(structure.feature, k -> HashMultimap.create());
|
||||
configuredMap.put(structure, biomeKey);
|
||||
|
||||
StructureFeatureConfiguration config = FabricStructureImpl.STRUCTURE_TO_CONFIG_MAP.get(structure.feature);
|
||||
if (config != null){
|
||||
configMap.put(structure.feature, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an existing StructureFeature to a Biome
|
||||
* @param biome The {@link Biome} you want to add teh feature to
|
||||
* @param structure The {@link ConfiguredStructureFeature} to add
|
||||
*/
|
||||
public static void addBiomeStructure(Biome biome, ConfiguredStructureFeature structure) {
|
||||
changeStructureStarts(BiomeAPI.getBiomeID(biome), structure, (structureMap, configMap) -> {
|
||||
Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>> configuredMap = structureMap.computeIfAbsent(structure.feature, k -> HashMultimap.create());
|
||||
var key = getBiomeKey(biome);
|
||||
if (key != null) {
|
||||
StructureFeatureConfiguration config = FabricStructureImpl.STRUCTURE_TO_CONFIG_MAP.get(structure.feature);
|
||||
if (config != null) {
|
||||
configMap.put(structure.feature, config);
|
||||
}
|
||||
configuredMap.put(structure, key);
|
||||
} else {
|
||||
BCLib.LOGGER.warning("Unable to find Biome " + getBiomeID(biome));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new structure feature to existing biome.
|
||||
* @param biomeKey {@link ResourceKey} for the {@link Biome} to add structure feature in.
|
||||
* @param structure {@link BCLStructureFeature} to add.
|
||||
*/
|
||||
public static void addBiomeStructure(ResourceKey biomeKey, BCLStructureFeature structure) {
|
||||
addBiomeStructure(biomeKey, structure.getFeatureConfigured());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new structure features to existing biome.
|
||||
* @param biomeKey {@link ResourceKey} for the {@link Biome} to add structure features in.
|
||||
* @param structures array of {@link BCLStructureFeature} to add.
|
||||
*/
|
||||
public static void addBiomeStructures(ResourceKey biomeKey, BCLStructureFeature... structures) {
|
||||
for (BCLStructureFeature structure: structures) {
|
||||
addBiomeStructure(biomeKey, structure.getFeatureConfigured());
|
||||
}
|
||||
accessor.bclib_setFeatureSet(featureSet);
|
||||
accessor.bclib_setFlowerFeatures(flowerFeatures);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -751,13 +676,20 @@ public class BiomeAPI {
|
|||
* @param carver {@link ConfiguredWorldCarver} to add.
|
||||
* @param stage {@link Carving} stage.
|
||||
*/
|
||||
public static void addBiomeCarver(Biome biome, ConfiguredWorldCarver carver, Carving stage) {
|
||||
public static void addBiomeCarver(Biome biome, Holder<? extends ConfiguredWorldCarver<?>> carver, Carving stage) {
|
||||
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings();
|
||||
Map<Carving, List<Supplier<ConfiguredWorldCarver<?>>>> carvers = CollectionsUtil.getMutable(accessor.bclib_getCarvers());
|
||||
List<Supplier<ConfiguredWorldCarver<?>>> carverList = CollectionsUtil.getMutable(carvers.getOrDefault(stage, new ArrayList<>()));
|
||||
carvers.put(stage, carverList);
|
||||
carverList.add(() -> carver);
|
||||
accessor.bclib_setCarvers(carvers);
|
||||
Map<Carving, HolderSet<ConfiguredWorldCarver<?>>> carverMap = CollectionsUtil.getMutable(accessor.bclib_getCarvers());
|
||||
HolderSet<ConfiguredWorldCarver<?>> carvers = carverMap.get(stage);
|
||||
|
||||
List<Holder<ConfiguredWorldCarver<?>>> carverList;
|
||||
if (carvers==null) {
|
||||
carverList = Lists.newArrayList();
|
||||
} else {
|
||||
carverList = carvers.stream().toList();
|
||||
}
|
||||
carverList.add((Holder<ConfiguredWorldCarver<?>>)carver);
|
||||
carverMap.put(stage, HolderSet.direct(carverList));
|
||||
accessor.bclib_setCarvers(carverMap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -788,7 +720,7 @@ public class BiomeAPI {
|
|||
* @param minGroupCount minimum mobs in group.
|
||||
* @param maxGroupCount maximum mobs in group.
|
||||
*/
|
||||
public static <M extends Mob> void addBiomeMobSpawn(Biome biome, BCLEntityWrapper<M> entityType, int weight, int minGroupCount, int maxGroupCount) {
|
||||
public static <M extends Mob> void addBiomeMobSpawn(Holder<Biome> biome, BCLEntityWrapper<M> entityType, int weight, int minGroupCount, int maxGroupCount) {
|
||||
if (entityType.canSpawn()){
|
||||
addBiomeMobSpawn(biome, entityType.type(), weight, minGroupCount, maxGroupCount);
|
||||
}
|
||||
|
@ -802,9 +734,9 @@ public class BiomeAPI {
|
|||
* @param minGroupCount minimum mobs in group.
|
||||
* @param maxGroupCount maximum mobs in group.
|
||||
*/
|
||||
public static <M extends Mob> void addBiomeMobSpawn(Biome biome, EntityType<M> entityType, int weight, int minGroupCount, int maxGroupCount) {
|
||||
public static <M extends Mob> void addBiomeMobSpawn(Holder<Biome> biome, EntityType<M> entityType, int weight, int minGroupCount, int maxGroupCount) {
|
||||
final MobCategory category = entityType.getCategory();
|
||||
MobSpawnSettingsAccessor accessor = (MobSpawnSettingsAccessor) biome.getMobSettings();
|
||||
MobSpawnSettingsAccessor accessor = (MobSpawnSettingsAccessor) biome.value().getMobSettings();
|
||||
Map<MobCategory, WeightedRandomList<SpawnerData>> spawners = CollectionsUtil.getMutable(accessor.bcl_getSpawners());
|
||||
List<SpawnerData> mobs = spawners.containsKey(category) ? CollectionsUtil.getMutable(spawners.get(category).unwrap()) : Lists.newArrayList();
|
||||
mobs.add(new SpawnerData(entityType, weight, minGroupCount, maxGroupCount));
|
||||
|
@ -815,11 +747,11 @@ public class BiomeAPI {
|
|||
/**
|
||||
* Get biome surface block. Can be used to get terrain material for features or other things.
|
||||
* @param pos {@link BlockPos} position to get block.
|
||||
* @param biome {@link Biome} to get block from.
|
||||
* @param biome {@link Holder<Biome>} to get block from.
|
||||
* @param level {@link ServerLevel} current server level.
|
||||
* @return {@link BlockState} with the biome surface or AIR if it fails.
|
||||
*/
|
||||
public static BlockState getBiomeSurfaceBlock(BlockPos pos, Biome biome, ServerLevel level) {
|
||||
public static BlockState getBiomeSurfaceBlock(BlockPos pos, Holder<Biome> biome, ServerLevel level) {
|
||||
ChunkGenerator generator = level.getChunkSource().getGenerator();
|
||||
if (generator instanceof NoiseBasedChunkGenerator) {
|
||||
SurfaceProvider provider = SurfaceProvider.class.cast(generator);
|
||||
|
@ -832,6 +764,10 @@ public class BiomeAPI {
|
|||
return findTopMaterial(getBiome(world.getBiome(pos)));
|
||||
}
|
||||
|
||||
public static Optional<BlockState> findTopMaterial(Holder<Biome> biome){
|
||||
return findTopMaterial(getBiome(biome.value()));
|
||||
}
|
||||
|
||||
public static Optional<BlockState> findTopMaterial(Biome biome){
|
||||
return findTopMaterial(getBiome(biome));
|
||||
}
|
||||
|
@ -847,6 +783,10 @@ public class BiomeAPI {
|
|||
return findUnderMaterial(getBiome(world.getBiome(pos)));
|
||||
}
|
||||
|
||||
public static Optional<BlockState> findUnderMaterial(Holder<Biome> biome){
|
||||
return findUnderMaterial(getBiome(biome.value()));
|
||||
}
|
||||
|
||||
public static Optional<BlockState> findUnderMaterial(Biome biome){
|
||||
return findUnderMaterial(getBiome(biome));
|
||||
}
|
||||
|
@ -862,11 +802,11 @@ public class BiomeAPI {
|
|||
* Set biome in chunk at specified position.
|
||||
* @param chunk {@link ChunkAccess} chunk to set biome in.
|
||||
* @param pos {@link BlockPos} biome position.
|
||||
* @param biome {@link Biome} instance. Should be biome from world.
|
||||
* @param biome {@link Holder<Biome>} instance. Should be biome from world.
|
||||
*/
|
||||
public static void setBiome(ChunkAccess chunk, BlockPos pos, Biome biome) {
|
||||
public static void setBiome(ChunkAccess chunk, BlockPos pos, Holder<Biome> biome) {
|
||||
int sectionY = (pos.getY() - chunk.getMinBuildHeight()) >> 4;
|
||||
PalettedContainer<Biome> biomes = chunk.getSection(sectionY).getBiomes();
|
||||
PalettedContainer<Holder<Biome>> biomes = chunk.getSection(sectionY).getBiomes();
|
||||
biomes.set((pos.getX() & 15) >> 2, (pos.getY() & 15) >> 2, (pos.getZ() & 15) >> 2, biome);
|
||||
}
|
||||
|
||||
|
@ -874,9 +814,9 @@ public class BiomeAPI {
|
|||
* Set biome in world at specified position.
|
||||
* @param level {@link LevelAccessor} world to set biome in.
|
||||
* @param pos {@link BlockPos} biome position.
|
||||
* @param biome {@link Biome} instance. Should be biome from world.
|
||||
* @param biome {@link Holder<Biome>} instance. Should be biome from world.
|
||||
*/
|
||||
public static void setBiome(LevelAccessor level, BlockPos pos, Biome biome) {
|
||||
public static void setBiome(LevelAccessor level, BlockPos pos, Holder<Biome> biome) {
|
||||
ChunkAccess chunk = level.getChunk(pos);
|
||||
setBiome(chunk, pos, biome);
|
||||
}
|
||||
|
@ -909,42 +849,24 @@ public class BiomeAPI {
|
|||
}
|
||||
}
|
||||
|
||||
private static void changeStructureStarts(ResourceLocation biomeID, ConfiguredStructureFeature structure, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>> modifier) {
|
||||
STRUCTURE_STARTS.put(new StructureID(biomeID, structure), modifier);
|
||||
}
|
||||
|
||||
private static void applyStructureStarts(StructureSettingsAccessor access, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>> modifier) {
|
||||
Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> structureMap;
|
||||
Map<StructureFeature<?>, StructureFeatureConfiguration> configMap;
|
||||
|
||||
structureMap = getMutableConfiguredStructures(access);
|
||||
configMap = getMutableStructureConfig(access);
|
||||
|
||||
modifier.accept(structureMap, configMap);
|
||||
|
||||
setMutableConfiguredStructures(access, structureMap);
|
||||
setMutableStructureConfig(access, configMap);
|
||||
}
|
||||
|
||||
private static void sortFeatures(List<Supplier<PlacedFeature>> features) {
|
||||
private static void sortFeatures(List<Holder<PlacedFeature>> features) {
|
||||
initFeatureOrder();
|
||||
|
||||
Set<PlacedFeature> featuresWithoutDuplicates = Sets.newHashSet();
|
||||
features.forEach(provider -> featuresWithoutDuplicates.add(provider.get()));
|
||||
Set<Holder<PlacedFeature>> featuresWithoutDuplicates = Sets.newHashSet();
|
||||
features.forEach(holder -> featuresWithoutDuplicates.add(holder));
|
||||
|
||||
if (featuresWithoutDuplicates.size() != features.size()) {
|
||||
features.clear();
|
||||
featuresWithoutDuplicates.forEach(feature -> features.add(() -> feature));
|
||||
featuresWithoutDuplicates.forEach(feature -> features.add(feature));
|
||||
}
|
||||
|
||||
features.forEach(provider -> {
|
||||
PlacedFeature feature = provider.get();
|
||||
features.forEach(feature -> {
|
||||
FEATURE_ORDER.computeIfAbsent(feature, f -> FEATURE_ORDER_ID.getAndIncrement());
|
||||
});
|
||||
|
||||
features.sort((f1, f2) -> {
|
||||
int v1 = FEATURE_ORDER.getOrDefault(f1.get(), 70000);
|
||||
int v2 = FEATURE_ORDER.getOrDefault(f2.get(), 70000);
|
||||
int v1 = FEATURE_ORDER.getOrDefault(f1, 70000);
|
||||
int v2 = FEATURE_ORDER.getOrDefault(f2, 70000);
|
||||
return Integer.compare(v1, v2);
|
||||
});
|
||||
}
|
||||
|
@ -966,44 +888,15 @@ public class BiomeAPI {
|
|||
lists.set(index, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<Holder<PlacedFeature>> getFeaturesListCopy(List<HolderSet<PlacedFeature>> features, Decoration step) {
|
||||
return getFeaturesListCopy(features, step.ordinal());
|
||||
}
|
||||
|
||||
private static List<Supplier<PlacedFeature>> getFeaturesList(List<List<Supplier<PlacedFeature>>> features, Decoration step) {
|
||||
int index = step.ordinal();
|
||||
private static List<Holder<PlacedFeature>> getFeaturesListCopy(List<HolderSet<PlacedFeature>> features, int index) {
|
||||
while (features.size() <= index) {
|
||||
features.add(Lists.newArrayList());
|
||||
features.add(HolderSet.direct(Lists.newArrayList()));
|
||||
}
|
||||
List<Supplier<PlacedFeature>> mutable = CollectionsUtil.getMutable(features.get(index));
|
||||
features.set(index, mutable);
|
||||
return mutable;
|
||||
}
|
||||
|
||||
//inspired by net.fabricmc.fabric.impl.biome.modification.BiomeStructureStartsImpl
|
||||
private static Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> getMutableConfiguredStructures(StructureSettingsAccessor access) {
|
||||
ImmutableMap<StructureFeature<?>, ImmutableMultimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> configuredStructures = access.bcl_getConfiguredStructures();
|
||||
Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> result = new HashMap<>(configuredStructures.size());
|
||||
|
||||
for (Map.Entry<StructureFeature<?>, ImmutableMultimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> entry : configuredStructures.entrySet()) {
|
||||
result.put(entry.getKey(), HashMultimap.create(entry.getValue()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//inspired by net.fabricmc.fabric.impl.biome.modification.BiomeStructureStartsImpl
|
||||
private static void setMutableConfiguredStructures(StructureSettingsAccessor access, Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> structureStarts) {
|
||||
access.bcl_setConfiguredStructures(
|
||||
structureStarts
|
||||
.entrySet()
|
||||
.stream()
|
||||
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, e -> ImmutableMultimap.copyOf(e.getValue())))
|
||||
);
|
||||
}
|
||||
|
||||
private static Map<StructureFeature<?>, StructureFeatureConfiguration> getMutableStructureConfig(StructureSettingsAccessor access) {
|
||||
return CollectionsUtil.getMutable(access.bcl_getStructureConfig());
|
||||
}
|
||||
|
||||
private static void setMutableStructureConfig(StructureSettingsAccessor access, Map<StructureFeature<?>, StructureFeatureConfiguration> structureConfig) {
|
||||
access.bcl_setStructureConfig(structureConfig);
|
||||
return features.get(index).stream().collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,24 +147,8 @@ public abstract class DataHandler extends BaseDataHandler {
|
|||
@Environment(EnvType.CLIENT)
|
||||
abstract protected void serializeDataOnClient(FriendlyByteBuf buf);
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
protected void deserializeIncomingDataOnServer(FriendlyByteBuf buf, PacketSender responseSender){ }
|
||||
|
||||
//TODO: should be abstract once deserializeIncomingDataOnServer(FriendlyByteBuf buf, PacketSender responseSender) was removed
|
||||
|
||||
protected void deserializeIncomingDataOnServer(FriendlyByteBuf buf, Player player, PacketSender responseSender) {
|
||||
deserializeIncomingDataOnServer(buf, responseSender);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
protected void runOnServerGameThread(MinecraftServer server){ }
|
||||
|
||||
|
||||
//TODO: should be abstract once runOnServerGameThread(MinecraftServer server) was removed
|
||||
protected void runOnServerGameThread(MinecraftServer server, Player player){
|
||||
runOnServerGameThread(server);
|
||||
}
|
||||
|
||||
protected abstract void deserializeIncomingDataOnServer(FriendlyByteBuf buf, Player player, PacketSender responseSender);
|
||||
protected abstract void runOnServerGameThread(MinecraftServer server, Player player);
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Override
|
||||
|
|
|
@ -127,7 +127,6 @@ public class SendFiles extends DataHandler.FromServer {
|
|||
if ( Configs.CLIENT_CONFIG.isAcceptingConfigs() || Configs.CLIENT_CONFIG.isAcceptingFiles() || Configs.CLIENT_CONFIG.isAcceptingMods()) {
|
||||
BCLib.LOGGER.info("Writing Files:");
|
||||
|
||||
//TODO: Reject files that were not in the last RequestFiles.
|
||||
for (Pair<AutoFileSyncEntry, byte[]> entry : receivedFiles) {
|
||||
final AutoFileSyncEntry e = entry.first;
|
||||
final byte[] data = entry.second;
|
||||
|
|
|
@ -4,6 +4,7 @@ import net.minecraft.data.worldgen.placement.PlacementUtils;
|
|||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.valueproviders.UniformInt;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.BiomeFilter;
|
||||
|
@ -18,12 +19,12 @@ import ru.bclib.world.features.BCLFeature;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BCLFeatureBuilder {
|
||||
public class BCLFeatureBuilder <FC extends FeatureConfiguration, F extends Feature<FC>>{
|
||||
private static final BCLFeatureBuilder INSTANCE = new BCLFeatureBuilder();
|
||||
private List<PlacementModifier> modifications = new ArrayList<>(16);
|
||||
private ResourceLocation featureID;
|
||||
private Decoration decoration;
|
||||
private Feature<?> feature;
|
||||
private F feature;
|
||||
|
||||
private BCLFeatureBuilder() {}
|
||||
|
||||
|
@ -60,6 +61,11 @@ public class BCLFeatureBuilder {
|
|||
modifications.add(modifier);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BCLFeatureBuilder modifier(List<PlacementModifier> modifiers) {
|
||||
modifications.addAll(modifiers);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate feature in certain iterations (per chunk).
|
||||
|
@ -134,10 +140,9 @@ public class BCLFeatureBuilder {
|
|||
* @param configuration any {@link FeatureConfiguration} for provided {@link Feature}.
|
||||
* @return created {@link BCLFeature} instance.
|
||||
*/
|
||||
public <FC extends FeatureConfiguration> BCLFeature build(FC configuration) {
|
||||
public BCLFeature build(FC configuration) {
|
||||
PlacementModifier [] modifiers = modifications.toArray(new PlacementModifier [modifications.size()]);
|
||||
PlacedFeature configured = ((Feature<FC>) feature).configured(configuration).placed(modifiers);
|
||||
return new BCLFeature(featureID, feature, decoration, configured);
|
||||
return new BCLFeature(featureID, feature, decoration, configuration, modifiers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,6 +151,6 @@ public class BCLFeatureBuilder {
|
|||
* @return created {@link BCLFeature} instance.
|
||||
*/
|
||||
public BCLFeature build() {
|
||||
return build(FeatureConfiguration.NONE);
|
||||
return build((FC)FeatureConfiguration.NONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class SurfaceRuleBuilder {
|
|||
public SurfaceRuleBuilder subsurface(BlockState state, int depth) {
|
||||
entryInstance = getFromCache("subsurface_" + depth + "_" + state.toString(), () -> {
|
||||
RuleSource rule = SurfaceRules.state(state);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(depth, false, false, CaveSurface.FLOOR), rule);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(depth, false, CaveSurface.FLOOR), rule);
|
||||
return new SurfaceRuleEntry(3, rule);
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
|
@ -117,7 +117,7 @@ public class SurfaceRuleBuilder {
|
|||
public SurfaceRuleBuilder belowFloor(BlockState state, int height, NoiseCondition noise) {
|
||||
entryInstance = getFromCache("below_floor_" + height + "_" + state.toString() + "_" + noise.getClass().getSimpleName(), () -> {
|
||||
RuleSource rule = SurfaceRules.state(state);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(height, false, false, CaveSurface.FLOOR), SurfaceRules.ifTrue(noise, rule));
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(height, false, CaveSurface.FLOOR), SurfaceRules.ifTrue(noise, rule));
|
||||
return new SurfaceRuleEntry(3, rule);
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
|
@ -133,7 +133,7 @@ public class SurfaceRuleBuilder {
|
|||
public SurfaceRuleBuilder belowFloor(BlockState state, int height) {
|
||||
entryInstance = getFromCache("below_floor_" + height + "_" + state.toString(), () -> {
|
||||
RuleSource rule = SurfaceRules.state(state);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(height, false, false, CaveSurface.FLOOR), rule);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(height, false, CaveSurface.FLOOR), rule);
|
||||
return new SurfaceRuleEntry(3, rule);
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
|
@ -163,7 +163,7 @@ public class SurfaceRuleBuilder {
|
|||
public SurfaceRuleBuilder aboveCeil(BlockState state, int height) {
|
||||
entryInstance = getFromCache("above_ceil_" + height + "_" + state.toString(), () -> {
|
||||
RuleSource rule = SurfaceRules.state(state);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(height, false, false, CaveSurface.CEILING), rule);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(height, false, CaveSurface.CEILING), rule);
|
||||
return new SurfaceRuleEntry(3, rule);
|
||||
});
|
||||
rules.add(entryInstance);
|
||||
|
@ -179,7 +179,7 @@ public class SurfaceRuleBuilder {
|
|||
public SurfaceRuleBuilder steep(BlockState state, int depth) {
|
||||
entryInstance = getFromCache("steep_" + depth + "_" + state.toString(), () -> {
|
||||
RuleSource rule = SurfaceRules.state(state);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(depth, false, false, CaveSurface.FLOOR), rule);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.stoneDepthCheck(depth, false, CaveSurface.FLOOR), rule);
|
||||
rule = SurfaceRules.ifTrue(SurfaceRules.steep(), rule);
|
||||
int priority = depth < 1 ? 0 : 1;
|
||||
return new SurfaceRuleEntry(priority, rule);
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
package ru.bclib.api.tag;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import ru.bclib.api.tag.TagAPI.TagNamed;
|
||||
|
||||
public class CommonBlockTags {
|
||||
public static final TagNamed<Block> BARREL = TagAPI.makeCommonBlockTag("barrel");
|
||||
public static final TagNamed<Block> BOOKSHELVES = TagAPI.makeCommonBlockTag("bookshelves");
|
||||
public static final TagNamed<Block> CHEST = TagAPI.makeCommonBlockTag("chest");
|
||||
public static final TagNamed<Block> END_STONES = TagAPI.makeCommonBlockTag("end_stones");
|
||||
public static final TagNamed<Block> GEN_END_STONES = END_STONES;
|
||||
public static final TagNamed<Block> IMMOBILE = TagAPI.makeCommonBlockTag("immobile");
|
||||
public static final TagNamed<Block> LEAVES = TagAPI.makeCommonBlockTag("leaves");
|
||||
public static final TagNamed<Block> NETHERRACK = TagAPI.makeCommonBlockTag("netherrack");
|
||||
public static final TagNamed<Block> NETHER_MYCELIUM = TagAPI.makeCommonBlockTag("nether_mycelium");
|
||||
public static final TagNamed<Block> NETHER_PORTAL_FRAME = TagAPI.makeCommonBlockTag("nether_pframe");
|
||||
public static final TagNamed<Block> NETHER_STONES = TagAPI.makeCommonBlockTag("nether_stones");
|
||||
public static final TagNamed<Block> SAPLINGS = TagAPI.makeCommonBlockTag("saplings");
|
||||
public static final TagNamed<Block> SOUL_GROUND = TagAPI.makeCommonBlockTag("soul_ground");
|
||||
public static final TagNamed<Block> WOODEN_BARREL = TagAPI.makeCommonBlockTag("wooden_barrels");
|
||||
public static final TagNamed<Block> WOODEN_CHEST = TagAPI.makeCommonBlockTag("wooden_chests");
|
||||
public static final TagNamed<Block> WORKBENCHES = TagAPI.makeCommonBlockTag("workbench");
|
||||
public static final TagKey<Block> BARREL = TagAPI.makeCommonBlockTag("barrel");
|
||||
public static final TagKey<Block> BOOKSHELVES = TagAPI.makeCommonBlockTag("bookshelves");
|
||||
public static final TagKey<Block> CHEST = TagAPI.makeCommonBlockTag("chest");
|
||||
public static final TagKey<Block> END_STONES = TagAPI.makeCommonBlockTag("end_stones");
|
||||
public static final TagKey<Block> GEN_END_STONES = END_STONES;
|
||||
public static final TagKey<Block> IMMOBILE = TagAPI.makeCommonBlockTag("immobile");
|
||||
public static final TagKey<Block> LEAVES = TagAPI.makeCommonBlockTag("leaves");
|
||||
public static final TagKey<Block> NETHERRACK = TagAPI.makeCommonBlockTag("netherrack");
|
||||
public static final TagKey<Block> NETHER_MYCELIUM = TagAPI.makeCommonBlockTag("nether_mycelium");
|
||||
public static final TagKey<Block> NETHER_PORTAL_FRAME = TagAPI.makeCommonBlockTag("nether_pframe");
|
||||
public static final TagKey<Block> NETHER_STONES = TagAPI.makeCommonBlockTag("nether_stones");
|
||||
public static final TagKey<Block> SAPLINGS = TagAPI.makeCommonBlockTag("saplings");
|
||||
public static final TagKey<Block> SOUL_GROUND = TagAPI.makeCommonBlockTag("soul_ground");
|
||||
public static final TagKey<Block> WOODEN_BARREL = TagAPI.makeCommonBlockTag("wooden_barrels");
|
||||
public static final TagKey<Block> WOODEN_CHEST = TagAPI.makeCommonBlockTag("wooden_chests");
|
||||
public static final TagKey<Block> WORKBENCHES = TagAPI.makeCommonBlockTag("workbench");
|
||||
|
||||
public static final TagKey<Block> MINABLE_WITH_HAMMER = TagAPI.makeCommonBlockTag("mineable/hammer");
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package ru.bclib.api.tag;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import ru.bclib.api.tag.TagAPI.TagNamed;
|
||||
|
||||
public class CommonItemTags {
|
||||
public final static TagNamed<Item> HAMMERS = TagAPI.makeCommonItemTag("hammers");
|
||||
public static final TagNamed<Item> BARREL = TagAPI.makeCommonItemTag("barrel");
|
||||
public static final TagNamed<Item> CHEST = TagAPI.makeCommonItemTag("chest");
|
||||
public static final TagNamed<Item> SHEARS = TagAPI.makeCommonItemTag("shears");
|
||||
public static final TagNamed<Item> FURNACES = TagAPI.makeCommonItemTag("furnaces");
|
||||
public static final TagNamed<Item> IRON_INGOTS = TagAPI.makeCommonItemTag("iron_ingots");
|
||||
public static final TagNamed<Item> LEAVES = TagAPI.makeCommonItemTag("leaves");
|
||||
public static final TagNamed<Item> SAPLINGS = TagAPI.makeCommonItemTag("saplings");
|
||||
public static final TagNamed<Item> SOUL_GROUND = TagAPI.makeCommonItemTag("soul_ground");
|
||||
public static final TagNamed<Item> WOODEN_BARREL = TagAPI.makeCommonItemTag("wooden_barrels");
|
||||
public static final TagNamed<Item> WOODEN_CHEST = TagAPI.makeCommonItemTag("wooden_chests");
|
||||
public static final TagNamed<Item> WORKBENCHES = TagAPI.makeCommonItemTag("workbench");
|
||||
public final static TagKey<Item> HAMMERS = TagAPI.makeCommonItemTag("hammers");
|
||||
public static final TagKey<Item> BARREL = TagAPI.makeCommonItemTag("barrel");
|
||||
public static final TagKey<Item> CHEST = TagAPI.makeCommonItemTag("chest");
|
||||
public static final TagKey<Item> SHEARS = TagAPI.makeCommonItemTag("shears");
|
||||
public static final TagKey<Item> FURNACES = TagAPI.makeCommonItemTag("furnaces");
|
||||
public static final TagKey<Item> IRON_INGOTS = TagAPI.makeCommonItemTag("iron_ingots");
|
||||
public static final TagKey<Item> LEAVES = TagAPI.makeCommonItemTag("leaves");
|
||||
public static final TagKey<Item> SAPLINGS = TagAPI.makeCommonItemTag("saplings");
|
||||
public static final TagKey<Item> SOUL_GROUND = TagAPI.makeCommonItemTag("soul_ground");
|
||||
public static final TagKey<Item> WOODEN_BARREL = TagAPI.makeCommonItemTag("wooden_barrels");
|
||||
public static final TagKey<Item> WOODEN_CHEST = TagAPI.makeCommonItemTag("wooden_chests");
|
||||
public static final TagKey<Item> WORKBENCHES = TagAPI.makeCommonItemTag("workbench");
|
||||
}
|
||||
|
|
|
@ -10,4 +10,5 @@ public class NamedMineableTags {
|
|||
public static final TagLocation<Block> SHEARS = new TagLocation<>("fabric", "mineable/shears");
|
||||
public static final TagLocation<Block> SHOVEL = new TagLocation<>("mineable/shovel");
|
||||
public static final TagLocation<Block> SWORD = new TagLocation<>("fabric", "mineable/sword");
|
||||
public static final TagLocation<Block> HAMMER = new TagLocation<>("c", "mineable/hammer");
|
||||
}
|
||||
|
|
|
@ -2,112 +2,178 @@ package ru.bclib.api.tag;
|
|||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.fabricmc.fabric.api.tag.TagFactory;
|
||||
import net.fabricmc.fabric.impl.tag.extension.TagDelegate;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.Tag.Named;
|
||||
import net.minecraft.tags.TagCollection;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import ru.bclib.api.biomes.BiomeAPI;
|
||||
import ru.bclib.mixin.common.DiggerItemAccessor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class TagAPI {
|
||||
private static final Map<ResourceLocation, Set<ResourceLocation>> TAGS_BLOCK = Maps.newConcurrentMap();
|
||||
private static final Map<ResourceLocation, Set<ResourceLocation>> TAGS_ITEM = Maps.newConcurrentMap();
|
||||
private static final Map<ResourceLocation, Set<ResourceLocation>> TAGS_BIOME = Maps.newConcurrentMap();
|
||||
|
||||
/**
|
||||
* Get or create {@link Tag.Named}.
|
||||
* Get or create {@link TagKey}.
|
||||
*
|
||||
* @param containerSupplier - {@link TagCollection} {@link Supplier} tag collection;
|
||||
* @param registry - {@link Registry<T>} tag collection;
|
||||
* @param id - {@link ResourceLocation} tag id.
|
||||
* @return {@link Tag.Named}.
|
||||
* @return {@link TagKey}.
|
||||
*/
|
||||
public static <T> TagNamed<T> makeTag(Supplier<TagCollection<T>> containerSupplier, TagLocation<T> id) {
|
||||
Tag<T> tag = containerSupplier.get().getTag(id);
|
||||
return tag == null ? new Delegate<>(id, containerSupplier) : CommonDelegate.proxy((Named<T>) tag);
|
||||
public static <T> TagKey<T> makeTag(Registry<T> registry, TagLocation<T> id) {
|
||||
return registry
|
||||
.getTagNames()
|
||||
.filter(tagKey -> tagKey.location().equals(id))
|
||||
.findAny()
|
||||
.orElse(TagKey.create(registry.key(), id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get or create {@link Block} {@link Tag.Named} with mod namespace.
|
||||
* Get or create {@link Block} {@link TagKey} with mod namespace.
|
||||
*
|
||||
* @param modID - {@link String} mod namespace (mod id);
|
||||
* @param name - {@link String} tag name.
|
||||
* @return {@link Block} {@link Tag.Named}.
|
||||
* @return {@link Block} {@link TagKey}.
|
||||
*/
|
||||
public static TagNamed<Block> makeBlockTag(String modID, String name) {
|
||||
return makeTag(BlockTags::getAllTags, new TagLocation<>(modID, name));
|
||||
public static TagKey<Biome> makeBiomeTag(String modID, String name) {
|
||||
return TagKey.create(Registry.BIOME_REGISTRY, new ResourceLocation(modID, name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get or create {@link Item} {@link Tag.Named} with mod namespace.
|
||||
* Get or create {@link Block} {@link TagKey} with mod namespace.
|
||||
*
|
||||
* @param modID - {@link String} mod namespace (mod id);
|
||||
* @param name - {@link String} tag name.
|
||||
* @return {@link Item} {@link Tag.Named}.
|
||||
* @return {@link Block} {@link TagKey}.
|
||||
*/
|
||||
public static TagNamed<Item> makeItemTag(String modID, String name) {
|
||||
return makeTag(ItemTags::getAllTags, new TagLocation<>(modID, name));
|
||||
public static TagKey<Block> makeBlockTag(String modID, String name) {
|
||||
return makeTag(Registry.BLOCK, new TagLocation<>(modID, name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create {@link Block} {@link TagKey} with mod namespace.
|
||||
*
|
||||
* @param id - {@link String} id for the tag;
|
||||
* @return {@link Block} {@link TagKey}.
|
||||
*/
|
||||
public static TagKey<Block> makeBlockTag(ResourceLocation id) {
|
||||
return makeTag(Registry.BLOCK, new TagLocation<>(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create {@link Block} {@link Tag.Named}.
|
||||
* Get or create {@link Item} {@link TagKey} with mod namespace.
|
||||
*
|
||||
* @param modID - {@link String} mod namespace (mod id);
|
||||
* @param name - {@link String} tag name.
|
||||
* @return {@link Item} {@link TagKey}.
|
||||
*/
|
||||
public static TagKey<Item> makeItemTag(String modID, String name) {
|
||||
return makeTag(Registry.ITEM, new TagLocation<>(modID, name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create {@link Item} {@link TagKey} with mod namespace.
|
||||
*
|
||||
* @param id - {@link String} id for the tag;
|
||||
* @return {@link Item} {@link TagKey}.
|
||||
*/
|
||||
public static TagKey<Item> makeItemTag(ResourceLocation id) {
|
||||
return makeTag(Registry.ITEM, new TagLocation<>(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create {@link Block} {@link TagKey}.
|
||||
*
|
||||
* @param name - {@link String} tag name.
|
||||
* @return {@link Block} {@link Tag.Named}.
|
||||
* @return {@link Block} {@link TagKey}.
|
||||
* @see <a href="https://fabricmc.net/wiki/tutorial:tags">Fabric Wiki (Tags)</a>
|
||||
*/
|
||||
public static TagNamed<Block> makeCommonBlockTag(String name) {
|
||||
return makeTag(BlockTags::getAllTags, new TagLocation<>("c", name));
|
||||
public static TagKey<Block> makeCommonBlockTag(String name) {
|
||||
return makeTag(Registry.BLOCK, new TagLocation<>("c", name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create {@link Item} {@link Tag.Named}.
|
||||
* Get or create {@link Item} {@link TagKey}.
|
||||
*
|
||||
* @param name - {@link String} tag name.
|
||||
* @return {@link Item} {@link Tag.Named}.
|
||||
* @return {@link Item} {@link TagKey}.
|
||||
* @see <a href="https://fabricmc.net/wiki/tutorial:tags">Fabric Wiki (Tags)</a>
|
||||
*/
|
||||
public static TagNamed<Item> makeCommonItemTag(String name) {
|
||||
return makeTag(ItemTags::getAllTags, new TagLocation<>("c", name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create Minecraft {@link Block} {@link Tag.Named}.
|
||||
*
|
||||
* @param name - {@link String} tag name.
|
||||
* @return {@link Block} {@link Tag.Named}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static TagNamed<Block> getMCBlockTag(String name) {
|
||||
ResourceLocation id = new ResourceLocation(name);
|
||||
Tag<Block> tag = BlockTags.getAllTags().getTag(id);
|
||||
return CommonDelegate.proxy(tag == null ? (Named<Block>) TagFactory.BLOCK.create(id): (Named<Block>) tag);
|
||||
public static TagKey<Item> makeCommonItemTag(String name) {
|
||||
return makeTag(Registry.ITEM, new TagLocation<>("c", name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes basic tags. Should be called only in BCLib main class.
|
||||
*/
|
||||
public static void init() {
|
||||
addBlockTag(CommonBlockTags.BOOKSHELVES.getName(), Blocks.BOOKSHELF);
|
||||
addBlockTag(CommonBlockTags.CHEST.getName(), Blocks.CHEST);
|
||||
addItemTag(CommonItemTags.CHEST.getName(), Items.CHEST);
|
||||
addItemTag(CommonItemTags.IRON_INGOTS.getName(), Items.IRON_INGOT);
|
||||
addItemTag(CommonItemTags.FURNACES.getName(), Blocks.FURNACE);
|
||||
addBlockTag(CommonBlockTags.BOOKSHELVES, Blocks.BOOKSHELF);
|
||||
addBlockTag(CommonBlockTags.CHEST, Blocks.CHEST);
|
||||
addItemTag(CommonItemTags.CHEST, Items.CHEST);
|
||||
addItemTag(CommonItemTags.IRON_INGOTS, Items.IRON_INGOT);
|
||||
addItemTag(CommonItemTags.FURNACES, Blocks.FURNACE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds multiple Tags to one Biome.
|
||||
* @param tagIDs array of {@link TagLocation<Biome>} tag IDs.
|
||||
* @param biome The {@link Biome} to add tag.
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static void addBiomeTags(Biome biome, TagLocation<Biome>... tagIDs) {
|
||||
for (TagLocation<Biome> tagID : tagIDs) {
|
||||
addBiomeTagUntyped(tagID, biome);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one Tag to multiple Biomes.
|
||||
* @param tagID {@link TagLocation<Biome>} tag ID.
|
||||
* @param biomes array of {@link Biome} to add into tag.
|
||||
*/
|
||||
public static void addBiomeTag(TagLocation<Biome> tagID, Biome... biomes) {
|
||||
addBiomeTagUntyped(tagID, biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one Tag to multiple Biomes.
|
||||
* @param tagID {@link TagKey<Biome>} tag ID.
|
||||
* @param biomes array of {@link Biome} to add into tag.
|
||||
*/
|
||||
public static void addBiomeTag(TagKey<Biome> tagID, Biome... biomes) {
|
||||
addBiomeTagUntyped(tagID.location(), biomes);
|
||||
}
|
||||
/**
|
||||
* Adds one Tag to multiple Biomes.
|
||||
* @param tagID {@link ResourceLocation} tag ID.
|
||||
* @param biomes array of {@link Biome} to add into tag.
|
||||
*/
|
||||
protected static void addBiomeTagUntyped(ResourceLocation tagID, Biome... biomes) {
|
||||
Set<ResourceLocation> set = TAGS_BIOME.computeIfAbsent(tagID, k -> Sets.newHashSet());
|
||||
for (Biome biome : biomes) {
|
||||
ResourceLocation id = BiomeAPI.getBiomeID(biome);
|
||||
if (id != null) {
|
||||
set.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds multiple Tags to one Block.
|
||||
* @param tagIDs array of {@link TagLocation<Block>} tag IDs.
|
||||
|
@ -128,6 +194,15 @@ public class TagAPI {
|
|||
public static void addBlockTag(TagLocation<Block> tagID, Block... blocks) {
|
||||
addBlockTagUntyped(tagID, blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one Tag to multiple Blocks.
|
||||
* @param tagID {@link TagKey<Block>} tag ID.
|
||||
* @param blocks array of {@link Block} to add into tag.
|
||||
*/
|
||||
public static void addBlockTag(TagKey<Block> tagID, Block... blocks) {
|
||||
addBlockTagUntyped(tagID.location(), blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one Tag to multiple Blocks.
|
||||
|
@ -164,6 +239,15 @@ public class TagAPI {
|
|||
public static void addItemTag(TagLocation<Item> tagID, ItemLike... items) {
|
||||
addItemTagUntyped(tagID, items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one Tag to multiple Items.
|
||||
* @param tagID {@link TagKey<Item>} tag ID.
|
||||
* @param items array of {@link ItemLike} to add into tag.
|
||||
*/
|
||||
public static void addItemTag(TagKey<Item> tagID, ItemLike... items) {
|
||||
addItemTagUntyped(tagID.location(), items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one Tag to multiple Items.
|
||||
|
@ -190,16 +274,17 @@ public class TagAPI {
|
|||
* @param tagsMap The map that will hold the registered Tags
|
||||
* @return The {@code tagsMap} Parameter.
|
||||
*/
|
||||
public static Map<ResourceLocation, Tag.Builder> apply(String directory, Map<ResourceLocation, Tag.Builder> tagsMap) {
|
||||
Map<ResourceLocation, Set<ResourceLocation>> tagMap = null;
|
||||
public static <T> Map<ResourceLocation, Tag.Builder> apply(String directory, Map<ResourceLocation, Tag.Builder> tagsMap) {
|
||||
final BiConsumer<ResourceLocation, Set<ResourceLocation>> consumer;
|
||||
consumer = (id, ids) -> apply(tagsMap.computeIfAbsent(id, key -> Tag.Builder.tag()), ids);
|
||||
if ("tags/blocks".equals(directory)) {
|
||||
tagMap = TAGS_BLOCK;
|
||||
TAGS_BLOCK.forEach(consumer);
|
||||
}
|
||||
else if ("tags/items".equals(directory)) {
|
||||
tagMap = TAGS_ITEM;
|
||||
TAGS_ITEM.forEach(consumer);
|
||||
}
|
||||
if (tagMap != null) {
|
||||
tagMap.forEach((id, ids) -> apply(tagsMap.computeIfAbsent(id, key -> Tag.Builder.tag()), ids));
|
||||
else if ("tags/worldgen/biome".equals(directory)) {
|
||||
TAGS_BIOME.forEach(consumer);
|
||||
}
|
||||
return tagsMap;
|
||||
}
|
||||
|
@ -215,16 +300,8 @@ public class TagAPI {
|
|||
ids.forEach(value -> builder.addElement(value, "BCLib Code"));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends {@link Tag.Named} to return a type safe {@link TagLocation}. This Type was introduced to
|
||||
* allow type-safe definition of Tags using their ResourceLocation.
|
||||
* @param <T> The Type of the underlying {@link Tag}
|
||||
*/
|
||||
public interface TagNamed<T> extends Tag.Named<T>{
|
||||
TagLocation<T> getName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extends (without changing) {@link ResourceLocation}. This Type was introduced to allow type-safe definition af
|
||||
* Tags using their ResourceLocation.
|
||||
|
@ -234,68 +311,32 @@ public class TagAPI {
|
|||
public TagLocation(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
|
||||
public TagLocation(String string, String string2) {
|
||||
super(string, string2);
|
||||
}
|
||||
|
||||
|
||||
public TagLocation(ResourceLocation location) {
|
||||
super(location.getNamespace(), location.getPath());
|
||||
}
|
||||
|
||||
public static<R> TagLocation<R> of(Tag.Named<R> tag){
|
||||
return new TagLocation<R>(tag.getName());
|
||||
public static<R> TagLocation<R> of(TagKey<R> tag){
|
||||
return new TagLocation<R>(tag.location());
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class CommonDelegate<T> implements TagNamed<T> {
|
||||
protected final Tag.Named<T> delegate;
|
||||
protected CommonDelegate(Tag.Named<T> source){
|
||||
this.delegate = source;
|
||||
}
|
||||
|
||||
public static<T> TagNamed<T> proxy(Tag.Named<T> source){
|
||||
if (source instanceof TagNamed typed) return typed;
|
||||
return new ProxyDelegate<>(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(T object) {
|
||||
return delegate.contains(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> getValues() {
|
||||
return delegate.getValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getRandomElement(Random random) {
|
||||
return delegate.getRandomElement(random);
|
||||
}
|
||||
|
||||
public static boolean isToolWithMineableTag(ItemStack stack, TagKey<Block> tag){
|
||||
return isToolWithUntypedMineableTag(stack, tag.location());
|
||||
}
|
||||
|
||||
private static final class ProxyDelegate<T> extends CommonDelegate<T>{
|
||||
private final TagLocation<T> id;
|
||||
private ProxyDelegate(Tag.Named<T> source) {
|
||||
super( source);
|
||||
id = new TagLocation<>(source.getName()
|
||||
.getNamespace(), source.getName()
|
||||
.getPath());
|
||||
}
|
||||
@Override
|
||||
public TagLocation<T> getName(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public static boolean isToolWithMineableTag(ItemStack stack, TagLocation<Block> tag){
|
||||
return isToolWithUntypedMineableTag(stack, tag);
|
||||
}
|
||||
|
||||
private static final class Delegate<T> extends CommonDelegate<T>{
|
||||
public Delegate(TagLocation<T> id, Supplier<TagCollection<T>> containerSupplier) {
|
||||
super( new TagDelegate<>(id, containerSupplier));
|
||||
}
|
||||
@Override
|
||||
public TagLocation<T> getName(){
|
||||
return (TagLocation<T>)delegate.getName();
|
||||
|
||||
private static boolean isToolWithUntypedMineableTag(ItemStack stack, ResourceLocation tag){
|
||||
if (stack.getItem() instanceof DiggerItemAccessor dig){
|
||||
return dig.bclib_getBlockTag().location().equals(tag);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ public class BaseCropBlock extends BasePlantBlock {
|
|||
public BaseCropBlock(Item drop, Block... terrain) {
|
||||
this(
|
||||
FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.randomTicks()
|
||||
.noCollission(),
|
||||
|
|
|
@ -2,7 +2,6 @@ package ru.bclib.blocks;
|
|||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
@ -32,6 +31,7 @@ import net.minecraft.world.phys.shapes.CollisionContext;
|
|||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.items.tool.BaseShearsItem;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -45,7 +45,6 @@ public abstract class BaseDoublePlantBlock extends BaseBlockNotFull implements R
|
|||
public BaseDoublePlantBlock() {
|
||||
this(
|
||||
FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.noCollission()
|
||||
);
|
||||
|
@ -54,7 +53,6 @@ public abstract class BaseDoublePlantBlock extends BaseBlockNotFull implements R
|
|||
public BaseDoublePlantBlock(int light) {
|
||||
this(
|
||||
FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.lightLevel((state) -> state.getValue(TOP) ? light : 0)
|
||||
.noCollission()
|
||||
|
@ -117,7 +115,8 @@ public abstract class BaseDoublePlantBlock extends BaseBlockNotFull implements R
|
|||
}
|
||||
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
//TODO: 1.18.2 Test if shearing still works
|
||||
if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
Enchantments.SILK_TOUCH,
|
||||
tool
|
||||
) > 0) {
|
||||
|
|
63
src/main/java/ru/bclib/blocks/BaseGlassBlock.java
Normal file
63
src/main/java/ru/bclib/blocks/BaseGlassBlock.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.interfaces.tools.AddMineablePickaxe;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class BaseGlassBlock extends BaseBlockNotFull implements AddMineablePickaxe, RenderLayerProvider {
|
||||
public BaseGlassBlock(Block block) {
|
||||
this(block, 0.3f);
|
||||
}
|
||||
public BaseGlassBlock(Block block, float resistance) {
|
||||
super(FabricBlockSettings.copyOf(block)
|
||||
.resistance(resistance)
|
||||
.nonOpaque()
|
||||
.isSuffocating((arg1, arg2, arg3) -> false)
|
||||
.isViewBlocking((arg1, arg2, arg3) -> false));
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public float getShadeBrightness(BlockState state, BlockGetter view, BlockPos pos) {
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean propagatesSkylightDown(BlockState state, BlockGetter view, BlockPos pos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public boolean skipRendering(BlockState state, BlockState neighbor, Direction facing) {
|
||||
return neighbor.getBlock() == this ? true : super.skipRendering(state, neighbor, facing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.TRANSLUCENT;
|
||||
}
|
||||
}
|
|
@ -24,6 +24,8 @@ import ru.bclib.client.render.BCLRenderLayer;
|
|||
import ru.bclib.interfaces.BlockModelProvider;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.interfaces.TagProvider;
|
||||
import ru.bclib.interfaces.tools.AddMineableHoe;
|
||||
import ru.bclib.interfaces.tools.AddMineableShears;
|
||||
import ru.bclib.items.tool.BaseShearsItem;
|
||||
import ru.bclib.util.MHelper;
|
||||
|
||||
|
@ -31,7 +33,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider, RenderLayerProvider, TagProvider {
|
||||
public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider, RenderLayerProvider, TagProvider, AddMineableShears, AddMineableHoe {
|
||||
protected final Block sapling;
|
||||
|
||||
private static FabricBlockSettings makeLeaves(MaterialColor color) {
|
||||
|
@ -100,8 +102,6 @@ public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider,
|
|||
|
||||
@Override
|
||||
public void addTags(List<TagLocation<Block>> blockTags, List<TagLocation<Item>> itemTags) {
|
||||
blockTags.add(NamedMineableTags.SHEARS);
|
||||
blockTags.add(NamedMineableTags.HOE);
|
||||
blockTags.add(NamedBlockTags.LEAVES);
|
||||
itemTags.add(NamedItemTags.LEAVES);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.fabricmc.fabric.impl.object.builder.FabricBlockInternals;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.valueproviders.UniformInt;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TieredItem;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.OreBlock;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -19,7 +19,11 @@ import net.minecraft.world.level.material.Material;
|
|||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import ru.bclib.api.tag.NamedCommonBlockTags;
|
||||
import ru.bclib.api.tag.NamedMineableTags;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
import ru.bclib.interfaces.BlockModelProvider;
|
||||
import ru.bclib.interfaces.TagProvider;
|
||||
import ru.bclib.util.LootUtil;
|
||||
import ru.bclib.util.MHelper;
|
||||
|
||||
|
@ -31,6 +35,7 @@ public class BaseOreBlock extends OreBlock implements BlockModelProvider {
|
|||
private final Supplier<Item> dropItem;
|
||||
private final int minCount;
|
||||
private final int maxCount;
|
||||
private final int miningLevel;
|
||||
|
||||
public BaseOreBlock(Supplier<Item> drop, int minCount, int maxCount, int experience) {
|
||||
this(drop, minCount, maxCount, experience, 0);
|
||||
|
@ -53,15 +58,11 @@ public class BaseOreBlock extends OreBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
public BaseOreBlock(Properties properties, Supplier<Item> drop, int minCount, int maxCount, int experience, int miningLevel) {
|
||||
super(makeProps(properties, miningLevel), UniformInt.of(experience>0?1:0, experience));
|
||||
super(properties, UniformInt.of(experience>0?1:0, experience));
|
||||
this.dropItem = drop;
|
||||
this.minCount = minCount;
|
||||
this.maxCount = maxCount;
|
||||
}
|
||||
|
||||
private static Properties makeProps(Properties properties, int level){
|
||||
FabricBlockInternals.computeExtraData(properties).addMiningLevel(FabricToolTags.PICKAXES, level);
|
||||
return properties;
|
||||
this.miningLevel = miningLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,30 +71,35 @@ public class BaseOreBlock extends OreBlock implements BlockModelProvider {
|
|||
return LootUtil
|
||||
.getDrops(this, state, builder)
|
||||
.orElseGet(
|
||||
()->BaseOreBlock.getDroppedItems(this, dropItem.get(), maxCount, minCount, state, builder)
|
||||
()->BaseOreBlock.getDroppedItems(this, dropItem.get(), maxCount, minCount, miningLevel, state, builder)
|
||||
);
|
||||
}
|
||||
|
||||
public static List<ItemStack> getDroppedItems(ItemLike block, Item dropItem, int maxCount, int minCount, BlockState state, LootContext.Builder builder) {
|
||||
public static List<ItemStack> getDroppedItems(ItemLike block, Item dropItem, int maxCount, int minCount, int miningLevel, BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && tool.isCorrectToolForDrops(state)) {
|
||||
if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(block));
|
||||
boolean canMine = miningLevel==0;
|
||||
if (tool.getItem() instanceof TieredItem tired) {
|
||||
canMine = tired.getTier().getLevel()>=miningLevel;
|
||||
}
|
||||
int count;
|
||||
int enchantment = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool);
|
||||
if (enchantment > 0) {
|
||||
int min = Mth.clamp(minCount + enchantment, minCount, maxCount);
|
||||
int max = maxCount + (enchantment / Enchantments.BLOCK_FORTUNE.getMaxLevel());
|
||||
if (min == max) {
|
||||
return Collections.singletonList(new ItemStack(dropItem, max));
|
||||
if (canMine) {
|
||||
if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(block));
|
||||
}
|
||||
count = MHelper.randRange(min, max, MHelper.RANDOM);
|
||||
int count;
|
||||
int enchantment = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool);
|
||||
if (enchantment > 0) {
|
||||
int min = Mth.clamp(minCount + enchantment, minCount, maxCount);
|
||||
int max = maxCount + (enchantment / Enchantments.BLOCK_FORTUNE.getMaxLevel());
|
||||
if (min == max) {
|
||||
return Collections.singletonList(new ItemStack(dropItem, max));
|
||||
}
|
||||
count = MHelper.randRange(min, max, MHelper.RANDOM);
|
||||
} else {
|
||||
count = MHelper.randRange(minCount, maxCount, MHelper.RANDOM);
|
||||
}
|
||||
return Collections.singletonList(new ItemStack(dropItem, count));
|
||||
}
|
||||
else {
|
||||
count = MHelper.randRange(minCount, maxCount, MHelper.RANDOM);
|
||||
}
|
||||
return Collections.singletonList(new ItemStack(dropItem, count));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.google.common.collect.Lists;
|
|||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
|
@ -40,12 +39,15 @@ import ru.bclib.client.models.PatternsHelper;
|
|||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.interfaces.TagProvider;
|
||||
import ru.bclib.interfaces.tools.AddMineableHoe;
|
||||
import ru.bclib.interfaces.tools.AddMineableShears;
|
||||
import ru.bclib.items.tool.BaseShearsItem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
public abstract class BasePlantBlock extends BaseBlockNotFull implements RenderLayerProvider, BonemealableBlock, TagProvider {
|
||||
public abstract class BasePlantBlock extends BaseBlockNotFull implements RenderLayerProvider, BonemealableBlock{
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||
|
||||
public BasePlantBlock() {
|
||||
|
@ -60,7 +62,6 @@ public abstract class BasePlantBlock extends BaseBlockNotFull implements RenderL
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(replaceable ? Material.REPLACEABLE_PLANT : Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.noCollission()
|
||||
);
|
||||
|
@ -70,7 +71,6 @@ public abstract class BasePlantBlock extends BaseBlockNotFull implements RenderL
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(replaceable ? Material.REPLACEABLE_PLANT : Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.luminance(light)
|
||||
.sound(SoundType.GRASS)
|
||||
.noCollission()
|
||||
|
@ -116,7 +116,8 @@ public abstract class BasePlantBlock extends BaseBlockNotFull implements RenderL
|
|||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
//TODO: 1.18.2 Test if shearing still works
|
||||
if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
Enchantments.SILK_TOUCH,
|
||||
tool
|
||||
) > 0) {
|
||||
|
@ -167,10 +168,4 @@ public abstract class BasePlantBlock extends BaseBlockNotFull implements RenderL
|
|||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_CROSS, resourceLocation);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTags(List<TagLocation<Block>> blockTags, List<TagLocation<Item>> itemTags) {
|
||||
blockTags.add(NamedMineableTags.SHEARS);
|
||||
blockTags.add(NamedMineableTags.HOE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ public abstract class BasePlantWithAgeBlock extends BasePlantBlock {
|
|||
public BasePlantWithAgeBlock() {
|
||||
this(
|
||||
FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.randomTicks()
|
||||
.noCollission()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
|
@ -15,6 +14,8 @@ import net.minecraft.world.level.block.RotatedPillarBlock;
|
|||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import ru.bclib.api.tag.NamedMineableTags;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
|
||||
public class BaseStripableLogBlock extends BaseRotatedPillarBlock {
|
||||
private final Block striped;
|
||||
|
@ -27,7 +28,7 @@ public class BaseStripableLogBlock extends BaseRotatedPillarBlock {
|
|||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (FabricToolTags.AXES.contains(player.getMainHandItem().getItem())) {
|
||||
if (TagAPI.isToolWithMineableTag(player.getMainHandItem(), NamedMineableTags.AXE)){
|
||||
world.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlock(pos,
|
||||
|
|
|
@ -3,8 +3,8 @@ package ru.bclib.blocks;
|
|||
import com.google.common.collect.Maps;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -33,6 +33,8 @@ import net.minecraft.world.level.storage.loot.LootContext;
|
|||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.bclib.api.tag.NamedMineableTags;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
@ -69,7 +71,9 @@ public class BaseTerrainBlock extends BaseBlock {
|
|||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (pathBlock != null && FabricToolTags.SHOVELS.contains(player.getMainHandItem().getItem())) {
|
||||
//TODO: 1.18.2 check
|
||||
if (pathBlock != null && TagAPI.isToolWithMineableTag(player.getMainHandItem(), NamedMineableTags.SHOVEL)){
|
||||
//if (pathBlock != null && FabricTagProvider.SHOVELS.contains(player.getMainHandItem().getItem())) {
|
||||
world.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlockAndUpdate(pos, pathBlock.defaultBlockState());
|
||||
|
|
|
@ -18,7 +18,6 @@ public abstract class BaseUnderwaterWallPlantBlock extends BaseWallPlantBlock im
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(Material.WATER_PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.noCollission()
|
||||
);
|
||||
|
@ -28,7 +27,6 @@ public abstract class BaseUnderwaterWallPlantBlock extends BaseWallPlantBlock im
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(Material.WATER_PLANT)
|
||||
.breakByHand(true)
|
||||
.luminance(light)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.noCollission()
|
||||
|
|
|
@ -2,7 +2,6 @@ package ru.bclib.blocks;
|
|||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
@ -31,6 +30,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
|||
import ru.bclib.blocks.BlockProperties.TripleShape;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.items.tool.BaseShearsItem;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -53,7 +53,6 @@ public class BaseVineBlock extends BaseBlockNotFull implements RenderLayerProvid
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.lightLevel((state) -> bottomOnly ? state.getValue(SHAPE) == TripleShape.BOTTOM ? light : 0 : light)
|
||||
.noCollission()
|
||||
|
@ -110,7 +109,7 @@ public class BaseVineBlock extends BaseBlockNotFull implements RenderLayerProvid
|
|||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
Enchantments.SILK_TOUCH,
|
||||
tool
|
||||
) > 0) {
|
||||
|
|
|
@ -39,7 +39,6 @@ public abstract class BaseWallPlantBlock extends BasePlantBlock {
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.noCollission()
|
||||
);
|
||||
|
@ -49,7 +48,6 @@ public abstract class BaseWallPlantBlock extends BasePlantBlock {
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.luminance(light)
|
||||
.sound(SoundType.GRASS)
|
||||
.noCollission()
|
||||
|
|
|
@ -44,7 +44,6 @@ public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProv
|
|||
|
||||
public FeatureSaplingBlock(Function<BlockState, Feature<?>> featureSupplier) {
|
||||
this(FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.collidable(false)
|
||||
.instabreak()
|
||||
.sound(SoundType.GRASS)
|
||||
|
@ -55,7 +54,6 @@ public class FeatureSaplingBlock extends SaplingBlock implements RenderLayerProv
|
|||
|
||||
public FeatureSaplingBlock(int light, Function<BlockState, Feature<?>> featureSupplier) {
|
||||
this(FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.collidable(false)
|
||||
.luminance(light)
|
||||
.instabreak()
|
||||
|
|
|
@ -14,10 +14,12 @@ import ru.bclib.api.tag.TagAPI.TagLocation;
|
|||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.interfaces.TagProvider;
|
||||
import ru.bclib.interfaces.tools.AddMineableHoe;
|
||||
import ru.bclib.interfaces.tools.AddMineableShears;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleLeavesBlock extends BaseBlockNotFull implements RenderLayerProvider, TagProvider {
|
||||
public class SimpleLeavesBlock extends BaseBlockNotFull implements RenderLayerProvider, TagProvider, AddMineableShears, AddMineableHoe {
|
||||
public SimpleLeavesBlock(MaterialColor color) {
|
||||
this(
|
||||
FabricBlockSettings
|
||||
|
@ -58,8 +60,6 @@ public class SimpleLeavesBlock extends BaseBlockNotFull implements RenderLayerPr
|
|||
|
||||
@Override
|
||||
public void addTags(List<TagLocation<Block>> blockTags, List<TagLocation<Item>> itemTags) {
|
||||
blockTags.add(NamedMineableTags.SHEARS);
|
||||
blockTags.add(NamedMineableTags.HOE);
|
||||
blockTags.add(NamedBlockTags.LEAVES);
|
||||
itemTags.add(NamedItemTags.LEAVES);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
|
@ -15,6 +14,8 @@ import net.minecraft.world.level.block.RotatedPillarBlock;
|
|||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import ru.bclib.api.tag.NamedMineableTags;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
|
||||
public class StripableBarkBlock extends BaseBarkBlock {
|
||||
private final Block striped;
|
||||
|
@ -27,7 +28,7 @@ public class StripableBarkBlock extends BaseBarkBlock {
|
|||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (FabricToolTags.AXES.contains(player.getMainHandItem().getItem())) {
|
||||
if (TagAPI.isToolWithMineableTag(player.getMainHandItem(), NamedMineableTags.AXE)){
|
||||
world.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlock(pos,
|
||||
|
|
|
@ -2,7 +2,6 @@ package ru.bclib.blocks;
|
|||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
@ -36,18 +35,20 @@ import ru.bclib.api.tag.TagAPI.TagLocation;
|
|||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.interfaces.TagProvider;
|
||||
import ru.bclib.interfaces.tools.AddMineableHoe;
|
||||
import ru.bclib.interfaces.tools.AddMineableShears;
|
||||
import ru.bclib.items.tool.BaseShearsItem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements RenderLayerProvider, BonemealableBlock, LiquidBlockContainer, TagProvider {
|
||||
public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements RenderLayerProvider, BonemealableBlock, LiquidBlockContainer {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||
|
||||
public UnderwaterPlantBlock() {
|
||||
this(
|
||||
FabricBlockSettings
|
||||
.of(Material.WATER_PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.noCollission()
|
||||
);
|
||||
|
@ -57,7 +58,6 @@ public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements R
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(Material.WATER_PLANT)
|
||||
.breakByHand(true)
|
||||
.luminance(light)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.noCollission()
|
||||
|
@ -105,7 +105,7 @@ public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements R
|
|||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
Enchantments.SILK_TOUCH,
|
||||
tool
|
||||
) > 0) {
|
||||
|
@ -158,10 +158,5 @@ public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements R
|
|||
public FluidState getFluidState(BlockState state) {
|
||||
return Fluids.WATER.getSource(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTags(List<TagLocation<Block>> blockTags, List<TagLocation<Item>> itemTags) {
|
||||
blockTags.add(NamedMineableTags.SHEARS);
|
||||
blockTags.add(NamedMineableTags.HOE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ public abstract class UnderwaterPlantWithAgeBlock extends UnderwaterPlantBlock {
|
|||
super(
|
||||
FabricBlockSettings
|
||||
.of(Material.WATER_PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.randomTicks()
|
||||
.noCollission()
|
||||
|
|
|
@ -2,7 +2,6 @@ package ru.bclib.blocks;
|
|||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
@ -30,16 +29,18 @@ import ru.bclib.api.tag.TagAPI.TagLocation;
|
|||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.RenderLayerProvider;
|
||||
import ru.bclib.interfaces.TagProvider;
|
||||
import ru.bclib.interfaces.tools.AddMineableHoe;
|
||||
import ru.bclib.interfaces.tools.AddMineableShears;
|
||||
import ru.bclib.items.tool.BaseShearsItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class UpDownPlantBlock extends BaseBlockNotFull implements RenderLayerProvider, TagProvider {
|
||||
public abstract class UpDownPlantBlock extends BaseBlockNotFull implements RenderLayerProvider, AddMineableShears, AddMineableHoe {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 16, 12);
|
||||
|
||||
public UpDownPlantBlock() {
|
||||
this(FabricBlockSettings
|
||||
.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.noCollission()
|
||||
);
|
||||
|
@ -83,7 +84,7 @@ public abstract class UpDownPlantBlock extends BaseBlockNotFull implements Rende
|
|||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
Enchantments.SILK_TOUCH,
|
||||
tool
|
||||
) > 0) {
|
||||
|
@ -104,10 +105,4 @@ public abstract class UpDownPlantBlock extends BaseBlockNotFull implements Rende
|
|||
super.playerDestroy(world, player, pos, state, blockEntity, stack);
|
||||
world.neighborChanged(pos, Blocks.AIR, pos.below());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTags(List<TagLocation<Block>> blockTags, List<TagLocation<Item>> itemTags) {
|
||||
blockTags.add(NamedMineableTags.SHEARS);
|
||||
blockTags.add(NamedMineableTags.HOE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ public abstract class WallMushroomBlock extends BaseWallPlantBlock {
|
|||
this(
|
||||
FabricBlockSettings
|
||||
.of(Material.PLANT)
|
||||
.breakByHand(true)
|
||||
.luminance(light)
|
||||
.destroyTime(0.2F)
|
||||
.sound(SoundType.GRASS)
|
||||
|
|
|
@ -108,12 +108,12 @@ public class CustomFogRenderer {
|
|||
}
|
||||
|
||||
private static boolean shouldIgnore(Level level, int x, int y, int z) {
|
||||
Biome biome = level.getBiome(MUT_POS.set(x, y, z));
|
||||
Biome biome = level.getBiome(MUT_POS.set(x, y, z)).value();
|
||||
return BiomeAPI.getRenderBiome(biome) == BiomeAPI.EMPTY_BIOME;
|
||||
}
|
||||
|
||||
private static float getFogDensityI(Level level, int x, int y, int z) {
|
||||
Biome biome = level.getBiome(MUT_POS.set(x, y, z));
|
||||
Biome biome = level.getBiome(MUT_POS.set(x, y, z)).value();
|
||||
BCLBiome renderBiome = BiomeAPI.getRenderBiome(biome);
|
||||
return renderBiome.getFogDensity();
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
|||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -32,8 +32,8 @@ public abstract class ComplexMaterial {
|
|||
private final List<BlockEntry> defaultBlockEntries = Lists.newArrayList();
|
||||
private final List<ItemEntry> defaultItemEntries = Lists.newArrayList();
|
||||
|
||||
private final Map<String, Tag.Named<Block>> blockTags = Maps.newHashMap();
|
||||
private final Map<String, Tag.Named<Item>> itemTags = Maps.newHashMap();
|
||||
private final Map<String, TagKey<Block>> blockTags = Maps.newHashMap();
|
||||
private final Map<String, TagKey<Item>> itemTags = Maps.newHashMap();
|
||||
private final Map<String, Block> blocks = Maps.newHashMap();
|
||||
private final Map<String, Item> items = Maps.newHashMap();
|
||||
|
||||
|
@ -105,39 +105,39 @@ public abstract class ComplexMaterial {
|
|||
|
||||
/**
|
||||
* Adds custom block tag for this {@link ComplexMaterial}, tag can be created with {@link TagAPI} or you can use one of already created tags.
|
||||
* @param tag {@link Tag.Named} for {@link Block}
|
||||
* @param tag {@link TagKey} for {@link Block}
|
||||
*/
|
||||
protected void addBlockTag(Tag.Named<Block> tag) {
|
||||
String key = tag.getName().getPath().replace(getBaseName() + "_", "");
|
||||
protected void addBlockTag(TagKey<Block> tag) {
|
||||
String key = tag.location().getPath().replace(getBaseName() + "_", "");
|
||||
blockTags.put(key, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom iten tag for this {@link ComplexMaterial}, tag can be created with {@link TagAPI} or you can use one of already created tags.
|
||||
* @param tag {@link Tag.Named} for {@link Item}
|
||||
* Adds custom item tag for this {@link ComplexMaterial}, tag can be created with {@link TagAPI} or you can use one of already created tags.
|
||||
* @param tag {@link TagKey} for {@link Item}
|
||||
*/
|
||||
protected void addItemTag(Tag.Named<Item> tag) {
|
||||
String key = tag.getName().getPath().replace(getBaseName() + "_", "");
|
||||
protected void addItemTag(TagKey<Item> tag) {
|
||||
String key = tag.location().getPath().replace(getBaseName() + "_", "");
|
||||
itemTags.put(key, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom {@link Block} {@link Tag.Named} from this {@link ComplexMaterial}.
|
||||
* Get custom {@link Block} {@link TagKey} from this {@link ComplexMaterial}.
|
||||
* @param key {@link String} tag name (path of its {@link ResourceLocation}), for inner tags created inside material its tag suffix.
|
||||
* @return {@link Tag.Named} for {@link Block} or {@code null} if nothing is stored.
|
||||
* @return {@link TagKey} for {@link Block} or {@code null} if nothing is stored.
|
||||
*/
|
||||
@Nullable
|
||||
public Tag.Named<Block> getBlockTag(String key) {
|
||||
public TagKey<Block> getBlockTag(String key) {
|
||||
return blockTags.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom {@link Item} {@link Tag.Named} from this {@link ComplexMaterial}.
|
||||
* Get custom {@link Item} {@link TagKey} from this {@link ComplexMaterial}.
|
||||
* @param key {@link String} tag name (path of its {@link ResourceLocation}), for inner tags created inside material its tag suffix.
|
||||
* @return {@link Tag.Named} for {@link Item} or {@code null} if nothing is stored.
|
||||
* @return {@link TagKey} for {@link Item} or {@code null} if nothing is stored.
|
||||
*/
|
||||
@Nullable
|
||||
public Tag.Named<Item> getItemTag(String key) {
|
||||
public TagKey<Item> getItemTag(String key) {
|
||||
return itemTags.get(key);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,8 +100,8 @@ public class WoodenComplexMaterial extends ComplexMaterial {
|
|||
}
|
||||
|
||||
final protected void initBase(FabricBlockSettings blockSettings, FabricItemSettings itemSettings) {
|
||||
TagLocation<Block> tagBlockLog = new TagLocation<>(getBlockTag(TAG_LOGS).getName());
|
||||
TagLocation<Item> tagItemLog = new TagLocation<>(getItemTag(TAG_LOGS).getName());
|
||||
TagLocation<Block> tagBlockLog = TagLocation.of(getBlockTag(TAG_LOGS));
|
||||
TagLocation<Item> tagItemLog = TagLocation.of(getItemTag(TAG_LOGS));
|
||||
|
||||
addBlockEntry(
|
||||
new BlockEntry(BLOCK_STRIPPED_LOG, (complexMaterial, settings) -> new BaseRotatedPillarBlock(settings))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package ru.bclib.integration;
|
||||
|
||||
import net.fabricmc.fabric.api.tag.TagFactory;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
@ -9,7 +9,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.Tag.Named;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
@ -19,6 +19,7 @@ import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
|||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
import ru.bclib.world.features.BCLFeature;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
@ -38,6 +39,10 @@ public abstract class ModIntegration {
|
|||
public ResourceLocation getID(String name) {
|
||||
return new ResourceLocation(modID, name);
|
||||
}
|
||||
|
||||
public ResourceKey<PlacedFeature> getFeatureKey(String name) {
|
||||
return ResourceKey.create(Registry.PLACED_FEATURE_REGISTRY, getID(name));
|
||||
}
|
||||
|
||||
public Block getBlock(String name) {
|
||||
return Registry.BLOCK.get(getID(name));
|
||||
|
@ -62,8 +67,8 @@ public abstract class ModIntegration {
|
|||
public BCLFeature getFeature(String featureID, String placedFeatureID, GenerationStep.Decoration featureStep) {
|
||||
ResourceLocation id = getID(featureID);
|
||||
Feature<?> feature = Registry.FEATURE.get(id);
|
||||
PlacedFeature featureConfigured = BuiltinRegistries.PLACED_FEATURE.get(getID(placedFeatureID));
|
||||
return new BCLFeature(id, feature, featureStep, featureConfigured);
|
||||
Holder<PlacedFeature> featurePlaced = BuiltinRegistries.PLACED_FEATURE.getHolder(getFeatureKey(placedFeatureID)).orElse(null);
|
||||
return new BCLFeature(id, feature, featureStep, featurePlaced);
|
||||
}
|
||||
|
||||
public BCLFeature getFeature(String name, GenerationStep.Decoration featureStep) {
|
||||
|
@ -74,8 +79,8 @@ public abstract class ModIntegration {
|
|||
return BuiltinRegistries.CONFIGURED_FEATURE.get(getID(name));
|
||||
}
|
||||
|
||||
public Biome getBiome(String name) {
|
||||
return BuiltinRegistries.BIOME.get(getID(name));
|
||||
public Holder<Biome> getBiome(String name) {
|
||||
return BuiltinRegistries.BIOME.getHolder(getKey(name)).orElseThrow();
|
||||
}
|
||||
|
||||
public Class<?> getClass(String path) {
|
||||
|
@ -197,18 +202,13 @@ public abstract class ModIntegration {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Tag.Named<Item> getItemTag(String name) {
|
||||
public TagKey<Item> getItemTag(String name) {
|
||||
ResourceLocation id = getID(name);
|
||||
Tag<Item> tag = ItemTags.getAllTags().getTag(id);
|
||||
|
||||
//return tag == null ? (Named<Item>) TagRegistry.item(id) : (Named<Item>) tag;
|
||||
return tag == null ? (Named<Item>) TagFactory.ITEM.create(id) : (Named<Item>) tag;
|
||||
return TagAPI.makeItemTag(id);
|
||||
}
|
||||
|
||||
public Tag.Named<Block> getBlockTag(String name) {
|
||||
public TagKey<Block> getBlockTag(String name) {
|
||||
ResourceLocation id = getID(name);
|
||||
Tag<Block> tag = BlockTags.getAllTags().getTag(id);
|
||||
//return tag == null ? (Named<Block>) TagRegistry.block(id) : (Named<Block>) tag;
|
||||
return tag == null ? (Named<Block>) TagFactory.BLOCK.create(id) : (Named<Block>) tag;
|
||||
return TagAPI.makeBlockTag(id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package ru.bclib.interfaces;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
|
||||
public interface ChunkGeneratorAccessor {
|
||||
Registry<StructureSet> bclib_getStructureSetsRegistry();
|
||||
}
|
|
@ -12,7 +12,7 @@ import java.util.function.Function;
|
|||
|
||||
public interface NumericProvider {
|
||||
ResourceKey<Registry<Codec<? extends NumericProvider>>> NUMERIC_PROVIDER_REGISTRY = ResourceKey.createRegistryKey(BCLib.makeID("worldgen/numeric_provider"));
|
||||
Registry<Codec<? extends NumericProvider>> NUMERIC_PROVIDER = new MappedRegistry<>(NUMERIC_PROVIDER_REGISTRY, Lifecycle.experimental());
|
||||
Registry<Codec<? extends NumericProvider>> NUMERIC_PROVIDER = new MappedRegistry<>(NUMERIC_PROVIDER_REGISTRY, Lifecycle.experimental(), null);
|
||||
Codec<NumericProvider> CODEC = NUMERIC_PROVIDER.byNameCodec().dispatch(NumericProvider::pcodec, Function.identity());
|
||||
int getNumber(SurfaceRulesContextAccessor context);
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package ru.bclib.interfaces;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public interface SurfaceProvider {
|
||||
public BlockState bclib_getSurface(BlockPos pos, Biome biome, ServerLevel level);
|
||||
public BlockState bclib_getSurface(BlockPos pos, Holder<Biome> biome, ServerLevel level);
|
||||
}
|
||||
|
|
33
src/main/java/ru/bclib/interfaces/SurvivesOnBlocks.java
Normal file
33
src/main/java/ru/bclib/interfaces/SurvivesOnBlocks.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package ru.bclib.interfaces;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface SurvivesOnBlocks extends SurvivesOnSpecialGround{
|
||||
List<Block> getSurvivableBlocks();
|
||||
|
||||
@Override
|
||||
default String getSurvivableBlocksString(){
|
||||
return getSurvivableBlocks()
|
||||
.stream()
|
||||
.filter(block -> block!= Blocks.AIR && block!=null)
|
||||
.map(block -> {
|
||||
ItemStack stack = new ItemStack(block);
|
||||
if (stack.hasCustomHoverName()) return stack.getHoverName().getString();
|
||||
else return block.getName().getString();
|
||||
})
|
||||
.sorted(Comparator.naturalOrder())
|
||||
.collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isSurvivable(BlockState state){
|
||||
return getSurvivableBlocks().contains(state.getBlock());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package ru.bclib.interfaces;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SurvivesOnSpecialGround {
|
||||
String getSurvivableBlocksString();
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
static List<String> splitLines(String input) {
|
||||
final int MAX_LEN = 45;
|
||||
List<String> lines = Lists.newArrayList();
|
||||
|
||||
while (input.length()>MAX_LEN){
|
||||
int idx = input.lastIndexOf(",", MAX_LEN);
|
||||
if (idx>=0) {
|
||||
lines.add( input.substring(0, idx+1).trim());
|
||||
input = input.substring(idx+1).trim();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lines.add(input.trim());
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
static void appendHoverText(List<Component> list, String description) {
|
||||
final int MAX_LINES = 7;
|
||||
List<String> lines = splitLines(description);
|
||||
if (lines.size()==1) {
|
||||
list.add(new TranslatableComponent("tooltip.bclib.place_on", lines.get(0)).withStyle(ChatFormatting.GREEN));
|
||||
} else if (lines.size()>1) {
|
||||
list.add(new TranslatableComponent("tooltip.bclib.place_on", "").withStyle(ChatFormatting.GREEN));
|
||||
for (int i = 0; i < Math.min(lines.size(), MAX_LINES); i++) {
|
||||
String line = lines.get(i);
|
||||
if (i == MAX_LINES - 1 && i < lines.size() - 1) line += " ...";
|
||||
list.add(new TextComponent(" " + line).withStyle(ChatFormatting.GREEN));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isSurvivable(BlockState state);
|
||||
|
||||
default boolean canSurviveOnTop(BlockState state, LevelReader world, BlockPos pos) {
|
||||
return isSurvivable(world.getBlockState(pos.below()));
|
||||
}
|
||||
|
||||
default boolean canSurviveOnBottom(BlockState state, LevelReader world, BlockPos pos) {
|
||||
return isSurvivable(world.getBlockState(pos.above()));
|
||||
}
|
||||
}
|
40
src/main/java/ru/bclib/interfaces/SurvivesOnTags.java
Normal file
40
src/main/java/ru/bclib/interfaces/SurvivesOnTags.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package ru.bclib.interfaces;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.NetherrackBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface SurvivesOnTags extends SurvivesOnSpecialGround{
|
||||
List<TagKey<Block>> getSurvivableTags();
|
||||
|
||||
@Override
|
||||
default String getSurvivableBlocksString(){
|
||||
return getSurvivableTags()
|
||||
.stream()
|
||||
.map(tag -> Registry.BLOCK.getTag(tag))
|
||||
.filter(named->named.isPresent())
|
||||
.map(named->named.get())
|
||||
.flatMap(named->named.stream())
|
||||
.filter(block -> block != Blocks.AIR && block != null)
|
||||
.map(block -> {
|
||||
ItemStack stack = new ItemStack(block.value());
|
||||
if (stack.hasCustomHoverName()) return stack.getHoverName().getString();
|
||||
else return block.value().getName().getString();
|
||||
})
|
||||
.sorted(Comparator.naturalOrder())
|
||||
.collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isSurvivable(BlockState state){
|
||||
return getSurvivableTags().stream().anyMatch(tag->state.is(tag));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ru.bclib.interfaces.tools;
|
||||
|
||||
public interface AddMineableAxe {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ru.bclib.interfaces.tools;
|
||||
|
||||
public interface AddMineableHammer {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ru.bclib.interfaces.tools;
|
||||
|
||||
public interface AddMineableHoe {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ru.bclib.interfaces.tools;
|
||||
|
||||
public interface AddMineablePickaxe {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ru.bclib.interfaces.tools;
|
||||
|
||||
public interface AddMineableShears {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ru.bclib.interfaces.tools;
|
||||
|
||||
public interface AddMineableShovel {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ru.bclib.interfaces.tools;
|
||||
|
||||
public interface AddMineableSword {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ru.bclib.interfaces.tools;
|
||||
|
||||
public interface PreventMineableAdd {
|
||||
}
|
|
@ -2,33 +2,18 @@ package ru.bclib.items.tool;
|
|||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.AxeItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Tier;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.interfaces.ItemModelProvider;
|
||||
|
||||
public class BaseAxeItem extends AxeItem implements DynamicAttributeTool, ItemModelProvider {
|
||||
public class BaseAxeItem extends AxeItem implements ItemModelProvider {
|
||||
public BaseAxeItem(Tier material, float attackDamage, float attackSpeed, Properties settings) {
|
||||
super(material, attackDamage, attackSpeed, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMiningLevel(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (tag.equals(FabricToolTags.AXES)) {
|
||||
return this.getTier().getLevel();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
|
|
|
@ -2,44 +2,18 @@ package ru.bclib.items.tool;
|
|||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
||||
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl.Entry;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.PickaxeItem;
|
||||
import net.minecraft.world.item.Tier;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.interfaces.ItemModelProvider;
|
||||
|
||||
public class BasePickaxeItem extends PickaxeItem implements DynamicAttributeTool, ItemModelProvider {
|
||||
public class BasePickaxeItem extends PickaxeItem implements ItemModelProvider {
|
||||
public BasePickaxeItem(Tier material, int attackDamage, float attackSpeed, Properties settings) {
|
||||
super(material, attackDamage, attackSpeed, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMiningLevel(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (tag.equals(FabricToolTags.PICKAXES)) {
|
||||
return getTier().getLevel();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDestroySpeed(ItemStack stack, BlockState state) {
|
||||
Entry entry = ToolManagerImpl.entryNullable(state.getBlock());
|
||||
return (entry != null && entry.getMiningLevel(FabricToolTags.PICKAXES) >= 0) ? speed : super.getDestroySpeed(
|
||||
stack,
|
||||
state
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package ru.bclib.items.tool;
|
||||
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
|
||||
import net.fabricmc.fabric.api.mininglevel.v1.FabricMineableTags;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.ShearsItem;
|
||||
import ru.bclib.api.tag.CommonItemTags;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
|
||||
public class BaseShearsItem extends ShearsItem {
|
||||
public BaseShearsItem(Properties properties) {
|
||||
|
@ -13,12 +15,12 @@ public class BaseShearsItem extends ShearsItem {
|
|||
}
|
||||
|
||||
public static boolean isShear(ItemStack tool){
|
||||
return tool.is(Items.SHEARS) | tool.is(CommonItemTags.SHEARS) || tool.is(FabricToolTags.SHEARS);
|
||||
return tool.is(Items.SHEARS) | tool.is(CommonItemTags.SHEARS) || TagAPI.isToolWithMineableTag(tool, FabricMineableTags.SHEARS_MINEABLE);
|
||||
}
|
||||
|
||||
public static boolean isShear(ItemStack itemStack, Item item){
|
||||
if (item == Items.SHEARS){
|
||||
return itemStack.is(item) | itemStack.is(CommonItemTags.SHEARS) || itemStack.is(FabricToolTags.SHEARS);
|
||||
return itemStack.is(item) | itemStack.is(CommonItemTags.SHEARS);
|
||||
} else {
|
||||
return itemStack.is(item);
|
||||
}
|
||||
|
|
|
@ -2,44 +2,18 @@ package ru.bclib.items.tool;
|
|||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
||||
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl.Entry;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.ShovelItem;
|
||||
import net.minecraft.world.item.Tier;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.interfaces.ItemModelProvider;
|
||||
|
||||
public class BaseShovelItem extends ShovelItem implements DynamicAttributeTool, ItemModelProvider {
|
||||
public class BaseShovelItem extends ShovelItem implements ItemModelProvider {
|
||||
public BaseShovelItem(Tier material, float attackDamage, float attackSpeed, Properties settings) {
|
||||
super(material, attackDamage, attackSpeed, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMiningLevel(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||
if (tag.equals(FabricToolTags.SHOVELS)) {
|
||||
return this.getTier().getLevel();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDestroySpeed(ItemStack stack, BlockState state) {
|
||||
Entry entry = ToolManagerImpl.entryNullable(state.getBlock());
|
||||
return (entry != null && entry.getMiningLevel(FabricToolTags.SHOVELS) >= 0) ? speed : super.getDestroySpeed(
|
||||
stack,
|
||||
state
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
|
|
|
@ -2,7 +2,6 @@ package ru.bclib.items.tool;
|
|||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.SwordItem;
|
||||
|
@ -10,7 +9,7 @@ import net.minecraft.world.item.Tier;
|
|||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.interfaces.ItemModelProvider;
|
||||
|
||||
public class BaseSwordItem extends SwordItem implements DynamicAttributeTool, ItemModelProvider {
|
||||
public class BaseSwordItem extends SwordItem implements ItemModelProvider {
|
||||
public BaseSwordItem(Tier material, int attackDamage, float attackSpeed, Properties settings) {
|
||||
super(material, attackDamage, attackSpeed, settings);
|
||||
}
|
||||
|
|
25
src/main/java/ru/bclib/mixin/client/BlockMixin.java
Normal file
25
src/main/java/ru/bclib/mixin/client/BlockMixin.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package ru.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.CallbackInfo;
|
||||
import ru.bclib.interfaces.SurvivesOnSpecialGround;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(Block.class)
|
||||
public class BlockMixin {
|
||||
@Inject(method="appendHoverText", at=@At("HEAD"))
|
||||
void bclib_appendSurvivalBlock(ItemStack itemStack, @Nullable BlockGetter blockGetter, List<Component> list, TooltipFlag tooltipFlag, CallbackInfo ci){
|
||||
if (this instanceof SurvivesOnSpecialGround surv){
|
||||
SurvivesOnSpecialGround.appendHoverText(list, surv.getSurvivableBlocksString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,13 +15,13 @@ public abstract class EnchantingTableBlockMixin extends Block {
|
|||
super(settings);
|
||||
}
|
||||
|
||||
@Redirect(method = "animateTick", at = @At(
|
||||
@Redirect(method = "isValidBookShelf", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z"),
|
||||
require = -1,
|
||||
expect = -1
|
||||
)
|
||||
private boolean bclib_isBookshelf(BlockState state, Block block) {
|
||||
private static boolean bclib_isBookshelf(BlockState state, Block block) {
|
||||
return block == Blocks.BOOKSHELF ? state.is(CommonBlockTags.BOOKSHELVES) : state.is(block);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ru.bclib.mixin.client;
|
||||
|
||||
import com.mojang.datafixers.util.Function4;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Minecraft.ExperimentalDialogType;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
|
@ -8,14 +7,11 @@ import net.minecraft.client.color.item.ItemColors;
|
|||
import net.minecraft.client.main.GameConfig;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.RegistryAccess.RegistryHolder;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.world.level.DataPackConfig;
|
||||
import net.minecraft.server.WorldStem;
|
||||
import net.minecraft.world.level.LevelSettings;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
|
||||
import net.minecraft.world.level.storage.WorldData;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -44,17 +40,15 @@ public abstract class MinecraftMixin {
|
|||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_onMCInit(GameConfig args, CallbackInfo info) {
|
||||
Registry.BLOCK.forEach(block -> {
|
||||
if (block instanceof CustomColorProvider) {
|
||||
CustomColorProvider provider = (CustomColorProvider) block;
|
||||
if (block instanceof CustomColorProvider provider) {
|
||||
blockColors.register(provider.getProvider(), block);
|
||||
itemColors.register(provider.getItemProvider(), block.asItem());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Shadow
|
||||
protected abstract void doLoadLevel(String string, RegistryHolder registryHolder, Function<LevelStorageAccess, DataPackConfig> function, Function4<LevelStorageAccess, RegistryHolder, ResourceManager, DataPackConfig, WorldData> function4, boolean bl, ExperimentalDialogType experimentalDialogType);
|
||||
|
||||
|
||||
@Shadow protected abstract void doLoadLevel(String string, Function<LevelStorageAccess, WorldStem.DataPackConfigSupplier> function, Function<LevelStorageAccess, WorldStem.WorldDataSupplier> function2, boolean bl, ExperimentalDialogType experimentalDialogType);
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private LevelStorageSource levelSource;
|
||||
|
@ -66,7 +60,7 @@ public abstract class MinecraftMixin {
|
|||
|
||||
if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> {
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
this.doLoadLevel(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false, appliedFixes ? ExperimentalDialogType.NONE : ExperimentalDialogType.BACKUP);
|
||||
this.doLoadLevel(levelID, WorldStem.DataPackConfigSupplier::loadFromWorld, WorldStem.WorldDataSupplier::loadFromWorld, false, appliedFixes ? ExperimentalDialogType.NONE : ExperimentalDialogType.BACKUP);
|
||||
})) {
|
||||
//cancle call when fix-screen is presented
|
||||
ci.cancel();
|
||||
|
@ -74,7 +68,7 @@ public abstract class MinecraftMixin {
|
|||
else {
|
||||
LifeCycleAPI._runBeforeLevelLoad();
|
||||
if (Configs.CLIENT_CONFIG.suppressExperimentalDialog()) {
|
||||
this.doLoadLevel(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false, ExperimentalDialogType.NONE);
|
||||
this.doLoadLevel(levelID, WorldStem.DataPackConfigSupplier::loadFromWorld, WorldStem.WorldDataSupplier::loadFromWorld, false, ExperimentalDialogType.NONE);
|
||||
//cancle call as we manually start the level load here
|
||||
ci.cancel();
|
||||
}
|
||||
|
@ -82,7 +76,7 @@ public abstract class MinecraftMixin {
|
|||
}
|
||||
|
||||
@Inject(method = "createLevel", at = @At("HEAD"))
|
||||
private void bclib_initPatchData(String levelID, LevelSettings levelSettings, RegistryHolder registryHolder, WorldGenSettings worldGenSettings, CallbackInfo ci) {
|
||||
private void bclib_initPatchData(String levelID, LevelSettings levelSettings, RegistryAccess registryAccess, WorldGenSettings worldGenSettings, CallbackInfo ci) {
|
||||
DataExchangeAPI.prepareServerside();
|
||||
BiomeAPI.prepareNewLevel();
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@ package ru.bclib.mixin.client;
|
|||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.FallbackResourceManager;
|
||||
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.server.packs.resources.SimpleReloadableResourceManager;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -18,14 +18,14 @@ import ru.bclib.client.render.EmissiveTextureInfo;
|
|||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(SimpleReloadableResourceManager.class)
|
||||
public class SimpleReloadableResourceManagerMixin {
|
||||
@Mixin(MultiPackResourceManager.class)
|
||||
public class MultiPackResourceManagerMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private Map<String, FallbackResourceManager> namespacedPacks;
|
||||
|
||||
private Map<String, FallbackResourceManager> namespacedManagers;
|
||||
|
||||
private ResourceLocation bclib_alphaEmissionMaterial = BCLib.makeID("materialmaps/block/alpha_emission.json");
|
||||
|
||||
|
||||
@Inject(method = "getResource", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_getResource(ResourceLocation resourceLocation, CallbackInfoReturnable<Resource> info) throws IOException {
|
||||
if (!ModIntegrationAPI.hasCanvas()) {
|
||||
|
@ -37,15 +37,15 @@ public class SimpleReloadableResourceManagerMixin {
|
|||
if (!resourceLocation.getPath().contains("/block/")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String name = resourceLocation.getPath().replace("materialmaps/block/", "").replace(".json", "");
|
||||
ResourceLocation blockID = new ResourceLocation(resourceLocation.getNamespace(), name);
|
||||
|
||||
|
||||
if (!EmissiveTextureInfo.isEmissiveBlock(blockID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceManager resourceManager = this.namespacedPacks.get(resourceLocation.getNamespace());
|
||||
|
||||
ResourceManager resourceManager = this.namespacedManagers.get(resourceLocation.getNamespace());
|
||||
if (resourceManager != null && !resourceManager.hasResource(resourceLocation)) {
|
||||
info.setReturnValue(resourceManager.getResource(bclib_alphaEmissionMaterial));
|
||||
}
|
|
@ -13,7 +13,7 @@ import ru.bclib.api.biomes.BiomeAPI;
|
|||
@Mixin(WorldPreset.class)
|
||||
public class WorldPresetMixin {
|
||||
@Inject(method = "create", at = @At("HEAD"))
|
||||
private void bclib_create(RegistryAccess.RegistryHolder registryHolder, long l, boolean bl, boolean bl2, CallbackInfoReturnable<WorldGenSettings> info) {
|
||||
BiomeAPI.initRegistry(registryHolder.registryOrThrow(Registry.BIOME_REGISTRY));
|
||||
private void bclib_create(RegistryAccess registryAccess, long l, boolean bl, boolean bl2, CallbackInfoReturnable<WorldGenSettings> info) {
|
||||
BiomeAPI.initRegistry(registryAccess.registryOrThrow(Registry.BIOME_REGISTRY));
|
||||
}
|
||||
}
|
||||
|
|
13
src/main/java/ru/bclib/mixin/common/BiomeAccessor.java
Normal file
13
src/main/java/ru/bclib/mixin/common/BiomeAccessor.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(Biome.class)
|
||||
public interface BiomeAccessor {
|
||||
@Accessor("biomeCategory")
|
||||
@Mutable
|
||||
Biome.BiomeCategory bclib_getBiomeCategory();
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.world.level.biome.BiomeGenerationSettings;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Carving;
|
||||
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
|
@ -17,21 +19,21 @@ import java.util.function.Supplier;
|
|||
@Mixin(BiomeGenerationSettings.class)
|
||||
public interface BiomeGenerationSettingsAccessor {
|
||||
@Accessor("features")
|
||||
List<List<Supplier<PlacedFeature>>> bclib_getFeatures();
|
||||
List<HolderSet<PlacedFeature>> bclib_getFeatures();
|
||||
|
||||
@Accessor("features")
|
||||
@Mutable
|
||||
void bclib_setFeatures(List<List<Supplier<PlacedFeature>>> value);
|
||||
void bclib_setFeatures(List<HolderSet<PlacedFeature>> value);
|
||||
|
||||
@Accessor("featureSet")
|
||||
Set<PlacedFeature> bclib_getFeatureSet();
|
||||
|
||||
@Accessor("featureSet")
|
||||
void bclib_setFeatureSet(Set<PlacedFeature> features);
|
||||
void bclib_setFeatureSet(Supplier<Set<PlacedFeature>> featureSet);
|
||||
|
||||
@Accessor("flowerFeatures")
|
||||
void bclib_setFlowerFeatures(Supplier<List<ConfiguredFeature<?, ?>>> flowerFeatures);
|
||||
|
||||
@Accessor("carvers")
|
||||
Map<Carving, List<Supplier<ConfiguredWorldCarver<?>>>> bclib_getCarvers();
|
||||
Map<GenerationStep.Carving, HolderSet<ConfiguredWorldCarver<?>>> bclib_getCarvers();
|
||||
|
||||
@Accessor("carvers")
|
||||
void bclib_setCarvers(Map<GenerationStep.Carving, List<Supplier<ConfiguredWorldCarver<?>>>> features);
|
||||
void bclib_setCarvers(Map<GenerationStep.Carving, HolderSet<ConfiguredWorldCarver<?>>> features);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.BiomeSource.StepFeatureData;
|
||||
|
@ -12,6 +13,7 @@ import ru.bclib.interfaces.BiomeSourceAccessor;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BiomeSource.class)
|
||||
public abstract class BiomeSourceMixin implements BiomeSourceAccessor {
|
||||
|
@ -19,10 +21,10 @@ public abstract class BiomeSourceMixin implements BiomeSourceAccessor {
|
|||
|
||||
@Shadow public abstract Set<Biome> possibleBiomes();
|
||||
|
||||
@Mutable @Shadow @Final private List<StepFeatureData> featuresPerStep;
|
||||
@Mutable @Shadow @Final private Supplier<List<StepFeatureData>> featuresPerStep;
|
||||
|
||||
public void bclRebuildFeatures(){
|
||||
BCLib.LOGGER.info("Rebuilding features in BiomeSource " + this);
|
||||
featuresPerStep = buildFeaturesPerStep(this.possibleBiomes().stream().toList(), true);
|
||||
featuresPerStep = Suppliers.memoize(() -> buildFeaturesPerStep(this.possibleBiomes().stream().toList(), true));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.StructureFeatureManager;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import ru.bclib.interfaces.ChunkGeneratorAccessor;
|
||||
|
||||
@Mixin(ChunkGenerator.class)
|
||||
public class ChunkGeneratorMixin {
|
||||
public class ChunkGeneratorMixin implements ChunkGeneratorAccessor {
|
||||
@Shadow @Final protected Registry<StructureSet> structureSets;
|
||||
private int bclib_featureIteratorSeed;
|
||||
|
||||
@ModifyArg(method = "applyBiomeDecoration", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/WorldgenRandom;setFeatureSeed(JII)V"))
|
||||
|
@ -23,4 +29,8 @@ public class ChunkGeneratorMixin {
|
|||
private void bclib_obBiomeGenerate(WorldGenLevel worldGenLevel, ChunkAccess chunkAccess, StructureFeatureManager structureFeatureManager, CallbackInfo ci) {
|
||||
bclib_featureIteratorSeed = 0;
|
||||
}
|
||||
|
||||
public Registry<StructureSet> bclib_getStructureSetsRegistry(){
|
||||
return structureSets;
|
||||
}
|
||||
}
|
||||
|
|
21
src/main/java/ru/bclib/mixin/common/DiggerItemAccessor.java
Normal file
21
src/main/java/ru/bclib/mixin/common/DiggerItemAccessor.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.DiggerItem;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(DiggerItem.class)
|
||||
public interface DiggerItemAccessor {
|
||||
@Accessor("blocks")
|
||||
@Mutable
|
||||
TagKey<Block> bclib_getBlockTag();
|
||||
}
|
|
@ -4,12 +4,17 @@ import com.mojang.serialization.Lifecycle;
|
|||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
@ -23,41 +28,42 @@ import java.util.OptionalInt;
|
|||
@Mixin(DimensionType.class)
|
||||
public class DimensionTypeMixin {
|
||||
@Inject(
|
||||
method = "defaultDimensions(Lnet/minecraft/core/RegistryAccess;JZ)Lnet/minecraft/core/MappedRegistry;",
|
||||
method = "defaultDimensions(Lnet/minecraft/core/RegistryAccess;JZ)Lnet/minecraft/core/Registry;",
|
||||
locals = LocalCapture.CAPTURE_FAILHARD,
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private static void bclib_updateDimensions(RegistryAccess registryAccess, long seed, boolean bl, CallbackInfoReturnable<MappedRegistry<LevelStem>> info, MappedRegistry<LevelStem> mappedRegistry, Registry<DimensionType> registry, Registry<Biome> biomeRegistry, Registry<NoiseGeneratorSettings> noiseSettingsRegistry, Registry<NormalNoise.NoiseParameters> noiseParamRegistry) {
|
||||
int id = mappedRegistry.getId(mappedRegistry.get(LevelStem.NETHER));
|
||||
mappedRegistry.registerOrOverride(
|
||||
OptionalInt.of(id),
|
||||
LevelStem.NETHER,
|
||||
new LevelStem(
|
||||
() -> registry.getOrThrow(DimensionType.NETHER_LOCATION),
|
||||
new NoiseBasedChunkGenerator(
|
||||
noiseParamRegistry,
|
||||
new BCLibNetherBiomeSource(biomeRegistry, seed),
|
||||
seed,
|
||||
() -> noiseSettingsRegistry.getOrThrow(NoiseGeneratorSettings.NETHER)
|
||||
)
|
||||
),
|
||||
Lifecycle.stable()
|
||||
private static void bclib_updateDimensions(RegistryAccess registryAccess, long seed, boolean bl, CallbackInfoReturnable<Registry> info, WritableRegistry writableRegistry, Registry registry, Registry biomeRegistry, Registry structureRegistry, Registry noiseSettingsRegistry, Registry noiseParamRegistry) {
|
||||
int id = writableRegistry.getId(writableRegistry.get(LevelStem.NETHER));
|
||||
writableRegistry.registerOrOverride(
|
||||
OptionalInt.of(id),
|
||||
LevelStem.NETHER,
|
||||
new LevelStem(
|
||||
registry.getOrCreateHolder(DimensionType.NETHER_LOCATION),
|
||||
new NoiseBasedChunkGenerator(
|
||||
structureRegistry,
|
||||
noiseParamRegistry,
|
||||
new BCLibNetherBiomeSource(biomeRegistry, seed),
|
||||
seed,
|
||||
noiseSettingsRegistry.getOrCreateHolder(NoiseGeneratorSettings.NETHER))
|
||||
),
|
||||
Lifecycle.stable()
|
||||
);
|
||||
|
||||
id = mappedRegistry.getId(mappedRegistry.get(LevelStem.END));
|
||||
mappedRegistry.registerOrOverride(
|
||||
OptionalInt.of(id),
|
||||
LevelStem.END,
|
||||
new LevelStem(
|
||||
() -> registry.getOrThrow(DimensionType.END_LOCATION),
|
||||
new NoiseBasedChunkGenerator(
|
||||
noiseParamRegistry,
|
||||
new BCLibEndBiomeSource(biomeRegistry, seed),
|
||||
seed,
|
||||
() -> noiseSettingsRegistry.getOrThrow(NoiseGeneratorSettings.END)
|
||||
)
|
||||
),
|
||||
Lifecycle.stable()
|
||||
|
||||
|
||||
id = writableRegistry.getId(writableRegistry.get(LevelStem.END));
|
||||
writableRegistry.registerOrOverride(
|
||||
OptionalInt.of(id),
|
||||
LevelStem.END,
|
||||
new LevelStem(
|
||||
registry.getOrCreateHolder(DimensionType.END_LOCATION),
|
||||
new NoiseBasedChunkGenerator(
|
||||
structureRegistry,
|
||||
noiseParamRegistry,
|
||||
new BCLibEndBiomeSource(biomeRegistry, seed),
|
||||
seed,
|
||||
noiseSettingsRegistry.getOrCreateHolder(NoiseGeneratorSettings.END))
|
||||
),
|
||||
Lifecycle.stable()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.EnchantmentMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import ru.bclib.api.tag.CommonBlockTags;
|
||||
|
||||
@Mixin(EnchantmentMenu.class)
|
||||
public abstract class EnchantmentMenuMixin extends AbstractContainerMenu {
|
||||
protected EnchantmentMenuMixin(MenuType<?> type, int syncId) {
|
||||
super(type, syncId);
|
||||
}
|
||||
|
||||
@Redirect(method = "lambda$slotsChanged$0(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z"),
|
||||
require = -1,
|
||||
expect = -1
|
||||
)
|
||||
private boolean bclib_isBookshelf(BlockState state, Block block) {
|
||||
return block == Blocks.BOOKSHELF ? state.is(CommonBlockTags.BOOKSHELVES) : state.is(block);
|
||||
}
|
||||
}
|
|
@ -3,10 +3,9 @@ package ru.bclib.mixin.common;
|
|||
import com.mojang.authlib.GameProfileRepository;
|
||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import net.minecraft.core.RegistryAccess.RegistryHolder;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.ServerResources;
|
||||
import net.minecraft.server.WorldStem;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
|
||||
import net.minecraft.server.packs.repository.PackRepository;
|
||||
|
@ -32,7 +31,7 @@ import java.util.concurrent.CompletableFuture;
|
|||
@Mixin(MinecraftServer.class)
|
||||
public class MinecraftServerMixin {
|
||||
@Shadow
|
||||
private ServerResources resources;
|
||||
private MinecraftServer.ReloadableResources resources;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
|
@ -43,7 +42,7 @@ public class MinecraftServerMixin {
|
|||
protected WorldData worldData;
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_onServerInit(Thread thread, RegistryHolder registryHolder, LevelStorageAccess levelStorageAccess, WorldData worldData, PackRepository packRepository, Proxy proxy, DataFixer dataFixer, ServerResources serverResources, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache gameProfileCache, ChunkProgressListenerFactory chunkProgressListenerFactory, CallbackInfo ci) {
|
||||
private void bclib_onServerInit(Thread thread, LevelStorageAccess levelStorageAccess, PackRepository packRepository, WorldStem worldStem, Proxy proxy, DataFixer dataFixer, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache gameProfileCache, ChunkProgressListenerFactory chunkProgressListenerFactory, CallbackInfo ci) {
|
||||
DataExchangeAPI.prepareServerside();
|
||||
}
|
||||
|
||||
|
@ -58,7 +57,7 @@ public class MinecraftServerMixin {
|
|||
}
|
||||
|
||||
private void bclib_injectRecipes() {
|
||||
RecipeManagerAccessor accessor = (RecipeManagerAccessor) resources.getRecipeManager();
|
||||
RecipeManagerAccessor accessor = (RecipeManagerAccessor) resources.managers().getRecipeManager();
|
||||
accessor.bclib_setRecipesByName(BCLRecipeManager.getMapByName(accessor.bclib_getRecipesByName()));
|
||||
accessor.bclib_setRecipes(BCLRecipeManager.getMap(accessor.bclib_getRecipes()));
|
||||
}
|
||||
|
|
|
@ -1,30 +1,21 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.FallbackResourceManager;
|
||||
import net.minecraft.server.packs.resources.SimpleReloadableResourceManager;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(SimpleReloadableResourceManager.class)
|
||||
public class SimpleReloadableResourceManagerMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private Map<String, FallbackResourceManager> namespacedPacks;
|
||||
|
||||
@Mixin(MultiPackResourceManager.class)
|
||||
public class MultiPackResourceManagerMixin {
|
||||
private static final String[] BCLIB_MISSING_RESOURCES = new String[] {
|
||||
"dimension/the_end.json",
|
||||
"dimension/the_nether.json",
|
||||
"dimension_type/the_end.json",
|
||||
"dimension_type/the_nether.json"
|
||||
};
|
||||
|
||||
|
||||
@Inject(method = "hasResource", at = @At("HEAD"), cancellable = true)
|
||||
private void bclib_hasResource(ResourceLocation resourceLocation, CallbackInfoReturnable<Boolean> info) {
|
||||
if (resourceLocation.getNamespace().equals("minecraft")) {
|
|
@ -1,18 +1,15 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.StructureFeatureManager;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.levelgen.Aquifer;
|
||||
import net.minecraft.world.level.levelgen.Beardifier;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.NoiseSampler;
|
||||
import net.minecraft.world.level.levelgen.*;
|
||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||
import net.minecraft.world.level.levelgen.carver.CarvingContext;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
@ -30,11 +27,13 @@ import java.util.function.Supplier;
|
|||
public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider, NoiseGeneratorSettingsProvider {
|
||||
@Final
|
||||
@Shadow
|
||||
private NoiseSampler sampler;
|
||||
|
||||
private Climate.Sampler sampler;
|
||||
|
||||
@Shadow @Final private NoiseRouter router;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
protected Supplier<NoiseGeneratorSettings> settings;
|
||||
protected Holder<NoiseGeneratorSettings> settings;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
|
@ -45,12 +44,12 @@ public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider,
|
|||
|
||||
@Override
|
||||
public NoiseGeneratorSettings bclib_getNoiseGeneratorSettings(){
|
||||
return settings.get();
|
||||
return settings.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState bclib_getSurface(BlockPos pos, Biome biome, ServerLevel level) {
|
||||
public BlockState bclib_getSurface(BlockPos pos, Holder<Biome> biome, ServerLevel level) {
|
||||
ChunkAccess chunkAccess = level.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
|
||||
StructureFeatureManager structureFeatureManager = level.structureFeatureManager();
|
||||
NoiseBasedChunkGenerator generator = NoiseBasedChunkGenerator.class.cast(this);
|
||||
|
@ -72,7 +71,7 @@ public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider,
|
|||
}
|
||||
|
||||
Beardifier finalBeardifier = beardifier;
|
||||
NoiseChunk noiseChunk = chunkAccess.getOrCreateNoiseChunk(this.sampler, () -> finalBeardifier, this.settings.get(), this.globalFluidPicker, Blender.empty());
|
||||
NoiseChunk noiseChunk = chunkAccess.getOrCreateNoiseChunk(router, () -> finalBeardifier, this.settings.value(), this.globalFluidPicker, Blender.empty());
|
||||
CarvingContext carvingContext = new CarvingContext(generator, level.registryAccess(), chunkAccess.getHeightAccessorForGeneration(), noiseChunk);
|
||||
Optional<BlockState> optional = carvingContext.topMaterial(bpos -> biome, chunkAccess, pos, false);
|
||||
return optional.isPresent() ? optional.get() : bclib_air;
|
||||
|
|
|
@ -26,14 +26,14 @@ public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider {
|
|||
private SurfaceRules.RuleSource bclib_originalSurfaceRule;
|
||||
private Set<BiomeSource> bclib_biomeSources = new HashSet<>();
|
||||
|
||||
private void bclib_updateCutomRules(){
|
||||
private void bclib_updateCustomRules(){
|
||||
bclib_setCustomRules(BiomeAPI.getRuleSources(bclib_biomeSources));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bclib_addBiomeSource(BiomeSource source) {
|
||||
bclib_biomeSources.add(source);
|
||||
bclib_updateCutomRules();
|
||||
bclib_updateCustomRules();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,7 +27,7 @@ public abstract class RecipeManagerMixin {
|
|||
}
|
||||
|
||||
@Inject(method = "getRecipeFor", at = @At(value = "HEAD"), cancellable = true)
|
||||
private <C extends Container, T extends Recipe<C>> void bclib_getRecipeFor(RecipeType<T> type, C inventory, Level world, CallbackInfoReturnable<Optional<T>> info) {
|
||||
private <C extends Container, T extends Recipe<C>> void bclib_getRecipeFor(RecipeType<T> type, C inventory, Level level, CallbackInfoReturnable<Optional<T>> info) {
|
||||
Collection<Recipe<C>> values = byType(type).values();
|
||||
List<Recipe<C>> list = new ArrayList<>(values);
|
||||
list.sort((v1, v2) -> {
|
||||
|
@ -35,6 +35,6 @@ public abstract class RecipeManagerMixin {
|
|||
boolean b2 = v2.getId().getNamespace().equals("minecraft");
|
||||
return b1 ^ b2 ? (b1 ? 1 : -1) : 0;
|
||||
});
|
||||
info.setReturnValue(list.stream().flatMap((recipe) -> Util.toStream(type.tryMatch(recipe, world, inventory))).findFirst());
|
||||
info.setReturnValue(list.stream().flatMap(recipe -> type.tryMatch(recipe, level, inventory).stream()).findFirst());
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
@ -9,6 +10,7 @@ import net.minecraft.world.level.CustomSpawner;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraft.world.level.storage.WritableLevelData;
|
||||
|
@ -28,12 +30,12 @@ import java.util.function.Supplier;
|
|||
public abstract class ServerLevelMixin extends Level {
|
||||
private static String bclib_lastWorld = null;
|
||||
|
||||
protected ServerLevelMixin(WritableLevelData writableLevelData, ResourceKey<Level> resourceKey, DimensionType dimensionType, Supplier<ProfilerFiller> supplier, boolean bl, boolean bl2, long l) {
|
||||
protected ServerLevelMixin(WritableLevelData writableLevelData, ResourceKey<Level> resourceKey, Holder<DimensionType> dimensionType, Supplier<ProfilerFiller> supplier, boolean bl, boolean bl2, long l) {
|
||||
super(writableLevelData, resourceKey, dimensionType, supplier, bl, bl2, l);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void bclib_onServerWorldInit(MinecraftServer server, Executor executor, LevelStorageAccess levelStorageAccess, ServerLevelData serverLevelData, ResourceKey<Level> resourceKey, DimensionType dimensionType, ChunkProgressListener chunkProgressListener, ChunkGenerator chunkGenerator, boolean bl, long l, List<CustomSpawner> list, boolean bl2, CallbackInfo info) {
|
||||
private void bclib_onServerWorldInit(MinecraftServer server, Executor executor, LevelStorageAccess levelStorageAccess, ServerLevelData serverLevelData, ResourceKey resourceKey, Holder<DimensionType> dimensionType, ChunkProgressListener chunkProgressListener, ChunkGenerator chunkGenerator, boolean bl, long l, List list, boolean bl2, CallbackInfo ci) {
|
||||
ServerLevel level = ServerLevel.class.cast(this);
|
||||
LifeCycleAPI._runLevelLoad(level, server, executor, levelStorageAccess, serverLevelData, resourceKey, dimensionType, chunkProgressListener, chunkGenerator, bl, l, list, bl2);
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(StructureFeature.class)
|
||||
public interface StructureFeatureAccessor {
|
||||
@Invoker
|
||||
static <F extends StructureFeature<?>> F callRegister(String name, F structureFeature, GenerationStep.Decoration step) {
|
||||
throw new RuntimeException("Unexpected call");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.data.worldgen.StructureFeatures;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(StructureFeatures.class)
|
||||
public interface StructureFeaturesAccessor {
|
||||
@Invoker
|
||||
static <FC extends FeatureConfiguration, F extends StructureFeature<FC>> Holder<ConfiguredStructureFeature<?, ?>> callRegister(ResourceKey<ConfiguredStructureFeature<?, ?>> resourceKey, ConfiguredStructureFeature<FC, F> configuredStructureFeature) {
|
||||
throw new RuntimeException("Unexpected call");
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.levelgen.StructureSettings;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.StructureFeatureConfiguration;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(StructureSettings.class)
|
||||
public interface StructureSettingsAccessor {
|
||||
@Accessor("configuredStructures")
|
||||
ImmutableMap<StructureFeature<?>, ImmutableMultimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> bcl_getConfiguredStructures();
|
||||
|
||||
@Accessor("structureConfig")
|
||||
Map<StructureFeature<?>, StructureFeatureConfiguration> bcl_getStructureConfig();
|
||||
|
||||
@Accessor("configuredStructures")
|
||||
@Mutable
|
||||
void bcl_setConfiguredStructures(ImmutableMap<StructureFeature<?>, ImmutableMultimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> configuredStructures);
|
||||
|
||||
@Accessor("structureConfig")
|
||||
@Mutable
|
||||
void bcl_setStructureConfig(Map<StructureFeature<?>, StructureFeatureConfiguration> structureConfig);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
|
@ -25,10 +26,7 @@ public interface SurfaceRulesContextAccessor {
|
|||
int getSurfaceDepth();
|
||||
|
||||
@Accessor("biome")
|
||||
Supplier<Biome> getBiome();
|
||||
|
||||
@Accessor("biomeKey")
|
||||
Supplier<ResourceKey<Biome>> getBiomeKey();
|
||||
Supplier<Holder<Biome>> getBiome();
|
||||
|
||||
@Accessor("chunk")
|
||||
ChunkAccess getChunk();
|
||||
|
|
|
@ -3,6 +3,7 @@ package ru.bclib.mixin.common;
|
|||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagLoader;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -13,10 +14,11 @@ import java.util.Map;
|
|||
|
||||
@Mixin(TagLoader.class)
|
||||
public class TagLoaderMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private String directory;
|
||||
|
||||
@ModifyArg(method = "loadAndBuild", at = @At(value = "INVOKE", target = "Lnet/minecraft/tags/TagLoader;build(Ljava/util/Map;)Lnet/minecraft/tags/TagCollection;"))
|
||||
@ModifyArg(method = "loadAndBuild", at = @At(value = "INVOKE", target = "Lnet/minecraft/tags/TagLoader;build(Ljava/util/Map;)Ljava/util/Map;"))
|
||||
public Map<ResourceLocation, Tag.Builder> be_modifyTags(Map<ResourceLocation, Tag.Builder> tagsMap) {
|
||||
return TagAPI.apply(directory, tagsMap);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ru.bclib.mixin.common.shears;
|
||||
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
@ -24,7 +23,7 @@ public abstract class ItemPredicateBuilderMixin {
|
|||
@Inject(method = "matches", at = @At("HEAD"), cancellable = true)
|
||||
void bclib_of(ItemStack itemStack, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (this.items != null && this.items.size() == 1 && this.items.contains(Items.SHEARS)) {
|
||||
if (itemStack.is(CommonItemTags.SHEARS) || itemStack.is(FabricToolTags.SHEARS)){
|
||||
if (itemStack.is(CommonItemTags.SHEARS) ){
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,16 @@ import com.google.gson.JsonObject;
|
|||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
|
@ -42,6 +46,10 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
);
|
||||
public final static ResourceLocation ID = BCLib.makeID(GROUP);
|
||||
|
||||
public static void register(){
|
||||
|
||||
}
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final Ingredient input;
|
||||
private final ItemStack output;
|
||||
|
@ -116,7 +124,8 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
|
||||
public boolean matches(Container craftingInventory) {
|
||||
ItemStack hammer = craftingInventory.getItem(1);
|
||||
if (hammer.isEmpty() || !CommonItemTags.HAMMERS.contains(hammer.getItem())) {
|
||||
//TODO: 1.18.2 Test if hammer still works
|
||||
if (hammer.isEmpty() || !hammer.is(CommonItemTags.HAMMERS)) {
|
||||
return false;
|
||||
}
|
||||
ItemStack material = craftingInventory.getItem(0);
|
||||
|
@ -139,12 +148,13 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
|
||||
@Override
|
||||
public NonNullList<Ingredient> getIngredients() {
|
||||
;
|
||||
NonNullList<Ingredient> defaultedList = NonNullList.create();
|
||||
defaultedList.add(Ingredient.of(CommonItemTags.HAMMERS
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(hammer -> ((TieredItem) hammer).getTier().getLevel() >= toolLevel)
|
||||
.map(ItemStack::new)));
|
||||
defaultedList.add(Ingredient.of(Registry.ITEM.stream()
|
||||
.filter(item->item.builtInRegistryHolder().is(CommonItemTags.HAMMERS))
|
||||
.filter(hammer -> ((TieredItem) hammer).getTier().getLevel() >= toolLevel)
|
||||
.map(ItemStack::new))
|
||||
);
|
||||
defaultedList.add(input);
|
||||
return defaultedList;
|
||||
}
|
||||
|
@ -209,7 +219,7 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setInput(Tag<Item> inputTag) {
|
||||
public Builder setInput(TagKey<Item> inputTag) {
|
||||
this.setInput(Ingredient.of(inputTag));
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.google.common.collect.Maps;
|
|||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.CraftingRecipe;
|
||||
|
@ -74,7 +75,7 @@ public class GridRecipe {
|
|||
return this;
|
||||
}
|
||||
|
||||
public GridRecipe addMaterial(char key, Tag<Item> value) {
|
||||
public GridRecipe addMaterial(char key, TagKey<Item> value) {
|
||||
return addMaterial(key, Ingredient.of(value));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package ru.bclib.recipes;
|
|||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
|
@ -59,7 +60,7 @@ public class SmithingTableRecipe {
|
|||
return this;
|
||||
}
|
||||
|
||||
public SmithingTableRecipe setBase(Tag<Item> tag) {
|
||||
public SmithingTableRecipe setBase(TagKey<Item> tag) {
|
||||
this.base = (Ingredient.of(tag));
|
||||
return this;
|
||||
}
|
||||
|
@ -70,7 +71,7 @@ public class SmithingTableRecipe {
|
|||
return this;
|
||||
}
|
||||
|
||||
public SmithingTableRecipe setAddition(Tag<Item> tag) {
|
||||
public SmithingTableRecipe setAddition(TagKey<Item> tag) {
|
||||
this.addition = (Ingredient.of(tag));
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ public class ItemRegistry extends BaseRegistry<Item> {
|
|||
if (!config.getBoolean("musicDiscs", itemId.getPath(), true)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
return register(itemId, new BaseDiscItem(power, sound, makeItemSettings().stacksTo(1)));
|
||||
register(itemId, item);
|
||||
return item;
|
||||
}
|
||||
|
||||
public Item register(ResourceLocation itemId) {
|
||||
|
|
|
@ -2,10 +2,13 @@ package ru.bclib.world.biomes;
|
|||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules;
|
||||
|
@ -15,25 +18,25 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.biomes.BiomeAPI;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
import ru.bclib.util.WeightedList;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BCLBiome extends BCLBiomeSettings {
|
||||
private final List<ConfiguredStructureFeature> structures = Lists.newArrayList();
|
||||
private final Set<TagKey<Biome>> structureTags = Sets.newHashSet();
|
||||
private final WeightedList<BCLBiome> subbiomes = new WeightedList<>();
|
||||
private final Map<String, Object> customData = Maps.newHashMap();
|
||||
private final ResourceLocation biomeID;
|
||||
private final Biome biome;
|
||||
|
||||
private Consumer<Biome> surfaceInit;
|
||||
private Consumer<Holder<Biome>> surfaceInit;
|
||||
private BCLBiome biomeParent;
|
||||
private Biome actualBiome;
|
||||
private Holder<Biome> actualBiome;
|
||||
|
||||
/**
|
||||
* Create wrapper for existing biome using its {@link ResourceLocation} identifier.
|
||||
|
@ -65,7 +68,7 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
* @param settings The Settings for this Biome or {@code null} if you want to apply default settings
|
||||
*/
|
||||
public BCLBiome(Biome biome, VanillaBiomeSettings settings) {
|
||||
this(BuiltinRegistries.BIOME.getKey(biome), biome, settings);
|
||||
this(BiomeAPI.getBiomeID(biome), biome, settings);
|
||||
}
|
||||
|
||||
public BCLBiome(ResourceLocation biomeID, Biome biome) {
|
||||
|
@ -164,7 +167,10 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
return biomeID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Holder<Biome> getBiomeHolder() {
|
||||
return BuiltinRegistries.BIOME.getOrCreateHolder(BiomeAPI.getBiomeKey(biome));
|
||||
}
|
||||
/**
|
||||
* Getter for biome from buil-in registry. For datapack biomes will be same as actual biome.
|
||||
* @return {@link Biome}.
|
||||
|
@ -177,7 +183,7 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
* Getter for actual biome (biome from current world registry with same {@link ResourceLocation} id).
|
||||
* @return {@link Biome}.
|
||||
*/
|
||||
public Biome getActualBiome() {
|
||||
public Holder<Biome> getActualBiome() {
|
||||
return this.actualBiome;
|
||||
}
|
||||
|
||||
|
@ -196,19 +202,23 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
if (edge != null && edge != this) {
|
||||
edge.updateActualBiomes(biomeRegistry);
|
||||
}
|
||||
this.actualBiome = biomeRegistry.get(biomeID);
|
||||
|
||||
final ResourceKey<Biome> key = biomeRegistry.getResourceKey(biomeRegistry.get(biomeID)).orElseThrow();
|
||||
this.actualBiome = biomeRegistry.getOrCreateHolder(key);
|
||||
if (actualBiome==null) {
|
||||
BCLib.LOGGER.error("Unable to find actual Biome for " + biomeID);
|
||||
}
|
||||
|
||||
if (!this.structures.isEmpty()) {
|
||||
structures.forEach(s -> BiomeAPI.addBiomeStructure(BiomeAPI.getBiomeKey(actualBiome), s));
|
||||
if (!this.structureTags.isEmpty()) {
|
||||
structureTags.forEach(tagKey -> TagAPI.addBiomeTag(tagKey, actualBiome.value()));
|
||||
}
|
||||
|
||||
if (this.surfaceInit != null) {
|
||||
surfaceInit.accept(actualBiome);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Getter for custom data. Will get custom data object or null if object doesn't exists.
|
||||
|
@ -276,8 +286,8 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
* Adds structures to this biome. For internal use only.
|
||||
* Used inside {@link ru.bclib.api.biomes.BCLBiomeBuilder}.
|
||||
*/
|
||||
public void attachStructures(List<ConfiguredStructureFeature> structures) {
|
||||
this.structures.addAll(structures);
|
||||
public void attachStructures(List<TagKey<Biome>> structures) {
|
||||
this.structureTags.addAll(structures);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -295,25 +305,7 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Map<Decoration, List<Supplier<PlacedFeature>>> features = new HashMap<>(0);
|
||||
|
||||
/**
|
||||
* Sets the biome features.
|
||||
* @param features the feature list.
|
||||
*/
|
||||
public void setFeatures(Map<Decoration, List<Supplier<PlacedFeature>>> features) {
|
||||
this.features = features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the built-in set of Features for this biome (as they were set with {@link #setFeatures(Map)})
|
||||
* @return List of all features
|
||||
*/
|
||||
public Map<Decoration, List<Supplier<PlacedFeature>>> getFeatures(){
|
||||
return features;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the group used in the config Files for this biome
|
||||
*
|
||||
|
|
|
@ -1,40 +1,59 @@
|
|||
package ru.bclib.world.features;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.data.worldgen.features.FeatureUtils;
|
||||
import net.minecraft.data.worldgen.placement.PlacementUtils;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.VerticalAnchor;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.HeightRangePlacement;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||
import ru.bclib.api.features.BCLCommonFeatures;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BCLFeature {
|
||||
private PlacedFeature placedFeature;
|
||||
private Decoration featureStep;
|
||||
private Feature<?> feature;
|
||||
|
||||
public BCLFeature(ResourceLocation id, Feature<?> feature, Decoration featureStep, PlacedFeature placedFeature) {
|
||||
private final Holder<PlacedFeature> placedFeature;
|
||||
private final Decoration featureStep;
|
||||
private final Feature<?> feature;
|
||||
|
||||
|
||||
public<FC extends FeatureConfiguration, F extends Feature<FC>> BCLFeature(ResourceLocation id, F feature, Decoration featureStep, FC configuration, PlacementModifier[] modifiers) {
|
||||
this(id, feature, featureStep, buildPlacedFeature(id, feature, configuration, modifiers));
|
||||
}
|
||||
|
||||
public BCLFeature(ResourceLocation id, Feature<?> feature, Decoration featureStep, Holder<PlacedFeature> placedFeature) {
|
||||
this.placedFeature = placedFeature;
|
||||
this.featureStep = featureStep;
|
||||
this.feature = feature;
|
||||
|
||||
|
||||
if (!BuiltinRegistries.PLACED_FEATURE.containsKey(id)) {
|
||||
Registry.register(BuiltinRegistries.PLACED_FEATURE, id, placedFeature);
|
||||
Registry.register(BuiltinRegistries.PLACED_FEATURE, id, placedFeature.value());
|
||||
}
|
||||
if (!Registry.FEATURE.containsKey(id) && !containsObj(Registry.FEATURE, feature)) {
|
||||
Registry.register(Registry.FEATURE, id, feature);
|
||||
}
|
||||
}
|
||||
|
||||
private static <FC extends FeatureConfiguration, F extends Feature<FC>> Holder<PlacedFeature> buildPlacedFeature(ResourceLocation id, F feature, FC configuration, PlacementModifier[] modifiers) {
|
||||
Holder<ConfiguredFeature<?, ?>> configuredFeature;
|
||||
if (!BuiltinRegistries.CONFIGURED_FEATURE.containsKey(id)) {
|
||||
configuredFeature = (Holder<ConfiguredFeature<?, ?>>)(Object)FeatureUtils.register(id.toString(), feature, configuration);
|
||||
} else {
|
||||
configuredFeature = BuiltinRegistries.CONFIGURED_FEATURE.getHolder(ResourceKey.create(BuiltinRegistries.CONFIGURED_FEATURE.key(), id)).orElseThrow();
|
||||
}
|
||||
|
||||
if (!BuiltinRegistries.PLACED_FEATURE.containsKey(id)) {
|
||||
return PlacementUtils.register(id.toString(), configuredFeature, modifiers);
|
||||
} else {
|
||||
return BuiltinRegistries.PLACED_FEATURE.getHolder(ResourceKey.create(BuiltinRegistries.PLACED_FEATURE.key(), id)).orElseThrow();
|
||||
}
|
||||
}
|
||||
|
||||
private static <E> boolean containsObj(Registry<E> registry, E obj) {
|
||||
Optional<Entry<ResourceKey<E>, E>> optional = registry
|
||||
|
@ -57,7 +76,7 @@ public class BCLFeature {
|
|||
* Get configured feature.
|
||||
* @return {@link PlacedFeature}.
|
||||
*/
|
||||
public PlacedFeature getPlacedFeature() {
|
||||
public Holder<PlacedFeature> getPlacedFeature() {
|
||||
return placedFeature;
|
||||
}
|
||||
|
||||
|
@ -68,92 +87,4 @@ public class BCLFeature {
|
|||
public Decoration getDecoration() {
|
||||
return featureStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use function from {@link BCLCommonFeatures} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeVegetationFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature, int density) {
|
||||
return BCLCommonFeatures.makeVegetationFeature(id, feature, density);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use function from {@link BCLCommonFeatures} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeVegetationFeature(ResourceLocation id, Feature<NoneFeatureConfiguration> feature, int density, boolean allHeight) {
|
||||
return BCLCommonFeatures.makeVegetationFeature(id, feature, density, allHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, moved to {@link BCLCommonFeatures}. Will be completely removed.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeOreFeature(ResourceLocation id, Block blockOre, Block hostBlock, int veins, int veinSize, float airDiscardChance, VerticalAnchor minY, VerticalAnchor maxY, boolean rare) {
|
||||
return BCLCommonFeatures.makeOreFeature(id, blockOre, hostBlock, veins, veinSize, airDiscardChance, HeightRangePlacement.uniform(minY, maxY), rare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, moved to {@link BCLCommonFeatures}. Will be completely removed.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeOreFeature(ResourceLocation id, Block blockOre, Block hostBlock, int veins, int veinSize, VerticalAnchor minY, VerticalAnchor maxY, boolean rare) {
|
||||
return BCLCommonFeatures.makeOreFeature(id, blockOre, hostBlock, veins, veinSize, 0.0f, HeightRangePlacement.uniform(minY, maxY), rare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use function from {@link BCLCommonFeatures} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeOreFeature(ResourceLocation id, Block blockOre, Block hostBlock, int veins, int veinSize, float airDiscardChance, PlacementModifier placement, boolean rare) {
|
||||
return BCLCommonFeatures.makeOreFeature(id, blockOre, hostBlock, veins, veinSize, airDiscardChance, placement, rare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use function from {@link BCLCommonFeatures} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeOreFeature(ResourceLocation id, Block blockOre, Block hostBlock, int veins, int veinSize, PlacementModifier placement, boolean rare) {
|
||||
return BCLCommonFeatures.makeOreFeature(id, blockOre, hostBlock, veins, veinSize, 0.0f, placement, rare);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use function from {@link BCLCommonFeatures} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeChunkFeature(ResourceLocation id, Decoration step, Feature<NoneFeatureConfiguration> feature) {
|
||||
return BCLCommonFeatures.makeChunkFeature(id, step, feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use function from {@link BCLCommonFeatures} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeChancedFeature(ResourceLocation id, Decoration step, Feature<NoneFeatureConfiguration> feature, int chance) {
|
||||
return BCLCommonFeatures.makeChancedFeature(id, step, feature, chance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use function from {@link BCLCommonFeatures} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeCountFeature(ResourceLocation id, Decoration step, Feature<NoneFeatureConfiguration> feature, int count) {
|
||||
return BCLCommonFeatures.makeCountFeature(id, step, feature, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use {@link ru.bclib.api.features.BCLFeatureBuilder} instead.
|
||||
*
|
||||
* Creates and configures new BCLib feature.
|
||||
* @param id {@link ResourceLocation} feature ID.
|
||||
* @param step {@link Decoration} feature step.
|
||||
* @param feature {@link Feature} with {@link NoneFeatureConfiguration} config.
|
||||
* @param placementModifiers array of {@link PlacementModifier}
|
||||
* @return new BCLFeature instance.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLFeature makeFeature(ResourceLocation id, Decoration step, Feature<NoneFeatureConfiguration> feature, PlacementModifier... placementModifiers) {
|
||||
PlacedFeature configured = feature.configured(FeatureConfiguration.NONE).placed(placementModifiers);
|
||||
return new BCLFeature(id, feature, step, configured);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package ru.bclib.world.features;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
|
@ -50,7 +51,7 @@ public abstract class NBTStructureFeature extends DefaultFeature {
|
|||
protected abstract void addStructureData(StructurePlaceSettings data);
|
||||
|
||||
protected BlockPos getGround(WorldGenLevel world, BlockPos center) {
|
||||
Biome biome = world.getBiome(center);
|
||||
Holder<Biome> biome = world.getBiome(center);
|
||||
ResourceLocation id = BiomeAPI.getBiomeID(biome);
|
||||
if (id.getNamespace().contains("moutain") || id.getNamespace().contains("lake")) {
|
||||
int y = getAverageY(world, center);
|
||||
|
@ -148,7 +149,7 @@ public abstract class NBTStructureFeature extends DefaultFeature {
|
|||
if (!isTerrain(stateSt)) {
|
||||
if (merge == TerrainMerge.SURFACE) {
|
||||
boolean isTop = mut.getY() == surfMax && state.getMaterial().isSolidBlocking();
|
||||
Biome b = world.getBiome(mut);
|
||||
Holder<Biome> b = world.getBiome(mut);
|
||||
BlockState top = (isTop ? BiomeAPI.findTopMaterial(b) : BiomeAPI.findUnderMaterial(b)).orElse(defaultBlock);
|
||||
BlocksHelper.setWithoutUpdate(world, mut, top);
|
||||
}
|
||||
|
@ -159,7 +160,7 @@ public abstract class NBTStructureFeature extends DefaultFeature {
|
|||
else {
|
||||
if (isTerrain(state) && state.getMaterial().isSolidBlocking()) {
|
||||
if (merge == TerrainMerge.SURFACE) {
|
||||
Biome b = world.getBiome(mut);
|
||||
Holder<Biome> b = world.getBiome(mut);
|
||||
BlockState bottom = BiomeAPI.findUnderMaterial(b).orElse(defaultBlock);
|
||||
BlocksHelper.setWithoutUpdate(world, mut, bottom);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ru.bclib.world.generator;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
|
@ -11,12 +12,12 @@ public abstract class BCLBiomeSource extends BiomeSource {
|
|||
protected final Registry<Biome> biomeRegistry;
|
||||
protected final long seed;
|
||||
|
||||
private static List<Biome> preInit(Registry<Biome> biomeRegistry, List<Biome> biomes){
|
||||
private static List<Holder<Biome>> preInit(Registry<Biome> biomeRegistry, List<Holder<Biome>> biomes){
|
||||
biomes.forEach(biome -> BiomeAPI.sortBiomeFeatures(biome));
|
||||
return biomes;
|
||||
}
|
||||
|
||||
protected BCLBiomeSource(Registry<Biome> biomeRegistry, long seed, List<Biome> list) {
|
||||
protected BCLBiomeSource(Registry<Biome> biomeRegistry, long seed, List<Holder<Biome>> list) {
|
||||
super(preInit(biomeRegistry, list));
|
||||
|
||||
this.seed = seed;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package ru.bclib.world.generator;
|
||||
|
||||
import com.mojang.datafixers.kinds.Applicative;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.RegistryLookupCodec;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biome.BiomeCategory;
|
||||
|
@ -19,6 +23,7 @@ import ru.bclib.api.biomes.BiomeAPI;
|
|||
import ru.bclib.config.ConfigKeeper.StringArrayEntry;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.interfaces.BiomeMap;
|
||||
import ru.bclib.mixin.common.BiomeAccessor;
|
||||
import ru.bclib.noise.OpenSimplexNoise;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
import ru.bclib.world.generator.map.hex.HexBiomeMap;
|
||||
|
@ -29,19 +34,13 @@ import java.util.List;
|
|||
import java.util.function.Function;
|
||||
|
||||
public class BCLibEndBiomeSource extends BCLBiomeSource {
|
||||
public static final Codec<BCLibEndBiomeSource> CODEC = RecordCodecBuilder.create((instance) -> {
|
||||
return instance.group(RegistryLookupCodec.create(Registry.BIOME_REGISTRY).forGetter((theEndBiomeSource) -> {
|
||||
return theEndBiomeSource.biomeRegistry;
|
||||
}), Codec.LONG.fieldOf("seed").stable().forGetter((theEndBiomeSource) -> {
|
||||
return theEndBiomeSource.seed;
|
||||
})).apply(instance, instance.stable(BCLibEndBiomeSource::new));
|
||||
});
|
||||
public static Codec<BCLibEndBiomeSource> CODEC = RecordCodecBuilder.create((instance) -> instance.group(RegistryOps.retrieveRegistry(Registry.BIOME_REGISTRY).forGetter((theEndBiomeSource) -> null), Codec.LONG.fieldOf("seed").stable().forGetter((theEndBiomeSource) -> theEndBiomeSource.seed)).apply(instance, instance.stable(BCLibEndBiomeSource::new)));
|
||||
private static final OpenSimplexNoise SMALL_NOISE = new OpenSimplexNoise(8324);
|
||||
private Function<Point, Boolean> endLandFunction;
|
||||
|
||||
private final SimplexNoise noise;
|
||||
private final Biome centerBiome;
|
||||
private final Biome barrens;
|
||||
private final Holder<Biome> centerBiome;
|
||||
private final Holder<Biome> barrens;
|
||||
private BiomeMap mapLand;
|
||||
private BiomeMap mapVoid;
|
||||
private final Point pos;
|
||||
|
@ -54,11 +53,11 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
|
|||
|
||||
List<String> includeVoid = Configs.BIOMES_CONFIG.getEntry("force_include", "end_void_biomes", StringArrayEntry.class).getValue();
|
||||
this.possibleBiomes().forEach(biome -> {
|
||||
ResourceLocation key = biomeRegistry.getKey(biome);
|
||||
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
|
||||
String group = key.getNamespace() + "." + key.getPath();
|
||||
|
||||
if (!BiomeAPI.hasBiome(key)) {
|
||||
BCLBiome bclBiome = new BCLBiome(key, biome);
|
||||
BCLBiome bclBiome = new BCLBiome(key, biome.value());
|
||||
|
||||
if (includeVoid.contains(key.toString())) {
|
||||
BiomeAPI.END_VOID_BIOME_PICKER.addBiomeMutable(bclBiome);
|
||||
|
@ -99,8 +98,8 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
|
|||
this.mapVoid = new HexBiomeMap(seed, GeneratorOptions.getBiomeSizeEndVoid(), BiomeAPI.END_VOID_BIOME_PICKER);
|
||||
}
|
||||
|
||||
this.centerBiome = biomeRegistry.getOrThrow(Biomes.THE_END);
|
||||
this.barrens = biomeRegistry.getOrThrow(Biomes.END_BARRENS);
|
||||
this.centerBiome = biomeRegistry.getOrCreateHolder(Biomes.THE_END);
|
||||
this.barrens = biomeRegistry.getOrCreateHolder(Biomes.END_BARRENS);
|
||||
|
||||
WorldgenRandom chunkRandom = new WorldgenRandom(new LegacyRandomSource(seed));
|
||||
chunkRandom.consumeCount(17292);
|
||||
|
@ -110,34 +109,44 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
|
|||
this.pos = new Point();
|
||||
}
|
||||
|
||||
private static List<Biome> getBiomes(Registry<Biome> biomeRegistry) {
|
||||
private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) {
|
||||
List<String> includeLand = Configs.BIOMES_CONFIG.getEntry("force_include", "end_land_biomes", StringArrayEntry.class).getValue();
|
||||
List<String> includeVoid = Configs.BIOMES_CONFIG.getEntry("force_include", "end_void_biomes", StringArrayEntry.class).getValue();
|
||||
|
||||
return biomeRegistry.stream().filter(biome -> {
|
||||
ResourceLocation key = biomeRegistry.getKey(biome);
|
||||
|
||||
if (includeLand.contains(key.toString()) || includeVoid.contains(key.toString())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GeneratorOptions.addEndBiomesByCategory() && biome.getBiomeCategory() == BiomeCategory.THEEND) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(key);
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome.getParentBiome() != null) {
|
||||
bclBiome = bclBiome.getParentBiome();
|
||||
}
|
||||
key = bclBiome.getID();
|
||||
}
|
||||
return BiomeAPI.END_LAND_BIOME_PICKER.containsImmutable(key) || BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(key) || (biome.getBiomeCategory() == BiomeCategory.THEEND && BiomeAPI.isDatapackBiome(key));
|
||||
return biomeRegistry.stream()
|
||||
.filter(biome -> biomeRegistry.getResourceKey(biome).isPresent())
|
||||
.map(biome -> biomeRegistry.getOrCreateHolder(biomeRegistry.getResourceKey(biome).get()))
|
||||
.filter(biome -> {
|
||||
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
|
||||
|
||||
|
||||
if (includeLand.contains(key.toString()) || includeVoid.contains(key.toString())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final boolean isEndBiome;
|
||||
if ((Object)biome instanceof BiomeAccessor bacc) {
|
||||
isEndBiome = bacc.bclib_getBiomeCategory() == BiomeCategory.THEEND;
|
||||
if (GeneratorOptions.addEndBiomesByCategory() && isEndBiome) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
isEndBiome = false;
|
||||
}
|
||||
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(key);
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome.getParentBiome() != null) {
|
||||
bclBiome = bclBiome.getParentBiome();
|
||||
}
|
||||
key = bclBiome.getID();
|
||||
}
|
||||
return BiomeAPI.END_LAND_BIOME_PICKER.containsImmutable(key) || BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(key) || (isEndBiome && BiomeAPI.isDatapackBiome(key));
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler sampler) {
|
||||
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler sampler) {
|
||||
long posX = biomeX << 2;
|
||||
long posZ = biomeZ << 2;
|
||||
long farEndBiomes = GeneratorOptions.getFarEndBiomes();
|
||||
|
|
|
@ -2,8 +2,10 @@ package ru.bclib.world.generator;
|
|||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.RegistryLookupCodec;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biome.BiomeCategory;
|
||||
|
@ -15,6 +17,7 @@ import ru.bclib.api.biomes.BiomeAPI;
|
|||
import ru.bclib.config.ConfigKeeper.StringArrayEntry;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.interfaces.BiomeMap;
|
||||
import ru.bclib.mixin.common.BiomeAccessor;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
import ru.bclib.world.generator.map.MapStack;
|
||||
import ru.bclib.world.generator.map.hex.HexBiomeMap;
|
||||
|
@ -23,13 +26,22 @@ import ru.bclib.world.generator.map.square.SquareBiomeMap;
|
|||
import java.util.List;
|
||||
|
||||
public class BCLibNetherBiomeSource extends BCLBiomeSource {
|
||||
public static final Codec<BCLibNetherBiomeSource> CODEC = RecordCodecBuilder.create((instance) -> {
|
||||
return instance.group(RegistryLookupCodec.create(Registry.BIOME_REGISTRY).forGetter((theEndBiomeSource) -> {
|
||||
return theEndBiomeSource.biomeRegistry;
|
||||
}), Codec.LONG.fieldOf("seed").stable().forGetter((theEndBiomeSource) -> {
|
||||
return theEndBiomeSource.seed;
|
||||
})).apply(instance, instance.stable(BCLibNetherBiomeSource::new));
|
||||
});
|
||||
|
||||
public static final Codec<BCLibNetherBiomeSource> CODEC = RecordCodecBuilder
|
||||
.create(instance -> instance
|
||||
.group(RegistryOps
|
||||
.retrieveRegistry(Registry.BIOME_REGISTRY)
|
||||
.forGetter(source -> source.biomeRegistry)
|
||||
,
|
||||
Codec
|
||||
.LONG
|
||||
.fieldOf("seed")
|
||||
.stable()
|
||||
.forGetter(source -> source.seed)
|
||||
)
|
||||
.apply(instance, instance.stable(BCLibNetherBiomeSource::new))
|
||||
);
|
||||
|
||||
private BiomeMap biomeMap;
|
||||
|
||||
private static boolean forceLegacyGenerator = false;
|
||||
|
@ -61,10 +73,10 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
|
|||
BiomeAPI.NETHER_BIOME_PICKER.clearMutables();
|
||||
|
||||
this.possibleBiomes().forEach(biome -> {
|
||||
ResourceLocation key = biomeRegistry.getKey(biome);
|
||||
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
|
||||
|
||||
if (!BiomeAPI.hasBiome(key)) {
|
||||
BCLBiome bclBiome = new BCLBiome(key, biome);
|
||||
BCLBiome bclBiome = new BCLBiome(key, biome.value());
|
||||
BiomeAPI.NETHER_BIOME_PICKER.addBiomeMutable(bclBiome);
|
||||
}
|
||||
else {
|
||||
|
@ -85,33 +97,42 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
|
|||
initMap();
|
||||
}
|
||||
|
||||
private static List<Biome> getBiomes(Registry<Biome> biomeRegistry) {
|
||||
private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) {
|
||||
List<String> include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class).getValue();
|
||||
|
||||
return biomeRegistry.stream().filter(biome -> {
|
||||
ResourceLocation key = biomeRegistry.getKey(biome);
|
||||
|
||||
if (include.contains(key.toString())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GeneratorOptions.addNetherBiomesByCategory() && biome.getBiomeCategory() == BiomeCategory.NETHER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(key);
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome.getParentBiome() != null) {
|
||||
bclBiome = bclBiome.getParentBiome();
|
||||
}
|
||||
key = bclBiome.getID();
|
||||
}
|
||||
return BiomeAPI.NETHER_BIOME_PICKER.containsImmutable(key) || (biome.getBiomeCategory() == BiomeCategory.NETHER && BiomeAPI.isDatapackBiome(key));
|
||||
|
||||
return biomeRegistry.stream()
|
||||
.filter(biome -> biomeRegistry.getResourceKey(biome).isPresent())
|
||||
.map(biome -> biomeRegistry.getOrCreateHolder(biomeRegistry.getResourceKey(biome).get()))
|
||||
.filter(biome -> {
|
||||
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
|
||||
|
||||
if (include.contains(key.toString())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GeneratorOptions.addNetherBiomesByCategory() && (biome instanceof BiomeAccessor) && ((BiomeAccessor)(Object)biome).bclib_getBiomeCategory()== BiomeCategory.NETHER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(key);
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome.getParentBiome() != null) {
|
||||
bclBiome = bclBiome.getParentBiome();
|
||||
}
|
||||
key = bclBiome.getID();
|
||||
}
|
||||
final boolean isNetherBiome;
|
||||
if ((Object)biome instanceof BiomeAccessor bacc) {
|
||||
isNetherBiome = bacc.bclib_getBiomeCategory() == BiomeCategory.NETHER;
|
||||
} else {
|
||||
isNetherBiome = false;
|
||||
}
|
||||
return BiomeAPI.NETHER_BIOME_PICKER.containsImmutable(key) || (isNetherBiome && BiomeAPI.isDatapackBiome(key));
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler var4) {
|
||||
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler var4) {
|
||||
if (lastWorldHeight != worldHeight) {
|
||||
lastWorldHeight = worldHeight;
|
||||
initMap();
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
package ru.bclib.world.structures;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.fabricmc.fabric.api.structure.v1.FabricStructureBuilder;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.QuartPos;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.worldgen.StructureSets;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadStructurePlacement;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.RandomSpreadType;
|
||||
import ru.bclib.api.tag.TagAPI;
|
||||
import ru.bclib.mixin.common.StructureFeatureAccessor;
|
||||
import ru.bclib.mixin.common.StructureFeaturesAccessor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
@ -19,23 +29,40 @@ import java.util.Random;
|
|||
public class BCLStructureFeature {
|
||||
private static final Random RANDOM = new Random(354);
|
||||
private final StructureFeature<NoneFeatureConfiguration> structure;
|
||||
private final ConfiguredStructureFeature<?, ?> featureConfigured;
|
||||
private final Holder<ConfiguredStructureFeature<?, ?>> featureConfigured;
|
||||
private final GenerationStep.Decoration featureStep;
|
||||
private final List<ResourceLocation> biomes = Lists.newArrayList();
|
||||
private final ResourceLocation id;
|
||||
|
||||
public final TagKey<Biome> biomeTag;
|
||||
public final ResourceKey<ConfiguredStructureFeature<?, ?>> structureKey;
|
||||
public final ResourceKey<StructureSet> structureSetKey;
|
||||
public final RandomSpreadStructurePlacement spreadConfig;
|
||||
|
||||
public BCLStructureFeature(ResourceLocation id, StructureFeature<NoneFeatureConfiguration> structure, GenerationStep.Decoration step, int spacing, int separation) {
|
||||
this(id, structure, step, spacing, separation, false);
|
||||
}
|
||||
public BCLStructureFeature(ResourceLocation id, StructureFeature<NoneFeatureConfiguration> structure, GenerationStep.Decoration step, int spacing, int separation, boolean adaptNoise) {
|
||||
this.id = id;
|
||||
this.featureStep = step;
|
||||
this.structure = FabricStructureBuilder
|
||||
.create(id, structure)
|
||||
.step(step)
|
||||
.defaultConfig(spacing, separation, RANDOM.nextInt(8192))
|
||||
.register();
|
||||
this.featureConfigured = this.structure.configured(NoneFeatureConfiguration.NONE);
|
||||
BuiltinRegistries.register(BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE, id, this.featureConfigured);
|
||||
//TODO: 1.18 check if structures are added correctly
|
||||
//FlatChunkGeneratorConfigAccessor.getStructureToFeatures().put(this.structure, this.featureConfigured);
|
||||
//parts from vanilla for Structure generation
|
||||
//public static final ResourceKey<ConfiguredStructureFeature<?, ?>> JUNGLE_TEMPLE =
|
||||
// BuiltinStructures.createKey("jungle_pyramid");
|
||||
//public static final Holder<ConfiguredStructureFeature<?, ?>> JUNGLE_TEMPLE =
|
||||
// StructureFeatures.register(BuiltinStructures.JUNGLE_TEMPLE, StructureFeature.JUNGLE_TEMPLE.configured(NoneFeatureConfiguration.INSTANCE, BiomeTags.HAS_JUNGLE_TEMPLE));
|
||||
//public static final Holder<StructureSet> JUNGLE_TEMPLES =
|
||||
// StructureSets.register(BuiltinStructureSets.JUNGLE_TEMPLES, StructureFeatures.JUNGLE_TEMPLE, new RandomSpreadStructurePlacement(32, 8, RandomSpreadType.LINEAR, 14357619));
|
||||
//public static final StructureFeature<NoneFeatureConfiguration> JUNGLE_TEMPLE =
|
||||
// StructureFeature.register("jungle_pyramid", new JunglePyramidFeature(NoneFeatureConfiguration.CODEC), GenerationStep.Decoration.SURFACE_STRUCTURES);
|
||||
//
|
||||
|
||||
this.spreadConfig = new RandomSpreadStructurePlacement(spacing, separation, RandomSpreadType.LINEAR, RANDOM.nextInt(8192));
|
||||
this.structureKey = ResourceKey.create(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY, id);
|
||||
this.structureSetKey = ResourceKey.create(Registry.STRUCTURE_SET_REGISTRY, id);
|
||||
|
||||
this.biomeTag = TagAPI.makeBiomeTag(id.getNamespace(), "has_structure/"+id.getPath());
|
||||
this.structure = StructureFeatureAccessor.callRegister(id.toString(), structure, step);
|
||||
this.featureConfigured = StructureFeaturesAccessor.callRegister(structureKey, this.structure.configured(NoneFeatureConfiguration.NONE, biomeTag, adaptNoise));
|
||||
StructureSets.register(structureSetKey, featureConfigured, spreadConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,7 +96,7 @@ public class BCLStructureFeature {
|
|||
return structure;
|
||||
}
|
||||
|
||||
public ConfiguredStructureFeature<?, ?> getFeatureConfigured() {
|
||||
public Holder<ConfiguredStructureFeature<?, ?>> getFeatureConfigured() {
|
||||
return featureConfigured;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue