diff --git a/src/main/java/com/minelittlepony/unicopia/block/GlowingGemBlock.java b/src/main/java/com/minelittlepony/unicopia/block/GlowingGemBlock.java index 41c1d180..5f3bb43d 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/GlowingGemBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/GlowingGemBlock.java @@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.block; import java.util.Random; -import com.minelittlepony.unicopia.gas.CloudType; +import com.minelittlepony.unicopia.gas.GasState; import com.minelittlepony.unicopia.gas.Gas; import com.minelittlepony.unicopia.particles.MagicParticleEffect; @@ -168,8 +168,8 @@ public class GlowingGemBlock extends TorchBlock implements Gas { } @Override - public CloudType getGasType(BlockState blockState) { - return CloudType.ENCHANTED; + public GasState getGasState(BlockState blockState) { + return GasState.ENCHANTED; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java index 1434772e..52f69d60 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java @@ -8,7 +8,7 @@ import com.minelittlepony.unicopia.gas.CloudFarmlandBlock; import com.minelittlepony.unicopia.gas.CloudFenceBlock; import com.minelittlepony.unicopia.gas.CloudSlabBlock; import com.minelittlepony.unicopia.gas.CloudStairsBlock; -import com.minelittlepony.unicopia.gas.CloudType; +import com.minelittlepony.unicopia.gas.GasState; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.structure.CustomSaplingGenerator; @@ -24,15 +24,15 @@ import net.minecraft.util.registry.Registry; public interface UBlocks { CloudFarmlandBlock CLOUD_FARMLAND = register(new CloudFarmlandBlock(FabricBlockSettings.of(UMaterials.CLOUD).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.WOOL).build()), "cloud_farmland"); - CloudBlock CLOUD_BLOCK = register(new CloudBlock(CloudType.NORMAL), "cloud_block"); - CloudBlock ENCHANTED_CLOUD_BLOCK = register(new CloudBlock(CloudType.ENCHANTED), "enchanted_cloud_block"); - CloudBlock DENSE_CLOUD_BLOCK = register(new CloudBlock(CloudType.DENSE), "dense_cloud_block"); + CloudBlock CLOUD_BLOCK = register(new CloudBlock(GasState.NORMAL), "cloud_block"); + CloudBlock ENCHANTED_CLOUD_BLOCK = register(new CloudBlock(GasState.ENCHANTED), "enchanted_cloud_block"); + CloudBlock DENSE_CLOUD_BLOCK = register(new CloudBlock(GasState.DENSE), "dense_cloud_block"); - CloudStairsBlock CLOUD_STAIRS = register(new CloudStairsBlock<>(CLOUD_BLOCK.getDefaultState(), CloudType.NORMAL.configure().build()), "cloud_stairs"); + CloudStairsBlock CLOUD_STAIRS = register(new CloudStairsBlock<>(CLOUD_BLOCK.getDefaultState(), GasState.NORMAL.configure().build()), "cloud_stairs"); - CloudSlabBlock CLOUD_SLAB = register(new CloudSlabBlock<>(CLOUD_BLOCK.getDefaultState(), CloudType.NORMAL.configure().build()), "cloud_slab"); - CloudSlabBlock ENCHANTED_CLOUD_SLAB = register(new CloudSlabBlock<>(ENCHANTED_CLOUD_BLOCK.getDefaultState(), CloudType.ENCHANTED.configure().build()), "enchanted_cloud_slab"); - CloudSlabBlock DENSE_CLOUD_SLAB = register(new CloudSlabBlock<>(ENCHANTED_CLOUD_BLOCK.getDefaultState(), CloudType.DENSE.configure().build()), "dense_cloud_slab"); + CloudSlabBlock CLOUD_SLAB = register(new CloudSlabBlock<>(CLOUD_BLOCK.getDefaultState(), GasState.NORMAL.configure().build()), "cloud_slab"); + CloudSlabBlock ENCHANTED_CLOUD_SLAB = register(new CloudSlabBlock<>(ENCHANTED_CLOUD_BLOCK.getDefaultState(), GasState.ENCHANTED.configure().build()), "enchanted_cloud_slab"); + CloudSlabBlock DENSE_CLOUD_SLAB = register(new CloudSlabBlock<>(ENCHANTED_CLOUD_BLOCK.getDefaultState(), GasState.DENSE.configure().build()), "dense_cloud_slab"); CloudDoorBlock MISTED_GLASS_DOOR = register(new CloudDoorBlock(), "misted_glass_door"); DutchDoorBlock LIBRARY_DOOR = register(new DutchDoorBlock(FabricBlockSettings.of(Material.WOOD).sounds(BlockSoundGroup.WOOD).hardness(3).build()), "library_door"); @@ -43,7 +43,7 @@ public interface UBlocks { CloudAnvilBlock CLOUD_ANVIL = register(new CloudAnvilBlock(), "cloud_anvil"); - CloudFenceBlock CLOUD_FENCE = register(new CloudFenceBlock(CloudType.NORMAL), "cloud_fence"); + CloudFenceBlock CLOUD_FENCE = register(new CloudFenceBlock(GasState.NORMAL), "cloud_fence"); TallCropBlock ALFALFA_CROPS = register(new TallCropBlock(FabricBlockSettings.of(Material.PLANT).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP).build()), "alfalfa_crops"); diff --git a/src/main/java/com/minelittlepony/unicopia/gas/CloudAnvilBlock.java b/src/main/java/com/minelittlepony/unicopia/gas/CloudAnvilBlock.java index fabe852c..16bb7b61 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/CloudAnvilBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/CloudAnvilBlock.java @@ -4,12 +4,15 @@ import java.util.Random; import com.minelittlepony.unicopia.util.WorldEvent; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.block.FabricBlockSettings; import net.fabricmc.fabric.api.tools.FabricToolTags; import net.minecraft.block.AnvilBlock; import net.minecraft.block.BlockState; import net.minecraft.block.Material; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityContext; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.BlockSoundGroup; @@ -17,6 +20,8 @@ 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.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.World; @@ -63,15 +68,17 @@ public class CloudAnvilBlock extends AnvilBlock implements Gas { @Override public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random rand) { - BlockState below = world.getBlockState(pos.down()); - - if (below.getBlock() instanceof Gas) { - if (((Gas)below.getBlock()).getGasType(below).isDense()) { - return; - } + if (!(world.getBlockState(pos.down()).getBlock() instanceof Gas)) { + super.scheduledTick(state, world, pos, rand); } + } - super.scheduledTick(state, world, pos, rand); + @Override + @Environment(EnvType.CLIENT) + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + if (!(world.getBlockState(pos.down()).getBlock() instanceof Gas)) { + super.randomDisplayTick(state, world, pos, random); + } } @Override @@ -81,10 +88,32 @@ public class CloudAnvilBlock extends AnvilBlock implements Gas { } } + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { + CloudInteractionContext ctx = (CloudInteractionContext)context; + + if (!getGasState(state).canPlace(ctx)) { + return VoxelShapes.empty(); + } + + return super.getOutlineShape(state, view, pos, context); + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { + CloudInteractionContext ctx = (CloudInteractionContext)context; + + if (!getGasState(state).canTouch(ctx)) { + return VoxelShapes.empty(); + } + + return super.getCollisionShape(state, view, pos, context); + } + @Deprecated @Override public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) { - if (!CloudType.NORMAL.canInteract(player)) { + if (!GasState.NORMAL.canTouch(player)) { return -1; } return super.calcBlockBreakingDelta(state, player, world, pos); @@ -92,7 +121,7 @@ public class CloudAnvilBlock extends AnvilBlock implements Gas { @Override - public CloudType getGasType(BlockState blockState) { - return CloudType.NORMAL; + public GasState getGasState(BlockState blockState) { + return GasState.NORMAL; } } diff --git a/src/main/java/com/minelittlepony/unicopia/gas/CloudBlock.java b/src/main/java/com/minelittlepony/unicopia/gas/CloudBlock.java index a666f910..f5a28d13 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/CloudBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/CloudBlock.java @@ -26,9 +26,9 @@ import net.minecraft.world.World; public class CloudBlock extends Block implements Gas, HoeUtil.Tillable { - private final CloudType variant; + private final GasState variant; - public CloudBlock(CloudType variant) { + public CloudBlock(GasState variant) { super(variant.configure() .ticksRandomly() .build() @@ -39,29 +39,29 @@ public class CloudBlock extends Block implements Gas, HoeUtil.Tillable { @Override public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { - return getGasType(state).isTranslucent(); + return getGasState(state).isTranslucent(); } @Override public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canPlace(ctx)) { return VoxelShapes.empty(); } - return super.getOutlineShape(state, view, pos, context); + return VoxelShapes.fullCube(); } @Override public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canTouch(ctx)) { return VoxelShapes.empty(); } - return super.getCollisionShape(state, view, pos, context); + return collidable ? VoxelShapes.fullCube() : VoxelShapes.empty(); } @Override @@ -115,14 +115,14 @@ public class CloudBlock extends Block implements Gas, HoeUtil.Tillable { @Deprecated @Override public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView worldIn, BlockPos pos) { - if (CloudType.NORMAL.canInteract(player)) { + if (GasState.NORMAL.canTouch(player)) { return super.calcBlockBreakingDelta(state, player, worldIn, pos); } return -1; } @Override - public CloudType getGasType(BlockState blockState) { + public GasState getGasState(BlockState blockState) { return variant; } diff --git a/src/main/java/com/minelittlepony/unicopia/gas/CloudDoorBlock.java b/src/main/java/com/minelittlepony/unicopia/gas/CloudDoorBlock.java index 30e51d6b..d43a43c2 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/CloudDoorBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/CloudDoorBlock.java @@ -26,13 +26,13 @@ public class CloudDoorBlock extends AbstractDoorBlock implements Gas { } @Override - public CloudType getGasType(BlockState blockState) { - return CloudType.NORMAL; + public GasState getGasState(BlockState blockState) { + return GasState.NORMAL; } @Override public ActionResult onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { - if (!getCanInteract(state, player)) { + if (!getGasState(state).canTouch(player)) { return ActionResult.PASS; } return super.onUse(state, worldIn, pos, player, hand, hit); @@ -56,7 +56,7 @@ public class CloudDoorBlock extends AbstractDoorBlock implements Gas { @Deprecated @Override public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView worldIn, BlockPos pos) { - if (CloudType.NORMAL.canInteract(player)) { + if (GasState.NORMAL.canTouch(player)) { return super.calcBlockBreakingDelta(state, player, worldIn, pos); } return -1; diff --git a/src/main/java/com/minelittlepony/unicopia/gas/CloudFarmlandBlock.java b/src/main/java/com/minelittlepony/unicopia/gas/CloudFarmlandBlock.java index e895c79b..7c0376d9 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/CloudFarmlandBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/CloudFarmlandBlock.java @@ -29,7 +29,7 @@ public class CloudFarmlandBlock extends FarmlandBlock implements Farmland, Gas { Gas cloud = ((Gas)beside.getBlock()); if (face.getAxis() == Axis.Y || cloud == this) { - if (cloud.getGasType(beside) == getGasType(state)) { + if (cloud.getGasState(beside) == getGasState(state)) { return true; } } @@ -63,7 +63,7 @@ public class CloudFarmlandBlock extends FarmlandBlock implements Farmland, Gas { public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canPlace(ctx)) { return VoxelShapes.empty(); } @@ -74,7 +74,7 @@ public class CloudFarmlandBlock extends FarmlandBlock implements Farmland, Gas { public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canTouch(ctx)) { return VoxelShapes.empty(); } @@ -84,15 +84,15 @@ public class CloudFarmlandBlock extends FarmlandBlock implements Farmland, Gas { @Deprecated @Override public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) { - if (CloudType.NORMAL.canInteract(player)) { + if (GasState.NORMAL.canTouch(player)) { return super.calcBlockBreakingDelta(state, player, world, pos); } return -1; } @Override - public CloudType getGasType(BlockState blockState) { - return CloudType.NORMAL; + public GasState getGasState(BlockState blockState) { + return GasState.NORMAL; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/gas/CloudFenceBlock.java b/src/main/java/com/minelittlepony/unicopia/gas/CloudFenceBlock.java index f427df9a..56bc6520 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/CloudFenceBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/CloudFenceBlock.java @@ -13,20 +13,20 @@ import net.minecraft.world.World; public class CloudFenceBlock extends FenceBlock implements Gas { - private final CloudType variant; + private final GasState variant; - public CloudFenceBlock(CloudType variant) { + public CloudFenceBlock(GasState variant) { super(variant.configure().build()); this.variant = variant; } @Override public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { - return getGasType(state).isTranslucent(); + return getGasState(state).isTranslucent(); } @Override - public CloudType getGasType(BlockState blockState) { + public GasState getGasState(BlockState blockState) { return variant; } @@ -48,7 +48,7 @@ public class CloudFenceBlock extends FenceBlock implements Gas { public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canPlace(ctx)) { return VoxelShapes.empty(); } @@ -59,7 +59,7 @@ public class CloudFenceBlock extends FenceBlock implements Gas { public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canTouch(ctx)) { return VoxelShapes.empty(); } @@ -76,7 +76,7 @@ public class CloudFenceBlock extends FenceBlock implements Gas { @Deprecated @Override public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) { - if (CloudType.NORMAL.canInteract(player)) { + if (GasState.NORMAL.canTouch(player)) { return super.calcBlockBreakingDelta(state, player, world, pos); } return -1; diff --git a/src/main/java/com/minelittlepony/unicopia/gas/CloudInteractionContext.java b/src/main/java/com/minelittlepony/unicopia/gas/CloudInteractionContext.java index 9de4cfdd..b8711482 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/CloudInteractionContext.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/CloudInteractionContext.java @@ -2,12 +2,17 @@ package com.minelittlepony.unicopia.gas; import com.minelittlepony.unicopia.EquinePredicates; import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; public interface CloudInteractionContext { static CloudInteractionContext of(Entity entity) { - return entity == null ? Impl.EMPTY : new Impl(entity); + return entity == null ? empty() : new Impl(entity); + } + + static CloudInteractionContext empty() { + return Impl.EMPTY; } default boolean isPlayer() { @@ -18,7 +23,15 @@ public interface CloudInteractionContext { return false; } - boolean canTouch(CloudType type); + default ItemStack getHeldStack() { + return ItemStack.EMPTY; + } + + default boolean isEmpty() { + return this == empty(); + } + + boolean canTouch(GasState type); interface Holder extends CloudInteractionContext { CloudInteractionContext getCloudInteractionContext(); @@ -34,20 +47,39 @@ public interface CloudInteractionContext { } @Override - default boolean canTouch(CloudType type) { + default ItemStack getHeldStack() { + return getCloudInteractionContext().getHeldStack(); + } + + @Override + default boolean canTouch(GasState type) { return getCloudInteractionContext().canTouch(type); } + + @Override + default boolean isEmpty() { + return getCloudInteractionContext().isEmpty(); + } } class Impl implements CloudInteractionContext { - public static final CloudInteractionContext EMPTY = type -> true; + private static final CloudInteractionContext EMPTY = type -> true; private final boolean isPlayer; private final boolean isPegasis; + private ItemStack main = ItemStack.EMPTY; + private Impl(Entity entity) { - this.isPlayer = entity instanceof PlayerEntity; + this.isPlayer = EquinePredicates.IS_PLAYER.test(entity); this.isPegasis = EquinePredicates.ENTITY_INTERACT_WITH_CLOUD_BLOCKS.test(entity); + + if (entity instanceof LivingEntity) { + main = ((LivingEntity)entity).getMainHandStack(); + if (main.isEmpty()) { + main = ((LivingEntity)entity).getOffHandStack(); + } + } } @Override @@ -61,8 +93,13 @@ public interface CloudInteractionContext { } @Override - public boolean canTouch(CloudType type) { - return type.isTouchable(isPlayer()) || isPegasis(); + public boolean canTouch(GasState type) { + return type.isTouchable(isPlayer(), isPegasis()); + } + + @Override + public ItemStack getHeldStack() { + return main; } } } diff --git a/src/main/java/com/minelittlepony/unicopia/gas/CloudSlabBlock.java b/src/main/java/com/minelittlepony/unicopia/gas/CloudSlabBlock.java index 031e604f..c596a503 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/CloudSlabBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/CloudSlabBlock.java @@ -21,15 +21,15 @@ public class CloudSlabBlock extends AbstractSlabBlock } @Override - public CloudType getGasType(BlockState blockState) { - return modelBlock.getGasType(blockState); + public GasState getGasState(BlockState blockState) { + return modelBlock.getGasState(blockState); } @Override public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canTouch(ctx)) { return VoxelShapes.empty(); } @@ -40,7 +40,7 @@ public class CloudSlabBlock extends AbstractSlabBlock public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canPlace(ctx)) { return VoxelShapes.empty(); } diff --git a/src/main/java/com/minelittlepony/unicopia/gas/CloudStairsBlock.java b/src/main/java/com/minelittlepony/unicopia/gas/CloudStairsBlock.java index dda03153..991b3897 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/CloudStairsBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/CloudStairsBlock.java @@ -21,15 +21,15 @@ public class CloudStairsBlock extends AbstractStairsBlock } @Override - public CloudType getGasType(BlockState state) { - return baseBlock.getGasType(baseBlockState); + public GasState getGasState(BlockState state) { + return baseBlock.getGasState(baseBlockState); } @Override public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canPlace(ctx)) { return VoxelShapes.empty(); } @@ -40,7 +40,7 @@ public class CloudStairsBlock extends AbstractStairsBlock public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) { CloudInteractionContext ctx = (CloudInteractionContext)context; - if (!ctx.canTouch(getGasType(state))) { + if (!getGasState(state).canPlace(ctx)) { return VoxelShapes.empty(); } diff --git a/src/main/java/com/minelittlepony/unicopia/gas/Gas.java b/src/main/java/com/minelittlepony/unicopia/gas/Gas.java index d40f253e..a1f609b6 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/Gas.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/Gas.java @@ -1,156 +1,53 @@ package com.minelittlepony.unicopia.gas; -import com.minelittlepony.unicopia.EquinePredicates; - -import net.minecraft.block.BedBlock; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.ChestBlock; -import net.minecraft.block.FallingBlock; -import net.minecraft.block.TorchBlock; -import net.minecraft.client.MinecraftClient; import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.BlockItem; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; public interface Gas { - CloudType getGasType(BlockState blockState); + GasState getGasState(BlockState blockState); - default boolean handleRayTraceSpecialCases(World world, BlockPos pos, BlockState state) { - if (world.isClient) { - PlayerEntity player = MinecraftClient.getInstance().player; - - if (player.abilities.creativeMode) { - return false; - } - - if (!getCanInteract(state, player)) { - return true; - } - - CloudType type = getGasType(state); - - ItemStack main = player.getMainHandStack(); - if (main.isEmpty()) { - main = player.getOffHandStack(); - } - - if (!main.isEmpty() && main.getItem() instanceof BlockItem) { - Block block = ((BlockItem)main.getItem()).getBlock(); - BlockState heldState = block.getDefaultState(); - - if (block == null || block.isAir(heldState)) { - return false; - } - - if (block instanceof Gas) { - CloudType other = ((Gas)block).getGasType(heldState); - - if (other.canInteract(player)) { - return false; - } - } - - if (!EquinePredicates.PLAYER_PEGASUS.test(player)) { - return type != CloudType.ENCHANTED; - } - - if (type == CloudType.NORMAL) { - return !isPlacementExcempt(block); - } - } + default boolean applyLanding(Entity entity, float fallDistance) { + if (entity.isSneaking()) { + return true; } + entity.handleFallDamage(fallDistance, 0); return false; } - default boolean isPlacementExcempt(Block block) { - return block instanceof TorchBlock - || block instanceof BedBlock - || block instanceof ChestBlock; - } - - default boolean applyLanding(Entity entity, float fallDistance) { - if (!entity.isSneaking()) { - entity.handleFallDamage(fallDistance, 0); + default boolean applyRebound(Entity entity) { + double y = entity.getVelocity().y; + if (entity.isSneaking() || y >= 0 || Math.abs(y) < 0.25) { return false; } + entity.setVelocity(entity.getVelocity().multiply(1, -1.2, 1)); + return true; } - default boolean applyRebound(Entity entity) { - Vec3d vel = entity.getVelocity(); - double y = vel.y; - - if (!entity.isSneaking() && y < 0) { - if (Math.abs(y) >= 0.25) { - y = -y * 1.2; - } else { - y = 0; - } - entity.setVelocity(vel.x, y, vel.z); - - return true; - } - - return false; - } - default boolean applyBouncyness(BlockState state, Entity entity) { - if (getCanInteract(state, entity)) { - Vec3d vel = entity.getVelocity(); - double y = vel.y; - - if (!entity.isSneaking() && Math.abs(y) >= 0.25) { - y += 0.0155 * (entity.fallDistance < 1 ? 1 : entity.fallDistance); - } else { - y = 0; - } - entity.setVelocity(vel.x, y, vel.z); - - return true; - } - - return false; - } - - default boolean getCanInteract(BlockState state, Entity e) { - if (getGasType(state).canInteract(e)) { - if (e instanceof ItemEntity) { - // @FUF(reason = "There is no TickEvents.EntityTickEvent. Waiting on mixins...") - e.setNoGravity(true); - } - return true; - } - - return false; - } - - /** - * Determines whether falling sand entities should fall through this block. - * @param state Our block state - * @param world The current world - * @param pos The current position - * - * @return True to allow blocks to pass. - * - * @fuf Hacked until we can get mixins to implement a proper hook - */ - default boolean allowsFallingBlockToPass(BlockState state, BlockView world, BlockPos pos) { - if (this.getGasType(state).isDense()) { + if (!getGasState(state).canTouch(entity)) { return false; } - Block above = world.getBlockState(pos.up()).getBlock(); - return !(above instanceof Gas) && above instanceof FallingBlock; + Vec3d vel = entity.getVelocity(); + double y = vel.y; + + if (entity.isSneaking() || Math.abs(y) < 0.25) { + y = 0; + } else { + y += 0.0155 * Math.max(1, entity.fallDistance); + } + entity.setVelocity(vel.x, y, vel.z); + + return true; + } + + default boolean isSupporting(BlockState state) { + return getGasState(state).isDense(); } } diff --git a/src/main/java/com/minelittlepony/unicopia/gas/GasState.java b/src/main/java/com/minelittlepony/unicopia/gas/GasState.java index d4032194..22bdaac6 100644 --- a/src/main/java/com/minelittlepony/unicopia/gas/GasState.java +++ b/src/main/java/com/minelittlepony/unicopia/gas/GasState.java @@ -1,11 +1,18 @@ package com.minelittlepony.unicopia.gas; +import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.block.UMaterials; import net.fabricmc.fabric.api.block.FabricBlockSettings; +import net.minecraft.block.BedBlock; +import net.minecraft.block.Block; +import net.minecraft.block.ChestBlock; +import net.minecraft.block.TorchBlock; import net.minecraft.entity.Entity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemStack; import net.minecraft.sound.BlockSoundGroup; -public enum CloudType { +public enum GasState { NORMAL, DENSE, ENCHANTED; @@ -25,11 +32,39 @@ public enum CloudType { return this != NORMAL; } - public boolean isTouchable(boolean isPlayer) { - return this == ENCHANTED || (this == DENSE && isPlayer); + public boolean isTouchable(boolean isPlayer, boolean isPegasus) { + return isPegasus || this == ENCHANTED || (this == DENSE && isPlayer); } - public boolean canInteract(Entity e) { - return CloudInteractionContext.of(e).canTouch(this); + public boolean canTouch(Entity e) { + return isTouchable(EquinePredicates.IS_PLAYER.test(e), EquinePredicates.ENTITY_INTERACT_WITH_CLOUD_BLOCKS.test(e)); } + + public boolean canTouch(CloudInteractionContext context) { + return context.canTouch(this); + } + + public boolean canPlace(CloudInteractionContext context) { + return context.isEmpty() || canTouch(context) && heldCanTouch(context); + } + + private boolean heldCanTouch(CloudInteractionContext context) { + ItemStack main = context.getHeldStack(); + + if (main.getItem() instanceof BlockItem) { + Block block = ((BlockItem)main.getItem()).getBlock(); + + if (block instanceof Gas && ((Gas)block).getGasState(block.getDefaultState()).canTouch(context)) { + return true; + } + + return this == GasState.NORMAL && ( + block instanceof TorchBlock + || block instanceof BedBlock + || block instanceof ChestBlock); + } + + return main.isEmpty(); + } + } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityContextImpl.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityContextImpl.java index 098bc8ad..88a0b9e4 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityContextImpl.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityContextImpl.java @@ -20,6 +20,6 @@ abstract class MixinEntityContextImpl implements CloudInteractionContext.Holder @Override public CloudInteractionContext getCloudInteractionContext() { - return cloudContext == null ? CloudInteractionContext.Impl.EMPTY : cloudContext; + return cloudContext == null ? CloudInteractionContext.empty() : cloudContext; } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinFallingBlock.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinFallingBlock.java new file mode 100644 index 00000000..274e1c47 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinFallingBlock.java @@ -0,0 +1,25 @@ +package com.minelittlepony.unicopia.mixin; + +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 com.minelittlepony.unicopia.gas.Gas; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.FallingBlock; + +@Mixin(FallingBlock.class) +abstract class MixinFallingBlock extends Block { + MixinFallingBlock() { super(null); } + @Inject(method = "canFallThrough(Lnet/minecraft/block/BlockState;)Z", + at = @At("HEAD"), + cancellable = true) + private static void onCanFallThrough(BlockState state, CallbackInfoReturnable info) { + if (state.getBlock() instanceof Gas) { + info.setReturnValue(!((Gas)state.getBlock()).isSupporting(state)); + } + } +} diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 3c3d4b51..632aeef5 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -8,6 +8,7 @@ "CriterionsRegistry", "MixinBlockItem", "MixinEntityContextImpl", + "MixinFallingBlock", "MixinFarmlandBlock", "MixinHoeItem", "MixinItem",