From 83fd4603accb5f7f6bee71c65418debe19116caa Mon Sep 17 00:00:00 2001 From: Aleksey Date: Sun, 7 Mar 2021 15:06:12 +0300 Subject: [PATCH] Targeted portals (WIP, bugged) --- .../ru/betterend/blocks/EndPortalBlock.java | 56 +++++++------- .../ru/betterend/blocks/EternalPedestal.java | 6 +- .../betterend/blocks/basis/PedestalBlock.java | 5 +- .../entities/EternalPedestalEntity.java | 12 +-- .../entities/InfusionPedestalEntity.java | 14 ++-- .../ru/betterend/registry/EndPortals.java | 18 ++--- .../ru/betterend/rituals/EternalRitual.java | 73 ++++++++++++------- .../ru/betterend/rituals/InfusionRitual.java | 10 +-- 8 files changed, 102 insertions(+), 92 deletions(-) diff --git a/src/main/java/ru/betterend/blocks/EndPortalBlock.java b/src/main/java/ru/betterend/blocks/EndPortalBlock.java index ff4ab7d6..ffd12fdc 100644 --- a/src/main/java/ru/betterend/blocks/EndPortalBlock.java +++ b/src/main/java/ru/betterend/blocks/EndPortalBlock.java @@ -1,8 +1,5 @@ package ru.betterend.blocks; -import java.util.Objects; -import java.util.Random; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; @@ -21,6 +18,7 @@ import net.minecraft.sound.SoundEvents; import net.minecraft.state.StateManager; import net.minecraft.state.property.IntProperty; import net.minecraft.util.BlockRotation; +import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction.Axis; @@ -38,6 +36,9 @@ import ru.betterend.interfaces.TeleportingEntity; import ru.betterend.registry.EndParticles; import ru.betterend.registry.EndPortals; +import java.util.Objects; +import java.util.Random; + public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable, IColorProvider { public static final IntProperty PORTAL = BlockProperties.PORTAL; @@ -83,11 +84,12 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { if (world instanceof ServerWorld && !entity.hasVehicle() && !entity.hasPassengers() && entity.canUsePortals()) { if (entity.hasNetherPortalCooldown()) return; - boolean isOverworld = world.getRegistryKey().equals(World.OVERWORLD); - MinecraftServer server = ((ServerWorld) world).getServer(); - ServerWorld destination = isOverworld ? server.getWorld(World.END) : EndPortals.getWorld(server, state.get(PORTAL)); - BlockPos exitPos = this.findExitPos(destination, pos, entity); - System.out.println(exitPos); + ServerWorld currentWorld = (ServerWorld) world; + MinecraftServer server = currentWorld.getServer(); + ServerWorld targetWorld = EndPortals.getWorld(server, state.get(PORTAL)); + boolean isTarget = world.getRegistryKey().equals(targetWorld.getRegistryKey()); + ServerWorld destination = isTarget ? server.getWorld(World.END) : targetWorld; + BlockPos exitPos = findExitPos(currentWorld, destination, pos, entity); if (exitPos == null) return; if (entity instanceof ServerPlayerEntity) { ServerPlayerEntity player = (ServerPlayerEntity) entity; @@ -119,31 +121,33 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable return ERenderLayer.TRANSLUCENT; } - private BlockPos findExitPos(ServerWorld world, BlockPos pos, Entity entity) { - if (world == null) return null; + private BlockPos findExitPos(ServerWorld current, ServerWorld target, BlockPos pos, Entity entity) { + if (target == null) return null; - Registry registry = world.getRegistryManager().getDimensionTypes(); - double mult = Objects.requireNonNull(registry.get(DimensionType.THE_END_ID)).getCoordinateScale(); - BlockPos.Mutable basePos; - if (!world.getRegistryKey().equals(World.END)) { - basePos = pos.mutableCopy().set(pos.getX() / mult, pos.getY(), pos.getZ() / mult); - } else { - basePos = pos.mutableCopy().set(pos.getX() * mult, pos.getY(), pos.getZ() * mult); - } + Registry registry = target.getRegistryManager().getDimensionTypes(); + Identifier targetWorldId = target.getRegistryKey().getValue(); + Identifier currentWorldId = current.getRegistryKey().getValue(); + double targetMultiplier = Objects.requireNonNull(registry.get(targetWorldId)).getCoordinateScale(); + double currentMultiplier = Objects.requireNonNull(registry.get(currentWorldId)).getCoordinateScale(); + double multiplier = targetMultiplier > currentMultiplier ? currentMultiplier / targetMultiplier : currentMultiplier; + BlockPos.Mutable basePos = pos.mutableCopy().set(pos.getX() * multiplier, pos.getY(), pos.getZ() * multiplier); + System.out.println(basePos); Direction direction = Direction.EAST; BlockPos.Mutable checkPos = basePos.mutableCopy(); for (int step = 1; step < 128; step++) { for (int i = 0; i < (step >> 1); i++) { - Chunk chunk = world.getChunk(checkPos); + Chunk chunk = target.getChunk(checkPos); if (chunk != null) { - int ceil = chunk.sampleHeightmap(Heightmap.Type.WORLD_SURFACE, checkPos.getX() & 15, checkPos.getZ() & 15); + int surfaceY = chunk.sampleHeightmap(Heightmap.Type.WORLD_SURFACE, checkPos.getX() & 15, checkPos.getZ() & 15); + int motionY = chunk.sampleHeightmap(Heightmap.Type.MOTION_BLOCKING, checkPos.getX() & 15, checkPos.getZ() & 15); + int ceil = Math.max(surfaceY, motionY) + 1; if (ceil > 5) { checkPos.setY(ceil); while (checkPos.getY() > 5) { - BlockState state = world.getBlockState(checkPos); + BlockState state = target.getBlockState(checkPos); if (state.isOf(this)) { Axis axis = state.get(AXIS); - checkPos = this.findCenter(world, checkPos, axis); + checkPos = findCenter(target, checkPos, axis); Direction frontDir = Direction.from(axis, AxisDirection.POSITIVE).rotateYClockwise(); Direction entityDir = entity.getMovementDirection(); @@ -195,15 +199,11 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable @Override public BlockColorProvider getProvider() { - return (state, world, pos, tintIndex) -> { - return EndPortals.getColor(state.get(PORTAL)); - }; + return (state, world, pos, tintIndex) -> EndPortals.getColor(state.get(PORTAL)); } @Override public ItemColorProvider getItemProvider() { - return (stack, tintIndex) -> { - return EndPortals.getColor(0); - }; + return (stack, tintIndex) -> EndPortals.getColor(0); } } diff --git a/src/main/java/ru/betterend/blocks/EternalPedestal.java b/src/main/java/ru/betterend/blocks/EternalPedestal.java index e1a7911e..b06ebfb7 100644 --- a/src/main/java/ru/betterend/blocks/EternalPedestal.java +++ b/src/main/java/ru/betterend/blocks/EternalPedestal.java @@ -34,7 +34,7 @@ public class EternalPedestal extends PedestalBlock { public EternalPedestal() { super(EndBlocks.FLAVOLITE_RUNED_ETERNAL); - this.setDefaultState(this.getDefaultState().with(ACTIVATED, false)); + this.setDefaultState(getDefaultState().with(ACTIVATED, false)); } @Override @@ -50,12 +50,12 @@ public class EternalPedestal extends PedestalBlock { int dim = EndPortals.getPortalState(Registry.ITEM.getId(item)); ritual.removePortal(dim); } - world.setBlockState(pos, updatedState.with(ACTIVATED, false)); + world.setBlockState(pos, updatedState.with(ACTIVATED, false).with(HAS_LIGHT, false)); } else { ItemStack itemStack = pedestal.getStack(0); Identifier id = Registry.ITEM.getId(itemStack.getItem()); if (EndPortals.isAvailableItem(id)) { - world.setBlockState(pos, updatedState.with(ACTIVATED, true)); + world.setBlockState(pos, updatedState.with(ACTIVATED, true).with(HAS_LIGHT, true)); if (pedestal.hasRitual()) { pedestal.getRitual().checkStructure(); } else { diff --git a/src/main/java/ru/betterend/blocks/basis/PedestalBlock.java b/src/main/java/ru/betterend/blocks/basis/PedestalBlock.java index c5d0d4df..208b4991 100644 --- a/src/main/java/ru/betterend/blocks/basis/PedestalBlock.java +++ b/src/main/java/ru/betterend/blocks/basis/PedestalBlock.java @@ -86,9 +86,7 @@ public class PedestalBlock extends BlockBaseNotFull implements BlockEntityProvid protected float height = 1.0F; public PedestalBlock(Block parent) { - super(FabricBlockSettings.copyOf(parent).luminance(state -> { - return state.get(HAS_LIGHT) ? 12 : 0; - })); + super(FabricBlockSettings.copyOf(parent).luminance(state -> state.get(HAS_LIGHT) ? 12 : 0)); this.setDefaultState(stateManager.getDefaultState().with(STATE, PedestalState.DEFAULT).with(HAS_ITEM, false).with(HAS_LIGHT, false)); this.parent = parent; } @@ -119,6 +117,7 @@ public class PedestalBlock extends BlockBaseNotFull implements BlockEntityProvid ItemStack itemStack = pedestal.getStack(0); if (player.giveItemStack(itemStack)) { pedestal.removeStack(0); + checkRitual(world, pos); return ActionResult.SUCCESS; } return ActionResult.FAIL; diff --git a/src/main/java/ru/betterend/blocks/entities/EternalPedestalEntity.java b/src/main/java/ru/betterend/blocks/entities/EternalPedestalEntity.java index a17ca46e..f244e71a 100644 --- a/src/main/java/ru/betterend/blocks/entities/EternalPedestalEntity.java +++ b/src/main/java/ru/betterend/blocks/entities/EternalPedestalEntity.java @@ -15,7 +15,7 @@ public class EternalPedestalEntity extends PedestalBlockEntity { } public boolean hasRitual() { - return this.linkedRitual != null; + return linkedRitual != null; } public void linkRitual(EternalRitual ritual) { @@ -23,14 +23,14 @@ public class EternalPedestalEntity extends PedestalBlockEntity { } public EternalRitual getRitual() { - return this.linkedRitual; + return linkedRitual; } @Override public void setLocation(World world, BlockPos pos) { super.setLocation(world, pos); if (hasRitual()) { - this.linkedRitual.setWorld(world); + linkedRitual.setWorld(world); } } @@ -38,14 +38,14 @@ public class EternalPedestalEntity extends PedestalBlockEntity { public void fromTag(BlockState state, CompoundTag tag) { super.fromTag(state, tag); if (tag.contains("ritual")) { - this.linkedRitual = new EternalRitual(world); - this.linkedRitual.fromTag(tag.getCompound("ritual")); + linkedRitual = new EternalRitual(world); + linkedRitual.fromTag(tag.getCompound("ritual")); } } @Override public CompoundTag toTag(CompoundTag tag) { - if (this.hasRitual()) { + if (hasRitual()) { tag.put("ritual", linkedRitual.toTag(new CompoundTag())); } return super.toTag(tag); diff --git a/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java b/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java index ee85a5bc..d8a8251b 100644 --- a/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java +++ b/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java @@ -19,26 +19,26 @@ public class InfusionPedestalEntity extends PedestalBlockEntity { public void setLocation(World world, BlockPos pos) { super.setLocation(world, pos); if (hasRitual()) { - this.linkedRitual.setLocation(world, pos); + linkedRitual.setLocation(world, pos); } } public void linkRitual(InfusionRitual ritual) { - this.linkedRitual = ritual; + linkedRitual = ritual; } public InfusionRitual getRitual() { - return this.linkedRitual; + return linkedRitual; } public boolean hasRitual() { - return this.linkedRitual != null; + return linkedRitual != null; } @Override public void tick() { if (hasRitual()) { - this.linkedRitual.tick(); + linkedRitual.tick(); } super.tick(); } @@ -52,8 +52,8 @@ public class InfusionPedestalEntity extends PedestalBlockEntity { public void fromTag(BlockState state, CompoundTag tag) { super.fromTag(state, tag); if (tag.contains("ritual")) { - this.linkedRitual = new InfusionRitual(world, pos); - this.linkedRitual.fromTag(tag.getCompound("ritual")); + linkedRitual = new InfusionRitual(world, pos); + linkedRitual.fromTag(tag.getCompound("ritual")); } } diff --git a/src/main/java/ru/betterend/registry/EndPortals.java b/src/main/java/ru/betterend/registry/EndPortals.java index 2ff462af..e6841e88 100644 --- a/src/main/java/ru/betterend/registry/EndPortals.java +++ b/src/main/java/ru/betterend/registry/EndPortals.java @@ -1,11 +1,8 @@ package ru.betterend.registry; -import java.io.File; -import java.util.Iterator; - import com.google.gson.JsonArray; import com.google.gson.JsonObject; - +import com.ibm.icu.impl.UResource; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; @@ -14,6 +11,8 @@ import ru.betterend.config.ConfigWriter; import ru.betterend.util.JsonFactory; import ru.betterend.util.MHelper; +import java.io.File; + public class EndPortals { private static PortalInfo[] portals; @@ -23,8 +22,7 @@ public class EndPortals { if (!file.exists()) { file.getParentFile().mkdirs(); json = makeDefault(file); - } - else { + } else { json = JsonFactory.getJsonObject(file); } if (!json.has("portals") || !json.get("portals").isJsonArray()) { @@ -66,8 +64,8 @@ public class EndPortals { } public static boolean isAvailableItem(Identifier item) { - for (int i = 0; i < portals.length; i++) { - if (portals[i].item.equals(item)) { + for (PortalInfo portal : portals) { + if (portal.item.equals(item)) { return true; } } @@ -114,9 +112,7 @@ public class EndPortals { if (world != null) { return world; } - Iterator iterator = server.getWorlds().iterator(); - while (iterator.hasNext()) { - ServerWorld world = iterator.next(); + for (ServerWorld world : server.getWorlds()) { if (world.getRegistryKey().getValue().equals(dimension)) { this.world = world; return world; diff --git a/src/main/java/ru/betterend/rituals/EternalRitual.java b/src/main/java/ru/betterend/rituals/EternalRitual.java index 3d203fc3..18cdb6ef 100644 --- a/src/main/java/ru/betterend/rituals/EternalRitual.java +++ b/src/main/java/ru/betterend/rituals/EternalRitual.java @@ -21,6 +21,7 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.state.property.BooleanProperty; +import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.registry.Registry; @@ -97,25 +98,26 @@ public class EternalRitual { moveX = Direction.SOUTH; moveY = Direction.EAST; } - boolean valid = this.checkFrame(); + boolean valid = checkFrame(); Item item = null; for (Point pos : STRUCTURE_MAP) { BlockPos.Mutable checkPos = center.mutableCopy(); checkPos.move(moveX, pos.x).move(moveY, pos.y); - valid &= this.isActive(checkPos); + valid &= isActive(checkPos); if (valid) { EternalPedestalEntity pedestal = (EternalPedestalEntity) world.getBlockEntity(checkPos); - Item pItem = pedestal.getStack(0).getItem(); - if (item == null) { - item = pItem; - } - else if (!item.equals(pItem)) { - valid = false; + if (pedestal != null) { + Item pItem = pedestal.getStack(0).getItem(); + if (item == null) { + item = pItem; + } else if (!item.equals(pItem)) { + valid = false; + } } } } if (valid && item != null) { - this.activatePortal(item); + activatePortal(item); } } @@ -141,18 +143,17 @@ public class EternalRitual { private void activatePortal(Item item) { if (active) return; int state = EndPortals.getPortalState(Registry.ITEM.getId(item)); - this.activatePortal(world, center, state); - this.doEffects((ServerWorld) world, center); + System.out.println(state); + activatePortal(world, center, state); + doEffects((ServerWorld) world, center); if (exit == null) { - this.exit = this.findPortalPos(state); - } - else { - World targetWorld = this.getTargetWorld(state); + this.exit = findPortalPos(state); + } else { + World targetWorld = getTargetWorld(state); if (targetWorld.getBlockState(exit.up()).isOf(EndBlocks.END_PORTAL_BLOCK)) { - this.exit = this.findPortalPos(state); - } - else { - this.activatePortal(targetWorld, exit, state); + this.exit = findPortalPos(state); + } else { + activatePortal(targetWorld, exit, state); } } this.active = true; @@ -216,9 +217,8 @@ public class EternalRitual { public void removePortal(int state) { if (!active || isInvalid()) return; - World targetWorld = this.getTargetWorld(state); - this.removePortal(world, center); - this.removePortal(targetWorld, exit); + removePortal(getTargetWorld(state), exit); + removePortal(world, center); } private void removePortal(World world, BlockPos center) { @@ -252,10 +252,11 @@ public class EternalRitual { private BlockPos findPortalPos(int state) { MinecraftServer server = world.getServer(); assert server != null; - ServerWorld targetWorld = (ServerWorld) this.getTargetWorld(state); + ServerWorld targetWorld = (ServerWorld) getTargetWorld(state); + Identifier targetWorldId = targetWorld.getRegistryKey().getValue(); Registry registry = server.getRegistryManager().getDimensionTypes(); - double mult = Objects.requireNonNull(registry.get(DimensionType.THE_END_ID)).getCoordinateScale(); - BlockPos.Mutable basePos = center.mutableCopy().set(center.getX() / mult, center.getY(), center.getZ() / mult); + double multiplier = Objects.requireNonNull(registry.get(targetWorldId)).getCoordinateScale(); + BlockPos.Mutable basePos = center.mutableCopy().set(center.getX() / multiplier, center.getY(), center.getZ() / multiplier); Direction.Axis portalAxis = (Direction.Axis.X == axis) ? Direction.Axis.Z : Direction.Axis.X; if (checkIsAreaValid(targetWorld, basePos, portalAxis)) { EternalRitual.generatePortal(targetWorld, basePos, portalAxis); @@ -465,9 +466,15 @@ public class EternalRitual { BlockState state = world.getBlockState(pos); if (state.isOf(PEDESTAL)) { EternalPedestalEntity pedestal = (EternalPedestalEntity) world.getBlockEntity(pos); - assert pedestal != null; - if (!pedestal.hasRitual()) { - pedestal.linkRitual(this); + if (pedestal != null) { + if (!pedestal.hasRitual()) { + pedestal.linkRitual(this); + } else { + EternalRitual ritual = pedestal.getRitual(); + if (!ritual.equals(this)) { + pedestal.linkRitual(this); + } + } } return state.get(ACTIVE); } @@ -492,4 +499,14 @@ public class EternalRitual { this.exit = NbtHelper.toBlockPos(tag.getCompound("exit")); } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EternalRitual ritual = (EternalRitual) o; + return world.equals(ritual.world) && + Objects.equals(center, ritual.center) && + Objects.equals(exit, ritual.exit); + } } diff --git a/src/main/java/ru/betterend/rituals/InfusionRitual.java b/src/main/java/ru/betterend/rituals/InfusionRitual.java index 849522ae..628b5a92 100644 --- a/src/main/java/ru/betterend/rituals/InfusionRitual.java +++ b/src/main/java/ru/betterend/rituals/InfusionRitual.java @@ -1,8 +1,5 @@ package ru.betterend.rituals; -import java.awt.Point; - -import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventory; @@ -17,6 +14,8 @@ import ru.betterend.blocks.entities.PedestalBlockEntity; import ru.betterend.particle.InfusionParticleType; import ru.betterend.recipe.builders.InfusionRecipe; +import java.awt.*; + public class InfusionRitual implements Inventory { private static final Point[] PEDESTALS_MAP = new Point[] { new Point(0, 3), new Point(2, 2), new Point(3, 0), new Point(2, -2), @@ -32,7 +31,7 @@ public class InfusionRitual implements Inventory { private int time = 0; private InfusionPedestalEntity input; - private PedestalBlockEntity[] catalysts = new PedestalBlockEntity[8]; + private final PedestalBlockEntity[] catalysts = new PedestalBlockEntity[8]; public InfusionRitual(World world, BlockPos pos) { this.world = world; @@ -108,7 +107,6 @@ public class InfusionRitual implements Inventory { if (!checkRecipe()) return; progress++; if (progress == time) { - BlockState inputState = world.getBlockState(input.getPos()); input.removeStack(0); input.setStack(0, activeRecipe.craft(this)); for (PedestalBlockEntity catalyst : catalysts) { @@ -198,7 +196,7 @@ public class InfusionRitual implements Inventory { if (slot == 0) { return input.removeStack(0); } else { - return catalysts[slot - 1].getStack(0); + return catalysts[slot - 1].removeStack(0); } }