Portal fixes and optimization
This commit is contained in:
parent
81e4098a72
commit
31f057eca5
11 changed files with 151 additions and 471 deletions
|
@ -18,18 +18,14 @@ 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;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeatures;
|
||||
|
||||
import ru.betterend.client.render.ERenderLayer;
|
||||
import ru.betterend.interfaces.IRenderTypeable;
|
||||
import ru.betterend.interfaces.TeleportingEntity;
|
||||
import ru.betterend.registry.EndParticles;
|
||||
import ru.betterend.registry.EndTags;
|
||||
import ru.betterend.util.EternalRitual;
|
||||
|
||||
public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable {
|
||||
public EndPortalBlock() {
|
||||
|
@ -71,15 +67,18 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
|||
if (world instanceof ServerWorld && entity instanceof LivingEntity && !entity.hasVehicle() && !entity.hasPassengers() && entity.canUsePortals()) {
|
||||
TeleportingEntity teleEntity = TeleportingEntity.class.cast(entity);
|
||||
if (teleEntity.hasCooldown()) return;
|
||||
teleEntity.beSetCooldown(300);
|
||||
boolean isOverworld = world.getRegistryKey().equals(World.OVERWORLD);
|
||||
ServerWorld destination = ((ServerWorld) world).getServer().getWorld(isOverworld ? World.END : World.OVERWORLD);
|
||||
BlockPos exitPos = this.findExitPos(destination, pos, entity);
|
||||
if (exitPos == null) return;
|
||||
if (entity instanceof ServerPlayerEntity) {
|
||||
((ServerPlayerEntity) entity).teleport(destination, exitPos.getX(), exitPos.getY(), exitPos.getZ(), entity.yaw, entity.pitch);
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) entity;
|
||||
player.teleport(destination, exitPos.getX(), exitPos.getY(), exitPos.getZ(), entity.yaw, entity.pitch);
|
||||
teleEntity.beSetCooldown(player.isCreative() ? 50 : 300);
|
||||
} else {
|
||||
teleEntity.beSetExitPos(exitPos);
|
||||
entity.moveToWorld(destination);
|
||||
teleEntity.beSetCooldown(300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,89 +97,26 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
|||
} else {
|
||||
basePos = pos.mutableCopy().set(pos.getX() * mult, pos.getY(), pos.getZ() * mult);
|
||||
}
|
||||
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);
|
||||
if(state.isOf(this)) {
|
||||
if (state.get(AXIS).equals(Direction.Axis.X)) {
|
||||
return position.add(0, 0, 1);
|
||||
} else {
|
||||
return position.add(1, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
bottom.setY(basePos.getY());
|
||||
Direction.Axis axis = entity.getMovementDirection().getAxis();
|
||||
if (checkIsAreaValid(world, bottom, axis)) {
|
||||
EternalRitual.generatePortal(world, bottom, axis);
|
||||
if (axis.equals(Direction.Axis.X)) {
|
||||
return bottom.add(0, 1, 1);
|
||||
} else {
|
||||
return bottom.add(1, 1, 0);
|
||||
}
|
||||
} else {
|
||||
if (bottom.getY() > top.getY()) {
|
||||
BlockPos buff = bottom;
|
||||
bottom = top.mutableCopy();
|
||||
top = buff;
|
||||
}
|
||||
for(BlockPos position : BlockPos.iterate(bottom, top)) {
|
||||
if (checkIsAreaValid(world, position, axis)) {
|
||||
EternalRitual.generatePortal(world, position, axis);
|
||||
if (axis.equals(Direction.Axis.X)) {
|
||||
return position.add(0, 1, 1);
|
||||
} else {
|
||||
return position.add(1, 1, 0);
|
||||
Direction direction = Direction.EAST;
|
||||
BlockPos.Mutable checkPos = basePos.mutableCopy();
|
||||
for (int step = 1; step < 64; step++) {
|
||||
for (int i = 0; i < step; i++) {
|
||||
checkPos.setY(5);
|
||||
while(checkPos.getY() < world.getHeight()) {
|
||||
BlockState state = world.getBlockState(checkPos);
|
||||
if(state.isOf(this)) {
|
||||
if (state.get(AXIS).equals(Direction.Axis.X)) {
|
||||
return checkPos.add(0, 0, 1);
|
||||
} else {
|
||||
return checkPos.add(1, 0, 0);
|
||||
}
|
||||
}
|
||||
checkPos.move(Direction.UP);
|
||||
}
|
||||
checkPos.move(direction);
|
||||
}
|
||||
direction = direction.rotateYClockwise();
|
||||
}
|
||||
if (world.getRegistryKey().equals(World.END)) {
|
||||
ConfiguredFeatures.END_ISLAND.generate(world, world.getChunkManager().getChunkGenerator(), new Random(basePos.asLong()), basePos);
|
||||
} else {
|
||||
basePos.setY(world.getChunk(basePos).sampleHeightmap(Heightmap.Type.WORLD_SURFACE, basePos.getX(), basePos.getZ()));
|
||||
}
|
||||
EternalRitual.generatePortal(world, basePos, axis);
|
||||
if (axis.equals(Direction.Axis.X)) {
|
||||
return basePos.add(0, 1, 1);
|
||||
} else {
|
||||
return basePos.add(1, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkIsAreaValid(World world, BlockPos pos, Direction.Axis axis) {
|
||||
if (!isBaseValid(world, pos, axis)) return false;
|
||||
return EternalRitual.checkArea(world, pos, axis);
|
||||
}
|
||||
|
||||
private boolean isBaseValid(World world, BlockPos pos, Direction.Axis axis) {
|
||||
boolean solid = true;
|
||||
if (axis.equals(Direction.Axis.X)) {
|
||||
pos = pos.down().add(0, 0, -3);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
BlockPos checkPos = pos.add(0, 0, i);
|
||||
BlockState state = world.getBlockState(checkPos);
|
||||
solid &= this.validBlock(world, checkPos, state);
|
||||
}
|
||||
} else {
|
||||
pos = pos.down().add(-3, 0, 0);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
BlockPos checkPos = pos.add(i, 0, 0);
|
||||
BlockState state = world.getBlockState(checkPos);
|
||||
solid &= this.validBlock(world, checkPos, state);
|
||||
}
|
||||
}
|
||||
return solid;
|
||||
}
|
||||
|
||||
private boolean validBlock(World world, BlockPos pos, BlockState state) {
|
||||
BlockState surfaceBlock = world.getBiome(pos).getGenerationSettings().getSurfaceConfig().getTopMaterial();
|
||||
return state.isSolidBlock(world, pos) &&
|
||||
(EndTags.validGenBlock(state) ||
|
||||
state.isOf(surfaceBlock.getBlock()) ||
|
||||
state.isOf(Blocks.STONE) ||
|
||||
state.isOf(Blocks.SAND) ||
|
||||
state.isOf(Blocks.GRAVEL));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,9 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
|
||||
import ru.betterend.blocks.basis.BlockBase;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
import ru.betterend.util.PortalFrameHelper;
|
||||
|
||||
public class RunedFlavolite extends BlockBase {
|
||||
public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVATED;
|
||||
|
@ -30,20 +25,4 @@ public class RunedFlavolite extends BlockBase {
|
|||
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
|
||||
stateManager.add(ACTIVATED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroken(WorldAccess world, BlockPos pos, BlockState state) {
|
||||
BlockPos bottom = PortalFrameHelper.findBottomCorner((World) world, pos, this);
|
||||
BlockPos top = PortalFrameHelper.findTopCorner((World) world, pos, this);
|
||||
if (bottom == null || top == null) return;
|
||||
for (BlockPos position : BlockPos.iterate(bottom, top)) {
|
||||
if (position.equals(pos)) continue;
|
||||
BlockState posState = world.getBlockState(position);
|
||||
if (posState.getBlock() instanceof RunedFlavolite && posState.get(ACTIVATED)) {
|
||||
BlocksHelper.setWithoutUpdate(world, position, posState.with(ACTIVATED, false));
|
||||
} else if (posState.isOf(EndBlocks.END_PORTAL_BLOCK)) {
|
||||
world.removeBlock(position, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
|||
import net.minecraft.util.Tickable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import ru.betterend.registry.EndBlockEntities;
|
||||
import ru.betterend.util.EternalRitual;
|
||||
|
||||
|
|
|
@ -1,34 +1,11 @@
|
|||
package ru.betterend.item;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import ru.betterend.blocks.RunedFlavolite;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndItems;
|
||||
import ru.betterend.util.PortalFrameHelper;
|
||||
|
||||
public class EternalCrystal extends Item {
|
||||
|
||||
public EternalCrystal() {
|
||||
super(EndItems.makeSettings());
|
||||
}
|
||||
|
||||
public ActionResult useOnBlock(ItemUsageContext context) {
|
||||
World world = context.getWorld();
|
||||
if (world.isClient) return ActionResult.CONSUME;
|
||||
BlockPos usedPos = context.getBlockPos();
|
||||
BlockState usedBlock = world.getBlockState(usedPos);
|
||||
if (usedBlock.isOf(EndBlocks.FLAVOLITE_RUNED) && !usedBlock.get(RunedFlavolite.ACTIVATED)) {
|
||||
if (PortalFrameHelper.checkPortalFrame((ServerWorld) world, usedPos, usedBlock.getBlock())) {
|
||||
context.getStack().decrement(1);
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,17 +9,15 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import ru.betterend.blocks.RunedFlavolite;
|
||||
|
||||
import ru.betterend.world.features.BlueVineFeature;
|
||||
import ru.betterend.world.features.CavePlantFeature;
|
||||
import ru.betterend.world.features.DefaultEndPortalFeature;
|
||||
import ru.betterend.world.features.DoublePlantFeature;
|
||||
import ru.betterend.world.features.EndFeature;
|
||||
import ru.betterend.world.features.EndLakeFeature;
|
||||
import ru.betterend.world.features.EndLilyFeature;
|
||||
import ru.betterend.world.features.EndLotusFeature;
|
||||
import ru.betterend.world.features.EndLotusLeafFeature;
|
||||
import ru.betterend.world.features.EndPortalFeature;
|
||||
import ru.betterend.world.features.EternalPortalFeature;
|
||||
import ru.betterend.world.features.LacugroveFeature;
|
||||
import ru.betterend.world.features.MossyGlowshroomFeature;
|
||||
|
@ -68,9 +66,6 @@ public class EndFeatures {
|
|||
public static final EndFeature FLAVOLITE_LAYER = EndFeature.makeLayerFeature("flavolite_layer", EndBlocks.FLAVOLITE, 12, 4, 96, 6);
|
||||
|
||||
// Other //
|
||||
public static final EndPortalFeature END_PORTAL = new EndPortalFeature(new DefaultEndPortalFeature(), (RunedFlavolite) EndBlocks.FLAVOLITE_RUNED);
|
||||
public static final EndPortalFeature END_PORTAL_ETERNAL = new EndPortalFeature(new DefaultEndPortalFeature(), (RunedFlavolite) EndBlocks.FLAVOLITE_RUNED_ETERNAL);
|
||||
|
||||
public static final EndFeature ETERNAL_PORTAL = EndFeature.makeChansedFeature("eternal_portal", new EternalPortalFeature(), 500);
|
||||
|
||||
public static void registerBiomeFeatures(Identifier id, Biome biome, List<List<Supplier<ConfiguredFeature<?, ?>>>> features) {
|
||||
|
|
|
@ -7,18 +7,24 @@ import com.google.common.collect.Sets;
|
|||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.state.property.BooleanProperty;
|
||||
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.dimension.DimensionType;
|
||||
import ru.betterend.blocks.BlockProperties;
|
||||
import ru.betterend.blocks.EndPortalBlock;
|
||||
import ru.betterend.blocks.RunedFlavolite;
|
||||
import ru.betterend.blocks.entities.PedestalBlockEntity;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndTags;
|
||||
|
||||
public class EternalRitual {
|
||||
private final static Set<Point> structureMap = Sets.newHashSet(
|
||||
|
@ -47,6 +53,7 @@ public class EternalRitual {
|
|||
private World world;
|
||||
private Direction.Axis axis;
|
||||
private BlockPos center;
|
||||
private BlockPos exit;
|
||||
private boolean active = false;
|
||||
|
||||
public EternalRitual(World world) {
|
||||
|
@ -66,8 +73,13 @@ public class EternalRitual {
|
|||
this.world = world;
|
||||
}
|
||||
|
||||
private boolean isValid() {
|
||||
return world != null && !world.isClient() &&
|
||||
center != null && axis != null;
|
||||
}
|
||||
|
||||
public void checkStructure() {
|
||||
if (center == null || axis == null) return;
|
||||
if (!isValid()) return;
|
||||
Direction moveX, moveY;
|
||||
if (Direction.Axis.X == axis) {
|
||||
moveX = Direction.EAST;
|
||||
|
@ -108,18 +120,29 @@ public class EternalRitual {
|
|||
|
||||
private void activatePortal() {
|
||||
if (active) return;
|
||||
this.activatePortal(world, center);
|
||||
if (exit == null) {
|
||||
this.exit = this.findPortalPos();
|
||||
} else {
|
||||
World overworld = world.getServer().getWorld(World.OVERWORLD);
|
||||
this.activatePortal(overworld, exit);
|
||||
}
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
private void activatePortal(World world, BlockPos center) {
|
||||
BlockPos framePos = center.down();
|
||||
Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH: Direction.EAST;
|
||||
BlockState frame = FRAME.getDefaultState().with(ACTIVE, true);
|
||||
frameMap.forEach(point -> {
|
||||
BlockPos pos = framePos.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!state.get(ACTIVE)) {
|
||||
if (state.contains(ACTIVE) && !state.get(ACTIVE)) {
|
||||
world.setBlockState(pos, frame);
|
||||
}
|
||||
pos = framePos.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||
state = world.getBlockState(pos);
|
||||
if (!state.get(ACTIVE)) {
|
||||
if (state.contains(ACTIVE) && !state.get(ACTIVE)) {
|
||||
world.setBlockState(pos, frame);
|
||||
}
|
||||
});
|
||||
|
@ -135,11 +158,16 @@ public class EternalRitual {
|
|||
world.setBlockState(pos, portal);
|
||||
}
|
||||
});
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
public void removePortal() {
|
||||
if (!active) return;
|
||||
if (!active || !isValid()) return;
|
||||
World overworld = world.getServer().getWorld(World.OVERWORLD);
|
||||
this.removePortal(world, center);
|
||||
this.removePortal(overworld, exit);
|
||||
}
|
||||
|
||||
private void removePortal(World world, BlockPos center) {
|
||||
BlockPos framePos = center.down();
|
||||
Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH: Direction.EAST;
|
||||
frameMap.forEach(point -> {
|
||||
|
@ -167,9 +195,89 @@ public class EternalRitual {
|
|||
this.active = false;
|
||||
}
|
||||
|
||||
private BlockPos findPortalPos() {
|
||||
MinecraftServer server = world.getServer();
|
||||
ServerWorld overworld = server.getWorld(World.OVERWORLD);
|
||||
Registry<DimensionType> registry = server.getRegistryManager().getDimensionTypes();
|
||||
double mult = registry.get(DimensionType.THE_END_ID).getCoordinateScale();
|
||||
BlockPos.Mutable basePos = center.mutableCopy().set(center.getX() / mult, center.getY(), center.getZ() / mult);
|
||||
Direction.Axis portalAxis = Direction.Axis.X == axis ? Direction.Axis.Z : Direction.Axis.X;
|
||||
if (checkIsAreaValid(overworld, basePos, portalAxis)) {
|
||||
EternalRitual.generatePortal(overworld, basePos, portalAxis);
|
||||
if (portalAxis.equals(Direction.Axis.X)) {
|
||||
return basePos.toImmutable();
|
||||
} else {
|
||||
return basePos.toImmutable();
|
||||
}
|
||||
} else {
|
||||
Direction direction = Direction.EAST;
|
||||
BlockPos.Mutable checkPos = basePos.mutableCopy();
|
||||
for (int step = 1; step < 64; step++) {
|
||||
for (int i = 0; i < step; i++) {
|
||||
checkPos.setY(5);
|
||||
while(checkPos.getY() < world.getHeight()) {
|
||||
if(checkIsAreaValid(overworld, checkPos, portalAxis)) {
|
||||
EternalRitual.generatePortal(overworld, checkPos, portalAxis);
|
||||
if (portalAxis.equals(Direction.Axis.X)) {
|
||||
return checkPos.toImmutable();
|
||||
} else {
|
||||
return checkPos.toImmutable();
|
||||
}
|
||||
}
|
||||
checkPos.move(Direction.UP);
|
||||
}
|
||||
checkPos.move(direction);
|
||||
}
|
||||
direction = direction.rotateYClockwise();
|
||||
}
|
||||
}
|
||||
basePos.setY(overworld.getChunk(basePos).sampleHeightmap(Heightmap.Type.WORLD_SURFACE, basePos.getX(), basePos.getZ()));
|
||||
EternalRitual.generatePortal(overworld, basePos, portalAxis);
|
||||
if (portalAxis.equals(Direction.Axis.X)) {
|
||||
return basePos.toImmutable();
|
||||
} else {
|
||||
return basePos.toImmutable();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkIsAreaValid(World world, BlockPos pos, Direction.Axis axis) {
|
||||
if (!isBaseValid(world, pos, axis)) return false;
|
||||
return EternalRitual.checkArea(world, pos, axis);
|
||||
}
|
||||
|
||||
private boolean isBaseValid(World world, BlockPos pos, Direction.Axis axis) {
|
||||
boolean solid = true;
|
||||
if (axis.equals(Direction.Axis.X)) {
|
||||
pos = pos.down().add(0, 0, -3);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
BlockPos checkPos = pos.add(0, 0, i);
|
||||
BlockState state = world.getBlockState(checkPos);
|
||||
solid &= this.validBlock(world, checkPos, state);
|
||||
}
|
||||
} else {
|
||||
pos = pos.down().add(-3, 0, 0);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
BlockPos checkPos = pos.add(i, 0, 0);
|
||||
BlockState state = world.getBlockState(checkPos);
|
||||
solid &= this.validBlock(world, checkPos, state);
|
||||
}
|
||||
}
|
||||
return solid;
|
||||
}
|
||||
|
||||
private boolean validBlock(World world, BlockPos pos, BlockState state) {
|
||||
BlockState surfaceBlock = world.getBiome(pos).getGenerationSettings().getSurfaceConfig().getTopMaterial();
|
||||
return state.isSolidBlock(world, pos) &&
|
||||
(EndTags.validGenBlock(state) ||
|
||||
state.isOf(surfaceBlock.getBlock()) ||
|
||||
state.isOf(Blocks.STONE) ||
|
||||
state.isOf(Blocks.SAND) ||
|
||||
state.isOf(Blocks.GRAVEL));
|
||||
}
|
||||
|
||||
public static void generatePortal(World world, BlockPos center, Direction.Axis axis) {
|
||||
BlockPos framePos = center.down();
|
||||
Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH: Direction.EAST;
|
||||
Direction moveDir = Direction.Axis.X == axis ? Direction.EAST: Direction.NORTH;
|
||||
BlockState frame = FRAME.getDefaultState().with(ACTIVE, true);
|
||||
frameMap.forEach(point -> {
|
||||
BlockPos pos = framePos.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||
|
@ -177,8 +285,7 @@ public class EternalRitual {
|
|||
pos = framePos.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||
world.setBlockState(pos, frame);
|
||||
});
|
||||
Direction.Axis portalAxis = Direction.Axis.X == axis ? Direction.Axis.Z : Direction.Axis.X;
|
||||
BlockState portal = PORTAL.getDefaultState().with(EndPortalBlock.AXIS, portalAxis);
|
||||
BlockState portal = PORTAL.getDefaultState().with(EndPortalBlock.AXIS, axis);
|
||||
portalMap.forEach(point -> {
|
||||
BlockPos pos = center.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||
world.setBlockState(pos, portal);
|
||||
|
@ -214,7 +321,6 @@ public class EternalRitual {
|
|||
if (!world.getBlockState(pos).isAir()) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -311,6 +417,9 @@ public class EternalRitual {
|
|||
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag.put("center", NbtHelper.fromBlockPos(center));
|
||||
if (exit != null) {
|
||||
tag.put("exit", NbtHelper.fromBlockPos(exit));
|
||||
}
|
||||
tag.putString("axis", axis.getName());
|
||||
tag.putBoolean("active", active);
|
||||
return tag;
|
||||
|
@ -320,5 +429,8 @@ public class EternalRitual {
|
|||
this.axis = Direction.Axis.fromName(tag.getString("axis"));
|
||||
this.center = NbtHelper.toBlockPos(tag.getCompound("center"));
|
||||
this.active = tag.getBoolean("active");
|
||||
if (tag.contains("exit")) {
|
||||
this.exit = NbtHelper.toBlockPos(tag.getCompound("exit"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,10 @@ public class MHelper {
|
|||
return max(a, max(b, c));
|
||||
}
|
||||
|
||||
public static boolean isEven(int num) {
|
||||
return (num & 1) == 0;
|
||||
}
|
||||
|
||||
public static float lengthSqr(float x, float y, float z) {
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
package ru.betterend.util;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndFeatures;
|
||||
|
||||
public class PortalFrameHelper {
|
||||
|
||||
public static boolean checkPortalFrame(ServerWorld world, BlockPos pos, Block frameBlock) {
|
||||
if (world == null || pos == null) return false;
|
||||
if (!world.getBlockState(pos).isOf(frameBlock)) return false;
|
||||
BlockPos bottomCorner = findBottomCorner(world, pos, frameBlock);
|
||||
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.Mutable checkPos = bottomCorner.up().mutableCopy();
|
||||
Direction moveDir = Direction.UP;
|
||||
while(valid && !checkPos.equals(bottomCorner)) {
|
||||
valid = world.getBlockState(checkPos).isOf(frameBlock);
|
||||
if (!valid) {
|
||||
checkPos = checkPos.move(moveDir.getOpposite());
|
||||
switch(moveDir) {
|
||||
case UP: {
|
||||
if (world.getBlockState(checkPos.east()).isOf(frameBlock)) {
|
||||
moveDir = Direction.EAST;
|
||||
valid = true;
|
||||
} else if (world.getBlockState(checkPos.south()).isOf(frameBlock)) {
|
||||
axis = Direction.Axis.Z;
|
||||
moveDir = Direction.SOUTH;
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DOWN: {
|
||||
if (world.getBlockState(checkPos.west()).isOf(frameBlock)) {
|
||||
moveDir = Direction.WEST;
|
||||
valid = true;
|
||||
} else if (world.getBlockState(checkPos.north()).isOf(frameBlock)) {
|
||||
moveDir = Direction.NORTH;
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOUTH:
|
||||
case EAST: {
|
||||
if (world.getBlockState(checkPos.down()).isOf(frameBlock)) {
|
||||
moveDir = Direction.DOWN;
|
||||
valid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (!valid) return false;
|
||||
checkPos = checkPos.move(moveDir);
|
||||
} else {
|
||||
if (moveDir.equals(Direction.EAST) || moveDir.equals(Direction.SOUTH)) {
|
||||
width++;
|
||||
} else if (moveDir.equals(Direction.UP)) {
|
||||
height++;
|
||||
}
|
||||
checkPos = checkPos.move(moveDir);
|
||||
}
|
||||
}
|
||||
if (width < 4 || height < 5 || width > 20 || height > 25) 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(EndBlocks.FLAVOLITE_RUNED)) {
|
||||
generatePortalFrame(world, bottomCorner, axis, width, height, true);
|
||||
} else {
|
||||
generateEternalPortalFrame(world, bottomCorner, axis, width, height, true);
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
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());
|
||||
BlockState south = world.getBlockState(pos.south());
|
||||
BlockState west = world.getBlockState(pos.west());
|
||||
BlockState east = world.getBlockState(pos.east());
|
||||
BlockPos.Mutable mutable = pos instanceof BlockPos.Mutable ? (BlockPos.Mutable) pos : pos.mutableCopy();
|
||||
if (up.isOf(frameBlock) && !down.isOf(frameBlock)) {
|
||||
if (south.isOf(frameBlock) || east.isOf(frameBlock)) {
|
||||
return pos.toImmutable();
|
||||
} else if (west.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, mutable.move(Direction.WEST), frameBlock);
|
||||
} else if (north.isOf(frameBlock)){
|
||||
return findBottomCorner(world, mutable.move(Direction.NORTH), frameBlock);
|
||||
}
|
||||
return null;
|
||||
} else if (down.isOf(frameBlock)) {
|
||||
if (west.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, mutable.move(Direction.WEST), frameBlock);
|
||||
} else if (north.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, mutable.move(Direction.NORTH), frameBlock);
|
||||
} else {
|
||||
return findBottomCorner(world, mutable.move(Direction.DOWN), frameBlock);
|
||||
}
|
||||
} else if (west.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, mutable.move(Direction.WEST), frameBlock);
|
||||
} else if (north.isOf(frameBlock)) {
|
||||
return findBottomCorner(world, mutable.move(Direction.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());
|
||||
BlockPos.Mutable mutable = pos instanceof BlockPos.Mutable ? (BlockPos.Mutable) pos : pos.mutableCopy();
|
||||
if (!up.isOf(frameBlock) && down.isOf(frameBlock)) {
|
||||
if (north.isOf(frameBlock) || west.isOf(frameBlock)) {
|
||||
return pos.toImmutable();
|
||||
} else if (east.isOf(frameBlock)) {
|
||||
return findTopCorner(world, mutable.move(Direction.EAST), frameBlock);
|
||||
} else if (south.isOf(frameBlock)){
|
||||
return findTopCorner(world, mutable.move(Direction.SOUTH), frameBlock);
|
||||
}
|
||||
return null;
|
||||
} else if (up.isOf(frameBlock)) {
|
||||
if (east.isOf(frameBlock)) {
|
||||
return findTopCorner(world, mutable.move(Direction.EAST), frameBlock);
|
||||
} else if (south.isOf(frameBlock)){
|
||||
return findTopCorner(world, mutable.move(Direction.SOUTH), frameBlock);
|
||||
} else {
|
||||
return findTopCorner(world, mutable.move(Direction.UP), frameBlock);
|
||||
}
|
||||
} else if (east.isOf(frameBlock)) {
|
||||
return findTopCorner(world, mutable.move(Direction.EAST), frameBlock);
|
||||
} else if (south.isOf(frameBlock)){
|
||||
return findTopCorner(world, mutable.move(Direction.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) {
|
||||
EndFeatures.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) {
|
||||
EndFeatures.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) {
|
||||
EndFeatures.END_PORTAL.configure(axis, active).getFeatureConfigured().generate(world, world.getChunkManager().getChunkGenerator(), new Random(), pos);
|
||||
}
|
||||
|
||||
public static void generateEternalPortalFrame(ServerWorld world, BlockPos pos, Direction.Axis axis, boolean active) {
|
||||
EndFeatures.END_PORTAL_ETERNAL.configure(axis, active).getFeatureConfigured().generate(world, world.getChunkManager().getChunkGenerator(), new Random(), pos);
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
package ru.betterend.world.features;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.StructureWorldAccess;
|
||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import ru.betterend.blocks.EndPortalBlock;
|
||||
import ru.betterend.blocks.RunedFlavolite;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
|
||||
public class DefaultEndPortalFeature extends Feature<EndPortalFeatureConfig> {
|
||||
|
||||
public DefaultEndPortalFeature() {
|
||||
super(EndPortalFeatureConfig.CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos,
|
||||
EndPortalFeatureConfig config) {
|
||||
|
||||
BlockState portalFrame = config.frameBlock.getDefaultState().with(RunedFlavolite.ACTIVATED, config.activated);
|
||||
BlockState portalBlock = EndBlocks.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(width, height, 0);
|
||||
} else {
|
||||
topCorner = bottomCorner.add(0, height, width);
|
||||
}
|
||||
|
||||
for(BlockPos position : BlockPos.iterate(bottomCorner, topCorner)) {
|
||||
if (position.equals(bottomCorner) || position.equals(topCorner) ||
|
||||
position.getX() == bottomCorner.getX() && position.getZ() == bottomCorner.getZ() ||
|
||||
position.getX() == topCorner.getX() && position.getZ() == topCorner.getZ()) {
|
||||
|
||||
BlocksHelper.setWithoutUpdate(world, position, portalFrame);
|
||||
} else if (config.axis.equals(Direction.Axis.X)) {
|
||||
if (position.getZ() == bottomCorner.getZ() && position.getY() == bottomCorner.getY() ||
|
||||
position.getZ() == topCorner.getZ() && position.getY() == topCorner.getY()) {
|
||||
|
||||
BlocksHelper.setWithoutUpdate(world, position, portalFrame);
|
||||
} else if (config.activated) {
|
||||
BlocksHelper.setWithoutUpdate(world, position, portalBlock);
|
||||
}
|
||||
} else {
|
||||
if (position.getX() == bottomCorner.getX() && position.getY() == bottomCorner.getY() ||
|
||||
position.getX() == topCorner.getX() && position.getY() == topCorner.getY()) {
|
||||
|
||||
BlocksHelper.setWithoutUpdate(world, position, portalFrame);
|
||||
} else if (config.activated) {
|
||||
BlocksHelper.setWithoutUpdate(world, position, portalBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package ru.betterend.world.features;
|
||||
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import ru.betterend.blocks.RunedFlavolite;
|
||||
|
||||
public class EndPortalFeature extends EndFeature {
|
||||
|
||||
private final RunedFlavolite frameBlock;
|
||||
|
||||
public EndPortalFeature(DefaultEndPortalFeature feature, RunedFlavolite frameBlock) {
|
||||
this.feature = feature;
|
||||
this.featureStep = GenerationStep.Feature.UNDERGROUND_STRUCTURES;
|
||||
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, 4, 5, active));
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package ru.betterend.world.features;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.gen.feature.FeatureConfig;
|
||||
import ru.betterend.blocks.RunedFlavolite;
|
||||
|
||||
public class EndPortalFeatureConfig implements FeatureConfig {
|
||||
public static final Codec<EndPortalFeatureConfig> CODEC = RecordCodecBuilder.create((instance) -> {
|
||||
return instance.group(Codec.STRING.fieldOf("frame_block").forGetter(endPortalFeatureConfig -> {
|
||||
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);
|
||||
});
|
||||
|
||||
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, 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, 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, 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