Compare commits

..

No commits in common. "0.10.1-pre" and "1.16.5" have entirely different histories.

33 changed files with 313 additions and 384 deletions

View file

@ -43,46 +43,39 @@ dependencies {
def useOptional(String dep) { def useOptional(String dep) {
dependencies.modRuntime (dep) { dependencies.modRuntime (dep) {
exclude group: 'net.fabricmc.fabric-api' exclude group: "net.fabricmc.fabric-api"
exclude group: 'net.fabricmc' exclude group: "net.fabricmc"
if (!dep.contains("me.shedaniel")) { if (!dep.contains("me.shedaniel")) {
exclude group: 'me.shedaniel.cloth' exclude group: "me.shedaniel"
exclude group: 'me.shedaniel'
} }
} }
dependencies.modCompileOnly (dep) { dependencies.modCompileOnly (dep) {
exclude group: 'net.fabricmc.fabric-api' exclude group: "net.fabricmc.fabric-api"
exclude group: 'net.fabricmc' exclude group: "net.fabricmc"
if (!dep.contains("me.shedaniel")) { if (!dep.contains("me.shedaniel")) {
exclude group: 'me.shedaniel.cloth' exclude group: "me.shedaniel"
exclude group: 'me.shedaniel'
} }
} }
} }
def useApi(String dep) { def useApi(String dep) {
dependencies.modApi (dep) { dependencies.modApi (dep) {
exclude group: 'net.fabricmc.fabric-api' exclude group: "net.fabricmc.fabric-api"
exclude group: 'net.fabricmc' exclude group: "net.fabricmc"
if (!dep.contains("me.shedaniel")) { if (!dep.contains("me.shedaniel")) {
exclude group: 'me.shedaniel.cloth' exclude group: "me.shedaniel"
exclude group: 'me.shedaniel'
} }
} }
} }
processResources { processResources {
inputs.property "version", project.version inputs.property "version", project.version
duplicatesStrategy = 'EXCLUDE' duplicatesStrategy = 'WARN'
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
include "fabric.mod.json" include "fabric.mod.json"
expand "version": project.version expand "version": project.version
} }
from(sourceSets.main.resources.srcDirs) {
exclude "fabric.mod.json"
}
} }
// ensure that the encoding is set to UTF-8, no matter what the system default is // ensure that the encoding is set to UTF-8, no matter what the system default is
@ -162,4 +155,4 @@ task release(dependsOn: [remapJar, sourcesJar, javadocJar]) {
// // uncomment to publish to the local maven // // uncomment to publish to the local maven
// // mavenLocal() // // mavenLocal()
// } // }
//} //}

View file

@ -8,14 +8,14 @@ yarn_mappings=6
loader_version=0.11.3 loader_version=0.11.3
# Mod Properties # Mod Properties
mod_version = 0.9.8.5-pre mod_version = 0.9.8-pre
maven_group = ru.betterend maven_group = ru.betterend
archives_base_name = better-end archives_base_name = better-end
# Dependencies # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
patchouli_version = 53-FABRIC patchouli_version = 50-FABRIC
fabric_version = 0.36.0+1.16 fabric_version = 0.32.9+1.16
bclib_version = 0.1.44 canvas_version = 1.0.+
rei_version = 5.12.248 bclib_version = 0.1.38
canvas_version = 1.0.+ rei_version = 5.8.10

View file

@ -7,8 +7,6 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
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.object.builder.v1.block.FabricBlockSettings;
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.BlockModel;
@ -59,7 +57,6 @@ public class BulbVineLanternBlock extends EndLanternBlock implements IRenderType
} }
@Override @Override
@Environment(EnvType.CLIENT)
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
Map<String, String> textures = Maps.newHashMap(); Map<String, String> textures = Maps.newHashMap();
textures.put("%glow%", getGlowTexture()); textures.put("%glow%", getGlowTexture());

View file

@ -8,8 +8,6 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
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.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.BlockModelRotation; import net.minecraft.client.resources.model.BlockModelRotation;
@ -48,13 +46,11 @@ public class ChandelierBlock extends BaseAttachedBlock implements IRenderTyped,
} }
@Override @Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation blockId) { public BlockModel getItemModel(ResourceLocation blockId) {
return ModelsHelper.createItemModel(blockId); return ModelsHelper.createItemModel(blockId);
} }
@Override @Override
@Environment(EnvType.CLIENT)
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
Optional<String> pattern; Optional<String> pattern;
switch (blockState.getValue(FACING)) { switch (blockState.getValue(FACING)) {
@ -71,7 +67,6 @@ public class ChandelierBlock extends BaseAttachedBlock implements IRenderTyped,
} }
@Override @Override
@Environment(EnvType.CLIENT)
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) { public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
String state = "_wall"; String state = "_wall";
BlockModelRotation rotation = BlockModelRotation.X0_Y0; BlockModelRotation rotation = BlockModelRotation.X0_Y0;

View file

@ -6,8 +6,6 @@ import java.util.Random;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
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.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -87,7 +85,6 @@ public class EmeraldIceBlock extends HalfTransparentBlock implements IRenderType
} }
@Override @Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation resourceLocation) { public BlockModel getItemModel(ResourceLocation resourceLocation) {
return getBlockModel(resourceLocation, defaultBlockState()); return getBlockModel(resourceLocation, defaultBlockState());
} }

View file

@ -52,7 +52,7 @@ public class EndStoneSmelter extends BaseBlockWithEntity {
.resistance(100F) .resistance(100F)
.requiresCorrectToolForDrops() .requiresCorrectToolForDrops()
.sound(SoundType.STONE)); .sound(SoundType.STONE));
registerDefaultState(this.stateDefinition.any() this.registerDefaultState(this.stateDefinition.any()
.setValue(FACING, Direction.NORTH) .setValue(FACING, Direction.NORTH)
.setValue(LIT, false)); .setValue(LIT, false));
} }
@ -75,7 +75,7 @@ public class EndStoneSmelter extends BaseBlockWithEntity {
@Override @Override
public BlockState getStateForPlacement(BlockPlaceContext ctx) { public BlockState getStateForPlacement(BlockPlaceContext ctx) {
return defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getOpposite()); return this.defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getOpposite());
} }
@Override @Override

View file

@ -18,8 +18,8 @@ import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import ru.bclib.interfaces.ISpetialItem;
import ru.betterend.blocks.basis.EndPlantBlock; import ru.betterend.blocks.basis.EndPlantBlock;
import ru.betterend.interfaces.ISpetialItem;
public class FlamaeaBlock extends EndPlantBlock implements ISpetialItem { public class FlamaeaBlock extends EndPlantBlock implements ISpetialItem {
private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 1, 16); private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 1, 16);

View file

@ -4,8 +4,6 @@ import java.util.Optional;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
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.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.color.item.ItemColor; import net.minecraft.client.color.item.ItemColor;
@ -33,7 +31,6 @@ public class HydraluxPetalColoredBlock extends HydraluxPetalBlock implements ICo
} }
@Override @Override
@Environment(EnvType.CLIENT)
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
String path = "betterend:block/block_petal_colored"; String path = "betterend:block/block_petal_colored";
Optional<String> pattern = Patterns.createJson(Patterns.BLOCK_PETAL_COLORED, path, path); Optional<String> pattern = Patterns.createJson(Patterns.BLOCK_PETAL_COLORED, path, path);

