WIP: portals
This commit is contained in:
parent
38a5f66a01
commit
446ca757b5
5 changed files with 164 additions and 92 deletions
|
@ -18,6 +18,7 @@ import net.minecraft.sound.SoundEvents;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
@ -28,7 +29,6 @@ import ru.betterend.interfaces.TeleportingEntity;
|
|||
import ru.betterend.registry.BlockTagRegistry;
|
||||
import ru.betterend.registry.ParticleRegistry;
|
||||
import ru.betterend.util.PortalFrameHelper;
|
||||
import ru.betterend.world.features.DefaultFeature;
|
||||
|
||||
public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable {
|
||||
public EndPortalBlock() {
|
||||
|
@ -91,16 +91,13 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
|||
private BlockPos findExitPos(ServerWorld world, BlockPos pos, Entity entity) {
|
||||
Registry<DimensionType> registry = world.getRegistryManager().getDimensionTypes();
|
||||
double mult = registry.get(DimensionType.THE_END_ID).getCoordinateScale();
|
||||
int topY;
|
||||
BlockPos.Mutable basePos;
|
||||
if (world.getRegistryKey().equals(World.OVERWORLD)) {
|
||||
basePos = pos.mutableCopy().set(pos.getX() / mult, pos.getY(), pos.getZ() / mult);
|
||||
topY = DefaultFeature.getPosOnSurface(world, basePos).getY();
|
||||
} else {
|
||||
basePos = pos.mutableCopy().set(pos.getX() * mult, pos.getY(), pos.getZ() * mult);
|
||||
topY = world.getHeight();
|
||||
}
|
||||
BlockPos top = basePos.mutableCopy().set(basePos.getX() + 32, topY, basePos.getZ() + 32);
|
||||
BlockPos top = basePos.mutableCopy().set(basePos.getX() + 32, world.getHeight(), basePos.getZ() + 32);
|
||||
BlockPos.Mutable bottom = basePos.mutableCopy().set(basePos.getX() - 32, 5, basePos.getZ() - 32);
|
||||
for(BlockPos position : BlockPos.iterate(bottom, top)) {
|
||||
BlockState state = world.getBlockState(position);
|
||||
|
@ -141,7 +138,7 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
|||
if (world.getRegistryKey().equals(World.END)) {
|
||||
ConfiguredFeatures.END_ISLAND.generate(world, world.getChunkManager().getChunkGenerator(), new Random(basePos.asLong()), basePos);
|
||||
} else {
|
||||
basePos.setY(topY);
|
||||
basePos.setY(world.getChunk(basePos).sampleHeightmap(Heightmap.Type.WORLD_SURFACE, basePos.getX(), basePos.getZ()));
|
||||
}
|
||||
PortalFrameHelper.generatePortalFrame(world, basePos, axis, true);
|
||||
if (axis.equals(Direction.Axis.X)) {
|
||||
|
|
|
@ -17,98 +17,107 @@ public class PortalFrameHelper {
|
|||
if (world == null || pos == null) return false;
|
||||
if (!world.getBlockState(pos).isOf(frameBlock)) return false;
|
||||
BlockPos bottomCorner = findBottomCorner(world, pos, frameBlock);
|
||||
if (bottomCorner == null) return false;
|
||||
BlockPos topCorner = findTopCorner(world, pos, frameBlock);
|
||||
if (bottomCorner == null || topCorner == null) return false;
|
||||
boolean valid = true;
|
||||
int width = 1, height = 1;
|
||||
Direction.Axis axis = Direction.Axis.X;
|
||||
BlockPos checkPos = bottomCorner.up();
|
||||
Direction moveDir = Direction.UP;
|
||||
while(!checkPos.equals(bottomCorner)) {
|
||||
while(valid && !checkPos.equals(bottomCorner)) {
|
||||
valid = world.getBlockState(checkPos).isOf(frameBlock);
|
||||
if (!valid) {
|
||||
switch(moveDir) {
|
||||
case UP: {
|
||||
checkPos = checkPos.down();
|
||||
if (world.getBlockState(checkPos.east()).isOf(frameBlock)) {
|
||||
checkPos = checkPos.east();
|
||||
moveDir = Direction.EAST;
|
||||
valid = true;
|
||||
} else if (world.getBlockState(checkPos.north()).isOf(frameBlock)) {
|
||||
axis = Direction.Axis.Z;
|
||||
checkPos = checkPos.north();
|
||||
moveDir = Direction.NORTH;
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DOWN: {
|
||||
checkPos = checkPos.up();
|
||||
if (world.getBlockState(checkPos.west()).isOf(frameBlock)) {
|
||||
checkPos = checkPos.west();
|
||||
moveDir = Direction.WEST;
|
||||
valid = true;
|
||||
} else if (world.getBlockState(checkPos.south()).isOf(frameBlock)) {
|
||||
checkPos = checkPos.south();
|
||||
moveDir = Direction.SOUTH;
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NORTH:
|
||||
case EAST: {
|
||||
checkPos = moveDir.equals(Direction.NORTH) ? checkPos.south() : checkPos.west();
|
||||
if (world.getBlockState(checkPos.down()).isOf(frameBlock)) {
|
||||
checkPos = checkPos.down();
|
||||
moveDir = Direction.DOWN;
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (!valid) return false;
|
||||
} else {
|
||||
switch(moveDir) {
|
||||
case UP: {
|
||||
checkPos = checkPos.up();
|
||||
break;
|
||||
}
|
||||
case DOWN: {
|
||||
checkPos = checkPos.down();
|
||||
break;
|
||||
}
|
||||
case NORTH: {
|
||||
checkPos = checkPos.north();
|
||||
break;
|
||||
}
|
||||
case SOUTH: {
|
||||
checkPos = checkPos.south();
|
||||
break;
|
||||
}
|
||||
case EAST: {
|
||||
while(valid && !checkPos.equals(bottomCorner)) {
|
||||
valid = world.getBlockState(checkPos).isOf(frameBlock);
|
||||
if (!valid) {
|
||||
switch(moveDir) {
|
||||
case UP: {
|
||||
checkPos = checkPos.down();
|
||||
if (world.getBlockState(checkPos.east()).isOf(frameBlock)) {
|
||||
checkPos = checkPos.east();
|
||||
break;
|
||||
moveDir = Direction.EAST;
|
||||
valid = true;
|
||||
} else if (world.getBlockState(checkPos.south()).isOf(frameBlock)) {
|
||||
axis = Direction.Axis.Z;
|
||||
checkPos = checkPos.south();
|
||||
moveDir = Direction.SOUTH;
|
||||
valid = true;
|
||||
}
|
||||
case WEST: {
|
||||
break;
|
||||
}
|
||||
case DOWN: {
|
||||
checkPos = checkPos.up();
|
||||
if (world.getBlockState(checkPos.west()).isOf(frameBlock)) {
|
||||
checkPos = checkPos.west();
|
||||
break;
|
||||
moveDir = Direction.WEST;
|
||||
valid = true;
|
||||
} else if (world.getBlockState(checkPos.north()).isOf(frameBlock)) {
|
||||
checkPos = checkPos.north();
|
||||
moveDir = Direction.NORTH;
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOUTH:
|
||||
case EAST: {
|
||||
checkPos = moveDir.equals(Direction.SOUTH) ? checkPos.north() : checkPos.west();
|
||||
if (world.getBlockState(checkPos.down()).isOf(frameBlock)) {
|
||||
checkPos = checkPos.down();
|
||||
moveDir = Direction.DOWN;
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (!valid) return false;
|
||||
} else {
|
||||
switch(moveDir) {
|
||||
case UP: {
|
||||
height++;
|
||||
checkPos = checkPos.up();
|
||||
break;
|
||||
}
|
||||
case DOWN: {
|
||||
checkPos = checkPos.down();
|
||||
break;
|
||||
}
|
||||
case NORTH: {
|
||||
checkPos = checkPos.north();
|
||||
break;
|
||||
}
|
||||
case SOUTH: {
|
||||
width++;
|
||||
checkPos = checkPos.south();
|
||||
break;
|
||||
}
|
||||
case EAST: {
|
||||
width++;
|
||||
checkPos = checkPos.east();
|
||||
break;
|
||||
}
|
||||
case WEST: {
|
||||
checkPos = checkPos.west();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (width < 4 || height < 5 || width > 40 || height > 40) return false;
|
||||
if (axis.equals(Direction.Axis.X)) {
|
||||
if(!checkIsAreaEmpty(world, bottomCorner.add(1, 1, 0), topCorner.add(-1, -1, 0))) return false;
|
||||
} else {
|
||||
if(!checkIsAreaEmpty(world, bottomCorner.add(0, 1, 1), topCorner.add(0, -1, -1))) return false;
|
||||
}
|
||||
if (valid) {
|
||||
if (world.getBlockState(bottomCorner).isOf(BlockRegistry.FLAVOLITE_RUNED)) {
|
||||
generatePortalFrame(world, bottomCorner, axis, true);
|
||||
generatePortalFrame(world, bottomCorner, axis, width, height, true);
|
||||
} else {
|
||||
generateEternalPortalFrame(world, bottomCorner, axis, true);
|
||||
generateEternalPortalFrame(world, bottomCorner, axis, width, height, true);
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
private static BlockPos findBottomCorner(World world, BlockPos pos, Block frameBlock) {
|
||||
public static BlockPos findBottomCorner(World world, BlockPos pos, Block frameBlock) {
|
||||
BlockState up = world.getBlockState(pos.up());
|
||||
BlockState down = world.getBlockState(pos.down());
|
||||
BlockState north = world.getBlockState(pos.north());
|
||||
|
@ -116,30 +125,79 @@ public class PortalFrameHelper {
|
|||
BlockState west = world.getBlockState(pos.west());
|
||||
BlockState east = world.getBlockState(pos.east());
|
||||
if (up.isOf(frameBlock) && !down.isOf(frameBlock)) {
|
||||
if (north.isOf(frameBlock) || east.isOf(frameBlock)) {
|
||||
if (south.isOf(frameBlock) || east.isOf(frameBlock)) {
|
||||
return pos;
|
||||
} else if (west.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, pos.west(), frameBlock);
|
||||
} else if (south.isOf(frameBlock)){
|
||||
return findBottomCorner(world, pos.south(), frameBlock);
|
||||
} else if (north.isOf(frameBlock)){
|
||||
return findBottomCorner(world, pos.north(), frameBlock);
|
||||
}
|
||||
return null;
|
||||
} else if (down.isOf(frameBlock)) {
|
||||
if (west.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, pos.west(), frameBlock);
|
||||
} else if (south.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, pos.south(), frameBlock);
|
||||
} else if (north.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, pos.north(), frameBlock);
|
||||
} else {
|
||||
return findBottomCorner(world, pos.down(), frameBlock);
|
||||
}
|
||||
} else if (west.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, pos.west(), frameBlock);
|
||||
} else if (south.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, pos.south(), frameBlock);
|
||||
} else if (north.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, pos.north(), frameBlock);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BlockPos findTopCorner(World world, BlockPos pos, Block frameBlock) {
|
||||
BlockState up = world.getBlockState(pos.up());
|
||||
BlockState down = world.getBlockState(pos.down());
|
||||
BlockState north = world.getBlockState(pos.north());
|
||||
BlockState south = world.getBlockState(pos.south());
|
||||
BlockState west = world.getBlockState(pos.west());
|
||||
BlockState east = world.getBlockState(pos.east());
|
||||
if (!up.isOf(frameBlock) && down.isOf(frameBlock)) {
|
||||
if (north.isOf(frameBlock) || west.isOf(frameBlock)) {
|
||||
return pos;
|
||||
} else if (east.isOf(frameBlock)) {
|
||||
return findTopCorner(world, pos.east(), frameBlock);
|
||||
} else if (south.isOf(frameBlock)){
|
||||
return findTopCorner(world, pos.south(), frameBlock);
|
||||
}
|
||||
return null;
|
||||
} else if (up.isOf(frameBlock)) {
|
||||
if (east.isOf(frameBlock)) {
|
||||
return findTopCorner(world, pos.east(), frameBlock);
|
||||
} else if (south.isOf(frameBlock)){
|
||||
return findTopCorner(world, pos.south(), frameBlock);
|
||||
} else {
|
||||
return findTopCorner(world, pos.up(), frameBlock);
|
||||
}
|
||||
} else if (east.isOf(frameBlock)) {
|
||||
return findTopCorner(world, pos.east(), frameBlock);
|
||||
} else if (south.isOf(frameBlock)){
|
||||
return findTopCorner(world, pos.south(), frameBlock);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean checkIsAreaEmpty(World world, BlockPos bottom, BlockPos top) {
|
||||
boolean valid = true;
|
||||
for (BlockPos current : BlockPos.iterate(bottom, top)) {
|
||||
BlockState state = world.getBlockState(current);
|
||||
valid &= state.isAir();
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
public static void generatePortalFrame(ServerWorld world, BlockPos pos, Direction.Axis axis, int width, int height, boolean active) {
|
||||
FeatureRegistry.END_PORTAL.configure(axis, width, height, active).getFeatureConfigured().generate(world, world.getChunkManager().getChunkGenerator(), new Random(), pos);
|
||||
}
|
||||
|
||||
public static void generateEternalPortalFrame(ServerWorld world, BlockPos pos, Direction.Axis axis, int width, int height, boolean active) {
|
||||
FeatureRegistry.END_PORTAL_ETERNAL.configure(axis, width, height, active).getFeatureConfigured().generate(world, world.getChunkManager().getChunkGenerator(), new Random(), pos);
|
||||
}
|
||||
|
||||
public static void generatePortalFrame(ServerWorld world, BlockPos pos, Direction.Axis axis, boolean active) {
|
||||
FeatureRegistry.END_PORTAL.configure(axis, active).getFeatureConfigured().generate(world, world.getChunkManager().getChunkGenerator(), new Random(), pos);
|
||||
}
|
||||
|
|
|
@ -27,10 +27,12 @@ public class DefaultEndPortalFeature extends Feature<EndPortalFeatureConfig> {
|
|||
BlockState portalBlock = BlockRegistry.END_PORTAL_BLOCK.getDefaultState().with(EndPortalBlock.AXIS, config.axis);
|
||||
BlockPos bottomCorner = pos;
|
||||
BlockPos topCorner;
|
||||
int width = config.width - 1;
|
||||
int height = config.height - 1;
|
||||
if (config.axis.equals(Direction.Axis.X)) {
|
||||
topCorner = bottomCorner.add(3, 4, 0);
|
||||
topCorner = bottomCorner.add(width, height, 0);
|
||||
} else {
|
||||
topCorner = bottomCorner.add(0, 4, 3);
|
||||
topCorner = bottomCorner.add(0, height, width);
|
||||
}
|
||||
|
||||
for(BlockPos position : BlockPos.iterate(bottomCorner, topCorner)) {
|
||||
|
|
|
@ -14,8 +14,13 @@ public class EndPortalFeature extends EndFeature {
|
|||
this.frameBlock = frameBlock;
|
||||
}
|
||||
|
||||
public EndPortalFeature configure(Direction.Axis axis, int width, int height, boolean active) {
|
||||
this.featureConfigured = ((DefaultEndPortalFeature) this.feature).configure(EndPortalFeatureConfig.create(frameBlock, axis, width, height, active));
|
||||
return this;
|
||||
}
|
||||
|
||||
public EndPortalFeature configure(Direction.Axis axis, boolean active) {
|
||||
this.featureConfigured = ((DefaultEndPortalFeature) this.feature).configure(EndPortalFeatureConfig.create(frameBlock, axis, active));
|
||||
this.featureConfigured = ((DefaultEndPortalFeature) this.feature).configure(EndPortalFeatureConfig.create(frameBlock, axis, 4, 5, active));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@ public class EndPortalFeatureConfig implements FeatureConfig {
|
|||
return Registry.BLOCK.getId(endPortalFeatureConfig.frameBlock).toString();
|
||||
}), Codec.STRING.fieldOf("axis").forGetter(endPortalFeatureConfig -> {
|
||||
return endPortalFeatureConfig.axis.getName();
|
||||
}), Codec.INT.fieldOf("width").forGetter(endPortalFeatureConfig -> {
|
||||
return endPortalFeatureConfig.width;
|
||||
}), Codec.INT.fieldOf("heigth").forGetter(endPortalFeatureConfig -> {
|
||||
return endPortalFeatureConfig.height;
|
||||
}), Codec.BOOL.fieldOf("activated").forGetter(endPortalFeatureConfig -> {
|
||||
return endPortalFeatureConfig.activated;
|
||||
})).apply(instance, EndPortalFeatureConfig::new);
|
||||
|
@ -23,20 +27,26 @@ public class EndPortalFeatureConfig implements FeatureConfig {
|
|||
public final RunedFlavolite frameBlock;
|
||||
public final Direction.Axis axis;
|
||||
public final boolean activated;
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
private EndPortalFeatureConfig(String frameBlock, String axis, boolean active) {
|
||||
private EndPortalFeatureConfig(String frameBlock, String axis, int width, int height, boolean active) {
|
||||
this.frameBlock = (RunedFlavolite) Registry.BLOCK.get(new Identifier(frameBlock));
|
||||
this.axis = Direction.Axis.fromName(axis);
|
||||
this.activated = active;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
private EndPortalFeatureConfig(RunedFlavolite frameBlock, Direction.Axis axis, boolean active) {
|
||||
private EndPortalFeatureConfig(RunedFlavolite frameBlock, Direction.Axis axis, int width, int height, boolean active) {
|
||||
this.frameBlock = frameBlock;
|
||||
this.axis = axis;
|
||||
this.activated = active;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public static EndPortalFeatureConfig create(RunedFlavolite block, Direction.Axis axis, boolean active) {
|
||||
return new EndPortalFeatureConfig(block, axis, active);
|
||||
public static EndPortalFeatureConfig create(RunedFlavolite block, Direction.Axis axis, int width, int height, boolean active) {
|
||||
return new EndPortalFeatureConfig(block, axis, width, height, active);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue