Eternal Portals

This commit is contained in:
Aleksey 2020-10-30 16:42:41 +03:00
parent 6d809df962
commit 81e4098a72
8 changed files with 430 additions and 82 deletions

View file

@ -5,7 +5,7 @@ import java.util.Random;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.NetherPortalBlock;
@ -23,12 +23,13 @@ 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.PortalFrameHelper;
import ru.betterend.util.EternalRitual;
public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable {
public EndPortalBlock() {
@ -112,7 +113,7 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
bottom.setY(basePos.getY());
Direction.Axis axis = entity.getMovementDirection().getAxis();
if (checkIsAreaValid(world, bottom, axis)) {
PortalFrameHelper.generatePortalFrame(world, bottom, axis, true);
EternalRitual.generatePortal(world, bottom, axis);
if (axis.equals(Direction.Axis.X)) {
return bottom.add(0, 1, 1);
} else {
@ -126,7 +127,7 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
}
for(BlockPos position : BlockPos.iterate(bottom, top)) {
if (checkIsAreaValid(world, position, axis)) {
PortalFrameHelper.generatePortalFrame(world, position, axis, true);
EternalRitual.generatePortal(world, position, axis);
if (axis.equals(Direction.Axis.X)) {
return position.add(0, 1, 1);
} else {
@ -140,7 +141,7 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
} else {
basePos.setY(world.getChunk(basePos).sampleHeightmap(Heightmap.Type.WORLD_SURFACE, basePos.getX(), basePos.getZ()));
}
PortalFrameHelper.generatePortalFrame(world, basePos, axis, true);
EternalRitual.generatePortal(world, basePos, axis);
if (axis.equals(Direction.Axis.X)) {
return basePos.add(0, 1, 1);
} else {
@ -149,51 +150,37 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
}
private boolean checkIsAreaValid(World world, BlockPos pos, Direction.Axis axis) {
BlockPos topCorner, bottomCorner;
if (axis.equals(Direction.Axis.X)) {
bottomCorner = pos.add(0, 0, -1);
topCorner = bottomCorner.add(0, 4, 4);
} else {
bottomCorner = pos.add(-1, 0, 0);
topCorner = bottomCorner.add(4, 4, 0);
}
if (!isBaseSolid(world, bottomCorner, axis)) return false;
int airBlocks = 0;
boolean free = true;
for (BlockPos position : BlockPos.iterate(bottomCorner, topCorner)) {
BlockState state = world.getBlockState(position);
if (state.isAir()) airBlocks++;
if (world.getRegistryKey().equals(World.END)) {
free &= state.isAir() || EndTags.validGenBlock(state);
} else {
BlockState surfaceBlock = world.getBiome(pos).getGenerationSettings().getSurfaceConfig().getTopMaterial();
free &= this.validBlock(state, surfaceBlock.getBlock());
}
}
return free && airBlocks >= 48;
if (!isBaseValid(world, pos, axis)) return false;
return EternalRitual.checkArea(world, pos, axis);
}
private boolean isBaseSolid(World world, BlockPos pos, Direction.Axis axis) {
private boolean isBaseValid(World world, BlockPos pos, Direction.Axis axis) {
boolean solid = true;
if (axis.equals(Direction.Axis.X)) {
for (int i = 0; i < 4; i++) {
BlockPos checkPos = pos.down().add(0, 0, i);
solid &= world.getBlockState(checkPos).isSolidBlock(world, checkPos);
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 {
for (int i = 0; i < 4; i++) {
BlockPos checkPos = pos.down().add(i, 0, 0);
solid &= world.getBlockState(checkPos).isSolidBlock(world, checkPos);
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(BlockState state, Block surfaceBlock) {
return state.isAir() ||
state.isOf(surfaceBlock) ||
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);
state.isOf(Blocks.GRAVEL));
}
}

View file

@ -28,6 +28,7 @@ import ru.betterend.blocks.basis.BlockPedestal;
import ru.betterend.blocks.entities.PedestalBlockEntity;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndItems;
import ru.betterend.util.EternalRitual;
public class EternalPedestal extends BlockPedestal {
public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVATED;
@ -46,11 +47,21 @@ public class EternalPedestal extends BlockPedestal {
PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity;
BlockState updatedState = world.getBlockState(pos);
if (pedestal.isEmpty() && updatedState.get(ACTIVATED)) {
if (pedestal.hasRitual()) {
EternalRitual ritual = pedestal.getRitual();
ritual.removePortal();
}
world.setBlockState(pos, updatedState.with(ACTIVATED, false));
} else {
ItemStack itemStack = pedestal.getStack(0);
if (itemStack.getItem() == EndItems.ETERNAL_CRYSTAL) {
world.setBlockState(pos, updatedState.with(ACTIVATED, true));
if (pedestal.hasRitual()) {
pedestal.getRitual().checkStructure();
} else {
EternalRitual ritual = new EternalRitual(world, pos);
ritual.checkStructure();
}
}
}
}

View file

@ -39,6 +39,7 @@ import ru.betterend.blocks.BlockProperties;
import ru.betterend.blocks.BlockProperties.PedestalState;
import ru.betterend.blocks.entities.PedestalBlockEntity;
import ru.betterend.interfaces.Patterned;
import ru.betterend.registry.EndBlocks;
import ru.betterend.util.BlocksHelper;
public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvider {
@ -52,6 +53,30 @@ public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvid
private static final VoxelShape SHAPE_COLUMN_TOP;
private static final VoxelShape SHAPE_BOTTOM;
/**
*
* Register new Pedestal block with Better End mod id.
*
* @param name
* @param source
* @return new Pedestal block with Better End id.
*/
public static Block registerPedestal(String name, Block source) {
return EndBlocks.registerBlock(name, new BlockPedestal(source));
}
/**
*
* Register new Pedestal block with specified mod id.
*
* @param id
* @param source
* @return new Pedestal block with specified id.
*/
public static Block registerPedestal(Identifier id, Block source) {
return EndBlocks.registerBlock(id, new BlockPedestal(source));
}
protected final Block parent;
public BlockPedestal(Block parent) {

View file

@ -8,17 +8,33 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
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;
public class PedestalBlockEntity extends BlockEntity implements Inventory, Tickable {
private ItemStack activeItem = ItemStack.EMPTY;
private EternalRitual linkedRitual;
private int age;
public PedestalBlockEntity() {
super(EndBlockEntities.PEDESTAL);
}
public boolean hasRitual() {
return this.linkedRitual != null;
}
public void linkRitual(EternalRitual ritual) {
this.linkedRitual = ritual;
}
public EternalRitual getRitual() {
return this.linkedRitual;
}
public int getAge() {
return this.age;
}
@ -73,6 +89,14 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka
return this.toTag(new CompoundTag());
}
@Override
public void setLocation(World world, BlockPos pos) {
super.setLocation(world, pos);
if (hasRitual()) {
this.linkedRitual.setWorld(world);
}
}
@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
@ -80,11 +104,18 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka
CompoundTag itemTag = tag.getCompound("active_item");
this.activeItem = ItemStack.fromTag(itemTag);
}
if (tag.contains("ritual")) {
this.linkedRitual = new EternalRitual(world);
this.linkedRitual.fromTag(tag.getCompound("ritual"));
}
}
@Override
public CompoundTag toTag(CompoundTag tag) {
tag.put("active_item", activeItem.toTag(new CompoundTag()));
if (this.hasRitual()) {
tag.put("ritual", linkedRitual.toTag(new CompoundTag()));
}
return super.toTag(tag);
}