View file

@ -7,8 +7,6 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.Lists; 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.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.color.item.ItemColor; import net.minecraft.client.color.item.ItemColor;
@ -73,13 +71,11 @@ public class JellyshroomCapBlock extends SlimeBlock implements IRenderTyped, Blo
} }
@Override @Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation resourceLocation) { public BlockModel getItemModel(ResourceLocation resourceLocation) {
return getBlockModel(resourceLocation, defaultBlockState()); return getBlockModel(resourceLocation, defaultBlockState());
} }
@Override @Override
@Environment(EnvType.CLIENT)
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
Optional<String> pattern = Patterns.createJson(Patterns.BLOCK_COLORED, "jellyshroom_cap"); Optional<String> pattern = Patterns.createJson(Patterns.BLOCK_COLORED, "jellyshroom_cap");
return ModelsHelper.fromPattern(pattern); return ModelsHelper.fromPattern(pattern);

View file

@ -81,7 +81,6 @@ public class UmbrellaTreeMembraneBlock extends SlimeBlock implements IRenderType
} }
@Override @Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation resourceLocation) { public BlockModel getItemModel(ResourceLocation resourceLocation) {
return getBlockModel(resourceLocation, defaultBlockState()); return getBlockModel(resourceLocation, defaultBlockState());
} }

View file

@ -2,8 +2,6 @@ package ru.betterend.blocks.basis;
import java.util.Map; import java.util.Map;
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.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -127,7 +125,6 @@ public class EndLanternBlock extends BaseBlockNotFull implements SimpleWaterlogg
} }
@Override @Override
@Environment(EnvType.CLIENT)
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) { public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
String floor = blockState.getValue(IS_FLOOR) ? "_floor" : ""; String floor = blockState.getValue(IS_FLOOR) ? "_floor" : "";
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),

View file

@ -10,8 +10,6 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.Lists; 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.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.client.resources.model.UnbakedModel;
@ -372,13 +370,11 @@ public class PedestalBlock extends BaseBlockNotFull implements EntityBlock {
} }
@Override @Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation blockId) { public BlockModel getItemModel(ResourceLocation blockId) {
return getBlockModel(blockId, defaultBlockState()); return getBlockModel(blockId, defaultBlockState());
} }
@Override @Override
@Environment(EnvType.CLIENT)
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
Map<String, String> textures = createTexturesMap(); Map<String, String> textures = createTexturesMap();
PedestalState state = blockState.getValue(STATE); PedestalState state = blockState.getValue(STATE);
@ -405,7 +401,6 @@ public class PedestalBlock extends BaseBlockNotFull implements EntityBlock {
} }
@Override @Override
@Environment(EnvType.CLIENT)
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) { public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
PedestalState state = blockState.getValue(STATE); PedestalState state = blockState.getValue(STATE);
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),

View file

@ -4,8 +4,6 @@ import java.util.Optional;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
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.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.color.item.ItemColor; import net.minecraft.client.color.item.ItemColor;
@ -46,7 +44,6 @@ public class StoneLanternBlock extends EndLanternBlock implements IColorProvider
} }
@Override @Override
@Environment(EnvType.CLIENT)
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
String blockName = resourceLocation.getPath(); String blockName = resourceLocation.getPath();
Optional<String> pattern = blockState.getValue(IS_FLOOR) ? Optional<String> pattern = blockState.getValue(IS_FLOOR) ?

View file

