diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java index b77cefd4..59dc6383 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java @@ -7,6 +7,7 @@ import java.util.List; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.block.cloud.CloudBlock; import com.minelittlepony.unicopia.block.cloud.CloudPillarBlock; +import com.minelittlepony.unicopia.block.cloud.CloudSlabBlock; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.group.ItemGroupRegistry; import com.minelittlepony.unicopia.server.world.UTreeGen; @@ -127,8 +128,10 @@ public interface UBlocks { Block MYSTERIOUS_EGG = register("mysterious_egg", new PileBlock(Settings.copy(Blocks.SLIME_BLOCK), PileBlock.MYSTERIOUS_EGG_SHAPES), ItemGroups.NATURAL); Block SLIME_PUSTULE = register("slime_pustule", new SlimePustuleBlock(Settings.copy(Blocks.SLIME_BLOCK)), ItemGroups.NATURAL); - Block CLOUD = register("cloud", new CloudBlock(Settings.create().mapColor(MapColor.OFF_WHITE).replaceable().hardness(0.3F).resistance(0).sounds(BlockSoundGroup.WOOL))); - Block DENSE_CLOUD = register("dense_cloud", new CloudBlock(Settings.create().mapColor(MapColor.GRAY).replaceable().hardness(0.5F).resistance(0).sounds(BlockSoundGroup.WOOL))); + Block CLOUD = register("cloud", new CloudBlock(Settings.create().mapColor(MapColor.OFF_WHITE).replaceable().hardness(0.3F).resistance(0).sounds(BlockSoundGroup.WOOL), true)); + Block CLOUD_SLAB = register("cloud_slab", new CloudSlabBlock(Settings.copy(CLOUD), true)); + Block DENSE_CLOUD = register("dense_cloud", new CloudBlock(Settings.create().mapColor(MapColor.GRAY).replaceable().hardness(0.5F).resistance(0).sounds(BlockSoundGroup.WOOL), false)); + Block DENSE_CLOUD_SLAB = register("dense_cloud_slab", new CloudSlabBlock(Settings.copy(DENSE_CLOUD), false)); Block CLOUD_PILLAR = register("cloud_pillar", new CloudPillarBlock(Settings.create().mapColor(MapColor.GRAY).replaceable().hardness(0.5F).resistance(0).sounds(BlockSoundGroup.WOOL))); SegmentedCropBlock OATS = register("oats", SegmentedCropBlock.create(11, 5, AbstractBlock.Settings.copy(Blocks.WHEAT), () -> UItems.OAT_SEEDS, null, null)); diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java index 0325568d..ba75c93c 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java @@ -16,17 +16,24 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.ai.pathing.NavigationType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemPlacementContext; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.EmptyBlockView; +import net.minecraft.world.LightType; import net.minecraft.world.World; public class CloudBlock extends TransparentBlock { - public CloudBlock(Settings settings) { - super(settings.nonOpaque()); + + private final boolean meltable; + + public CloudBlock(Settings settings, boolean meltable) { + super((meltable ? settings.ticksRandomly() : settings).nonOpaque()); + this.meltable = meltable; } @Override @@ -101,7 +108,7 @@ public class CloudBlock extends TransparentBlock { @Deprecated @Override - public boolean canReplace(BlockState state, ItemPlacementContext context) { + public final boolean canReplace(BlockState state, ItemPlacementContext context) { EquineContext equineContext = EquineContext.of(context); if (canInteract(state, context.getWorld(), context.getBlockPos(), equineContext)) { return canReplace(state, context, equineContext); @@ -112,9 +119,6 @@ public class CloudBlock extends TransparentBlock { @Deprecated @Override public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { - if (stateFrom.isOf(this)) { - return true; - } VoxelShape shape = state.getCullingShape(EmptyBlockView.INSTANCE, BlockPos.ORIGIN); VoxelShape shapeFrom = stateFrom.getCullingShape(EmptyBlockView.INSTANCE, BlockPos.ORIGIN); return !shape.isEmpty() && !shapeFrom.isEmpty() && VoxelShapes.isSideCovered(shape, shapeFrom, direction); @@ -143,4 +147,12 @@ public class CloudBlock extends TransparentBlock { protected BlockState getPlacementState(ItemPlacementContext placementContext, EquineContext equineContext) { return super.getPlacementState(placementContext); } + + @Override + public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + if (meltable && world.getLightLevel(LightType.BLOCK, pos) > 11) { + dropStacks(state, world, pos); + world.removeBlock(pos, false); + } + } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java index 8e85985d..5655b652 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java @@ -41,7 +41,7 @@ public class CloudPillarBlock extends CloudBlock { // [1,0] [1,1] public CloudPillarBlock(Settings settings) { - super(settings); + super(settings, false); setDefaultState(getDefaultState().with(NORTH, true).with(SOUTH, true)); } diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudSlabBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudSlabBlock.java new file mode 100644 index 00000000..07b0b7c4 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudSlabBlock.java @@ -0,0 +1,95 @@ +package com.minelittlepony.unicopia.block.cloud; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.EquineContext; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.SlabBlock; +import net.minecraft.block.enums.SlabType; +import net.minecraft.fluid.Fluid; +import net.minecraft.fluid.FluidState; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.state.StateManager; +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.WorldAccess; + +public class CloudSlabBlock extends WaterloggableCloudBlock { + private static final VoxelShape BOTTOM_SHAPE = Block.createCuboidShape(0.0, 0.0, 0.0, 16.0, 8.0, 16.0); + private static final VoxelShape TOP_SHAPE = Block.createCuboidShape(0.0, 8.0, 0.0, 16.0, 16.0, 16.0); + + public CloudSlabBlock(Settings settings, boolean meltable) { + super(settings, meltable); + } + + @Override + public boolean hasSidedTransparency(BlockState state) { + return state.get(SlabBlock.TYPE) != SlabType.DOUBLE; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder); + builder.add(SlabBlock.TYPE); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, EquineContext equineContext) { + return switch (state.get(SlabBlock.TYPE)) { + case DOUBLE -> VoxelShapes.fullCube(); + case TOP -> TOP_SHAPE; + case BOTTOM -> BOTTOM_SHAPE; + }; + } + + @Override + @Nullable + public BlockState getPlacementState(ItemPlacementContext ctx, EquineContext equineContext) { + BlockPos blockPos = ctx.getBlockPos(); + BlockState blockState = ctx.getWorld().getBlockState(blockPos); + if (blockState.isOf(this)) { + return blockState.with(SlabBlock.TYPE, SlabType.DOUBLE).with(WATERLOGGED, false); + } + BlockState state = super.getPlacementState(ctx, equineContext).with(SlabBlock.TYPE, SlabType.BOTTOM); + Direction direction = ctx.getSide(); + if (direction == Direction.DOWN || direction != Direction.UP && ctx.getHitPos().y - blockPos.getY() > 0.5) { + return state.with(SlabBlock.TYPE, SlabType.TOP); + } + return state; + } + + @Override + public boolean canReplace(BlockState state, ItemPlacementContext context, EquineContext equineContext) { + SlabType slabType = state.get(SlabBlock.TYPE); + if (slabType == SlabType.DOUBLE || !context.getStack().isOf(asItem())) { + return false; + } + + if (!context.canReplaceExisting()) { + return true; + } + + boolean hitTop = context.getHitPos().y - context.getBlockPos().getY() > 0.5; + Direction side = context.getSide(); + if (slabType == SlabType.BOTTOM) { + return side == Direction.UP || hitTop && side.getAxis().isHorizontal(); + } + return side == Direction.DOWN || !hitTop && side.getAxis().isHorizontal(); + } + + @Override + public boolean tryFillWithFluid(WorldAccess world, BlockPos pos, BlockState state, FluidState fluidState) { + return state.get(SlabBlock.TYPE) != SlabType.DOUBLE && super.tryFillWithFluid(world, pos, state, fluidState); + } + + @Override + public boolean canFillWithFluid(BlockView world, BlockPos pos, BlockState state, Fluid fluid) { + return state.get(SlabBlock.TYPE) != SlabType.DOUBLE && super.canFillWithFluid(world, pos, state, fluid); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java index 232743c3..b383be2f 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java @@ -12,8 +12,8 @@ public class StormyCloudBlock extends CloudBlock { private static final int MAX_CHARGE = 6; private static final IntProperty CHARGE = IntProperty.of("charge", 0, MAX_CHARGE); - public StormyCloudBlock(Settings settings) { - super(settings); + public StormyCloudBlock(Settings settings, boolean meltable) { + super(settings, meltable); setDefaultState(getDefaultState().with(CHARGE, 0)); } diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/WaterloggableCloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/WaterloggableCloudBlock.java new file mode 100644 index 00000000..07b95fd4 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/WaterloggableCloudBlock.java @@ -0,0 +1,63 @@ +package com.minelittlepony.unicopia.block.cloud; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.EquineContext; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Waterloggable; +import net.minecraft.entity.ai.pathing.NavigationType; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.registry.tag.FluidTags; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.Properties; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; +import net.minecraft.world.WorldAccess; + +public class WaterloggableCloudBlock extends CloudBlock implements Waterloggable { + public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; + + public WaterloggableCloudBlock(Settings settings, boolean meltable) { + super(settings, meltable); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(WATERLOGGED); + } + + @Override + @Nullable + public BlockState getPlacementState(ItemPlacementContext ctx, EquineContext equineContext) { + return getDefaultState().with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER); + } + + @Deprecated + @Override + public FluidState getFluidState(BlockState state) { + if (state.get(WATERLOGGED).booleanValue()) { + return Fluids.WATER.getStill(false); + } + return super.getFluidState(state); + } + + @Deprecated + @Override + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { + if (state.get(WATERLOGGED).booleanValue()) { + world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + } + return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos); + } + + @Override + public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { + return (type == NavigationType.WATER) == world.getFluidState(pos).isIn(FluidTags.WATER); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index c747b2aa..8d142261 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -174,7 +174,8 @@ public interface URenderers { BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), UBlocks.TRANSLUCENT_BLOCKS.stream().toArray(Block[]::new)); BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getTranslucent(), UBlocks.MYSTERIOUS_EGG, UBlocks.SLIME_PUSTULE, - UBlocks.CLOUD, UBlocks.DENSE_CLOUD, UBlocks.CLOUD_PILLAR + UBlocks.CLOUD, UBlocks.DENSE_CLOUD, UBlocks.CLOUD_PILLAR, + UBlocks.CLOUD_SLAB, UBlocks.DENSE_CLOUD_SLAB ); // for lava boats BlockRenderLayerMap.INSTANCE.putFluids(RenderLayer.getTranslucent(), Fluids.LAVA, Fluids.FLOWING_LAVA); diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index dd29fa11..954c20fd 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -145,7 +145,9 @@ public interface UItems { Item GIANT_BALLOON = register("giant_balloon", new HotAirBalloonItem(new Item.Settings().maxCount(1)), ItemGroups.TOOLS); Item CLOUD = register("cloud", new CloudBlockItem(UBlocks.CLOUD, new Item.Settings()), ItemGroups.NATURAL); + Item CLOUD_SLAB = register("cloud_slab", new CloudBlockItem(UBlocks.CLOUD_SLAB, new Item.Settings()), ItemGroups.NATURAL); Item DENSE_CLOUD = register("dense_cloud", new CloudBlockItem(UBlocks.DENSE_CLOUD, new Item.Settings()), ItemGroups.NATURAL); + Item DENSE_CLOUD_SLAB = register("dense_cloud_slab", new CloudBlockItem(UBlocks.DENSE_CLOUD_SLAB, new Item.Settings()), ItemGroups.NATURAL); Item CLOUD_PILLAR = register("cloud_pillar", new CloudBlockItem(UBlocks.CLOUD_PILLAR, new Item.Settings()), ItemGroups.NATURAL); AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new PegasusAmuletItem(new FabricItemSettings() diff --git a/src/main/resources/assets/unicopia/blockstates/cloud_slab.json b/src/main/resources/assets/unicopia/blockstates/cloud_slab.json new file mode 100644 index 00000000..a6d27918 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/cloud_slab.json @@ -0,0 +1,7 @@ +{ + "variants": { + "type=double": { "model": "unicopia:block/cloud" }, + "type=bottom": { "model": "unicopia:block/cloud_slab" }, + "type=top": { "model": "unicopia:block/cloud_slab_top" } + } +} diff --git a/src/main/resources/assets/unicopia/blockstates/dense_cloud_slab.json b/src/main/resources/assets/unicopia/blockstates/dense_cloud_slab.json new file mode 100644 index 00000000..a6d27918 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/dense_cloud_slab.json @@ -0,0 +1,7 @@ +{ + "variants": { + "type=double": { "model": "unicopia:block/cloud" }, + "type=bottom": { "model": "unicopia:block/cloud_slab" }, + "type=top": { "model": "unicopia:block/cloud_slab_top" } + } +} diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 1e847754..88f68bc7 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -218,8 +218,10 @@ "block.unicopia.chiselled_chitin_stairs": "Chiselled Chitin Stairs", "block.unicopia.cloud": "Cloud", + "block.unicopia.cloud_slab": "Cloud Slab", "block.unicopia.cloud_pillar": "Cloud Pillar", "block.unicopia.dense_cloud": "Dense Cloud", + "block.unicopia.dense_cloud_slab": "Dense Cloud Slab", "block.unicopia.oats": "Oats", "block.unicopia.oats_stem": "Oats", diff --git a/src/main/resources/assets/unicopia/models/block/cloud_slab.json b/src/main/resources/assets/unicopia/models/block/cloud_slab.json new file mode 100644 index 00000000..5d896354 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/cloud_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab", + "textures": { + "bottom": "unicopia:block/cloud", + "side": "unicopia:block/cloud", + "top": "unicopia:block/cloud" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/cloud_slab_top.json b/src/main/resources/assets/unicopia/models/block/cloud_slab_top.json new file mode 100644 index 00000000..3866a2c3 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/cloud_slab_top.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab_top", + "textures": { + "bottom": "unicopia:block/cloud", + "side": "unicopia:block/cloud", + "top": "unicopia:block/cloud" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/dense_cloud_slab.json b/src/main/resources/assets/unicopia/models/block/dense_cloud_slab.json new file mode 100644 index 00000000..05ae2d19 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/dense_cloud_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab", + "textures": { + "bottom": "unicopia:block/dense_cloud", + "side": "unicopia:block/dense_cloud", + "top": "unicopia:block/dense_cloud" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/dense_cloud_slab_top.json b/src/main/resources/assets/unicopia/models/block/dense_cloud_slab_top.json new file mode 100644 index 00000000..c756b02a --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/dense_cloud_slab_top.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab_top", + "textures": { + "bottom": "unicopia:block/dense_cloud", + "side": "unicopia:block/dense_cloud", + "top": "unicopia:block/dense_cloud" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/item/cloud_slab.json b/src/main/resources/assets/unicopia/models/item/cloud_slab.json new file mode 100644 index 00000000..7f1b60e7 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/cloud_slab.json @@ -0,0 +1,3 @@ +{ + "parent": "unicopia:block/cloud_slab" +} diff --git a/src/main/resources/assets/unicopia/models/item/dense_cloud_slab.json b/src/main/resources/assets/unicopia/models/item/dense_cloud_slab.json new file mode 100644 index 00000000..fcc96c78 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/dense_cloud_slab.json @@ -0,0 +1,3 @@ +{ + "parent": "unicopia:block/dense_cloud_slab" +}