From ea94092b2cae3d0fdc57aaae3379fa9ad455fa34 Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 18 Oct 2023 23:15:48 +0100 Subject: [PATCH] Added soggy clouds. Clouds will soak up water when it rains and slowly dry out when the weather is clear --- .../unicopia/block/UBlocks.java | 17 ++- .../unicopia/block/cloud/CloudBlock.java | 17 +-- .../unicopia/block/cloud/CloudSlabBlock.java | 6 +- .../block/cloud/PoreousCloudBlock.java | 41 +++++++ .../unicopia/block/cloud/Soakable.java | 115 ++++++++++++++++++ .../unicopia/block/cloud/SoggyCloudBlock.java | 57 +++++++++ .../block/cloud/SoggyCloudSlabBlock.java | 58 +++++++++ .../block/cloud/StormyCloudBlock.java | 36 ------ .../block/cloud/WaterloggableCloudBlock.java | 9 +- .../unicopia/client/URenderers.java | 3 +- .../unicopia/item/cloud/CloudBlockItem.java | 16 +-- .../unicopia/blockstates/soggy_cloud.json | 5 + .../blockstates/soggy_cloud_slab.json | 7 ++ .../unicopia/blockstates/unstable_cloud.json | 5 + .../resources/assets/unicopia/lang/en_us.json | 2 + .../unicopia/models/block/soggy_cloud.json | 8 ++ .../models/block/soggy_cloud_slab.json | 8 ++ .../models/block/soggy_cloud_slab_top.json | 8 ++ .../unicopia/models/item/soggy_cloud.json | 3 + .../models/item/soggy_cloud_slab.json | 3 + .../unicopia/models/item/unstable_cloud.json | 3 + .../textures/block/soggy_cloud_side.png | Bin 0 -> 7346 bytes .../textures/block/soggy_cloud_slab_side.png | Bin 0 -> 7391 bytes .../textures/block/soggy_cloud_top.png | Bin 0 -> 7270 bytes 24 files changed, 357 insertions(+), 70 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/block/cloud/PoreousCloudBlock.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/cloud/Soakable.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/cloud/SoggyCloudBlock.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/cloud/SoggyCloudSlabBlock.java delete mode 100644 src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java create mode 100644 src/main/resources/assets/unicopia/blockstates/soggy_cloud.json create mode 100644 src/main/resources/assets/unicopia/blockstates/soggy_cloud_slab.json create mode 100644 src/main/resources/assets/unicopia/blockstates/unstable_cloud.json create mode 100644 src/main/resources/assets/unicopia/models/block/soggy_cloud.json create mode 100644 src/main/resources/assets/unicopia/models/block/soggy_cloud_slab.json create mode 100644 src/main/resources/assets/unicopia/models/block/soggy_cloud_slab_top.json create mode 100644 src/main/resources/assets/unicopia/models/item/soggy_cloud.json create mode 100644 src/main/resources/assets/unicopia/models/item/soggy_cloud_slab.json create mode 100644 src/main/resources/assets/unicopia/models/item/unstable_cloud.json create mode 100644 src/main/resources/assets/unicopia/textures/block/soggy_cloud_side.png create mode 100644 src/main/resources/assets/unicopia/textures/block/soggy_cloud_slab_side.png create mode 100644 src/main/resources/assets/unicopia/textures/block/soggy_cloud_top.png diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java index 59dc6383..4beeaa01 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java @@ -5,9 +5,12 @@ import java.util.Collections; 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.block.cloud.PoreousCloudBlock; +import com.minelittlepony.unicopia.block.cloud.CloudBlock; +import com.minelittlepony.unicopia.block.cloud.SoggyCloudBlock; +import com.minelittlepony.unicopia.block.cloud.SoggyCloudSlabBlock; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.group.ItemGroupRegistry; import com.minelittlepony.unicopia.server.world.UTreeGen; @@ -128,11 +131,13 @@ 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), 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))); + Block CLOUD = register("cloud", new PoreousCloudBlock(Settings.create().mapColor(MapColor.OFF_WHITE).hardness(0.3F).resistance(0).sounds(BlockSoundGroup.WOOL), true, () -> UBlocks.SOGGY_CLOUD)); + Block CLOUD_SLAB = register("cloud_slab", new CloudSlabBlock(Settings.copy(CLOUD), true, () -> UBlocks.SOGGY_CLOUD_SLAB)); + SoggyCloudBlock SOGGY_CLOUD = register("soggy_cloud", new SoggyCloudBlock(Settings.copy(CLOUD), () -> UBlocks.CLOUD)); + SoggyCloudSlabBlock SOGGY_CLOUD_SLAB = register("soggy_cloud_slab", new SoggyCloudSlabBlock(Settings.copy(CLOUD), () -> UBlocks.CLOUD_SLAB)); + Block DENSE_CLOUD = register("dense_cloud", new CloudBlock(Settings.create().mapColor(MapColor.GRAY).hardness(0.5F).resistance(0).sounds(BlockSoundGroup.WOOL), false)); + Block DENSE_CLOUD_SLAB = register("dense_cloud_slab", new CloudSlabBlock(Settings.copy(DENSE_CLOUD), false, null)); + Block CLOUD_PILLAR = register("cloud_pillar", new CloudPillarBlock(Settings.create().mapColor(MapColor.GRAY).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)); SegmentedCropBlock OATS_STEM = register("oats_stem", OATS.createNext(5)); 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 ba75c93c..c11fc3d3 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java @@ -4,14 +4,11 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.EquineContext; import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.entity.player.Pony; -import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; import net.minecraft.block.TransparentBlock; -import net.minecraft.client.render.RenderLayer; import net.minecraft.entity.Entity; import net.minecraft.entity.ai.pathing.NavigationType; import net.minecraft.entity.player.PlayerEntity; @@ -29,7 +26,7 @@ import net.minecraft.world.World; public class CloudBlock extends TransparentBlock { - private final boolean meltable; + protected final boolean meltable; public CloudBlock(Settings settings, boolean meltable) { super((meltable ? settings.ticksRandomly() : settings).nonOpaque()); @@ -43,10 +40,6 @@ public class CloudBlock extends TransparentBlock { if (bounce) { entity.addVelocity(0, 0.2F, 0); } - BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getTranslucent(), - UBlocks.MYSTERIOUS_EGG, UBlocks.SLIME_PUSTULE, - UBlocks.CLOUD, UBlocks.DENSE_CLOUD, UBlocks.CLOUD_PILLAR - ); } @Override @@ -150,9 +143,11 @@ public class CloudBlock extends TransparentBlock { @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); + if (meltable) { + if (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/CloudSlabBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudSlabBlock.java index 07b0b7c4..e4b721ac 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudSlabBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudSlabBlock.java @@ -1,5 +1,7 @@ package com.minelittlepony.unicopia.block.cloud; +import java.util.function.Supplier; + import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.EquineContext; @@ -24,8 +26,8 @@ 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); + public CloudSlabBlock(Settings settings, boolean meltable, @Nullable Supplier soggyBlock) { + super(settings, meltable, soggyBlock); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/PoreousCloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/PoreousCloudBlock.java new file mode 100644 index 00000000..591ea39e --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/PoreousCloudBlock.java @@ -0,0 +1,41 @@ +package com.minelittlepony.unicopia.block.cloud; + +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.block.BlockState; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.random.Random; + +public class PoreousCloudBlock extends CloudBlock implements Soakable { + @Nullable + private final Supplier soggyBlock; + + public PoreousCloudBlock(Settings settings, boolean meltable, @Nullable Supplier soggyBlock) { + super(settings.nonOpaque(), meltable); + this.soggyBlock = soggyBlock; + } + + @Nullable + @Override + public BlockState getSoggyState(int moisture) { + return soggyBlock == null ? null : soggyBlock.get().getSoggyState(moisture); + } + + @Override + public int getMoisture(BlockState state) { + return 0; + } + + @Override + public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + if (soggyBlock != null && world.hasRain(pos) && world.isAir(pos.up())) { + world.setBlockState(pos, Soakable.copyProperties(state, soggyBlock.get().getSoggyState(random.nextBetween(1, 5)))); + return; + } + + super.randomTick(state, world, pos, random); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/Soakable.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/Soakable.java new file mode 100644 index 00000000..4623e92a --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/Soakable.java @@ -0,0 +1,115 @@ +package com.minelittlepony.unicopia.block.cloud; + +import java.util.Arrays; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.USounds; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.state.property.IntProperty; +import net.minecraft.state.property.Property; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Util; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.World; +import net.minecraft.world.event.GameEvent; + +public interface Soakable { + IntProperty MOISTURE = IntProperty.of("moisture", 1, 7); + Direction[] DIRECTIONS = Arrays.stream(Direction.values()).filter(d -> d != Direction.UP).toArray(Direction[]::new); + + BlockState getSoggyState(int moisture); + + int getMoisture(BlockState state); + + static void addMoistureParticles(BlockState state, World world, BlockPos pos, Random random) { + if (random.nextInt(5) == 0) { + world.addParticle(ParticleTypes.DRIPPING_WATER, + pos.getX() + random.nextFloat(), + pos.getY(), + pos.getZ() + random.nextFloat(), + 0, 0, 0 + ); + } + } + + static ActionResult tryCollectMoisture(Block dryBlock, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + ItemStack stack = player.getStackInHand(hand); + if (stack.getItem() == Items.GLASS_BOTTLE) { + if (!player.isCreative()) { + stack.split(1); + } + if (stack.isEmpty()) { + player.setStackInHand(hand, Items.POTION.getDefaultStack()); + } else { + player.giveItemStack(Items.POTION.getDefaultStack()); + } + world.playSound(player, player.getX(), player.getY(), player.getZ(), USounds.Vanilla.ITEM_BOTTLE_FILL, SoundCategory.NEUTRAL, 1, 1); + world.emitGameEvent(player, GameEvent.FLUID_PICKUP, pos); + updateMoisture(dryBlock, state, world, pos, state.get(MOISTURE) - 1); + + return ActionResult.SUCCESS; + } + + return ActionResult.PASS; + } + + static void tickMoisture(Block dryBlock, BlockState state, ServerWorld world, BlockPos pos, Random random) { + int moisture = state.get(MOISTURE); + + if (world.hasRain(pos) && world.isAir(pos.up())) { + if (moisture < 7) { + world.setBlockState(pos, state.with(MOISTURE, moisture + 1)); + } + } else { + if (moisture > 1) { + BlockPos neighborPos = pos.offset(Util.getRandom(Soakable.DIRECTIONS, random)); + BlockState neighborState = world.getBlockState(neighborPos); + + if (neighborState.getBlock() instanceof Soakable soakable && soakable.getMoisture(neighborState) < moisture) { + int half = Math.max(1, moisture / 2); + @Nullable + BlockState newNeighborState = soakable.getSoggyState(half); + if (newNeighborState != null) { + updateMoisture(dryBlock, state, world, pos, moisture - half); + world.setBlockState(neighborPos, soakable.getSoggyState(half)); + world.emitGameEvent(null, GameEvent.BLOCK_CHANGE, neighborPos); + return; + } + } + } + updateMoisture(dryBlock, state, world, pos, moisture - 1); + } + } + + private static void updateMoisture(Block dryBlock, BlockState state, World world, BlockPos pos, int newMoisture) { + if (newMoisture <= 0) { + world.setBlockState(pos, copyProperties(state, dryBlock.getDefaultState())); + } else { + world.setBlockState(pos, state.with(MOISTURE, newMoisture)); + } + world.playSound(null, pos, SoundEvents.ENTITY_SALMON_FLOP, SoundCategory.BLOCKS, 1, (float)world.random.nextTriangular(0.5, 0.3F)); + } + + + @SuppressWarnings({ "rawtypes", "unchecked" }) + static BlockState copyProperties(BlockState from, BlockState to) { + for (Property property : from.getProperties()) { + to = to.withIfExists(property, from.get(property)); + } + return to; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/SoggyCloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/SoggyCloudBlock.java new file mode 100644 index 00000000..d7d5ff69 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/SoggyCloudBlock.java @@ -0,0 +1,57 @@ +package com.minelittlepony.unicopia.block.cloud; + +import java.util.function.Supplier; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.state.StateManager; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.World; + +public class SoggyCloudBlock extends CloudBlock implements Soakable { + + private final Supplier dryBlock; + + public SoggyCloudBlock(Settings settings, Supplier dryBlock) { + super(settings.ticksRandomly(), false); + setDefaultState(getDefaultState().with(MOISTURE, 7)); + this.dryBlock = dryBlock; + } + + @Override + public BlockState getSoggyState(int moisture) { + return getDefaultState().with(MOISTURE, moisture); + } + + @Override + public int getMoisture(BlockState state) { + return state.get(MOISTURE); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(MOISTURE); + } + + @Override + @Deprecated + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + return Soakable.tryCollectMoisture(dryBlock.get(), state, world, pos, player, hand, hit); + } + + @Override + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + Soakable.addMoistureParticles(state, world, pos, random); + } + + @Override + public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + Soakable.tickMoisture(dryBlock.get(), state, world, pos, random); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/SoggyCloudSlabBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/SoggyCloudSlabBlock.java new file mode 100644 index 00000000..e07fb744 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/SoggyCloudSlabBlock.java @@ -0,0 +1,58 @@ +package com.minelittlepony.unicopia.block.cloud; + +import java.util.function.Supplier; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.state.StateManager; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.World; + +public class SoggyCloudSlabBlock extends CloudSlabBlock { + + private final Supplier dryBlock; + + public SoggyCloudSlabBlock(Settings settings, Supplier dryBlock) { + super(settings.ticksRandomly(), false, null); + setDefaultState(getDefaultState().with(MOISTURE, 7)); + this.dryBlock = dryBlock; + } + + @Override + public BlockState getSoggyState(int moisture) { + return getDefaultState().with(MOISTURE, moisture); + } + + @Override + public int getMoisture(BlockState state) { + return state.get(MOISTURE); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder); + builder.add(MOISTURE); + } + + @Override + @Deprecated + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + return Soakable.tryCollectMoisture(dryBlock.get(), state, world, pos, player, hand, hit); + } + + @Override + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + Soakable.addMoistureParticles(state, world, pos, random); + } + + @Override + public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + Soakable.tickMoisture(dryBlock.get(), state, world, pos, random); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java deleted file mode 100644 index b383be2f..00000000 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.minelittlepony.unicopia.block.cloud; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.entity.Entity; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.IntProperty; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -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, boolean meltable) { - super(settings, meltable); - setDefaultState(getDefaultState().with(CHARGE, 0)); - } - - @Override - protected void appendProperties(StateManager.Builder builder) { - builder.add(CHARGE); - } - - @Override - public void onLandedUpon(World world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { - super.onLandedUpon(world, state, pos, entity, fallDistance); - if (state.get(CHARGE) < MAX_CHARGE) { - if (world.random.nextInt(5) == 0) { - world.setBlockState(pos, state.cycle(CHARGE)); - } - } else { - - } - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/WaterloggableCloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/WaterloggableCloudBlock.java index 07b95fd4..38efed62 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/WaterloggableCloudBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/WaterloggableCloudBlock.java @@ -1,5 +1,7 @@ package com.minelittlepony.unicopia.block.cloud; +import java.util.function.Supplier; + import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.EquineContext; @@ -20,11 +22,12 @@ import net.minecraft.util.math.Direction; import net.minecraft.world.BlockView; import net.minecraft.world.WorldAccess; -public class WaterloggableCloudBlock extends CloudBlock implements Waterloggable { +public class WaterloggableCloudBlock extends PoreousCloudBlock implements Waterloggable { public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; - public WaterloggableCloudBlock(Settings settings, boolean meltable) { - super(settings, meltable); + public WaterloggableCloudBlock(Settings settings, boolean meltable, @Nullable Supplier soggyBlock) { + super(settings, meltable, soggyBlock); + setDefaultState(getDefaultState().with(WATERLOGGED, false)); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index 8d142261..1954b271 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -175,7 +175,8 @@ public interface URenderers { BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getTranslucent(), UBlocks.MYSTERIOUS_EGG, UBlocks.SLIME_PUSTULE, UBlocks.CLOUD, UBlocks.DENSE_CLOUD, UBlocks.CLOUD_PILLAR, - UBlocks.CLOUD_SLAB, UBlocks.DENSE_CLOUD_SLAB + UBlocks.CLOUD_SLAB, UBlocks.DENSE_CLOUD_SLAB, + UBlocks.SOGGY_CLOUD, UBlocks.SOGGY_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/cloud/CloudBlockItem.java b/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java index 3a59c0fc..4652d8e9 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java @@ -1,7 +1,5 @@ package com.minelittlepony.unicopia.item.cloud; -import com.minelittlepony.unicopia.block.cloud.CloudBlock; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -16,6 +14,7 @@ import net.minecraft.util.TypedActionResult; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; public class CloudBlockItem @@ -26,22 +25,17 @@ extends BlockItem { @Override public ActionResult useOnBlock(ItemUsageContext context) { - BlockState state = context.getWorld().getBlockState(context.getBlockPos()); - - if (state.getBlock() instanceof CloudBlock) { - return super.useOnBlock(context); - } - - return ActionResult.PASS; + return super.useOnBlock(context); } @Override public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + Vec3d targetPos = user.getEyePos().add(user.getRotationVec(1).multiply(1, 1.5, 1).normalize().multiply(2)); ItemPlacementContext context = new ItemPlacementContext(user, hand, user.getStackInHand(hand), new BlockHitResult( - user.getEyePos(), + targetPos, Direction.UP, - BlockPos.ofFloored(user.getEyePos()), + BlockPos.ofFloored(targetPos), true )); diff --git a/src/main/resources/assets/unicopia/blockstates/soggy_cloud.json b/src/main/resources/assets/unicopia/blockstates/soggy_cloud.json new file mode 100644 index 00000000..2a3c83f4 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/soggy_cloud.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "unicopia:block/soggy_cloud" } + } +} diff --git a/src/main/resources/assets/unicopia/blockstates/soggy_cloud_slab.json b/src/main/resources/assets/unicopia/blockstates/soggy_cloud_slab.json new file mode 100644 index 00000000..1df56d0e --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/soggy_cloud_slab.json @@ -0,0 +1,7 @@ +{ + "variants": { + "type=double": { "model": "unicopia:block/soggy_cloud" }, + "type=bottom": { "model": "unicopia:block/soggy_cloud_slab" }, + "type=top": { "model": "unicopia:block/soggy_cloud_slab_top" } + } +} diff --git a/src/main/resources/assets/unicopia/blockstates/unstable_cloud.json b/src/main/resources/assets/unicopia/blockstates/unstable_cloud.json new file mode 100644 index 00000000..3afda0a3 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/unstable_cloud.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "unicopia:block/cloud" } + } +} diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 88f68bc7..d3df60ba 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -219,6 +219,8 @@ "block.unicopia.cloud": "Cloud", "block.unicopia.cloud_slab": "Cloud Slab", + "block.unicopia.soggy_cloud": "Soggy Cloud", + "block.unicopia.soggy_cloud_slab": "Soggy Cloud Slab", "block.unicopia.cloud_pillar": "Cloud Pillar", "block.unicopia.dense_cloud": "Dense Cloud", "block.unicopia.dense_cloud_slab": "Dense Cloud Slab", diff --git a/src/main/resources/assets/unicopia/models/block/soggy_cloud.json b/src/main/resources/assets/unicopia/models/block/soggy_cloud.json new file mode 100644 index 00000000..669150b0 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/soggy_cloud.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "bottom": "unicopia:block/cloud", + "top": "unicopia:block/soggy_cloud_top", + "side": "unicopia:block/soggy_cloud_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/soggy_cloud_slab.json b/src/main/resources/assets/unicopia/models/block/soggy_cloud_slab.json new file mode 100644 index 00000000..e3b7191d --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/soggy_cloud_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab", + "textures": { + "bottom": "unicopia:block/cloud", + "side": "unicopia:block/soggy_cloud_slab_side", + "top": "unicopia:block/soggy_cloud_top" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/soggy_cloud_slab_top.json b/src/main/resources/assets/unicopia/models/block/soggy_cloud_slab_top.json new file mode 100644 index 00000000..d7fa2ddc --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/soggy_cloud_slab_top.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab_top", + "textures": { + "bottom": "unicopia:block/cloud", + "side": "unicopia:block/soggy_cloud_slab_side", + "top": "unicopia:block/soggy_cloud_top" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/item/soggy_cloud.json b/src/main/resources/assets/unicopia/models/item/soggy_cloud.json new file mode 100644 index 00000000..7babfca8 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/soggy_cloud.json @@ -0,0 +1,3 @@ +{ + "parent": "unicopia:block/cloud" +} diff --git a/src/main/resources/assets/unicopia/models/item/soggy_cloud_slab.json b/src/main/resources/assets/unicopia/models/item/soggy_cloud_slab.json new file mode 100644 index 00000000..7f1b60e7 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/soggy_cloud_slab.json @@ -0,0 +1,3 @@ +{ + "parent": "unicopia:block/cloud_slab" +} diff --git a/src/main/resources/assets/unicopia/models/item/unstable_cloud.json b/src/main/resources/assets/unicopia/models/item/unstable_cloud.json new file mode 100644 index 00000000..7babfca8 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/unstable_cloud.json @@ -0,0 +1,3 @@ +{ + "parent": "unicopia:block/cloud" +} diff --git a/src/main/resources/assets/unicopia/textures/block/soggy_cloud_side.png b/src/main/resources/assets/unicopia/textures/block/soggy_cloud_side.png new file mode 100644 index 0000000000000000000000000000000000000000..6557ad1d93514f3f17756d8b7e9a073bb6e4477f GIT binary patch literal 7346 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/block/soggy_cloud_slab_side.png b/src/main/resources/assets/unicopia/textures/block/soggy_cloud_slab_side.png new file mode 100644 index 0000000000000000000000000000000000000000..c7880d4ccbd4ed296320496f6bec119af14801b5 GIT binary patch literal 7391 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