@ -16,7 +16,6 @@ import ru.bclib.blocks.BaseBarkBlock;
import ru.bclib.blocks.BaseBarrelBlock; import ru.bclib.blocks.BaseBarrelBlock;
import ru.bclib.blocks.BaseBlock; import ru.bclib.blocks.BaseBlock;
import ru.bclib.blocks.BaseBookshelfBlock; import ru.bclib.blocks.BaseBookshelfBlock;
import ru.bclib.blocks.BaseChestBlock;
import ru.bclib.blocks.BaseComposterBlock; import ru.bclib.blocks.BaseComposterBlock;
import ru.bclib.blocks.BaseCraftingTableBlock; import ru.bclib.blocks.BaseCraftingTableBlock;
import ru.bclib.blocks.BaseDoorBlock; import ru.bclib.blocks.BaseDoorBlock;
@ -91,7 +90,7 @@ public class WoodenMaterial {
ladder = EndBlocks.registerBlock(name + "_ladder", new BaseLadderBlock(planks)); ladder = EndBlocks.registerBlock(name + "_ladder", new BaseLadderBlock(planks));
sign = EndBlocks.registerBlock(name + "_sign", new BaseSignBlock(planks)); sign = EndBlocks.registerBlock(name + "_sign", new BaseSignBlock(planks));
chest = EndBlocks.registerBlock(name + "_chest", new BaseChestBlock(planks)); chest = EndBlocks.registerBlock(name + "_chest", new BaseFenceBlock(planks));
barrel = EndBlocks.registerBlock(name + "_barrel", new BaseBarrelBlock(planks)); barrel = EndBlocks.registerBlock(name + "_barrel", new BaseBarrelBlock(planks));
shelf = EndBlocks.registerBlock(name + "_bookshelf", new BaseBookshelfBlock(planks)); shelf = EndBlocks.registerBlock(name + "_bookshelf", new BaseBookshelfBlock(planks));
composter = EndBlocks.registerBlock(name + "_composter", new BaseComposterBlock(planks)); composter = EndBlocks.registerBlock(name + "_composter", new BaseComposterBlock(planks));

View file

@ -246,7 +246,7 @@ public class EndStoneSmelterBlockEntity extends BaseContainerBlockEntity impleme
if (recipe == null) { if (recipe == null) {
recipe = level.getRecipeManager().getRecipeFor(RecipeType.BLASTING, this, level).orElse(null); recipe = level.getRecipeManager().getRecipeFor(RecipeType.BLASTING, this, level).orElse(null);
} }
boolean accepted = canAcceptRecipeOutput(recipe); boolean accepted = this.canAcceptRecipeOutput(recipe);
if (!burning && accepted) { if (!burning && accepted) {
burnTime = getFuelTime(fuel); burnTime = getFuelTime(fuel);
fuelTime = burnTime; fuelTime = burnTime;
@ -265,7 +265,7 @@ public class EndStoneSmelterBlockEntity extends BaseContainerBlockEntity impleme
} }
if (burning && accepted) { if (burning && accepted) {
smeltTime++; this.smeltTime++;
if (smeltTime == smeltTimeTotal) { if (smeltTime == smeltTimeTotal) {
smeltTime = 0; smeltTime = 0;
smeltTimeTotal = getSmeltTime(); smeltTimeTotal = getSmeltTime();
@ -276,7 +276,7 @@ public class EndStoneSmelterBlockEntity extends BaseContainerBlockEntity impleme
smeltTime = 0; smeltTime = 0;
} }
} }
burning = isBurning();
if (initialBurning != burning) { if (initialBurning != burning) {
level.setBlock(worldPosition, level.getBlockState(worldPosition).setValue(EndStoneSmelter.LIT, burning), 3); level.setBlock(worldPosition, level.getBlockState(worldPosition).setValue(EndStoneSmelter.LIT, burning), 3);
setChanged(); setChanged();

View file

@ -0,0 +1,7 @@
package ru.betterend.interfaces;
public interface ISpetialItem {
public int getStackSize();
public boolean canPlaceOnWater();
}

View file

@ -1,7 +1,5 @@
package ru.betterend.item; package ru.betterend.item;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -27,7 +25,6 @@ public class EnchantedItem extends ModelProviderItem {
} }
@Override @Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation resourceLocation) { public BlockModel getItemModel(ResourceLocation resourceLocation) {
ResourceLocation sourceId = Registry.ITEM.getKey(source); ResourceLocation sourceId = Registry.ITEM.getKey(source);
return ModelsHelper.createItemModel(sourceId); return ModelsHelper.createItemModel(sourceId);

View file

@ -1,7 +1,5 @@
package ru.betterend.item; package ru.betterend.item;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -32,7 +30,6 @@ public class EndAnvilItem extends BaseAnvilItem {
} }
@Override @Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation resourceLocation) { public BlockModel getItemModel(ResourceLocation resourceLocation) {
Block block = getBlock(); Block block = getBlock();
ResourceLocation blockId = Registry.BLOCK.getKey(block); ResourceLocation blockId = Registry.BLOCK.getKey(block);

View file

@ -8,8 +8,6 @@ import com.google.common.collect.Multimap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import io.netty.util.internal.ThreadLocalRandom; import io.netty.util.internal.ThreadLocalRandom;
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.DynamicAttributeTool;
import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -135,7 +133,6 @@ public class EndHammerItem extends DiggerItem implements DynamicAttributeTool, I
} }
@Override @Override
@Environment(EnvType.CLIENT)
public BlockModel getItemModel(ResourceLocation resourceLocation) { public BlockModel getItemModel(ResourceLocation resourceLocation) {
return ModelsHelper.createHandheldItem(resourceLocation); return ModelsHelper.createHandheldItem(resourceLocation);
} }

View file

@ -32,7 +32,6 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import ru.betterend.BetterEnd;
import ru.betterend.interfaces.FallFlyingItem; import ru.betterend.interfaces.FallFlyingItem;
import ru.betterend.interfaces.MobEffectApplier; import ru.betterend.interfaces.MobEffectApplier;
import ru.betterend.item.CrystaliteArmor; import ru.betterend.item.CrystaliteArmor;
@ -90,12 +89,8 @@ public abstract class LivingEntityMixin extends Entity {
@Inject(method = "canBeAffected", at = @At("HEAD"), cancellable = true) @Inject(method = "canBeAffected", at = @At("HEAD"), cancellable = true)
public void be_canBeAffected(MobEffectInstance mobEffectInstance, CallbackInfoReturnable<Boolean> info) { public void be_canBeAffected(MobEffectInstance mobEffectInstance, CallbackInfoReturnable<Boolean> info) {
try { if (mobEffectInstance.getEffect() == MobEffects.BLINDNESS && getAttributes().getValue(EndAttributes.BLINDNESS_RESISTANCE) > 0.0) {
if (mobEffectInstance.getEffect() == MobEffects.BLINDNESS && getAttributes().getValue(EndAttributes.BLINDNESS_RESISTANCE) > 0.0) { info.setReturnValue(false);
info.setReturnValue(false);
}
} catch (Exception ex) {
BetterEnd.LOGGER.warning("Blindness resistance attribute haven't been registered.");
} }
} }

View file

@ -17,10 +17,11 @@ import ru.bclib.util.ColorUtil;
import ru.betterend.registry.EndParticles; import ru.betterend.registry.EndParticles;
public class InfusionParticleType extends ParticleType<InfusionParticleType> implements ParticleOptions { public class InfusionParticleType extends ParticleType<InfusionParticleType> implements ParticleOptions {
public static final Codec<InfusionParticleType> CODEC = ItemStack.CODEC.xmap( public static final Codec<InfusionParticleType> CODEC = ItemStack.CODEC.xmap(itemStack -> {
itemStack -> new InfusionParticleType(EndParticles.INFUSION, itemStack), return new InfusionParticleType(EndParticles.INFUSION, itemStack);
infusionParticleType -> infusionParticleType.itemStack); }, infusionParticleType -> {
return infusionParticleType.itemStack;
});
public static final ParticleOptions.Deserializer<InfusionParticleType> PARAMETERS_FACTORY = new ParticleOptions.Deserializer<InfusionParticleType>() { public static final ParticleOptions.Deserializer<InfusionParticleType> PARAMETERS_FACTORY = new ParticleOptions.Deserializer<InfusionParticleType>() {
public InfusionParticleType fromCommand(ParticleType<InfusionParticleType> particleType, StringReader stringReader) throws CommandSyntaxException { public InfusionParticleType fromCommand(ParticleType<InfusionParticleType> particleType, StringReader stringReader) throws CommandSyntaxException {
stringReader.expect(' '); stringReader.expect(' ');
@ -34,8 +35,8 @@ public class InfusionParticleType extends ParticleType<InfusionParticleType> imp
} }
}; };
private final ParticleType<InfusionParticleType> type; private ParticleType<InfusionParticleType> type;
private final ItemStack itemStack; private ItemStack itemStack;
public InfusionParticleType(ParticleType<InfusionParticleType> particleType, ItemStack stack) { public InfusionParticleType(ParticleType<InfusionParticleType> particleType, ItemStack stack) {
super(true, PARAMETERS_FACTORY); super(true, PARAMETERS_FACTORY);

View file

@ -4,12 +4,9 @@ import java.util.Objects;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.TagParser;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
@ -279,15 +276,6 @@ public class AnvilRecipe implements Recipe<Container>, BetterEndRecipe {
if (output == null) { if (output == null) {
throw new IllegalStateException("Output item does not exists!"); throw new IllegalStateException("Output item does not exists!");
} }
if (result.has("nbt")) {
try {
String nbtData = GsonHelper.getAsString(result, "nbt");
CompoundTag nbt = TagParser.parseTag(nbtData);
output.setTag(nbt);
} catch (CommandSyntaxException ex) {
BetterEnd.LOGGER.warning("Error parse nbt data for output.", ex);
}
}
int inputCount = GsonHelper.getAsInt(json, "inputCount", 1); int inputCount = GsonHelper.getAsInt(json, "inputCount", 1);
int toolLevel = GsonHelper.getAsInt(json, "toolLevel", 1); int toolLevel = GsonHelper.getAsInt(json, "toolLevel", 1);
int anvilLevel = GsonHelper.getAsInt(json, "anvilLevel", 1); int anvilLevel = GsonHelper.getAsInt(json, "anvilLevel", 1);

View file

@ -4,15 +4,11 @@ import java.util.Arrays;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.util.NbtType;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.nbt.*;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagLoader;
import net.minecraft.util.GsonHelper; import net.minecraft.util.GsonHelper;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
@ -21,7 +17,6 @@ import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.storage.loot.GsonAdapterFactory;
import ru.bclib.recipes.BCLRecipeManager; import ru.bclib.recipes.BCLRecipeManager;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
import ru.betterend.config.Configs; import ru.betterend.config.Configs;
@ -214,15 +209,6 @@ public class InfusionRecipe implements Recipe<InfusionRitual>, BetterEndRecipe {
if (recipe.output == null) { if (recipe.output == null) {
throw new IllegalStateException("Output item does not exists!"); throw new IllegalStateException("Output item does not exists!");
} }
if (result.has("nbt")) {
try {
String nbtData = GsonHelper.getAsString(result, "nbt");
CompoundTag nbt = TagParser.parseTag(nbtData);
recipe.output.setTag(nbt);
} catch (CommandSyntaxException ex) {
BetterEnd.LOGGER.warning("Error parse nbt data for output.", ex);
}
}
recipe.group = GsonHelper.getAsString(json, "group", GROUP); recipe.group = GsonHelper.getAsString(json, "group", GROUP);
recipe.time = GsonHelper.getAsInt(json, "time", 1); recipe.time = GsonHelper.getAsInt(json, "time", 1);

View file

@ -61,6 +61,7 @@ import ru.betterend.world.generator.BiomeType;
import ru.betterend.world.generator.GeneratorOptions; import ru.betterend.world.generator.GeneratorOptions;
public class EndBiomes { public class EndBiomes {
private static final Map<ResourceLocation, EndBiome> ID_MAP = Maps.newHashMap();
public static final Set<ResourceLocation> FABRIC_VOID = Sets.newHashSet(); public static final Set<ResourceLocation> FABRIC_VOID = Sets.newHashSet();
private static final Set<ResourceLocation> SUBBIOMES_UNMUTABLES = Sets.newHashSet(); private static final Set<ResourceLocation> SUBBIOMES_UNMUTABLES = Sets.newHashSet();
@ -160,7 +161,7 @@ public class EndBiomes {
else { else {
LAND_BIOMES.addBiomeMutable(endBiome); LAND_BIOMES.addBiomeMutable(endBiome);
} }
BiomeAPI.registerBiome(endBiome); ID_MAP.put(id, endBiome);
} }
} }
} }
@ -273,7 +274,7 @@ public class EndBiomes {
parent.addSubBiome(endBiome); parent.addSubBiome(endBiome);
SUBBIOMES.add(endBiome); SUBBIOMES.add(endBiome);
SUBBIOMES_UNMUTABLES.add(endBiome.getID()); SUBBIOMES_UNMUTABLES.add(endBiome.getID());
BiomeAPI.registerBiome(endBiome); ID_MAP.put(endBiome.getID(), endBiome);
} }
return endBiome; return endBiome;
} }
@ -290,6 +291,7 @@ public class EndBiomes {
parent.addSubBiome(biome); parent.addSubBiome(biome);
SUBBIOMES.add(biome); SUBBIOMES.add(biome);
SUBBIOMES_UNMUTABLES.add(biome.getID()); SUBBIOMES_UNMUTABLES.add(biome.getID());
ID_MAP.put(biome.getID(), biome);
BiomeAPI.addEndLandBiomeToFabricApi(biome); BiomeAPI.addEndLandBiomeToFabricApi(biome);
} }
return biome; return biome;
@ -305,6 +307,7 @@ public class EndBiomes {
if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) {
BiomeAPI.registerBiome(biome); BiomeAPI.registerBiome(biome);
addToPicker(biome, type); addToPicker(biome, type);
ID_MAP.put(biome.getID(), biome);
if (type == BiomeType.LAND) { if (type == BiomeType.LAND) {
BiomeAPI.addEndLandBiomeToFabricApi(biome); BiomeAPI.addEndLandBiomeToFabricApi(biome);
} }
@ -325,6 +328,7 @@ public class EndBiomes {
BiomeAPI.registerBiome(biome); BiomeAPI.registerBiome(biome);
SUBBIOMES.add(biome); SUBBIOMES.add(biome);
SUBBIOMES_UNMUTABLES.add(biome.getID()); SUBBIOMES_UNMUTABLES.add(biome.getID());
ID_MAP.put(biome.getID(), biome);
BiomeAPI.addEndLandBiomeToFabricApi(biome); BiomeAPI.addEndLandBiomeToFabricApi(biome);
} }
return biome; return biome;
@ -337,7 +341,7 @@ public class EndBiomes {
*/ */
public static void addSubBiomeIntegration(EndBiome biome, ResourceLocation parent) { public static void addSubBiomeIntegration(EndBiome biome, ResourceLocation parent) {
if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) {
BCLBiome parentBiome = BiomeAPI.getBiome(parent); EndBiome parentBiome = ID_MAP.get(parent);
if (parentBiome != null && !parentBiome.containsSubBiome(biome)) { if (parentBiome != null && !parentBiome.containsSubBiome(biome)) {
parentBiome.addSubBiome(biome); parentBiome.addSubBiome(biome);
} }
@ -365,6 +369,7 @@ public class EndBiomes {
if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) {
BiomeAPI.registerBiome(biome); BiomeAPI.registerBiome(biome);
CAVE_BIOMES.addBiome(biome); CAVE_BIOMES.addBiome(biome);
ID_MAP.put(biome.getID(), biome);
} }
return biome; return biome;
} }
@ -372,4 +377,8 @@ public class EndBiomes {
public static EndCaveBiome getCaveBiome(int x, int z) { public static EndCaveBiome getCaveBiome(int x, int z) {
return (EndCaveBiome) caveBiomeMap.getBiome(x, z); return (EndCaveBiome) caveBiomeMap.getBiome(x, z);
} }
public static boolean hasBiome(ResourceLocation biomeID) {
return ID_MAP.containsKey(biomeID);
}
} }

