Reimplement cloud interaction exclusions

This commit is contained in:
Sollace 2020-04-26 13:46:49 +02:00
parent 4b87f21bf5
commit 660954f6dd
17 changed files with 307 additions and 100 deletions

View file

@ -5,7 +5,6 @@ import java.util.Random;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.SlabBlock; import net.minecraft.block.SlabBlock;
import net.minecraft.block.enums.SlabType;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
@ -13,13 +12,16 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
public abstract class USlab<T extends Block> extends SlabBlock { public abstract class AbstractSlabBlock<T extends Block> extends SlabBlock {
protected final T modelBlock; protected final T modelBlock;
protected final BlockState modelState;
public USlab(T model, Block.Settings settings) { @SuppressWarnings("unchecked")
public AbstractSlabBlock(BlockState inherited, Block.Settings settings) {
super(settings); super(settings);
this.modelBlock = model; modelState = inherited;
modelBlock = (T)inherited.getBlock();
} }
@Deprecated @Deprecated
@ -33,10 +35,6 @@ public abstract class USlab<T extends Block> extends SlabBlock {
return modelBlock.isAir(state); return modelBlock.isAir(state);
} }
public boolean isDouble(BlockState state) {
return state.get(TYPE) == SlabType.DOUBLE;
}
@Override @Override
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random rand) { public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random rand) {
modelBlock.scheduledTick(state, world, pos, rand); modelBlock.scheduledTick(state, world, pos, rand);

View file

@ -9,14 +9,15 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
public class UStairs extends StairsBlock { public abstract class AbstractStairsBlock<T extends Block> extends StairsBlock {
protected final Block baseBlock; protected final T baseBlock;
protected final BlockState baseBlockState; protected final BlockState baseBlockState;
public UStairs(BlockState inherited, Settings settings) { @SuppressWarnings("unchecked")
public AbstractStairsBlock(BlockState inherited, Settings settings) {
super(inherited, settings); super(inherited, settings);
baseBlock = inherited.getBlock(); baseBlock = (T)inherited.getBlock();
baseBlockState = inherited; baseBlockState = inherited;
} }

View file

@ -168,7 +168,7 @@ public class GlowingGemBlock extends TorchBlock implements Gas {
} }
@Override @Override
public CloudType getCloudMaterialType(BlockState blockState) { public CloudType getGasType(BlockState blockState) {
return CloudType.ENCHANTED; return CloudType.ENCHANTED;
} }

View file

@ -37,7 +37,7 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldView; import net.minecraft.world.WorldView;
public class BlockGrowingCuccoon extends Block implements Climbable { public class SlimeDropBlock extends Block implements Climbable {
public static final IntProperty AGE = IntProperty.of("age", 0, 7); public static final IntProperty AGE = IntProperty.of("age", 0, 7);
public static final EnumProperty<Shape> SHAPE = EnumProperty.of("shape", Shape.class); public static final EnumProperty<Shape> SHAPE = EnumProperty.of("shape", Shape.class);
@ -55,7 +55,7 @@ public class BlockGrowingCuccoon extends Block implements Climbable {
Block.createCuboidShape(2, 0, 2, 14, 12, 14), Block.createCuboidShape(2, 0, 2, 14, 12, 14),
}; };
public BlockGrowingCuccoon() { public SlimeDropBlock() {
super(FabricBlockSettings.of(UMaterials.HIVE) super(FabricBlockSettings.of(UMaterials.HIVE)
.ticksRandomly() .ticksRandomly()
.breakInstantly() .breakInstantly()
@ -135,7 +135,7 @@ public class BlockGrowingCuccoon extends Block implements Climbable {
} }
return Math.min(higher.get(AGE), return Math.min(higher.get(AGE),
((BlockGrowingCuccoon)higher.getBlock()).getMaximumAge(world, pos.up(), higher, false) - 1 ((SlimeDropBlock)higher.getBlock()).getMaximumAge(world, pos.up(), higher, false) - 1
); );
} }

View file

@ -28,11 +28,11 @@ public interface UBlocks {
CloudBlock ENCHANTED_CLOUD_BLOCK = register(new CloudBlock(CloudType.ENCHANTED), "enchanted_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 DENSE_CLOUD_BLOCK = register(new CloudBlock(CloudType.DENSE), "dense_cloud_block");
CloudStairsBlock CLOUD_STAIRS = register(new CloudStairsBlock(CLOUD_BLOCK.getDefaultState(), FabricBlockSettings.of(UMaterials.CLOUD).build()), "cloud_stairs"); CloudStairsBlock<CloudBlock> CLOUD_STAIRS = register(new CloudStairsBlock<>(CLOUD_BLOCK.getDefaultState(), FabricBlockSettings.of(UMaterials.CLOUD).build()), "cloud_stairs");
CloudSlabBlock<CloudBlock> CLOUD_SLAB = register(new CloudSlabBlock<>(CLOUD_BLOCK, UMaterials.CLOUD), "cloud_slab"); CloudSlabBlock<CloudBlock> CLOUD_SLAB = register(new CloudSlabBlock<>(CLOUD_BLOCK.getDefaultState(), UMaterials.CLOUD), "cloud_slab");
CloudSlabBlock<CloudBlock> ENCHANTED_CLOUD_SLAB = register(new CloudSlabBlock<>(ENCHANTED_CLOUD_BLOCK, UMaterials.CLOUD), "enchanted_cloud_slab"); CloudSlabBlock<CloudBlock> ENCHANTED_CLOUD_SLAB = register(new CloudSlabBlock<>(ENCHANTED_CLOUD_BLOCK.getDefaultState(), UMaterials.CLOUD), "enchanted_cloud_slab");
CloudSlabBlock<CloudBlock> DENSE_CLOUD_SLAB = register(new CloudSlabBlock<>(ENCHANTED_CLOUD_BLOCK, UMaterials.CLOUD), "dense_cloud_slab"); CloudSlabBlock<CloudBlock> DENSE_CLOUD_SLAB = register(new CloudSlabBlock<>(ENCHANTED_CLOUD_BLOCK.getDefaultState(), UMaterials.CLOUD), "dense_cloud_slab");
CloudDoorBlock MISTED_GLASS_DOOR = register(new CloudDoorBlock(), "misted_glass_door"); 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"); DutchDoorBlock LIBRARY_DOOR = register(new DutchDoorBlock(FabricBlockSettings.of(Material.WOOD).sounds(BlockSoundGroup.WOOD).hardness(3).build()), "library_door");
@ -54,7 +54,7 @@ public interface UBlocks {
ChitinBlock CHITIN_SHELL_BLOCK = register(new ChitinBlock(), "chitin_shell_block"); ChitinBlock CHITIN_SHELL_BLOCK = register(new ChitinBlock(), "chitin_shell_block");
Block CHISELED_CHITIN_SHELL_BLOCK = register(new ChiselledChitinBlock(), "chiseled_chitin_shell_block"); Block CHISELED_CHITIN_SHELL_BLOCK = register(new ChiselledChitinBlock(), "chiseled_chitin_shell_block");
BlockGrowingCuccoon SLIME_DROP = register(new BlockGrowingCuccoon(), "slime_drop"); SlimeDropBlock SLIME_DROP = register(new SlimeDropBlock(), "slime_drop");
SlimeLayerBlock SLIME_LAYER = register(new SlimeLayerBlock(), "slime_layer"); SlimeLayerBlock SLIME_LAYER = register(new SlimeLayerBlock(), "slime_layer");
Block SUGAR_BLOCK = register(new SugarBlock(), "sugar_block"); Block SUGAR_BLOCK = register(new SugarBlock(), "sugar_block");

View file

@ -66,7 +66,7 @@ public class CloudAnvilBlock extends AnvilBlock implements Gas {
BlockState below = world.getBlockState(pos.down()); BlockState below = world.getBlockState(pos.down());
if (below.getBlock() instanceof Gas) { if (below.getBlock() instanceof Gas) {
if (((Gas)below.getBlock()).isDense(below)) { if (((Gas)below.getBlock()).getGasType(below).isDense()) {
return; return;
} }
} }
@ -92,7 +92,7 @@ public class CloudAnvilBlock extends AnvilBlock implements Gas {
@Override @Override
public CloudType getCloudMaterialType(BlockState blockState) { public CloudType getGasType(BlockState blockState) {
return CloudType.NORMAL; return CloudType.NORMAL;
} }
} }

View file

@ -10,10 +10,13 @@ import com.minelittlepony.unicopia.util.HoeUtil;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityContext;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemUsageContext; import net.minecraft.item.ItemUsageContext;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -33,7 +36,29 @@ public class CloudBlock extends Block implements Gas, HoeUtil.Tillable {
@Override @Override
public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) {
return variant == CloudType.NORMAL; return getGasType(state).isTranslucent();
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) {
CloudInteractionContext ctx = (CloudInteractionContext)context;
if (!ctx.canTouch(getGasType(state))) {
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 (!ctx.canTouch(getGasType(state))) {
return VoxelShapes.empty();
}
return super.getCollisionShape(state, view, pos, context);
} }
@Override @Override
@ -55,7 +80,7 @@ public class CloudBlock extends Block implements Gas, HoeUtil.Tillable {
if (beside.getBlock() instanceof Gas) { if (beside.getBlock() instanceof Gas) {
Gas cloud = ((Gas)beside.getBlock()); Gas cloud = ((Gas)beside.getBlock());
if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) { if (cloud.getGasType(beside) == getGasType(state)) {
return true; return true;
} }
} }
@ -94,7 +119,7 @@ public class CloudBlock extends Block implements Gas, HoeUtil.Tillable {
} }
@Override @Override
public CloudType getCloudMaterialType(BlockState blockState) { public CloudType getGasType(BlockState blockState) {
return variant; return variant;
} }

View file

@ -1,11 +1,10 @@
package com.minelittlepony.unicopia.gas; package com.minelittlepony.unicopia.gas;
import com.minelittlepony.unicopia.block.AbstractDoorBlock; import com.minelittlepony.unicopia.block.AbstractDoorBlock;
import com.minelittlepony.unicopia.block.UMaterials;
import net.fabricmc.fabric.api.block.FabricBlockSettings; import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.fabricmc.fabric.api.tools.FabricToolTags; import net.fabricmc.fabric.api.tools.FabricToolTags;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.sound.BlockSoundGroup; import net.minecraft.sound.BlockSoundGroup;
@ -18,14 +17,19 @@ import net.minecraft.world.World;
public class CloudDoorBlock extends AbstractDoorBlock implements Gas { public class CloudDoorBlock extends AbstractDoorBlock implements Gas {
public CloudDoorBlock() { public CloudDoorBlock() {
super(FabricBlockSettings.of(UMaterials.CLOUD) super(FabricBlockSettings.of(Material.GLASS)
.sounds(BlockSoundGroup.WOOL) .sounds(BlockSoundGroup.GLASS)
.hardness(3) .hardness(3)
.resistance(200) .resistance(200)
.breakByTool(FabricToolTags.SHOVELS, 0) .breakByTool(FabricToolTags.PICKAXES, 0)
.build()); .build());
} }
@Override
public CloudType getGasType(BlockState blockState) {
return CloudType.NORMAL;
}
@Override @Override
public ActionResult onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { public ActionResult onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!getCanInteract(state, player)) { if (!getCanInteract(state, player)) {
@ -57,9 +61,4 @@ public class CloudDoorBlock extends AbstractDoorBlock implements Gas {
} }
return -1; return -1;
} }
@Override
public CloudType getCloudMaterialType(BlockState blockState) {
return CloudType.NORMAL;
}
} }

View file

@ -6,10 +6,13 @@ import com.minelittlepony.unicopia.ducks.Farmland;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.FarmlandBlock; import net.minecraft.block.FarmlandBlock;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityContext;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Direction.Axis; import net.minecraft.util.math.Direction.Axis;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -26,7 +29,7 @@ public class CloudFarmlandBlock extends FarmlandBlock implements Farmland, Gas {
Gas cloud = ((Gas)beside.getBlock()); Gas cloud = ((Gas)beside.getBlock());
if (face.getAxis() == Axis.Y || cloud == this) { if (face.getAxis() == Axis.Y || cloud == this) {
if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) { if (cloud.getGasType(beside) == getGasType(state)) {
return true; return true;
} }
} }
@ -56,6 +59,28 @@ public class CloudFarmlandBlock extends FarmlandBlock implements Farmland, Gas {
} }
} }
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) {
CloudInteractionContext ctx = (CloudInteractionContext)context;
if (!ctx.canTouch(getGasType(state))) {
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 (!ctx.canTouch(getGasType(state))) {
return VoxelShapes.empty();
}
return super.getCollisionShape(state, view, pos, context);
}
@Deprecated @Deprecated
@Override @Override
public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) { public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) {
@ -66,7 +91,7 @@ public class CloudFarmlandBlock extends FarmlandBlock implements Farmland, Gas {
} }
@Override @Override
public CloudType getCloudMaterialType(BlockState blockState) { public CloudType getGasType(BlockState blockState) {
return CloudType.NORMAL; return CloudType.NORMAL;
} }

View file

@ -3,8 +3,11 @@ package com.minelittlepony.unicopia.gas;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.FenceBlock; import net.minecraft.block.FenceBlock;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityContext;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; 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.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -19,11 +22,11 @@ public class CloudFenceBlock extends FenceBlock implements Gas {
@Override @Override
public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) {
return variant == CloudType.NORMAL; return getGasType(state) == CloudType.NORMAL;
} }
@Override @Override
public CloudType getCloudMaterialType(BlockState blockState) { public CloudType getGasType(BlockState blockState) {
return variant; return variant;
} }
@ -41,6 +44,28 @@ public class CloudFenceBlock extends FenceBlock implements Gas {
} }
} }
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) {
CloudInteractionContext ctx = (CloudInteractionContext)context;
if (!ctx.canTouch(getGasType(state))) {
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 (!ctx.canTouch(getGasType(state))) {
return VoxelShapes.empty();
}
return super.getCollisionShape(state, view, pos, context);
}
@Override @Override
public void onEntityCollision(BlockState state, World w, BlockPos pos, Entity entity) { public void onEntityCollision(BlockState state, World w, BlockPos pos, Entity entity) {
if (!applyBouncyness(state, entity)) { if (!applyBouncyness(state, entity)) {

View file

@ -0,0 +1,69 @@
package com.minelittlepony.unicopia.gas;
import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.entity.CloudEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
public interface CloudInteractionContext {
static CloudInteractionContext of(Entity entity) {
return entity == null ? Impl.EMPTY : new Impl(entity);
}
default boolean isPlayer() {
return false;
}
default boolean isPegasis() {
return false;
}
boolean canTouch(CloudType type);
class Impl implements CloudInteractionContext {
private static final CloudInteractionContext EMPTY = type -> false;
private final boolean isPlayer;
private final boolean isPegasis;
private Impl(Entity entity) {
this.isPlayer = entity instanceof PlayerEntity;
this.isPegasis = isPegasis(entity);
}
private boolean isPegasis(Entity entity) {
if (entity instanceof PlayerEntity) {
return EquinePredicates.INTERACT_WITH_CLOUDS.test((PlayerEntity)entity)
|| (EquinePredicates.MAGI.test(entity) && CloudEntity.getFeatherEnchantStrength((PlayerEntity)entity) > 0);
}
if (entity instanceof ItemEntity) {
return EquinePredicates.ITEM_INTERACT_WITH_CLOUDS.test((ItemEntity)entity);
}
if (entity instanceof CloudEntity && entity.hasVehicle()) {
return isPegasis(entity.getVehicle());
}
return false;
}
@Override
public boolean isPlayer() {
return isPlayer;
}
@Override
public boolean isPegasis() {
return isPegasis;
}
@Override
public boolean canTouch(CloudType type) {
return type.isTouchable(isPlayer()) || isPegasis();
}
}
}

View file

@ -1,6 +1,6 @@
package com.minelittlepony.unicopia.gas; package com.minelittlepony.unicopia.gas;
import com.minelittlepony.unicopia.block.USlab; import com.minelittlepony.unicopia.block.AbstractSlabBlock;
import net.fabricmc.fabric.api.block.FabricBlockSettings; import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -8,27 +8,54 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.Material; import net.minecraft.block.Material;
import net.minecraft.block.StairsBlock; import net.minecraft.block.StairsBlock;
import net.minecraft.block.enums.SlabType; import net.minecraft.block.enums.SlabType;
import net.minecraft.entity.EntityContext;
import net.minecraft.state.property.Properties; import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
public class CloudSlabBlock<T extends Block & Gas> extends USlab<T> implements Gas { public class CloudSlabBlock<T extends Block & Gas> extends AbstractSlabBlock<T> implements Gas {
public CloudSlabBlock(T modelBlock, Material material) { public CloudSlabBlock(BlockState inherited, Material material) {
super(modelBlock, FabricBlockSettings.of(material).build()); super(inherited, FabricBlockSettings.of(material).build());
} }
@Override @Override
public CloudType getCloudMaterialType(BlockState blockState) { public CloudType getGasType(BlockState blockState) {
return modelBlock.getCloudMaterialType(blockState); return modelBlock.getGasType(blockState);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) {
CloudInteractionContext ctx = (CloudInteractionContext)context;
if (!ctx.canTouch(getGasType(state))) {
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 (!ctx.canTouch(getGasType(state))) {
return VoxelShapes.empty();
}
return super.getCollisionShape(state, view, pos, context);
} }
@Override @Override
public boolean isSideInvisible(BlockState state, BlockState beside, Direction face) { public boolean isSideInvisible(BlockState state, BlockState beside, Direction face) {
if (isDouble(state)) { if (state.get(TYPE) == SlabType.DOUBLE) {
if (beside.getBlock() instanceof Gas) { if (beside.getBlock() instanceof Gas) {
Gas cloud = ((Gas)beside.getBlock()); Gas cloud = ((Gas)beside.getBlock());
if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) { if (cloud.getGasType(beside) == getGasType(state)) {
return true; return true;
} }
} }
@ -38,7 +65,7 @@ public class CloudSlabBlock<T extends Block & Gas> extends USlab<T> implements G
if (beside.getBlock() instanceof Gas) { if (beside.getBlock() instanceof Gas) {
Gas cloud = ((Gas)beside.getBlock()); Gas cloud = ((Gas)beside.getBlock());
if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) { if (cloud.getGasType(beside) == getGasType(state)) {
SlabType half = state.get(TYPE); SlabType half = state.get(TYPE);

View file

@ -1,6 +1,6 @@
package com.minelittlepony.unicopia.gas; package com.minelittlepony.unicopia.gas;
import com.minelittlepony.unicopia.block.UStairs; import com.minelittlepony.unicopia.block.AbstractStairsBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -8,21 +8,51 @@ import net.minecraft.block.SlabBlock;
import net.minecraft.block.enums.BlockHalf; import net.minecraft.block.enums.BlockHalf;
import net.minecraft.block.enums.SlabType; import net.minecraft.block.enums.SlabType;
import net.minecraft.entity.EntityContext; import net.minecraft.entity.EntityContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
public class CloudStairsBlock extends UStairs implements Gas { public class CloudStairsBlock<T extends Block & Gas> extends AbstractStairsBlock<T> implements Gas {
public CloudStairsBlock(BlockState inherited, Settings settings) { public CloudStairsBlock(BlockState inherited, Settings settings) {
super(inherited, settings); super(inherited, settings);
} }
@Override
public CloudType getGasType(BlockState state) {
return baseBlock.getGasType(baseBlockState);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) {
CloudInteractionContext ctx = (CloudInteractionContext)context;
if (!ctx.canTouch(getGasType(state))) {
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 (!ctx.canTouch(getGasType(state))) {
return VoxelShapes.empty();
}
return super.getCollisionShape(state, view, pos, context);
}
@Override @Override
public boolean isSideInvisible(BlockState state, BlockState beside, Direction face) { public boolean isSideInvisible(BlockState state, BlockState beside, Direction face) {
if (beside.getBlock() instanceof Gas) { if (beside.getBlock() instanceof Gas) {
Gas cloud = ((Gas)beside.getBlock()); Gas cloud = ((Gas)beside.getBlock());
if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) { if (cloud.getGasType(beside) == getGasType(state)) {
Direction front = state.get(FACING); Direction front = state.get(FACING);
BlockHalf half = state.get(HALF); BlockHalf half = state.get(HALF);
@ -71,9 +101,4 @@ public class CloudStairsBlock extends UStairs implements Gas {
return false; return false;
} }
@Override
public CloudType getCloudMaterialType(BlockState blockState) {
return CloudType.NORMAL;
}
} }

View file

@ -1,13 +1,8 @@
package com.minelittlepony.unicopia.gas; package com.minelittlepony.unicopia.gas;
import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.block.UMaterials; import com.minelittlepony.unicopia.block.UMaterials;
import com.minelittlepony.unicopia.entity.CloudEntity;
import net.fabricmc.fabric.api.block.FabricBlockSettings; import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.sound.BlockSoundGroup; import net.minecraft.sound.BlockSoundGroup;
public enum CloudType { public enum CloudType {
@ -25,33 +20,19 @@ public enum CloudType {
return settings; return settings;
} }
public boolean isTranslucent() {
return this == NORMAL;
}
public boolean isDense() {
return this != NORMAL;
}
public boolean isTouchable(boolean isPlayer) {
return this == ENCHANTED || (this == DENSE && isPlayer);
}
public boolean canInteract(Entity e) { public boolean canInteract(Entity e) {
if (e == null) { return CloudInteractionContext.of(e).canTouch(this);
return false;
}
if (this == ENCHANTED) {
return true;
}
if (e instanceof PlayerEntity) {
if (this == DENSE) {
return true;
}
return EquinePredicates.INTERACT_WITH_CLOUDS.test((PlayerEntity)e)
|| (EquinePredicates.MAGI.test(e) && CloudEntity.getFeatherEnchantStrength((PlayerEntity)e) > 0);
}
if (e instanceof ItemEntity) {
return EquinePredicates.ITEM_INTERACT_WITH_CLOUDS.test((ItemEntity)e);
}
if (e instanceof CloudEntity && e.hasVehicle()) {
return canInteract(e.getVehicle());
}
return false;
} }
} }

View file

@ -21,7 +21,7 @@ import net.minecraft.world.World;
public interface Gas { public interface Gas {
CloudType getCloudMaterialType(BlockState blockState); CloudType getGasType(BlockState blockState);
default boolean handleRayTraceSpecialCases(World world, BlockPos pos, BlockState state) { default boolean handleRayTraceSpecialCases(World world, BlockPos pos, BlockState state) {
if (world.isClient) { if (world.isClient) {
@ -35,7 +35,7 @@ public interface Gas {
return true; return true;
} }
CloudType type = getCloudMaterialType(state); CloudType type = getGasType(state);
ItemStack main = player.getMainHandStack(); ItemStack main = player.getMainHandStack();
if (main.isEmpty()) { if (main.isEmpty()) {
@ -51,7 +51,7 @@ public interface Gas {
} }
if (block instanceof Gas) { if (block instanceof Gas) {
CloudType other = ((Gas)block).getCloudMaterialType(heldState); CloudType other = ((Gas)block).getGasType(heldState);
if (other.canInteract(player)) { if (other.canInteract(player)) {
return false; return false;
@ -88,7 +88,6 @@ public interface Gas {
} }
default boolean applyRebound(Entity entity) { default boolean applyRebound(Entity entity) {
Vec3d vel = entity.getVelocity(); Vec3d vel = entity.getVelocity();
double y = vel.y; double y = vel.y;
@ -124,9 +123,8 @@ public interface Gas {
return false; return false;
} }
default boolean getCanInteract(BlockState state, Entity e) { default boolean getCanInteract(BlockState state, Entity e) {
if (getCloudMaterialType(state).canInteract(e)) { if (getGasType(state).canInteract(e)) {
if (e instanceof ItemEntity) { if (e instanceof ItemEntity) {
// @FUF(reason = "There is no TickEvents.EntityTickEvent. Waiting on mixins...") // @FUF(reason = "There is no TickEvents.EntityTickEvent. Waiting on mixins...")
e.setNoGravity(true); e.setNoGravity(true);
@ -137,10 +135,6 @@ public interface Gas {
return false; return false;
} }
default boolean isDense(BlockState blockState) {
return getCloudMaterialType(blockState) != CloudType.NORMAL;
}
/** /**
* Determines whether falling sand entities should fall through this block. * Determines whether falling sand entities should fall through this block.
* @param state Our block state * @param state Our block state
@ -152,7 +146,7 @@ public interface Gas {
* @fuf Hacked until we can get mixins to implement a proper hook * @fuf Hacked until we can get mixins to implement a proper hook
*/ */
default boolean allowsFallingBlockToPass(BlockState state, BlockView world, BlockPos pos) { default boolean allowsFallingBlockToPass(BlockState state, BlockView world, BlockPos pos) {
if (isDense(state)) { if (this.getGasType(state).isDense()) {
return false; return false;
} }

View file

@ -0,0 +1,37 @@
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.CallbackInfo;
import com.minelittlepony.unicopia.gas.CloudInteractionContext;
import com.minelittlepony.unicopia.gas.CloudType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityContextImpl;
@Mixin(EntityContextImpl.class)
abstract class MixinEntityContextImpl implements CloudInteractionContext {
private CloudInteractionContext cloudContext;
@Inject(method = "<init>(Lnet/minecraft/entity/Entity;)V", at = @At("RETURN"))
private void onInit(Entity e, CallbackInfo into) {
cloudContext = CloudInteractionContext.of(e);
}
@Override
public boolean isPlayer() {
return cloudContext != null && cloudContext.isPlayer();
}
@Override
public boolean isPegasis() {
return cloudContext != null && cloudContext.isPegasis();
}
@Override
public boolean canTouch(CloudType type) {
return cloudContext != null && cloudContext.canTouch(type);
}
}

View file

@ -7,6 +7,7 @@
"mixins": [ "mixins": [
"CriterionsRegistry", "CriterionsRegistry",
"MixinBlockItem", "MixinBlockItem",
"MixinEntityContextImpl",
"MixinFarmlandBlock", "MixinFarmlandBlock",
"MixinHoeItem", "MixinHoeItem",
"MixinItem", "MixinItem",