use of com.qouteall.immersive_portals.my_util.IntegerAABBInclusive in project ImmersivePortalsMod by qouteall.
the class NewNetherPortalGenerator method onFireLit.
// return null for not found
// executed on main server thread
public static boolean onFireLit(ServerWorld fromWorld, BlockPos firePos) {
DimensionType fromDimension = fromWorld.dimension.getType();
DimensionType toDimension = NetherPortalGenerator.getDestinationDimension(fromDimension);
if (toDimension == null)
return false;
NetherPortalShape foundShape = Arrays.stream(Direction.Axis.values()).map(axis -> NetherPortalShape.findArea(firePos, axis, blockPos -> NetherPortalMatcher.isAirOrFire(fromWorld, blockPos), blockPos -> NetherPortalMatcher.isObsidian(fromWorld, blockPos))).filter(Objects::nonNull).findFirst().orElse(null);
if (foundShape == null) {
return false;
}
NetherPortalShape fromShape = foundShape;
ServerWorld toWorld = McHelper.getServer().getWorld(toDimension);
BlockPos fromPos = fromShape.innerAreaBox.getCenter();
boolean isOtherGenerationRunning = McHelper.getEntitiesNearby(fromWorld, new Vec3d(fromPos), LoadingIndicatorEntity.class, 1).findAny().isPresent();
if (isOtherGenerationRunning) {
return false;
}
BlockPos toPos = NetherPortalGenerator.getPosInOtherDimension(fromPos, fromWorld.dimension.getType(), toWorld.dimension.getType());
// avoid blockpos object creation
BlockPos.Mutable temp = new BlockPos.Mutable();
IntegerAABBInclusive toWorldHeightLimit = NetherPortalMatcher.getHeightLimit(toWorld.dimension.getType());
Iterator<NetherPortalShape> iterator = NetherPortalMatcher.fromNearToFarWithinHeightLimit(toPos, 150, toWorldHeightLimit).map(blockPos -> {
if (!toWorld.isAir(blockPos)) {
return null;
}
return fromShape.matchShape(toWorld::isAir, p -> NetherPortalMatcher.isObsidian(toWorld, p), blockPos, temp);
}).iterator();
LoadingIndicatorEntity indicatorEntity = LoadingIndicatorEntity.entityType.create(fromWorld);
indicatorEntity.isAlive = true;
indicatorEntity.setPosition(fromPos.getX() + 0.5, fromPos.getY() + 0.5, fromPos.getZ() + 0.5);
fromWorld.spawnEntity(indicatorEntity);
McHelper.performSplitedFindingTaskOnServer(iterator, Objects::nonNull, (i) -> {
boolean isIntact = recheckTheFrameThatIsBeingLighted(fromWorld, fromShape);
if ((!isIntact)) {
Helper.log("Nether Portal Generation Aborted");
indicatorEntity.remove();
return false;
}
double progress = i / 20000000.0;
indicatorEntity.setText("Searching for matched obsidian frame on the other side\n" + (int) (progress * 100) + "%");
return true;
}, toShape -> {
finishGeneratingPortal(new Info(fromDimension, toDimension, fromShape, toShape));
}, () -> {
indicatorEntity.setText("Existing frame could not be found.\n" + "Generating new portal");
ModMain.serverTaskList.addTask(() -> {
IntegerAABBInclusive airCubePlacement = NetherPortalGenerator.findAirCubePlacement(toWorld, toPos, toWorldHeightLimit, fromShape.axis, fromShape.totalAreaBox.getSize());
NetherPortalShape toShape = fromShape.getShapeWithMovedAnchor(airCubePlacement.l.subtract(fromShape.totalAreaBox.l).add(fromShape.anchor));
toShape.frameAreaWithCorner.forEach(blockPos -> toWorld.setBlockState(blockPos, Blocks.OBSIDIAN.getDefaultState()));
finishGeneratingPortal(new Info(fromDimension, toDimension, fromShape, toShape));
return true;
});
});
return true;
}
use of com.qouteall.immersive_portals.my_util.IntegerAABBInclusive in project ImmersivePortalsMod by qouteall.
the class NetherPortalMatcher method findEmptyObsidianFrame.
// ------------------------------------------------------------
// detect existing obsidian frame
// @Nullable
public static ObsidianFrame findEmptyObsidianFrame(IWorld world, BlockPos searchingCenter, Direction.Axis normalAxis, Predicate<IntegerAABBInclusive> filter, int findingRadius) {
Pair<Direction.Axis, Direction.Axis> anotherTwoAxis = Helper.getAnotherTwoAxis(normalAxis);
Direction roughTestObsidianFace1 = Direction.get(Direction.AxisDirection.POSITIVE, anotherTwoAxis.getLeft());
Direction roughTestObsidianFace2 = Direction.get(Direction.AxisDirection.POSITIVE, anotherTwoAxis.getRight());
Optional<ObsidianFrame> result = fromNearToFarWithinHeightLimit(searchingCenter, findingRadius, heightLimitOverworld).filter(blockPos -> isAirOnObsidian(world, blockPos, roughTestObsidianFace1, roughTestObsidianFace2)).map(blockPos -> detectFrameFromInnerPos(world, blockPos, normalAxis, filter)).filter(Objects::nonNull).findFirst();
return result.orElse(null);
}
use of com.qouteall.immersive_portals.my_util.IntegerAABBInclusive in project ImmersivePortalsMod by qouteall.
the class NetherPortalMatcher method detectStick.
// @Nullable
private static IntegerAABBInclusive detectStick(IWorld world, BlockPos center, Direction.Axis axis, Predicate<BlockPos> predicate, int minLength) {
BlockPos lowExtremity = detectStickForOneDirection(center, Direction.get(Direction.AxisDirection.NEGATIVE, axis), predicate);
if (lowExtremity == null) {
return null;
}
BlockPos highExtremity = detectStickForOneDirection(center, Direction.get(Direction.AxisDirection.POSITIVE, axis), predicate);
if (highExtremity == null) {
return null;
}
int stickLength = Math.abs(Helper.getCoordinate(lowExtremity, axis) - Helper.getCoordinate(highExtremity, axis));
if (stickLength < minLength) {
return null;
}
return new IntegerAABBInclusive(lowExtremity, highExtremity);
}
use of com.qouteall.immersive_portals.my_util.IntegerAABBInclusive in project ImmersivePortalsMod by qouteall.
the class NetherPortalMatcher method detectFrameFromInnerPos.
// return null for no legal obsidian frame
public static ObsidianFrame detectFrameFromInnerPos(IWorld world, BlockPos innerPos, Direction.Axis normalAxis, Predicate<IntegerAABBInclusive> innerAreaFilter) {
if (!isAirOrFire(world, innerPos)) {
return null;
}
Pair<Direction.Axis, Direction.Axis> anotherTwoAxis = Helper.getAnotherTwoAxis(normalAxis);
IntegerAABBInclusive innerArea = detectInnerArea(world, innerPos, normalAxis, anotherTwoAxis);
if (innerArea == null) {
return null;
}
if (!innerAreaFilter.test(innerArea)) {
return null;
}
if (!isObsidianFrameIntact(world, normalAxis, innerArea)) {
return null;
}
return new ObsidianFrame(normalAxis, innerArea);
}
use of com.qouteall.immersive_portals.my_util.IntegerAABBInclusive in project ImmersivePortalsMod by qouteall.
the class NetherPortalMatcher method detectInnerArea.
private static IntegerAABBInclusive detectInnerArea(IWorld world, BlockPos innerPos, Direction.Axis normalAxis, Pair<Direction.Axis, Direction.Axis> anotherTwoAxis) {
IntegerAABBInclusive stick1 = detectStick(world, innerPos, anotherTwoAxis.getLeft(), blockPos -> isAirOrFire(world, blockPos), 1);
if (stick1 == null)
return null;
IntegerAABBInclusive stick2 = detectStick(world, innerPos, anotherTwoAxis.getRight(), blockPos -> isAirOrFire(world, blockPos), 1);
if (stick2 == null)
return null;
IntegerAABBInclusive innerArea = IntegerAABBInclusive.getContainingBox(stick1, stick2);
assert Math.abs(Helper.getCoordinate(innerArea.getSize(), normalAxis)) == 1;
// check inner air
if (!innerArea.stream().allMatch(blockPos -> isAirOrFire(world, blockPos))) {
return null;
}
return innerArea;
}
Aggregations