View file

@ -1,14 +1,20 @@
package ru.betterend.registry; package ru.betterend.registry;
import java.util.List; import java.util.List;
import java.util.function.Supplier;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import net.fabricmc.fabric.api.tag.TagRegistry;
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl; import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
import net.fabricmc.fabric.impl.tool.attribute.handlers.ModdedToolsVanillaBlocksToolHandler; import net.fabricmc.fabric.impl.tool.attribute.handlers.ModdedToolsVanillaBlocksToolHandler;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ItemTags; import net.minecraft.tags.ItemTags;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
import net.minecraft.tags.Tag.Named;
import net.minecraft.tags.TagCollection;
import net.minecraft.world.food.FoodProperties; import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
@ -33,12 +39,43 @@ public class EndTags {
// https://fabricmc.net/wiki/tutorial:tags // https://fabricmc.net/wiki/tutorial:tags
// Block Tags // Block Tags
public static final Tag.Named<Block> PEDESTALS = TagAPI.makeBlockTag(BetterEnd.MOD_ID, "pedestal"); public static final Tag.Named<Block> PEDESTALS = makeBlockTag("pedestal");
public static final Tag.Named<Block> END_STONES = TagAPI.makeCommonBlockTag("end_stones"); public static final Tag.Named<Block> END_STONES = makeCommonBlockTag("end_stones");
public static final Tag.Named<Block> DRAGON_IMMUNE = TagAPI.getMCBlockTag("dragon_immune"); public static final Tag.Named<Block> DRAGON_IMMUNE = getMCBlockTag("dragon_immune");
// Item Tags // Item Tags
public final static Tag.Named<Item> HAMMERS = TagAPI.makeItemTag("fabric", "hammers"); public final static Tag.Named<Item> HAMMERS = makeFabricItemTag("hammers");
public static <T> Tag.Named<T> makeTag(Supplier<TagCollection<T>> containerSupplier, ResourceLocation id) {
Tag<T> tag = containerSupplier.get().getTag(id);
return tag == null ? TagRegistry.create(id, containerSupplier) : (Named<T>) tag;
}
public static Tag.Named<Block> makeBlockTag(String name) {
return makeTag(BlockTags::getAllTags, BetterEnd.makeID(name));
}
public static Tag.Named<Item> makeItemTag(String name) {
return makeTag(ItemTags::getAllTags, BetterEnd.makeID(name));
}
public static Tag.Named<Block> makeCommonBlockTag(String name) {
return makeTag(BlockTags::getAllTags, new ResourceLocation("c", name));
}
public static Tag.Named<Item> makeCommonItemTag(String name) {
return makeTag(ItemTags::getAllTags, new ResourceLocation("c", name));
}
public static Tag.Named<Item> makeFabricItemTag(String name) {
return makeTag(ItemTags::getAllTags, new ResourceLocation("fabric", name));
}
public static Tag.Named<Block> getMCBlockTag(String name) {
ResourceLocation id = new ResourceLocation(name);
Tag<Block> tag = BlockTags.getAllTags().getTag(id);
return tag == null ? (Named<Block>) TagRegistry.block(id) : (Named<Block>) tag;
}
public static void register() { public static void register() {
TagAPI.addEndGround(EndBlocks.THALLASIUM.ore); TagAPI.addEndGround(EndBlocks.THALLASIUM.ore);
@ -67,8 +104,6 @@ public class EndTags {
ComposterBlockAccessor.callAdd(0.1F, block); ComposterBlockAccessor.callAdd(0.1F, block);
} }
}); });
TagAPI.addEndGround(EndBlocks.CAVE_MOSS);
TagHelper.addTag(BlockTags.NYLIUM, EndBlocks.CAVE_MOSS);
BonemealAPI.addSpreadableBlock(EndBlocks.CAVE_MOSS); BonemealAPI.addSpreadableBlock(EndBlocks.CAVE_MOSS);
List<Item> hammers = Lists.newArrayList(); List<Item> hammers = Lists.newArrayList();

View file

@ -11,6 +11,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;

View file

@ -1,7 +1,6 @@
package ru.betterend.util; package ru.betterend.util;
import java.util.Set; import java.util.Set;
import java.util.stream.IntStream;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
@ -21,194 +20,187 @@ import ru.betterend.blocks.basis.FurBlock;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
public class BlockFixer { public class BlockFixer {
private static final MutableBlockPos POS = new MutableBlockPos();
private static final BlockState AIR = Blocks.AIR.defaultBlockState(); private static final BlockState AIR = Blocks.AIR.defaultBlockState();
private static final BlockState WATER = Blocks.WATER.defaultBlockState(); private static final BlockState WATER = Blocks.WATER.defaultBlockState();
public static void fixBlocks(LevelAccessor world, BlockPos start, BlockPos end) { public static void fixBlocks(LevelAccessor world, BlockPos start, BlockPos end) {
Set<BlockPos> doubleCheck = Sets.newConcurrentHashSet(); BlockState state;
int dx = end.getX() - start.getX() + 1; Set<BlockPos> doubleCheck = Sets.newHashSet();
int dz = end.getZ() - start.getZ() + 1; for (int x = start.getX(); x <= end.getX(); x++) {
int count = dx * dz; POS.setX(x);
IntStream.range(0, count).parallel().forEach(index -> { for (int z = start.getZ(); z <= end.getZ(); z++) {
MutableBlockPos POS = new MutableBlockPos(); POS.setZ(z);
POS.setX((index % dx) + start.getX()); for (int y = start.getY(); y <= end.getY(); y++) {
POS.setZ((index / dx) + start.getZ()); POS.setY(y);
BlockState state; state = world.getBlockState(POS);
for (int y = start.getY(); y <= end.getY(); y++) {
POS.setY(y); if (state.getBlock() instanceof FurBlock) {
state = world.getBlockState(POS); doubleCheck.add(POS.immutable());
}
if (state.getBlock() instanceof FurBlock) { // Liquids
doubleCheck.add(POS.immutable()); else if (!state.getFluidState().isEmpty()) {
} if (!state.canSurvive(world, POS)) {
// Liquids BlocksHelper.setWithoutUpdate(world, POS, WATER);
else if (!state.getFluidState().isEmpty()) {
if (!state.canSurvive(world, POS)) {
setWithoutUpdate(world, POS, WATER);
POS.setY(POS.getY() - 1);
state = world.getBlockState(POS);
while (!state.canSurvive(world, POS)) {
state = state.getFluidState().isEmpty() ? AIR : WATER;
setWithoutUpdate(world, POS, state);
POS.setY(POS.getY() - 1); POS.setY(POS.getY() - 1);
state = world.getBlockState(POS); state = world.getBlockState(POS);
} while (!state.canSurvive(world, POS)) {
} state = state.getFluidState().isEmpty() ? AIR : WATER;
POS.setY(y - 1); BlocksHelper.setWithoutUpdate(world, POS, state);
if (world.isEmptyBlock(POS)) {
POS.setY(y);
while (!world.getFluidState(POS).isEmpty()) {
setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
}
continue;
}
for (Direction dir : BlocksHelper.HORIZONTAL) {
if (world.isEmptyBlock(POS.relative(dir))) {
world.getLiquidTicks().scheduleTick(POS, state.getFluidState().getType(), 0);
break;
}
}
}
else if (state.is(EndBlocks.SMARAGDANT_CRYSTAL)) {
POS.setY(POS.getY() - 1);
if (world.isEmptyBlock(POS)) {
POS.setY(POS.getY() + 1);
while (state.is(EndBlocks.SMARAGDANT_CRYSTAL)) {
setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
state = world.getBlockState(POS);
}
}
}
else if (state.getBlock() instanceof StalactiteBlock) {
if (!state.canSurvive(world, POS)) {
if (world.getBlockState(POS.above()).getBlock() instanceof StalactiteBlock) {
while (state.getBlock() instanceof StalactiteBlock) {
setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
state = world.getBlockState(POS);
}
}
else {
while (state.getBlock() instanceof StalactiteBlock) {
setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() - 1); POS.setY(POS.getY() - 1);
state = world.getBlockState(POS); state = world.getBlockState(POS);
} }
} }
POS.setY(y - 1);
if (world.isEmptyBlock(POS)) {
POS.setY(y);
while (!world.getFluidState(POS).isEmpty()) {
BlocksHelper.setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
}
continue;
}
for (Direction dir : BlocksHelper.HORIZONTAL) {
if (world.isEmptyBlock(POS.relative(dir))) {
world.getLiquidTicks().scheduleTick(POS, state.getFluidState().getType(), 0);
break;
}
}
} }
} else if (state.is(EndBlocks.SMARAGDANT_CRYSTAL)) {
else if (state.is(EndBlocks.CAVE_PUMPKIN)) { POS.setY(POS.getY() - 1);
if (!world.getBlockState(POS.above()).is(EndBlocks.CAVE_PUMPKIN_SEED)) { if (world.isEmptyBlock(POS)) {
setWithoutUpdate(world, POS, AIR); POS.setY(POS.getY() + 1);
while (state.is(EndBlocks.SMARAGDANT_CRYSTAL)) {
BlocksHelper.setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
state = world.getBlockState(POS);
}
}
} }
} else if (state.getBlock() instanceof StalactiteBlock) {
else if (!state.canSurvive(world, POS)) { if (!state.canSurvive(world, POS)) {
// Chorus if (world.getBlockState(POS.above()).getBlock() instanceof StalactiteBlock) {
if (state.is(Blocks.CHORUS_PLANT)) { while (state.getBlock() instanceof StalactiteBlock) {
Set<BlockPos> ends = Sets.newHashSet(); BlocksHelper.setWithoutUpdate(world, POS, AIR);
Set<BlockPos> add = Sets.newHashSet(); POS.setY(POS.getY() + 1);
ends.add(POS.immutable()); state = world.getBlockState(POS);
}
}
else {
while (state.getBlock() instanceof StalactiteBlock) {
BlocksHelper.setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() - 1);
state = world.getBlockState(POS);
}
}
}
}
else if (state.is(EndBlocks.CAVE_PUMPKIN)) {
if (!world.getBlockState(POS.above()).is(EndBlocks.CAVE_PUMPKIN_SEED)) {
BlocksHelper.setWithoutUpdate(world, POS, AIR);
}
}
else if (!state.canSurvive(world, POS)) {
// Chorus
if (state.is(Blocks.CHORUS_PLANT)) {
Set<BlockPos> ends = Sets.newHashSet();
Set<BlockPos> add = Sets.newHashSet();
ends.add(POS.immutable());
for (int i = 0; i < 64 && !ends.isEmpty(); i++) { for (int i = 0; i < 64 && !ends.isEmpty(); i++) {
ends.forEach((pos) -> { ends.forEach((pos) -> {
setWithoutUpdate(world, pos, AIR); BlocksHelper.setWithoutUpdate(world, pos, AIR);
for (Direction dir : BlocksHelper.HORIZONTAL) { for (Direction dir : BlocksHelper.HORIZONTAL) {
BlockPos p = pos.relative(dir); BlockPos p = pos.relative(dir);
BlockState st = world.getBlockState(p);
if ((st.is(Blocks.CHORUS_PLANT) || st.is(Blocks.CHORUS_FLOWER)) && !st.canSurvive(world, p)) {
add.add(p);
}
}
BlockPos p = pos.above();
BlockState st = world.getBlockState(p); BlockState st = world.getBlockState(p);
if ((st.is(Blocks.CHORUS_PLANT) || st.is(Blocks.CHORUS_FLOWER)) && !st.canSurvive(world, p)) { if ((st.is(Blocks.CHORUS_PLANT) || st.is(Blocks.CHORUS_FLOWER)) && !st.canSurvive(world, p)) {
add.add(p); add.add(p);
} }
} });
BlockPos p = pos.above(); ends.clear();
BlockState st = world.getBlockState(p); ends.addAll(add);
if ((st.is(Blocks.CHORUS_PLANT) || st.is(Blocks.CHORUS_FLOWER)) && !st.canSurvive(world, p)) { add.clear();
add.add(p); }
}
});
ends.clear();
ends.addAll(add);
add.clear();
} }
} // Vines
// Vines else if (state.getBlock() instanceof BaseVineBlock) {
else if (state.getBlock() instanceof BaseVineBlock) { while (world.getBlockState(POS).getBlock() instanceof BaseVineBlock) {
while (world.getBlockState(POS).getBlock() instanceof BaseVineBlock) { BlocksHelper.setWithoutUpdate(world, POS, AIR);
setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() - 1);
}
}
// Falling blocks
else if (state.getBlock() instanceof FallingBlock) {
BlockState falling = state;
POS.setY(POS.getY() - 1);
state = world.getBlockState(POS);
int ray = BlocksHelper.downRayRep(world, POS.immutable(), 64);
if (ray > 32) {
setWithoutUpdate(world, POS, Blocks.END_STONE.defaultBlockState());
if (world.getRandom().nextBoolean()) {
POS.setY(POS.getY() - 1); POS.setY(POS.getY() - 1);
state = world.getBlockState(POS);
setWithoutUpdate(world, POS, Blocks.END_STONE.defaultBlockState());
} }
} }
else { // Falling blocks
POS.setY(y); else if (state.getBlock() instanceof FallingBlock) {
BlockState replacement = AIR; BlockState falling = state;
for (Direction dir : BlocksHelper.HORIZONTAL) {
state = world.getBlockState(POS.relative(dir)); POS.setY(POS.getY() - 1);
if (!state.getFluidState().isEmpty()) { state = world.getBlockState(POS);
replacement = state;
break; int ray = BlocksHelper.downRayRep(world, POS.immutable(), 64);
if (ray > 32) {
BlocksHelper.setWithoutUpdate(world, POS, Blocks.END_STONE.defaultBlockState());
if (world.getRandom().nextBoolean()) {
POS.setY(POS.getY() - 1);
state = world.getBlockState(POS);
BlocksHelper.setWithoutUpdate(world, POS, Blocks.END_STONE.defaultBlockState());
} }
} }
setWithoutUpdate(world, POS, replacement); else {
POS.setY(y - ray); POS.setY(y);
setWithoutUpdate(world, POS, falling); BlockState replacement = AIR;
} for (Direction dir : BlocksHelper.HORIZONTAL) {
} state = world.getBlockState(POS.relative(dir));
// Blocks without support if (!state.getFluidState().isEmpty()) {
else { replacement = state;
// Blue Vine break;
if (state.getBlock() instanceof BlueVineBlock) { }
while (state.is(EndBlocks.BLUE_VINE) || state.is(EndBlocks.BLUE_VINE_LANTERN) || state.is(EndBlocks.BLUE_VINE_FUR)) { }
setWithoutUpdate(world, POS, AIR); BlocksHelper.setWithoutUpdate(world, POS, replacement);
POS.setY(POS.getY() + 1); POS.setY(y - ray);
state = world.getBlockState(POS); BlocksHelper.setWithoutUpdate(world, POS, falling);
} }
} }
// Double plants // Blocks without support
if (state.getBlock() instanceof BaseDoublePlantBlock) {
setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
setWithoutUpdate(world, POS, AIR);
}
// Other blocks
else { else {
setWithoutUpdate(world, POS, getAirOrFluid(state)); // Blue Vine
if (state.getBlock() instanceof BlueVineBlock) {
while (state.is(EndBlocks.BLUE_VINE) || state.is(EndBlocks.BLUE_VINE_LANTERN) || state.is(EndBlocks.BLUE_VINE_FUR)) {
BlocksHelper.setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
state = world.getBlockState(POS);
}
}
// Double plants
if (state.getBlock() instanceof BaseDoublePlantBlock) {
BlocksHelper.setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
BlocksHelper.setWithoutUpdate(world, POS, AIR);
}
// Other blocks
else {
BlocksHelper.setWithoutUpdate(world, POS, getAirOrFluid(state));
}
} }
} }
} }
} }
}); }
doubleCheck.forEach((pos) -> { doubleCheck.forEach((pos) -> {
if (!world.getBlockState(pos).canSurvive(world, pos)) { if (!world.getBlockState(pos).canSurvive(world, pos)) {
setWithoutUpdate(world, pos, AIR); BlocksHelper.setWithoutUpdate(world, pos, AIR);
} }
}); });
} }
private static BlockState getAirOrFluid(BlockState state) { private static BlockState getAirOrFluid(BlockState state) {
return state.getFluidState().isEmpty() ? AIR : state.getFluidState().createLegacyBlock(); return state.getFluidState().isEmpty() ? AIR : state.getFluidState().createLegacyBlock();
} }
private static void setWithoutUpdate(LevelAccessor world, BlockPos pos, BlockState state) {
synchronized (world) {
BlocksHelper.setWithoutUpdate(world, pos, state);
}
}
} }

View file

@ -5,22 +5,14 @@ import net.minecraft.world.level.biome.Biome;
import ru.bclib.world.biomes.BCLBiome; import ru.bclib.world.biomes.BCLBiome;
import ru.bclib.world.biomes.BCLBiomeDef; import ru.bclib.world.biomes.BCLBiomeDef;
import ru.betterend.config.Configs; import ru.betterend.config.Configs;
import ru.betterend.registry.EndFeatures;
public class EndBiome extends BCLBiome { public class EndBiome extends BCLBiome {
public EndBiome(BCLBiomeDef def) { public EndBiome(BCLBiomeDef definition) {
super(updateDef(def)); super(definition.loadConfigValues(Configs.BIOME_CONFIG));
} }
public EndBiome(ResourceLocation id, Biome biome, float fogDensity, float genChance, boolean hasCaves) { public EndBiome(ResourceLocation id, Biome biome, float fogDensity, float genChance, boolean hasCaves) {
super(id, biome, fogDensity, genChance); super(id, biome, fogDensity, genChance);
this.addCustomData("has_caves", hasCaves); this.addCustomData("has_caves", hasCaves);
} }
private static BCLBiomeDef updateDef(BCLBiomeDef def) {
def.loadConfigValues(Configs.BIOME_CONFIG);
EndFeatures.addDefaultFeatures(def);
return def;
}
} }

View file

@ -58,17 +58,19 @@ public abstract class EndCaveFeature extends DefaultFeature {
if (!caveBlocks.isEmpty()) { if (!caveBlocks.isEmpty()) {
if (biome != null) { if (biome != null) {
setBiomes(world, biome, caveBlocks); setBiomes(world, biome, caveBlocks);
Set<BlockPos> floorPositions = Sets.newConcurrentHashSet(); Set<BlockPos> floorPositions = Sets.newHashSet();
Set<BlockPos> ceilPositions = Sets.newConcurrentHashSet(); Set<BlockPos> ceilPositions = Sets.newHashSet();
caveBlocks.parallelStream().forEach((bpos) -> { MutableBlockPos mut = new MutableBlockPos();
if (world.getBlockState(bpos).getMaterial().isReplaceable()) { caveBlocks.forEach((bpos) -> {
BlockPos side = bpos.below(); mut.set(bpos);
if (world.getBlockState(side).is(TagAPI.GEN_TERRAIN)) { if (world.getBlockState(mut).getMaterial().isReplaceable()) {
floorPositions.add(side); mut.setY(bpos.getY() - 1);
if (world.getBlockState(mut).is(TagAPI.GEN_TERRAIN)) {
floorPositions.add(mut.immutable());
} }
side = bpos.above(); mut.setY(bpos.getY() + 1);
if (world.getBlockState(side).is(TagAPI.GEN_TERRAIN)) { if (world.getBlockState(mut).is(TagAPI.GEN_TERRAIN)) {
ceilPositions.add(side); ceilPositions.add(mut.immutable());
} }
} }
}); });

View file

@ -2,7 +2,6 @@ package ru.betterend.world.features.terrain.caves;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.stream.IntStream;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
@ -31,45 +30,47 @@ public class RoundCaveFeature extends EndCaveFeature {
double hr = radius * 0.75; double hr = radius * 0.75;
double nr = radius * 0.25; double nr = radius * 0.25;
int dx = x2 - x1 + 1; BlockState state;
int dz = z2 - z1 + 1; MutableBlockPos bpos = new MutableBlockPos();
int count = dx * dz; Set<BlockPos> blocks = Sets.newHashSet();
Set<BlockPos> blocks = Sets.newConcurrentHashSet(); for (int x = x1; x <= x2; x++) {
IntStream.range(0, count).parallel().forEach(index -> { int xsq = x - center.getX();
MutableBlockPos bpos = new MutableBlockPos(); xsq *= xsq;
int x = (index % dx) + x1;
int z = (index / dx) + z1;
bpos.setX(x); bpos.setX(x);
bpos.setZ(z); for (int z = z1; z <= z2; z++) {
int xsq = MHelper.sqr(x - center.getX()); int zsq = z - center.getZ();
int zsq = MHelper.sqr(z - center.getZ()); zsq *= zsq;
int dxz = xsq + zsq; bpos.setZ(z);
BlockState state; for (int y = y1; y <= y2; y++) {
for (int y = y1; y <= y2; y++) { int ysq = y - center.getY();
int ysq = (int) MHelper.sqr((y - center.getY()) * 1.6); ysq *= 1.6;
double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; ysq *= ysq;
double dist = dxz + ysq;
if (dist < r * r) {
bpos.setY(y); bpos.setY(y);
state = world.getBlockState(bpos); double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr;
if (isReplaceable(state) && !isWaterNear(world, bpos)) { double dist = xsq + ysq + zsq;
blocks.add(bpos.immutable()); if (dist < r * r) {
state = world.getBlockState(bpos);
while (state.getMaterial().equals(Material.LEAVES)) { if (isReplaceable(state) && !isWaterNear(world, bpos)) {
bpos.setY(bpos.getY() + 1); BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR);
state = world.getBlockState(bpos); blocks.add(bpos.immutable());
}
while (state.getMaterial().equals(Material.LEAVES)) {
bpos.setY(y - 1); BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR);
while (state.getMaterial().equals(Material.LEAVES)) { bpos.setY(bpos.getY() + 1);
bpos.setY(bpos.getY() - 1); state = world.getBlockState(bpos);
state = world.getBlockState(bpos); }
bpos.setY(y - 1);
while (state.getMaterial().equals(Material.LEAVES)) {
BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR);
bpos.setY(bpos.getY() - 1);
state = world.getBlockState(bpos);
}
} }
} }
} }
} }
}); }
blocks.forEach(bpos -> BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR));
return blocks; return blocks;
} }

