Unicopia/src/main/java/com/minelittlepony/unicopia/block/BlockGrowingCuccoon.java

341 lines
11 KiB
Java
Raw Normal View History

2019-03-02 17:45:28 +01:00
package com.minelittlepony.unicopia.block;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.Predicates;
2020-01-16 12:35:46 +01:00
import com.minelittlepony.unicopia.UBlocks;
import com.minelittlepony.unicopia.UMaterials;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.util.MagicalDamageSource;
2019-03-02 17:45:28 +01:00
import com.minelittlepony.util.PosHelper;
import net.minecraft.block.Block;
2020-01-16 12:35:46 +01:00
import net.minecraft.block.BlockState;
2019-03-02 17:45:28 +01:00
import net.minecraft.entity.Entity;
2020-01-16 12:35:46 +01:00
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
2019-03-02 17:45:28 +01:00
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
2020-01-16 12:35:46 +01:00
import net.minecraft.particle.ParticleTypes;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.property.IntProperty;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.Box;
2019-03-02 17:45:28 +01:00
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
2020-01-16 12:35:46 +01:00
import net.minecraft.world.BlockView;
2019-03-02 17:45:28 +01:00
import net.minecraft.world.World;
public class BlockGrowingCuccoon extends Block {
2020-01-16 12:35:46 +01:00
public static final DamageSource DAMAGE_SOURCE = MagicalDamageSource.mundane("acid");
2020-01-16 12:35:46 +01:00
public static final IntProperty AGE = IntProperty.of("age", 0, 7);
public static final EnumProperty<Shape> SHAPE = EnumProperty.of("shape", Shape.class);
2019-03-02 17:45:28 +01:00
2020-01-16 12:35:46 +01:00
public static final Box[] SHAFTS = new Box[] {
new Box(7/16F, 0, 7/16F, 9/16F, 1, 7/16F),
new Box(6/16F, 0, 6/16F, 10/16F, 1, 10/16F),
new Box(5/16F, 0, 5/16F, 11/16F, 1, 11/16F),
new Box(4/16F, 0, 4/16F, 12/16F, 1, 12/16F)
2019-03-02 17:45:28 +01:00
};
2020-01-16 12:35:46 +01:00
public static final Box[] BULBS = new Box[] {
new Box(6/16F, 1/16F, 6/16F, 10/16F, 8/16F, 10/16F),
new Box(4/16F, 0, 4/16F, 12/16F, 9/16F, 12/16F),
new Box(3/16F, 0, 3/16F, 13/16F, 10/16F, 13/16F),
new Box(2/16F, 0, 2/16F, 14/16F, 12/16F, 14/16F),
2019-03-02 17:45:28 +01:00
};
public BlockGrowingCuccoon(String domain, String name) {
super(UMaterials.hive);
setTranslationKey(name);
setRegistryName(domain, name);
setResistance(0);
setSoundType(SoundType.SLIME);
setDefaultSlipperiness(0.5F);
setHarvestLevel("shovel", 2);
setLightLevel(0.6F);
setLightOpacity(0);
useNeighborBrightness = true;
setDefaultState(getBlockState().getBaseState()
2020-01-16 12:35:46 +01:00
.with(AGE, 0)
.with(SHAPE, Shape.BULB));
2019-03-02 17:45:28 +01:00
}
@Override
2020-01-16 16:46:24 +01:00
public boolean isTranslucent(BlockState state) {
2019-03-02 17:45:28 +01:00
return true;
}
@Override
2020-01-16 16:46:24 +01:00
public boolean isOpaqueCube(BlockState state) {
2019-03-02 17:45:28 +01:00
return false;
}
@Override
//Push player out of block
2020-01-16 16:46:24 +01:00
public boolean isFullCube(BlockState state) {
2019-03-02 17:45:28 +01:00
return false;
}
@Override
2020-01-16 16:46:24 +01:00
public boolean isNormalCube(BlockState state) {
2019-03-02 17:45:28 +01:00
return false;
}
@Override
public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.TRANSLUCENT;
}
@Deprecated
@Override
2020-01-16 16:46:24 +01:00
public Box getCollisionBoundingBox(BlockState state, BlockView world, BlockPos pos) {
2019-03-02 17:45:28 +01:00
return getBoundingBox(state, world, pos);
}
@Override
public Block.EnumOffsetType getOffsetType() {
return Block.EnumOffsetType.XZ;
}
@Override
2020-01-16 16:46:24 +01:00
public void updateTick(World world, BlockPos pos, BlockState state, Random rand) {
2019-03-02 17:45:28 +01:00
if (!checkSupport(world, pos)) {
2019-03-02 18:18:29 +01:00
breakConnected(world, pos);
2019-03-02 17:45:28 +01:00
return;
}
2020-01-16 12:35:46 +01:00
int age = state.get(AGE);
2019-03-02 17:45:28 +01:00
BlockPos below = pos.down();
if (world.isBlockLoaded(below)) {
boolean spaceBelow = world.isAirBlock(below);
2020-01-16 12:35:46 +01:00
Shape shape = state.get(SHAPE);
2019-03-02 17:45:28 +01:00
if (shape == Shape.STRING && spaceBelow) {
2020-01-16 12:35:46 +01:00
world.setBlockState(pos, state.with(SHAPE, Shape.BULB).with(AGE, age / 2));
2019-03-02 17:45:28 +01:00
} else if (shape == Shape.BULB && !spaceBelow) {
2020-01-16 12:35:46 +01:00
world.setBlockState(pos, state.with(SHAPE, Shape.STRING).with(AGE, age / 2));
2019-03-02 17:45:28 +01:00
} else if (age >= 7) {
if (rand.nextInt(12) == 0 && spaceBelow) {
2020-01-16 12:35:46 +01:00
world.setBlockState(below, state.with(AGE, age / 2));
world.setBlockState(pos, getDefaultState().with(AGE, age / 2).with(SHAPE, Shape.STRING));
2019-03-02 17:45:28 +01:00
world.playSound(null, pos, USounds.SLIME_ADVANCE, SoundCategory.BLOCKS, 1, 1);
}
} else {
if (age < getMaximumAge(world, pos, state, spaceBelow)) {
if (rand.nextInt(5 * (age + 1)) == 0) {
world.setBlockState(pos, state.cycleProperty(AGE));
}
}
}
}
world.scheduleUpdate(pos, this, tickRate(world));
}
2019-03-02 18:18:29 +01:00
protected void breakConnected(World world, BlockPos pos) {
world.destroyBlock(pos, true);
pos = pos.down();
if (world.getBlockState(pos).getBlock() == this) {
breakConnected(world, pos);
}
}
2020-01-16 16:46:24 +01:00
protected int getMaximumAge(World world, BlockPos pos, BlockState state, boolean spaceBelow) {
2020-01-16 12:35:46 +01:00
if (state.get(SHAPE) == Shape.STRING) {
2020-01-16 16:46:24 +01:00
BlockState higher = world.getBlockState(pos.up());
2019-03-02 17:45:28 +01:00
if (higher.getBlock() != this) {
return 7;
}
2020-01-16 12:35:46 +01:00
return Math.min(higher.get(AGE),
2019-03-02 18:18:29 +01:00
((BlockGrowingCuccoon)higher.getBlock()).getMaximumAge(world, pos.up(), higher, false) - 1
);
2019-03-02 17:45:28 +01:00
}
if (!spaceBelow) {
return 0;
}
return 7;
}
@Override
2020-01-16 16:46:24 +01:00
public int quantityDropped(BlockState state, int fortune, Random random) {
2020-01-16 12:35:46 +01:00
return random.nextInt(3) == 0 ? state.get(AGE) : 0;
2019-03-02 17:45:28 +01:00
}
@Override
2020-01-16 16:46:24 +01:00
public Item getItemDropped(BlockState state, Random rand, int fortune) {
2019-03-02 18:18:29 +01:00
return Items.SLIME_BALL;
2019-03-02 17:45:28 +01:00
}
@Override
public boolean canPlaceBlockAt(World world, BlockPos pos) {
return super.canPlaceBlockAt(world, pos) && checkSupport(world, pos);
}
@Override
2020-01-16 16:46:24 +01:00
public void onNeighborChange(BlockView world, BlockPos pos, BlockPos neighbor) {
2019-03-02 17:45:28 +01:00
if (world instanceof World && !checkSupport(world, pos)) {
2019-03-02 18:18:29 +01:00
breakConnected((World)world, pos);
2019-03-02 17:45:28 +01:00
}
}
@Override
2020-01-16 16:46:24 +01:00
public void breakBlock(World world, BlockPos pos, BlockState state) {
2019-03-02 17:45:28 +01:00
world.notifyNeighborsOfStateChange(pos, this, true);
super.breakBlock(world, pos, state);
}
@Override
2020-01-16 16:46:24 +01:00
public void onBlockAdded(World world, BlockPos pos, BlockState state) {
2019-03-02 17:45:28 +01:00
world.scheduleUpdate(pos, this, 10);
}
@Override
2020-01-16 16:46:24 +01:00
public void onEntityCollision(World world, BlockPos pos, BlockState state, Entity entity) {
2020-01-16 12:35:46 +01:00
if (entity instanceof LivingEntity && !entity.isDead) {
LivingEntity living = (LivingEntity)entity;
if (!Predicates.BUGGY.test(living) && living.getHealth() > 0) {
living.attackEntityFrom(DAMAGE_SOURCE, 1);
living.setInWeb();
2020-01-16 12:35:46 +01:00
if (!world.isClient) {
if (living.getHealth() <= 0) {
living.dropItem(Items.BONE, 3);
2020-01-16 16:46:24 +01:00
if (living instanceof PlayerEntity) {
ItemStack skull = new ItemStack(Items.SKULL, 1);
if (world.rand.nextInt(13000) == 0) {
2020-01-16 16:46:24 +01:00
PlayerEntity player = (PlayerEntity)living;
skull.setTagCompound(new NBTTagCompound());
skull.getTagCompound().setTag("SkullOwner", NBTUtil.writeGameProfile(new NBTTagCompound(), player.getGameProfile()));
skull.setItemDamage(3);
} else {
living.dropItem(Items.SKULL, 1);
}
living.entityDropItem(skull, 0);
}
}
}
}
}
}
2020-01-16 16:46:24 +01:00
public boolean checkSupport(BlockView world, BlockPos pos) {
2019-03-02 17:45:28 +01:00
2020-01-16 16:46:24 +01:00
if (PosHelper.some(pos, p -> !world.isAirBlock(p), Direction.HORIZONTALS)) {
2019-03-02 17:45:28 +01:00
return false;
}
pos = pos.up();
2020-01-16 16:46:24 +01:00
BlockState above = world.getBlockState(pos);
2019-03-02 17:45:28 +01:00
if (above.getBlock() == this || above.getBlock() == UBlocks.hive) {
return true;
}
2020-01-16 16:46:24 +01:00
switch (above.getBlockFaceShape(world, pos, Direction.DOWN)) {
2019-03-02 17:45:28 +01:00
case SOLID:
case CENTER:
case CENTER_BIG:
case CENTER_SMALL: return true;
default: return false;
}
}
@Deprecated
@Override
2020-01-16 16:46:24 +01:00
public void addCollisionBoxToList(BlockState state, World world, BlockPos pos, Box entityBox, List<Box> collidingBoxes, @Nullable Entity entity, boolean isActualState) {
2019-03-02 17:45:28 +01:00
if (!isActualState) {
state = state.getActualState(world, pos);
}
2020-01-16 12:35:46 +01:00
int age = state.get(AGE) / 2;
2019-03-02 17:45:28 +01:00
Vec3d offset = state.getOffset(world, pos);
addCollisionBoxToList(pos, entityBox, collidingBoxes, SHAFTS[age % SHAFTS.length].offset(offset));
2020-01-16 12:35:46 +01:00
if (state.get(SHAPE) == Shape.BULB) {
2019-03-02 17:45:28 +01:00
addCollisionBoxToList(pos, entityBox, collidingBoxes, BULBS[age % BULBS.length].offset(offset));
}
}
@Deprecated
@Override
2020-01-16 16:46:24 +01:00
public Box getBoundingBox(BlockState state, BlockView source, BlockPos pos) {
2019-03-02 17:45:28 +01:00
state = state.getActualState(source, pos);
2020-01-16 12:35:46 +01:00
if (state.get(SHAPE) == Shape.BULB) {
return BULBS[state.get(AGE) / 2].offset(state.getOffset(source, pos));
2019-03-02 17:45:28 +01:00
}
2020-01-16 12:35:46 +01:00
return SHAFTS[state.get(AGE) / 2].offset(state.getOffset(source, pos));
2019-03-02 17:45:28 +01:00
}
@Override
protected BlockStateContainer createBlockState() {
return new BlockStateContainer(this, AGE, SHAPE);
}
2019-03-02 18:18:29 +01:00
@Override
2020-01-16 12:35:46 +01:00
public boolean isLadder(BlockState state, BlockView world, BlockPos pos, LivingEntity entity) {
2019-03-02 18:18:29 +01:00
return true;
}
2020-01-16 12:35:46 +01:00
@Override
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random rand) {
if (state.get(SHAPE) == Shape.BULB) {
2019-03-02 18:18:29 +01:00
if (rand.nextInt(8) == 0) {
2020-01-16 12:35:46 +01:00
Box bounds = BULBS[state.get(AGE) / 2]
2019-03-02 18:18:29 +01:00
.offset(pos)
2020-01-16 12:35:46 +01:00
.offset(state.getOffsetPos(world, pos));
2019-03-02 18:18:29 +01:00
double x = bounds.minX + (bounds.maxX - bounds.minX) * rand.nextFloat();
double y = bounds.minY;
double z = bounds.minZ + (bounds.maxZ - bounds.minZ) * rand.nextFloat();
2020-01-16 12:35:46 +01:00
world.addParticle(ParticleTypes.DRIPPING_LAVA, x, y, z, 0, 0, 0);
2019-03-02 18:18:29 +01:00
}
}
}
2020-01-16 12:35:46 +01:00
enum Shape implements StringIdentifiable {
2019-03-02 17:45:28 +01:00
BULB,
STRING;
static final Shape[] VALUES = values();
@Override
public String toString() {
2020-01-16 12:35:46 +01:00
return asString();
2019-03-02 17:45:28 +01:00
}
@Override
2020-01-16 12:35:46 +01:00
public String asString() {
2019-03-02 17:45:28 +01:00
return name().toLowerCase();
}
}
}