diff --git a/src/main/java/ru/betterend/blocks/BlockHydrothermalVent.java b/src/main/java/ru/betterend/blocks/BlockHydrothermalVent.java index 8f418e90..1e379307 100644 --- a/src/main/java/ru/betterend/blocks/BlockHydrothermalVent.java +++ b/src/main/java/ru/betterend/blocks/BlockHydrothermalVent.java @@ -12,7 +12,6 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import net.minecraft.block.BubbleColumnBlock; import net.minecraft.block.FluidFillable; import net.minecraft.block.Material; import net.minecraft.block.ShapeContext; @@ -41,6 +40,7 @@ import ru.betterend.blocks.basis.BlockBaseNotFull; import ru.betterend.blocks.entities.BlockEntityHydrothermalVent; import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndParticles; +import ru.betterend.util.BlocksHelper; public class BlockHydrothermalVent extends BlockBaseNotFull implements BlockEntityProvider, FluidFillable, Waterloggable { public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; @@ -112,7 +112,11 @@ public class BlockHydrothermalVent extends BlockBaseNotFull implements BlockEnti @Override public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { - BubbleColumnBlock.update(world, pos.up(), false); + BlockPos up = pos.up(); + if (world.getBlockState(up).isOf(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate(world, up, EndBlocks.VENT_BUBBLE_COLUMN); + world.getBlockTickScheduler().schedule(up, EndBlocks.VENT_BUBBLE_COLUMN, 5); + } } @Override diff --git a/src/main/java/ru/betterend/blocks/BlockVentBubbleColumn.java b/src/main/java/ru/betterend/blocks/BlockVentBubbleColumn.java new file mode 100644 index 00000000..dd22d3c4 --- /dev/null +++ b/src/main/java/ru/betterend/blocks/BlockVentBubbleColumn.java @@ -0,0 +1,121 @@ +package ru.betterend.blocks; + +import java.util.Random; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.FluidDrainable; +import net.minecraft.block.FluidFillable; +import net.minecraft.block.Material; +import net.minecraft.block.ShapeContext; +import net.minecraft.entity.Entity; +import net.minecraft.fluid.Fluid; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import net.minecraft.world.WorldView; +import ru.betterend.blocks.basis.BlockBaseNotFull; +import ru.betterend.registry.EndBlocks; +import ru.betterend.util.BlocksHelper; + +public class BlockVentBubbleColumn extends BlockBaseNotFull implements FluidDrainable, FluidFillable { + public BlockVentBubbleColumn() { + super(FabricBlockSettings.of(Material.BUBBLE_COLUMN).nonOpaque().noCollision().dropsNothing()); + } + + @Override + public Fluid tryDrainFluid(WorldAccess world, BlockPos pos, BlockState state) { + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + return Fluids.WATER; + } + + @Override + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.INVISIBLE; + } + + @Override + public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) { + BlockState blockState = world.getBlockState(pos.down()); + return blockState.isOf(this) || blockState.isOf(EndBlocks.HYDROTHERMAL_VENT); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return VoxelShapes.empty(); + } + + @Override + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) { + if (!state.canPlaceAt(world, pos)) { + return Blocks.WATER.getDefaultState(); + } + else { + BlockPos up = pos.up(); + if (world.getBlockState(up).isOf(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate(world, up, this); + world.getBlockTickScheduler().schedule(up, this, 5); + } + } + return state; + } + + @Environment(EnvType.CLIENT) + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + double px = pos.getX() + random.nextDouble(); + double py = pos.getY() + random.nextDouble(); + double pz = pos.getZ() + random.nextDouble(); + world.addImportantParticle(ParticleTypes.BUBBLE_COLUMN_UP, px, py, pz, 0, 0.04, 0); + if (random.nextInt(200) == 0) { + world.playSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.BLOCK_BUBBLE_COLUMN_UPWARDS_AMBIENT, SoundCategory.BLOCKS, 0.2F + random.nextFloat() * 0.2F, 0.9F + random.nextFloat() * 0.15F, false); + } + } + + @Environment(EnvType.CLIENT) + public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { + BlockState blockState = world.getBlockState(pos.up()); + if (blockState.isAir()) { + entity.onBubbleColumnSurfaceCollision(false); + if (!world.isClient) { + ServerWorld serverWorld = (ServerWorld) world; + + for (int i = 0; i < 2; ++i) { + serverWorld.spawnParticles(ParticleTypes.SPLASH, (double) pos.getX() + world.random.nextDouble(), (double) (pos.getY() + 1), (double) pos.getZ() + world.random.nextDouble(), 1, 0.0D, 0.0D, 0.0D, 1.0D); + serverWorld.spawnParticles(ParticleTypes.BUBBLE, (double) pos.getX() + world.random.nextDouble(), (double) (pos.getY() + 1), (double) pos.getZ() + world.random.nextDouble(), 1, 0.0D, 0.01D, 0.0D, 0.2D); + } + } + } + else { + entity.onBubbleColumnCollision(false); + } + } + + @Override + public boolean canFillWithFluid(BlockView world, BlockPos pos, BlockState state, Fluid fluid) { + return false; + } + + @Override + public boolean tryFillWithFluid(WorldAccess world, BlockPos pos, BlockState state, FluidState fluidState) { + return false; + } + + @Override + public FluidState getFluidState(BlockState state) { + return Fluids.WATER.getStill(false); + } +} diff --git a/src/main/java/ru/betterend/config/IdConfig.java b/src/main/java/ru/betterend/config/IdConfig.java index e496dc83..1248b5f8 100644 --- a/src/main/java/ru/betterend/config/IdConfig.java +++ b/src/main/java/ru/betterend/config/IdConfig.java @@ -1,7 +1,9 @@ package ru.betterend.config; import java.util.function.BiFunction; + import org.jetbrains.annotations.Nullable; + import net.minecraft.util.Identifier; import ru.betterend.config.ConfigKeeper.Entry; import ru.betterend.config.ConfigKeeper.FloatRange; diff --git a/src/main/java/ru/betterend/mixin/common/BubbleColumnBlockMixin.java b/src/main/java/ru/betterend/mixin/common/BubbleColumnBlockMixin.java deleted file mode 100644 index 968b1ffa..00000000 --- a/src/main/java/ru/betterend/mixin/common/BubbleColumnBlockMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.BubbleColumnBlock; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockView; -import net.minecraft.world.WorldView; -import ru.betterend.registry.EndBlocks; - -@Mixin(value = BubbleColumnBlock.class, priority = 100) -public abstract class BubbleColumnBlockMixin extends Block { - public BubbleColumnBlockMixin(Settings settings) { - super(settings); - } - - @Inject(method = "canPlaceAt", at = @At("HEAD"), cancellable = true) - private void beCanPlace(BlockState state, WorldView world, BlockPos pos, CallbackInfoReturnable info) { - BlockState blockState = world.getBlockState(pos.down()); - if (blockState.isOf(EndBlocks.HYDROTHERMAL_VENT)) { - info.setReturnValue(true); - info.cancel(); - } - } - - @Inject(method = "calculateDrag", at = @At("RETURN"), cancellable = true) - private static void beCalculateDrag(BlockView world, BlockPos pos, CallbackInfoReturnable info) { - if (info.getReturnValue()) { - BlockState state = world.getBlockState(pos.down()); - if (state.isOf(EndBlocks.HYDROTHERMAL_VENT)) { - info.setReturnValue(false); - info.cancel(); - } - } - } -} diff --git a/src/main/java/ru/betterend/registry/EndBlocks.java b/src/main/java/ru/betterend/registry/EndBlocks.java index 990bc5f7..e4cdb239 100644 --- a/src/main/java/ru/betterend/registry/EndBlocks.java +++ b/src/main/java/ru/betterend/registry/EndBlocks.java @@ -63,6 +63,7 @@ import ru.betterend.blocks.BlockTerrain; import ru.betterend.blocks.BlockTerrainPlant; import ru.betterend.blocks.BlockUmbrellaMoss; import ru.betterend.blocks.BlockUmbrellaMossTall; +import ru.betterend.blocks.BlockVentBubbleColumn; import ru.betterend.blocks.EndPortalBlock; import ru.betterend.blocks.EndStoneSmelter; import ru.betterend.blocks.EnderBlock; @@ -127,6 +128,7 @@ public class EndBlocks { public static final Block PURPUR_PEDESTAL = registerBlock("purpur_pedestal", new PedestalVanilla(Blocks.PURPUR_BLOCK)); public static final Block HYDROTHERMAL_VENT = registerBlock("hydrothermal_vent", new BlockHydrothermalVent()); + public static final Block VENT_BUBBLE_COLUMN = registerBlockNI("vent_bubble_column", new BlockVentBubbleColumn()); public static final Block DENSE_SNOW = registerBlock("dense_snow", new BlockDenseSnow()); public static final Block EMERALD_ICE = registerBlock("emerald_ice", new BlockEmeraldIce()); diff --git a/src/main/java/ru/betterend/registry/EndItems.java b/src/main/java/ru/betterend/registry/EndItems.java index 9ca0569a..bb426036 100644 --- a/src/main/java/ru/betterend/registry/EndItems.java +++ b/src/main/java/ru/betterend/registry/EndItems.java @@ -5,7 +5,6 @@ import java.util.List; import com.google.common.collect.Lists; import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; - import net.minecraft.block.DispenserBlock; import net.minecraft.block.dispenser.ItemDispenserBehavior; import net.minecraft.entity.EntityType; @@ -32,7 +31,6 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPointer; import net.minecraft.util.math.Direction; import net.minecraft.util.registry.Registry; - import ru.betterend.BetterEnd; import ru.betterend.config.Configs; import ru.betterend.item.EndArmorMaterial; diff --git a/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java b/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java index 50eb4046..412c3bae 100644 --- a/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java @@ -5,7 +5,6 @@ import java.util.function.Function; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import net.minecraft.block.BubbleColumnBlock; import net.minecraft.block.HorizontalFacingBlock; import net.minecraft.block.Material; import net.minecraft.client.util.math.Vector3f; @@ -178,8 +177,7 @@ public class GeyserFeature extends DefaultFeature { mut.setY(mut.getY() + 1); state = world.getBlockState(mut); while (state.isOf(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.BUBBLE_COLUMN.getDefaultState().with(BubbleColumnBlock.DRAG, false)); - world.getBlockTickScheduler().schedule(mut, Blocks.BUBBLE_COLUMN, MHelper.randRange(8, 32, random)); + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.getDefaultState()); mut.setY(mut.getY() + 1); state = world.getBlockState(mut); } @@ -207,8 +205,7 @@ public class GeyserFeature extends DefaultFeature { mut.setY(mut.getY() + 1); state = world.getBlockState(mut); while (state.isOf(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.BUBBLE_COLUMN.getDefaultState().with(BubbleColumnBlock.DRAG, false)); - world.getBlockTickScheduler().schedule(mut, Blocks.BUBBLE_COLUMN, MHelper.randRange(8, 32, random)); + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.getDefaultState()); mut.setY(mut.getY() + 1); state = world.getBlockState(mut); } diff --git a/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java index 05bdcda2..f1070531 100644 --- a/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java @@ -7,7 +7,6 @@ import com.google.common.collect.Sets; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import net.minecraft.block.BubbleColumnBlock; import net.minecraft.block.HorizontalFacingBlock; import net.minecraft.block.Material; import net.minecraft.util.math.BlockPos; @@ -128,8 +127,8 @@ public class SulphuricCaveFeature extends DefaultFeature { mut.setY(mut.getY() + 1); state = world.getBlockState(mut); while (state.isOf(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.BUBBLE_COLUMN.getDefaultState().with(BubbleColumnBlock.DRAG, false)); - world.getBlockTickScheduler().schedule(mut, Blocks.BUBBLE_COLUMN, MHelper.randRange(8, 32, random)); + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.getDefaultState()); + world.getBlockTickScheduler().schedule(mut, EndBlocks.VENT_BUBBLE_COLUMN, MHelper.randRange(8, 32, random)); mut.setY(mut.getY() + 1); state = world.getBlockState(mut); } @@ -146,7 +145,7 @@ public class SulphuricCaveFeature extends DefaultFeature { private boolean isReplaceable(BlockState state) { return state.isIn(EndTags.GEN_TERRAIN) || state.isOf(EndBlocks.HYDROTHERMAL_VENT) - || state.isOf(Blocks.BUBBLE_COLUMN) + || state.isOf(EndBlocks.VENT_BUBBLE_COLUMN) || state.isOf(EndBlocks.SULPHUR_CRYSTAL) || state.getMaterial().isReplaceable() || state.getMaterial().equals(Material.PLANT) diff --git a/src/main/resources/assets/betterend/textures/block/charnia_green.png b/src/main/resources/assets/betterend/textures/block/charnia_green.png new file mode 100644 index 00000000..e71bafa5 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/charnia_green.png differ diff --git a/src/main/resources/assets/betterend/textures/item/charnia_green.png b/src/main/resources/assets/betterend/textures/item/charnia_green.png new file mode 100644 index 00000000..fa164095 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/charnia_green.png differ diff --git a/src/main/resources/betterend.mixins.common.json b/src/main/resources/betterend.mixins.common.json index 96268298..9308e018 100644 --- a/src/main/resources/betterend.mixins.common.json +++ b/src/main/resources/betterend.mixins.common.json @@ -11,7 +11,6 @@ "AnvilScreenHandlerMixin", "ServerPlayerEntityMixin", "ChorusPlantFeatureMixin", - "BubbleColumnBlockMixin", "ChorusFlowerBlockMixin", "LandPathNodeMakerMixin", "ChorusPlantBlockMixin",