TheBrokenRail
ce2e2df2d5
All checks were successful
EnergonRelics/pipeline/head This commit looks good
166 lines
6.6 KiB
Java
166 lines
6.6 KiB
Java
package com.thebrokenrail.energonrelics.block.portal;
|
|
|
|
import com.thebrokenrail.energonrelics.EnergonRelics;
|
|
import com.thebrokenrail.energonrelics.api.block.SimpleBlock;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|
import net.minecraft.block.BlockState;
|
|
import net.minecraft.block.Blocks;
|
|
import net.minecraft.block.Material;
|
|
import net.minecraft.block.ShapeContext;
|
|
import net.minecraft.block.piston.PistonBehavior;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.server.world.ServerWorld;
|
|
import net.minecraft.sound.BlockSoundGroup;
|
|
import net.minecraft.sound.SoundCategory;
|
|
import net.minecraft.sound.SoundEvents;
|
|
import net.minecraft.util.function.BooleanBiFunction;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.util.math.Direction;
|
|
import net.minecraft.util.shape.VoxelShape;
|
|
import net.minecraft.util.shape.VoxelShapes;
|
|
import net.minecraft.world.BlockView;
|
|
import net.minecraft.world.World;
|
|
import net.minecraft.world.WorldAccess;
|
|
|
|
import java.util.Random;
|
|
|
|
@SuppressWarnings("deprecation")
|
|
public class EnergyPortalBlock extends SimpleBlock {
|
|
public EnergyPortalBlock() {
|
|
super(FabricBlockSettings.of(Material.PORTAL).strength(-1f, 3600000.8f).lightLevel(11).sounds(BlockSoundGroup.GLASS).dropsNothing().emissiveLighting((state, world, pos) -> true).noCollision());
|
|
}
|
|
|
|
@Override
|
|
protected boolean registerItem() {
|
|
return false;
|
|
}
|
|
|
|
private static final VoxelShape SHAPE = createCuboidShape(0, 6, 0, 16, 10, 16);
|
|
|
|
@Override
|
|
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
|
return SHAPE;
|
|
}
|
|
|
|
public static boolean isValidDirection(Direction dir) {
|
|
return dir != Direction.UP && dir != Direction.DOWN;
|
|
}
|
|
|
|
private static boolean isObsidian(BlockState state) {
|
|
return state.getBlock() == Blocks.OBSIDIAN || state.getBlock() == EnergonRelics.ENERGIZED_OBSIDIAN_BLOCK;
|
|
}
|
|
|
|
public static boolean isValidFrame(WorldAccess world, BlockPos centerPos) {
|
|
int validSides = 0;
|
|
for (Direction side : Direction.values()) {
|
|
if (isValidDirection(side)) {
|
|
BlockPos energizedPos = centerPos.offset(side, 2);
|
|
BlockState energizedObsidian = world.getBlockState(energizedPos);
|
|
if (energizedObsidian.getBlock() == EnergonRelics.ENERGIZED_OBSIDIAN_BLOCK) {
|
|
BlockState obsidian1 = world.getBlockState(energizedPos.offset(side.rotateYClockwise(), 1));
|
|
BlockState obsidian2 = world.getBlockState(energizedPos.offset(side.rotateYCounterclockwise(), 1));
|
|
if (isObsidian(obsidian1) && isObsidian(obsidian2)) {
|
|
validSides++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return validSides == 4;
|
|
}
|
|
|
|
static BlockPos getCenterPos(WorldAccess world, BlockPos pos) {
|
|
BlockPos centerPos = pos;
|
|
for (Direction side : Direction.values()) {
|
|
if (isValidDirection(side)) {
|
|
if (world.getBlockState(pos.offset(side)).getBlock() != EnergonRelics.ENERGY_PORTAL_BLOCK) {
|
|
centerPos = centerPos.offset(side.getOpposite());
|
|
}
|
|
}
|
|
}
|
|
return centerPos;
|
|
}
|
|
|
|
private static boolean isValidCenter(WorldAccess world, BlockPos centerPos) {
|
|
boolean valid = true;
|
|
BlockPos startPos = centerPos.add(-1, 0, -1);
|
|
for (int x = 0; x < 3; x++) {
|
|
for (int z = 0; z < 3; z++) {
|
|
if (world.getBlockState(startPos.add(x, 0, z)).getBlock() != EnergonRelics.ENERGY_PORTAL_BLOCK) {
|
|
valid = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return valid;
|
|
}
|
|
|
|
public static void fillFrame(WorldAccess world, BlockPos centerPos) {
|
|
BlockPos startPos = centerPos.add(-1, 0, -1);
|
|
for (int x = 0; x < 3; x++) {
|
|
for (int z = 0; z < 3; z++) {
|
|
BlockState state = world.getBlockState(startPos.add(x, 0, z));
|
|
if (state.getBlock() != EnergonRelics.ENERGY_PORTAL_BLOCK && !state.isAir()) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int x = 0; x < 3; x++) {
|
|
for (int z = 0; z < 3; z++) {
|
|
world.setBlockState(startPos.add(x, 0, z), EnergonRelics.ENERGY_PORTAL_BLOCK.getDefaultState(), 3 | 16);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) {
|
|
boolean valid;
|
|
if (isValidDirection(direction)) {
|
|
BlockPos centerPos = getCenterPos(world, pos);
|
|
boolean isValidFrame = isValidFrame(world, centerPos);
|
|
boolean isValidCenter = isValidCenter(world, centerPos);
|
|
valid = isValidCenter && isValidFrame;
|
|
} else {
|
|
valid = true;
|
|
}
|
|
|
|
if (valid) {
|
|
return super.getStateForNeighborUpdate(state, direction, newState, world, pos, posFrom);
|
|
} else {
|
|
return Blocks.AIR.getDefaultState();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public PistonBehavior getPistonBehavior(BlockState state) {
|
|
return PistonBehavior.BLOCK;
|
|
}
|
|
|
|
@Override
|
|
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
|
|
super.onEntityCollision(state, world, pos, entity);
|
|
|
|
World entityWorld = entity.getEntityWorld();
|
|
|
|
if (entityWorld == world && !entityWorld.isClient() && !entity.hasVehicle() && entity.canUsePortals() && VoxelShapes.matchesAnywhere(VoxelShapes.cuboid(entity.getBoundingBox().offset(-pos.getX(), -pos.getY(), -pos.getZ())), state.getOutlineShape(entityWorld, pos), BooleanBiFunction.AND)) {
|
|
boolean cooling = ((PortalCooldownEntity) entity).isEnergyPortalCooldown();
|
|
((PortalCooldownEntity) entity).resetEnergyPortalCooldown();
|
|
if (!cooling) {
|
|
EnergyTeleporter.teleport((ServerWorld) entityWorld, entity.getPos(), pos, entity);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@Environment(EnvType.CLIENT)
|
|
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
|
super.randomDisplayTick(state, world, pos, random);
|
|
|
|
if (random.nextInt(100) == 0) {
|
|
world.playSound((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.BLOCK_PORTAL_AMBIENT, SoundCategory.BLOCKS, 0.5f, random.nextFloat() * 0.4f + 0.8f, false);
|
|
}
|
|
}
|
|
}
|