Eternal Portals
This commit is contained in:
parent
6d809df962
commit
81e4098a72
8 changed files with 430 additions and 82 deletions
|
@ -5,7 +5,7 @@ import java.util.Random;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.NetherPortalBlock;
|
import net.minecraft.block.NetherPortalBlock;
|
||||||
|
@ -23,12 +23,13 @@ import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldAccess;
|
import net.minecraft.world.WorldAccess;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeatures;
|
import net.minecraft.world.gen.feature.ConfiguredFeatures;
|
||||||
|
|
||||||
import ru.betterend.client.render.ERenderLayer;
|
import ru.betterend.client.render.ERenderLayer;
|
||||||
import ru.betterend.interfaces.IRenderTypeable;
|
import ru.betterend.interfaces.IRenderTypeable;
|
||||||
import ru.betterend.interfaces.TeleportingEntity;
|
import ru.betterend.interfaces.TeleportingEntity;
|
||||||
import ru.betterend.registry.EndParticles;
|
import ru.betterend.registry.EndParticles;
|
||||||
import ru.betterend.registry.EndTags;
|
import ru.betterend.registry.EndTags;
|
||||||
import ru.betterend.util.PortalFrameHelper;
|
import ru.betterend.util.EternalRitual;
|
||||||
|
|
||||||
public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable {
|
public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable {
|
||||||
public EndPortalBlock() {
|
public EndPortalBlock() {
|
||||||
|
@ -112,7 +113,7 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
bottom.setY(basePos.getY());
|
bottom.setY(basePos.getY());
|
||||||
Direction.Axis axis = entity.getMovementDirection().getAxis();
|
Direction.Axis axis = entity.getMovementDirection().getAxis();
|
||||||
if (checkIsAreaValid(world, bottom, axis)) {
|
if (checkIsAreaValid(world, bottom, axis)) {
|
||||||
PortalFrameHelper.generatePortalFrame(world, bottom, axis, true);
|
EternalRitual.generatePortal(world, bottom, axis);
|
||||||
if (axis.equals(Direction.Axis.X)) {
|
if (axis.equals(Direction.Axis.X)) {
|
||||||
return bottom.add(0, 1, 1);
|
return bottom.add(0, 1, 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -126,7 +127,7 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
}
|
}
|
||||||
for(BlockPos position : BlockPos.iterate(bottom, top)) {
|
for(BlockPos position : BlockPos.iterate(bottom, top)) {
|
||||||
if (checkIsAreaValid(world, position, axis)) {
|
if (checkIsAreaValid(world, position, axis)) {
|
||||||
PortalFrameHelper.generatePortalFrame(world, position, axis, true);
|
EternalRitual.generatePortal(world, position, axis);
|
||||||
if (axis.equals(Direction.Axis.X)) {
|
if (axis.equals(Direction.Axis.X)) {
|
||||||
return position.add(0, 1, 1);
|
return position.add(0, 1, 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -140,7 +141,7 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
} else {
|
} else {
|
||||||
basePos.setY(world.getChunk(basePos).sampleHeightmap(Heightmap.Type.WORLD_SURFACE, basePos.getX(), basePos.getZ()));
|
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)) {
|
if (axis.equals(Direction.Axis.X)) {
|
||||||
return basePos.add(0, 1, 1);
|
return basePos.add(0, 1, 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -149,51 +150,37 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkIsAreaValid(World world, BlockPos pos, Direction.Axis axis) {
|
private boolean checkIsAreaValid(World world, BlockPos pos, Direction.Axis axis) {
|
||||||
BlockPos topCorner, bottomCorner;
|
if (!isBaseValid(world, pos, axis)) return false;
|
||||||
if (axis.equals(Direction.Axis.X)) {
|
return EternalRitual.checkArea(world, pos, axis);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBaseSolid(World world, BlockPos pos, Direction.Axis axis) {
|
private boolean isBaseValid(World world, BlockPos pos, Direction.Axis axis) {
|
||||||
boolean solid = true;
|
boolean solid = true;
|
||||||
if (axis.equals(Direction.Axis.X)) {
|
if (axis.equals(Direction.Axis.X)) {
|
||||||
for (int i = 0; i < 4; i++) {
|
pos = pos.down().add(0, 0, -3);
|
||||||
BlockPos checkPos = pos.down().add(0, 0, i);
|
for (int i = 0; i < 7; i++) {
|
||||||
solid &= world.getBlockState(checkPos).isSolidBlock(world, checkPos);
|
BlockPos checkPos = pos.add(0, 0, i);
|
||||||
|
BlockState state = world.getBlockState(checkPos);
|
||||||
|
solid &= this.validBlock(world, checkPos, state);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 4; i++) {
|
pos = pos.down().add(-3, 0, 0);
|
||||||
BlockPos checkPos = pos.down().add(i, 0, 0);
|
for (int i = 0; i < 7; i++) {
|
||||||
solid &= world.getBlockState(checkPos).isSolidBlock(world, checkPos);
|
BlockPos checkPos = pos.add(i, 0, 0);
|
||||||
|
BlockState state = world.getBlockState(checkPos);
|
||||||
|
solid &= this.validBlock(world, checkPos, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return solid;
|
return solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validBlock(BlockState state, Block surfaceBlock) {
|
private boolean validBlock(World world, BlockPos pos, BlockState state) {
|
||||||
return state.isAir() ||
|
BlockState surfaceBlock = world.getBiome(pos).getGenerationSettings().getSurfaceConfig().getTopMaterial();
|
||||||
state.isOf(surfaceBlock) ||
|
return state.isSolidBlock(world, pos) &&
|
||||||
|
(EndTags.validGenBlock(state) ||
|
||||||
|
state.isOf(surfaceBlock.getBlock()) ||
|
||||||
state.isOf(Blocks.STONE) ||
|
state.isOf(Blocks.STONE) ||
|
||||||
state.isOf(Blocks.SAND) ||
|
state.isOf(Blocks.SAND) ||
|
||||||
state.isOf(Blocks.GRAVEL);
|
state.isOf(Blocks.GRAVEL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import ru.betterend.blocks.basis.BlockPedestal;
|
||||||
import ru.betterend.blocks.entities.PedestalBlockEntity;
|
import ru.betterend.blocks.entities.PedestalBlockEntity;
|
||||||
import ru.betterend.registry.EndBlocks;
|
import ru.betterend.registry.EndBlocks;
|
||||||
import ru.betterend.registry.EndItems;
|
import ru.betterend.registry.EndItems;
|
||||||
|
import ru.betterend.util.EternalRitual;
|
||||||
|
|
||||||
public class EternalPedestal extends BlockPedestal {
|
public class EternalPedestal extends BlockPedestal {
|
||||||
public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVATED;
|
public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVATED;
|
||||||
|
@ -46,11 +47,21 @@ public class EternalPedestal extends BlockPedestal {
|
||||||
PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity;
|
PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity;
|
||||||
BlockState updatedState = world.getBlockState(pos);
|
BlockState updatedState = world.getBlockState(pos);
|
||||||
if (pedestal.isEmpty() && updatedState.get(ACTIVATED)) {
|
if (pedestal.isEmpty() && updatedState.get(ACTIVATED)) {
|
||||||
|
if (pedestal.hasRitual()) {
|
||||||
|
EternalRitual ritual = pedestal.getRitual();
|
||||||
|
ritual.removePortal();
|
||||||
|
}
|
||||||
world.setBlockState(pos, updatedState.with(ACTIVATED, false));
|
world.setBlockState(pos, updatedState.with(ACTIVATED, false));
|
||||||
} else {
|
} else {
|
||||||
ItemStack itemStack = pedestal.getStack(0);
|
ItemStack itemStack = pedestal.getStack(0);
|
||||||
if (itemStack.getItem() == EndItems.ETERNAL_CRYSTAL) {
|
if (itemStack.getItem() == EndItems.ETERNAL_CRYSTAL) {
|
||||||
world.setBlockState(pos, updatedState.with(ACTIVATED, true));
|
world.setBlockState(pos, updatedState.with(ACTIVATED, true));
|
||||||
|
if (pedestal.hasRitual()) {
|
||||||
|
pedestal.getRitual().checkStructure();
|
||||||
|
} else {
|
||||||
|
EternalRitual ritual = new EternalRitual(world, pos);
|
||||||
|
ritual.checkStructure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import ru.betterend.blocks.BlockProperties;
|
||||||
import ru.betterend.blocks.BlockProperties.PedestalState;
|
import ru.betterend.blocks.BlockProperties.PedestalState;
|
||||||
import ru.betterend.blocks.entities.PedestalBlockEntity;
|
import ru.betterend.blocks.entities.PedestalBlockEntity;
|
||||||
import ru.betterend.interfaces.Patterned;
|
import ru.betterend.interfaces.Patterned;
|
||||||
|
import ru.betterend.registry.EndBlocks;
|
||||||
import ru.betterend.util.BlocksHelper;
|
import ru.betterend.util.BlocksHelper;
|
||||||
|
|
||||||
public class BlockPedestal extends BlockBaseNotFull implements BlockEntityProvider {
|
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_COLUMN_TOP;
|
||||||
private static final VoxelShape SHAPE_BOTTOM;
|
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;
|
protected final Block parent;
|
||||||
|
|
||||||
public BlockPedestal(Block parent) {
|
public BlockPedestal(Block parent) {
|
||||||
|
|
|
@ -8,17 +8,33 @@ import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
||||||
import net.minecraft.util.Tickable;
|
import net.minecraft.util.Tickable;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import ru.betterend.registry.EndBlockEntities;
|
import ru.betterend.registry.EndBlockEntities;
|
||||||
|
import ru.betterend.util.EternalRitual;
|
||||||
|
|
||||||
public class PedestalBlockEntity extends BlockEntity implements Inventory, Tickable {
|
public class PedestalBlockEntity extends BlockEntity implements Inventory, Tickable {
|
||||||
private ItemStack activeItem = ItemStack.EMPTY;
|
private ItemStack activeItem = ItemStack.EMPTY;
|
||||||
|
|
||||||
|
private EternalRitual linkedRitual;
|
||||||
private int age;
|
private int age;
|
||||||
|
|
||||||
public PedestalBlockEntity() {
|
public PedestalBlockEntity() {
|
||||||
super(EndBlockEntities.PEDESTAL);
|
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() {
|
public int getAge() {
|
||||||
return this.age;
|
return this.age;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +89,14 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka
|
||||||
return this.toTag(new CompoundTag());
|
return this.toTag(new CompoundTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLocation(World world, BlockPos pos) {
|
||||||
|
super.setLocation(world, pos);
|
||||||
|
if (hasRitual()) {
|
||||||
|
this.linkedRitual.setWorld(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromTag(BlockState state, CompoundTag tag) {
|
public void fromTag(BlockState state, CompoundTag tag) {
|
||||||
super.fromTag(state, tag);
|
super.fromTag(state, tag);
|
||||||
|
@ -80,11 +104,18 @@ public class PedestalBlockEntity extends BlockEntity implements Inventory, Ticka
|
||||||
CompoundTag itemTag = tag.getCompound("active_item");
|
CompoundTag itemTag = tag.getCompound("active_item");
|
||||||
this.activeItem = ItemStack.fromTag(itemTag);
|
this.activeItem = ItemStack.fromTag(itemTag);
|
||||||
}
|
}
|
||||||
|
if (tag.contains("ritual")) {
|
||||||
|
this.linkedRitual = new EternalRitual(world);
|
||||||
|
this.linkedRitual.fromTag(tag.getCompound("ritual"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag toTag(CompoundTag tag) {
|
public CompoundTag toTag(CompoundTag tag) {
|
||||||
tag.put("active_item", activeItem.toTag(new CompoundTag()));
|
tag.put("active_item", activeItem.toTag(new CompoundTag()));
|
||||||
|
if (this.hasRitual()) {
|
||||||
|
tag.put("ritual", linkedRitual.toTag(new CompoundTag()));
|
||||||
|
}
|
||||||
return super.toTag(tag);
|
return super.toTag(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.MaterialColor;
|
import net.minecraft.block.MaterialColor;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import ru.betterend.BetterEnd;
|
import ru.betterend.BetterEnd;
|
||||||
import ru.betterend.blocks.AeterniumBlock;
|
import ru.betterend.blocks.AeterniumBlock;
|
||||||
|
@ -137,12 +138,16 @@ public class EndBlocks {
|
||||||
|
|
||||||
public static void register() {}
|
public static void register() {}
|
||||||
|
|
||||||
public static Block registerBlock(String name, Block block) {
|
public static Block registerBlock(Identifier id, Block block) {
|
||||||
Registry.register(Registry.BLOCK, BetterEnd.makeID(name), block);
|
Registry.register(Registry.BLOCK, id, block);
|
||||||
EndItems.registerItem(name, new BlockItem(block, new Item.Settings().group(CreativeTab.END_TAB)));
|
EndItems.registerItem(id, new BlockItem(block, new Item.Settings().group(CreativeTab.END_TAB)));
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Block registerBlock(String name, Block block) {
|
||||||
|
return registerBlock(BetterEnd.makeID(name), block);
|
||||||
|
}
|
||||||
|
|
||||||
public static Block registerBlockNI(String name, Block block) {
|
public static Block registerBlockNI(String name, Block block) {
|
||||||
return Registry.register(Registry.BLOCK, BetterEnd.makeID(name), block);
|
return Registry.register(Registry.BLOCK, BetterEnd.makeID(name), block);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import net.minecraft.item.SwordItem;
|
||||||
import net.minecraft.item.ToolItem;
|
import net.minecraft.item.ToolItem;
|
||||||
import net.minecraft.item.ToolMaterials;
|
import net.minecraft.item.ToolMaterials;
|
||||||
import net.minecraft.tag.Tag;
|
import net.minecraft.tag.Tag;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPointer;
|
import net.minecraft.util.math.BlockPointer;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
|
@ -80,8 +81,12 @@ public class EndItems {
|
||||||
public static final Item ETERNAL_CRYSTAL = registerItem("eternal_crystal", new EternalCrystal());
|
public static final Item ETERNAL_CRYSTAL = registerItem("eternal_crystal", new EternalCrystal());
|
||||||
|
|
||||||
protected static Item registerItem(String name, Item item) {
|
protected static Item registerItem(String name, Item item) {
|
||||||
|
return registerItem(BetterEnd.makeID(name), item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item registerItem(Identifier id, Item item) {
|
||||||
if (item != Items.AIR) {
|
if (item != Items.AIR) {
|
||||||
Registry.register(Registry.ITEM, BetterEnd.makeID(name), item);
|
Registry.register(Registry.ITEM, id, item);
|
||||||
if (item instanceof BlockItem)
|
if (item instanceof BlockItem)
|
||||||
MOD_BLOCKS.add(item);
|
MOD_BLOCKS.add(item);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
package ru.betterend.util;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import ru.betterend.blocks.EternalPedestal;
|
|
||||||
import ru.betterend.registry.EndBlocks;
|
|
||||||
|
|
||||||
public class EternalPortalHelper {
|
|
||||||
private final static Map<Integer, Integer> structureMap = new HashMap<Integer, Integer>() {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
{
|
|
||||||
put(0, 7);
|
|
||||||
put(1, 1);
|
|
||||||
put(1, 11);
|
|
||||||
put(11, 1);
|
|
||||||
put(11, 11);
|
|
||||||
put(12, 7);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private final static Block PEDESTAL = EndBlocks.ETERNAL_PEDESTAL;
|
|
||||||
private final static BooleanProperty ACTIVE = EternalPedestal.ACTIVATED;
|
|
||||||
|
|
||||||
private static int centerX = 6;
|
|
||||||
private static int centerZ = 6;
|
|
||||||
|
|
||||||
public static boolean checkPortalStructure(World world, BlockPos pos) {
|
|
||||||
if (!world.getBlockState(pos).isOf(PEDESTAL)) return false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BlockPos finedCorner(World world, BlockPos pos) {
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
}
|
|
324
src/main/java/ru/betterend/util/EternalRitual.java
Normal file
324
src/main/java/ru/betterend/util/EternalRitual.java
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
package ru.betterend.util;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.NbtHelper;
|
||||||
|
import net.minecraft.state.property.BooleanProperty;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class EternalRitual {
|
||||||
|
private final static Set<Point> structureMap = Sets.newHashSet(
|
||||||
|
new Point(-4, -5), new Point(-4, 5), new Point(-6, 0),
|
||||||
|
new Point(4, -5), new Point(4, 5), new Point(6, 0));
|
||||||
|
private final static Set<Point> frameMap = Sets.newHashSet(
|
||||||
|
new Point(0, 0), new Point(0, 6), new Point(1, 0),
|
||||||
|
new Point(1, 6), new Point(2, 1), new Point(2, 5),
|
||||||
|
new Point(3, 2), new Point(3, 3), new Point(3, 4));
|
||||||
|
private final static Set<Point> portalMap = Sets.newHashSet(
|
||||||
|
new Point(0, 0), new Point(0, 1), new Point(0, 2),
|
||||||
|
new Point(0, 3), new Point(0, 4), new Point(1, 0),
|
||||||
|
new Point(1, 1), new Point(1, 2), new Point(1, 3),
|
||||||
|
new Point(1, 4), new Point(2, 1), new Point(2, 2),
|
||||||
|
new Point(2, 3));
|
||||||
|
private final static Set<Point> baseMap = Sets.newHashSet(
|
||||||
|
new Point(3, 0), new Point(2, 0), new Point(2, 1), new Point(1, 1),
|
||||||
|
new Point(1, 2), new Point(0, 1), new Point(0, 2));
|
||||||
|
|
||||||
|
private final static Block BASE = EndBlocks.FLAVOLITE.tiles;
|
||||||
|
private final static Block PEDESTAL = EndBlocks.ETERNAL_PEDESTAL;
|
||||||
|
private final static Block FRAME = EndBlocks.FLAVOLITE_RUNED_ETERNAL;
|
||||||
|
private final static Block PORTAL = EndBlocks.END_PORTAL_BLOCK;
|
||||||
|
private final static BooleanProperty ACTIVE = BlockProperties.ACTIVATED;
|
||||||
|
|
||||||
|
private World world;
|
||||||
|
private Direction.Axis axis;
|
||||||
|
private BlockPos center;
|
||||||
|
private boolean active = false;
|
||||||
|
|
||||||
|
public EternalRitual(World world) {
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EternalRitual(World world, BlockPos initial) {
|
||||||
|
this(world);
|
||||||
|
this.configure(initial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasWorld() {
|
||||||
|
return this.world != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorld(World world) {
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkStructure() {
|
||||||
|
if (center == null || axis == null) return;
|
||||||
|
Direction moveX, moveY;
|
||||||
|
if (Direction.Axis.X == axis) {
|
||||||
|
moveX = Direction.EAST;
|
||||||
|
moveY = Direction.NORTH;
|
||||||
|
} else {
|
||||||
|
moveX = Direction.SOUTH;
|
||||||
|
moveY = Direction.EAST;
|
||||||
|
}
|
||||||
|
boolean valid = this.checkFrame();
|
||||||
|
for (Point pos : structureMap) {
|
||||||
|
BlockPos.Mutable checkPos = center.mutableCopy();
|
||||||
|
checkPos.move(moveX, pos.x).move(moveY, pos.y);
|
||||||
|
valid &= this.isActive(checkPos);
|
||||||
|
}
|
||||||
|
if (valid) {
|
||||||
|
this.activatePortal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkFrame() {
|
||||||
|
BlockPos framePos = center.down();
|
||||||
|
Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH: Direction.EAST;
|
||||||
|
boolean valid = true;
|
||||||
|
for (Point point : frameMap) {
|
||||||
|
BlockPos pos = framePos.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||||
|
BlockState state = world.getBlockState(pos);
|
||||||
|
valid &= state.getBlock() instanceof RunedFlavolite;
|
||||||
|
pos = framePos.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||||
|
state = world.getBlockState(pos);
|
||||||
|
valid &= state.getBlock() instanceof RunedFlavolite;
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return this.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void activatePortal() {
|
||||||
|
if (active) return;
|
||||||
|
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)) {
|
||||||
|
world.setBlockState(pos, frame);
|
||||||
|
}
|
||||||
|
pos = framePos.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||||
|
state = world.getBlockState(pos);
|
||||||
|
if (!state.get(ACTIVE)) {
|
||||||
|
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);
|
||||||
|
portalMap.forEach(point -> {
|
||||||
|
BlockPos pos = center.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||||
|
if (!world.getBlockState(pos).isOf(PORTAL)) {
|
||||||
|
world.setBlockState(pos, portal);
|
||||||
|
}
|
||||||
|
pos = center.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||||
|
if (!world.getBlockState(pos).isOf(PORTAL)) {
|
||||||
|
world.setBlockState(pos, portal);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePortal() {
|
||||||
|
if (!active) return;
|
||||||
|
BlockPos framePos = center.down();
|
||||||
|
Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH: Direction.EAST;
|
||||||
|
frameMap.forEach(point -> {
|
||||||
|
BlockPos pos = framePos.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||||
|
BlockState state = world.getBlockState(pos);
|
||||||
|
if (state.isOf(FRAME) && state.get(ACTIVE)) {
|
||||||
|
world.setBlockState(pos, state.with(ACTIVE, false));
|
||||||
|
}
|
||||||
|
pos = framePos.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||||
|
state = world.getBlockState(pos);
|
||||||
|
if (state.isOf(FRAME) && state.get(ACTIVE)) {
|
||||||
|
world.setBlockState(pos, state.with(ACTIVE, false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
portalMap.forEach(point -> {
|
||||||
|
BlockPos pos = center.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||||
|
if (world.getBlockState(pos).isOf(PORTAL)) {
|
||||||
|
world.removeBlock(pos, false);
|
||||||
|
}
|
||||||
|
pos = center.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||||
|
if (world.getBlockState(pos).isOf(PORTAL)) {
|
||||||
|
world.removeBlock(pos, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
BlockState frame = FRAME.getDefaultState().with(ACTIVE, true);
|
||||||
|
frameMap.forEach(point -> {
|
||||||
|
BlockPos pos = framePos.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||||
|
world.setBlockState(pos, frame);
|
||||||
|
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);
|
||||||
|
portalMap.forEach(point -> {
|
||||||
|
BlockPos pos = center.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||||
|
world.setBlockState(pos, portal);
|
||||||
|
pos = center.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||||
|
world.setBlockState(pos, portal);
|
||||||
|
});
|
||||||
|
generateBase(world, framePos, moveDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void generateBase(World world, BlockPos center, Direction moveX) {
|
||||||
|
BlockState base = BASE.getDefaultState();
|
||||||
|
Direction moveY = moveX.rotateYClockwise();
|
||||||
|
baseMap.forEach(point -> {
|
||||||
|
BlockPos pos = center.offset(moveX, point.x).offset(moveY, point.y);
|
||||||
|
world.setBlockState(pos, base);
|
||||||
|
pos = center.offset(moveX, -point.x).offset(moveY, point.y);
|
||||||
|
world.setBlockState(pos, base);
|
||||||
|
pos = center.offset(moveX, point.x).offset(moveY, -point.y);
|
||||||
|
world.setBlockState(pos, base);
|
||||||
|
pos = center.offset(moveX, -point.x).offset(moveY, -point.y);
|
||||||
|
world.setBlockState(pos, base);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkArea(World world, BlockPos center, Direction.Axis axis) {
|
||||||
|
Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH: Direction.EAST;
|
||||||
|
for (BlockPos checkPos : BlockPos.iterate(center.offset(moveDir.rotateYClockwise()),
|
||||||
|
center.offset(moveDir.rotateYCounterclockwise()))) {
|
||||||
|
for (Point point : portalMap) {
|
||||||
|
BlockPos pos = checkPos.offset(moveDir, point.x).offset(Direction.UP, point.y);
|
||||||
|
if (!world.getBlockState(pos).isAir()) return false;
|
||||||
|
pos = checkPos.offset(moveDir, -point.x).offset(Direction.UP, point.y);
|
||||||
|
if (!world.getBlockState(pos).isAir()) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configure(BlockPos initial) {
|
||||||
|
BlockPos checkPos = initial.east(12);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.axis = Direction.Axis.X;
|
||||||
|
this.center = initial.east(6);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkPos = initial.west(12);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.axis = Direction.Axis.X;
|
||||||
|
this.center = initial.west(6);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkPos = initial.south(12);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.axis = Direction.Axis.Z;
|
||||||
|
this.center = initial.south(6);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkPos = initial.north(12);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.axis = Direction.Axis.Z;
|
||||||
|
this.center = initial.north(6);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkPos = initial.north(10);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.axis = Direction.Axis.X;
|
||||||
|
checkPos = checkPos.east(8);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.center = initial.north(5).east(4);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.center = initial.north(5).west(4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkPos = initial.south(10);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.axis = Direction.Axis.X;
|
||||||
|
checkPos = checkPos.east(8);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.center = initial.south(5).east(4);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.center = initial.south(5).west(4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkPos = initial.east(10);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.axis = Direction.Axis.Z;
|
||||||
|
checkPos = checkPos.south(8);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.center = initial.east(5).south(4);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.center = initial.east(5).north(4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkPos = initial.west(10);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.axis = Direction.Axis.Z;
|
||||||
|
checkPos = checkPos.south(8);
|
||||||
|
if (this.hasPedestal(checkPos)) {
|
||||||
|
this.center = initial.west(5).south(4);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.center = initial.west(5).north(4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasPedestal(BlockPos pos) {
|
||||||
|
return world.getBlockState(pos).isOf(PEDESTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isActive(BlockPos pos) {
|
||||||
|
BlockState state = world.getBlockState(pos);
|
||||||
|
if (state.isOf(PEDESTAL)) {
|
||||||
|
PedestalBlockEntity pedestal = (PedestalBlockEntity) world.getBlockEntity(pos);
|
||||||
|
if (!pedestal.hasRitual()) {
|
||||||
|
pedestal.linkRitual(this);
|
||||||
|
}
|
||||||
|
return state.get(ACTIVE);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundTag toTag(CompoundTag tag) {
|
||||||
|
tag.put("center", NbtHelper.fromBlockPos(center));
|
||||||
|
tag.putString("axis", axis.getName());
|
||||||
|
tag.putBoolean("active", active);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fromTag(CompoundTag tag) {
|
||||||
|
this.axis = Direction.Axis.fromName(tag.getString("axis"));
|
||||||
|
this.center = NbtHelper.toBlockPos(tag.getCompound("center"));
|
||||||
|
this.active = tag.getBoolean("active");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue