This repository has been archived on 2023-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
EnergonRelics/src/main/java/com/thebrokenrail/energonrelics/block/portal/EnergyPortalBlock.java

159 lines
6.3 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.ShapeContext;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.entity.Entity;
import net.minecraft.server.world.ServerWorld;
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.copy(Blocks.NETHER_PORTAL).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);
if (!world.isClient() && !entity.hasVehicle() && entity.canUsePortals() && !((PortalCooldownEntity) entity).isEnergyPortalCooldown() && VoxelShapes.matchesAnywhere(VoxelShapes.cuboid(entity.getBoundingBox().offset(-pos.getX(), -pos.getY(), -pos.getZ())), state.getOutlineShape(world, pos), BooleanBiFunction.AND)) {
((PortalCooldownEntity) entity).resetEnergyPortalCooldown();
EnergyTeleporter.teleport((ServerWorld) world, 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);
}
}
}