View file

@ -3,7 +3,6 @@ package ru.betterend.world.features.terrain.caves;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.stream.IntStream;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
@ -13,18 +12,14 @@ import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap.Types; import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import ru.bclib.api.BiomeAPI;
import ru.bclib.api.TagAPI; import ru.bclib.api.TagAPI;
import ru.bclib.util.BlocksHelper; import ru.bclib.util.BlocksHelper;
import ru.bclib.world.biomes.BCLBiome;
import ru.betterend.noise.OpenSimplexNoise; import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.registry.EndBiomes; import ru.betterend.registry.EndBiomes;
import ru.betterend.world.biome.cave.EndCaveBiome; import ru.betterend.world.biome.cave.EndCaveBiome;
@ -36,56 +31,42 @@ public class TunelCaveFeature extends EndCaveFeature {
if ((long) cx * (long) cx + (long) cz + (long) cz < 256) { if ((long) cx * (long) cx + (long) cz + (long) cz < 256) {
return Sets.newHashSet(); return Sets.newHashSet();
} }
int x1 = cx << 4; int x1 = cx << 4;
int z1 = cz << 4; int z1 = cz << 4;
int x2 = x1 + 16; int x2 = x1 + 16;
int z2 = z1 + 16; int z2 = z1 + 16;
int y2 = world.getHeight();
Random rand = new Random(world.getSeed()); Random rand = new Random(world.getSeed());
OpenSimplexNoise noiseH = new OpenSimplexNoise(rand.nextInt()); OpenSimplexNoise noiseH = new OpenSimplexNoise(rand.nextInt());
OpenSimplexNoise noiseV = new OpenSimplexNoise(rand.nextInt()); OpenSimplexNoise noiseV = new OpenSimplexNoise(rand.nextInt());
OpenSimplexNoise noiseD = new OpenSimplexNoise(rand.nextInt()); OpenSimplexNoise noiseD = new OpenSimplexNoise(rand.nextInt());
Set<BlockPos> positions = Sets.newConcurrentHashSet(); Set<BlockPos> positions = Sets.newHashSet();
MutableBlockPos pos = new MutableBlockPos();
float a = hasCaves(world, new BlockPos(x1, 0, z1)) ? 1F : 0F; for (int x = x1; x < x2; x++) {
float b = hasCaves(world, new BlockPos(x2, 0, z1)) ? 1F : 0F; pos.setX(x);
float c = hasCaves(world, new BlockPos(x1, 0, z2)) ? 1F : 0F; for (int z = z1; z < z2; z++) {
float d = hasCaves(world, new BlockPos(x2, 0, z2)) ? 1F : 0F; pos.setZ(z);
for (int y = 0; y < y2; y++) {
ChunkAccess chunk = world.getChunk(cx, cz);
IntStream.range(0, 256).parallel().forEach(index -> {
MutableBlockPos pos = new MutableBlockPos();
int x = index & 15;
int z = index >> 4;
int wheight = chunk.getHeight(Types.WORLD_SURFACE_WG, x, z);
float dx = x / 16F;
float dz = z / 16F;
pos.setX(x + x1);
pos.setZ(z + z1);
float da = Mth.lerp(dx, a, b);
float db = Mth.lerp(dx, c, d);
float density = 1 - Mth.lerp(dz, da, db);
if (density < 0.5) {
for (int y = 0; y < wheight; y++) {
pos.setY(y); pos.setY(y);
float gradient = 1 - Mth.clamp((wheight - y) * 0.1F, 0F, 1F); float val = Mth.abs((float) noiseH.eval(x * 0.02, y * 0.01, z * 0.02));
if (gradient > 0.5) { float vert = Mth.sin((y + (float) noiseV.eval(x * 0.01, z * 0.01) * 20) * 0.1F) * 0.9F;
break; float dist = (float) noiseD.eval(x * 0.1, y * 0.1, z * 0.1) * 0.12F;
} vert *= vert;
float val = Mth.abs((float) noiseH.eval(pos.getX() * 0.02, y * 0.01, pos.getZ() * 0.02)); if (val + vert + dist < 0.15 && world.getBlockState(pos).is(TagAPI.GEN_TERRAIN) && noWaterNear(world, pos)) {
float vert = Mth.sin((y + (float) noiseV.eval(pos.getX() * 0.01, pos.getZ() * 0.01) * 20) * 0.1F) * 0.9F; BlocksHelper.setWithoutUpdate(world, pos, AIR);
float dist = (float) noiseD.eval(pos.getX() * 0.1, y * 0.1, pos.getZ() * 0.1) * 0.12F;
val = (val + vert * vert + dist) + density + gradient;
if (val < 0.15 && world.getBlockState(pos).is(TagAPI.GEN_TERRAIN) && noWaterNear(world, pos)) {
positions.add(pos.immutable()); positions.add(pos.immutable());
int height = world.getHeight(Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
if (height < pos.getY() + 4) {
while (pos.getY() < height && noWaterNear(world, pos)) {
pos.setY(pos.getY() + 1);
BlocksHelper.setWithoutUpdate(world, pos, AIR);
}
}
} }
} }
} }
}); }
positions.forEach(bpos -> BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR));
return positions; return positions;
} }
@ -211,17 +192,4 @@ public class TunelCaveFeature extends EndCaveFeature {
} }
}); });
} }
protected boolean hasCaves(WorldGenLevel world, BlockPos pos) {
return hasCavesInBiome(world, pos.offset(-8, 0, -8)) &&
hasCavesInBiome(world, pos.offset(8, 0, -8)) &&
hasCavesInBiome(world, pos.offset(-8, 0, 8)) &&
hasCavesInBiome(world, pos.offset(8, 0, 8));
}
protected boolean hasCavesInBiome(WorldGenLevel world, BlockPos pos) {
Biome biome = world.getBiome(pos);
BCLBiome endBiome = BiomeAPI.getFromBiome(biome);
return endBiome.getCustomData("has_caves", true);
}
} }

View file

@ -63,8 +63,7 @@ public class BetterEndBiomeSource extends BiomeSource {
private static List<Biome> getBiomes(Registry<Biome> biomeRegistry) { private static List<Biome> getBiomes(Registry<Biome> biomeRegistry) {
List<Biome> list = Lists.newArrayList(); List<Biome> list = Lists.newArrayList();
biomeRegistry.forEach((biome) -> { biomeRegistry.forEach((biome) -> {
BCLBiome bclBiome = BiomeAPI.getBiome(biomeRegistry.getKey(biome)); if (EndBiomes.hasBiome(biomeRegistry.getKey(biome))) {
if (bclBiome instanceof EndBiome) {
list.add(biome); list.add(biome);
} }
}); });

View file

@ -46,7 +46,7 @@
"fabricloader": ">=0.11.0", "fabricloader": ">=0.11.0",
"fabric": ">=0.32.0", "fabric": ">=0.32.0",
"minecraft": ">=1.16.4", "minecraft": ">=1.16.4",
"bclib": ">=0.1.44" "bclib": ">=0.1.38"
}, },
"suggests": { "suggests": {
"byg": ">=1.1.3", "byg": ">=1.1.3",