2018-09-16 00:45:44 +02:00
|
|
|
package com.minelittlepony.unicopia.block;
|
|
|
|
|
|
|
|
import com.minelittlepony.unicopia.CloudType;
|
2019-02-04 22:12:12 +01:00
|
|
|
import com.minelittlepony.unicopia.Predicates;
|
2019-01-30 11:26:00 +01:00
|
|
|
import com.minelittlepony.unicopia.UClient;
|
|
|
|
import com.minelittlepony.unicopia.forgebullshit.FUF;
|
2018-09-19 09:07:39 +02:00
|
|
|
import net.minecraft.block.Block;
|
2019-02-05 10:01:49 +01:00
|
|
|
import net.minecraft.block.BlockBed;
|
|
|
|
import net.minecraft.block.BlockChest;
|
2018-09-19 09:07:39 +02:00
|
|
|
import net.minecraft.block.BlockFalling;
|
2019-01-13 21:06:27 +01:00
|
|
|
import net.minecraft.block.BlockTorch;
|
2018-09-16 00:45:44 +02:00
|
|
|
import net.minecraft.block.state.IBlockState;
|
|
|
|
import net.minecraft.entity.Entity;
|
2019-01-27 16:35:39 +01:00
|
|
|
import net.minecraft.entity.item.EntityItem;
|
2019-01-13 21:06:27 +01:00
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
|
|
import net.minecraft.init.Blocks;
|
|
|
|
import net.minecraft.item.ItemBlock;
|
|
|
|
import net.minecraft.item.ItemStack;
|
2018-09-19 09:07:39 +02:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
|
|
|
import net.minecraft.world.IBlockAccess;
|
2019-01-13 21:06:27 +01:00
|
|
|
import net.minecraft.world.World;
|
2018-09-16 00:45:44 +02:00
|
|
|
|
|
|
|
public interface ICloudBlock {
|
|
|
|
|
|
|
|
CloudType getCloudMaterialType(IBlockState blockState);
|
|
|
|
|
2019-01-13 21:06:27 +01:00
|
|
|
default boolean handleRayTraceSpecialCases(World world, BlockPos pos, IBlockState state) {
|
|
|
|
if (world.isRemote) {
|
2019-01-30 11:26:00 +01:00
|
|
|
EntityPlayer player = UClient.instance().getPlayer();
|
2019-01-13 21:06:27 +01:00
|
|
|
|
2019-02-07 14:37:24 +01:00
|
|
|
if (player.capabilities.isCreativeMode) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-01-13 21:06:27 +01:00
|
|
|
if (!getCanInteract(state, player)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-02-04 22:12:12 +01:00
|
|
|
CloudType type = getCloudMaterialType(state);
|
|
|
|
|
2019-01-13 21:06:27 +01:00
|
|
|
ItemStack main = player.getHeldItemMainhand();
|
|
|
|
if (main.isEmpty()) {
|
|
|
|
main = player.getHeldItemOffhand();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!main.isEmpty() && main.getItem() instanceof ItemBlock) {
|
|
|
|
Block block = ((ItemBlock)main.getItem()).getBlock();
|
|
|
|
|
2019-02-04 22:12:12 +01:00
|
|
|
if (block == null || block == Blocks.AIR) {
|
2019-01-13 21:06:27 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-02-05 10:01:49 +01:00
|
|
|
if (isPlacementExcempt(block)) {
|
2019-02-07 18:18:51 +01:00
|
|
|
|
|
|
|
if (block instanceof ICloudBlock) {
|
|
|
|
CloudType other = ((ICloudBlock)block).getCloudMaterialType(block.getDefaultState());
|
|
|
|
|
|
|
|
if (other.canInteract(player)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-04 22:12:12 +01:00
|
|
|
if (Predicates.INTERACT_WITH_CLOUDS.apply(player)) {
|
|
|
|
return type == CloudType.NORMAL;
|
|
|
|
}
|
|
|
|
return type != CloudType.ENCHANTED;
|
2019-01-13 21:06:27 +01:00
|
|
|
}
|
|
|
|
|
2019-02-04 22:12:12 +01:00
|
|
|
if (!(block instanceof ICloudBlock)) {
|
|
|
|
return type != CloudType.ENCHANTED;
|
2019-01-13 21:06:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-02-05 10:01:49 +01:00
|
|
|
default boolean isPlacementExcempt(Block block) {
|
|
|
|
return block instanceof BlockTorch
|
|
|
|
|| block instanceof BlockBed
|
|
|
|
|| block instanceof BlockChest;
|
|
|
|
}
|
|
|
|
|
2019-02-04 17:16:17 +01:00
|
|
|
default boolean applyLanding(Entity entity, float fallDistance) {
|
|
|
|
if (!entity.isSneaking()) {
|
|
|
|
entity.fall(fallDistance, 0);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
default boolean applyRebound(Entity entity) {
|
|
|
|
if (!entity.isSneaking() && entity.motionY < 0) {
|
|
|
|
if (Math.abs(entity.motionY) >= 0.25) {
|
|
|
|
entity.motionY = -entity.motionY * 1.2;
|
|
|
|
} else {
|
|
|
|
entity.motionY = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
default boolean applyBouncyness(IBlockState state, Entity entity) {
|
|
|
|
if (getCanInteract(state, entity)) {
|
|
|
|
if (!entity.isSneaking() && Math.abs(entity.motionY) >= 0.25) {
|
|
|
|
entity.motionY += 0.0155 * (entity.fallDistance < 1 ? 1 : entity.fallDistance);
|
|
|
|
} else {
|
|
|
|
entity.motionY = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-09-16 00:45:44 +02:00
|
|
|
default boolean getCanInteract(IBlockState state, Entity e) {
|
2019-01-27 16:35:39 +01:00
|
|
|
if (getCloudMaterialType(state).canInteract(e)) {
|
|
|
|
if (e instanceof EntityItem) {
|
2019-01-30 11:26:00 +01:00
|
|
|
// @FUF(reason = "There is no TickEvents.EntityTickEvent. Waiting on mixins...")
|
2019-01-27 16:35:39 +01:00
|
|
|
e.setNoGravity(true);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2018-09-16 00:45:44 +02:00
|
|
|
}
|
|
|
|
|
2018-09-19 09:07:39 +02:00
|
|
|
default boolean isDense(IBlockState blockState) {
|
|
|
|
return getCloudMaterialType(blockState) != CloudType.NORMAL;
|
|
|
|
}
|
|
|
|
|
2019-01-30 11:26:00 +01:00
|
|
|
/**
|
|
|
|
* 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(reason = "Hacked until we can get mixins to implement a proper hook")
|
2018-09-19 09:07:39 +02:00
|
|
|
default boolean allowsFallingBlockToPass(IBlockState state, IBlockAccess world, BlockPos pos) {
|
|
|
|
if (isDense(state)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Block above = world.getBlockState(pos.up()).getBlock();
|
|
|
|
return !(above instanceof ICloudBlock) && above instanceof BlockFalling;
|
|
|
|
}
|
2018-09-16 00:45:44 +02:00
|
|
|
}
|