0

I have recently had the problem where I am unable to fill in the ancient city frame/portal. (1.21.1) The issue I have come across is that I have to place 2 blocks of reinforced deepslate or else it does not work at all. This can be seen more clearly below in this image:

The Problem

However it will still not work to expectations as it will offset the frame filling by one block as seen below...

Another Problem

I will show my code below, sorry if I am making some silly mistake:

package poseidon.smp.customPortal;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.HashSet;
import java.util.Set;

public final class CustomPortal extends JavaPlugin implements Listener {

    @Override
    public void onEnable() {
        Bukkit.getPluginManager().registerEvents(this, this);
    }

    @EventHandler
    public void onRightClick(PlayerInteractEvent event) {
        if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
            Block clickedBlock = event.getClickedBlock();
            if (clickedBlock != null && clickedBlock.getType() == Material.REINFORCED_DEEPSLATE) {
                Set<Block> frameBlocks = new HashSet<>();
                findFrame(clickedBlock, frameBlocks);
                fillFrameWithIce(frameBlocks);
            }
        }
    }

    private void findFrame(Block start, Set<Block> frameBlocks) {
        findFrameRecursive(start, frameBlocks);
        int minX = frameBlocks.stream().mapToInt(b -> b.getX()).min().orElse(0);
        int maxX = frameBlocks.stream().mapToInt(b -> b.getX()).max().orElse(0);
        int minY = frameBlocks.stream().mapToInt(b -> b.getY()).min().orElse(0);
        int maxY = frameBlocks.stream().mapToInt(b -> b.getY()).max().orElse(0);
        int minZ = frameBlocks.stream().mapToInt(b -> b.getZ()).min().orElse(0);
        int maxZ = frameBlocks.stream().mapToInt(b -> b.getZ()).max().orElse(0);

        for (int x = minX; x <= maxX; x++) {
            for (int y = minY; y <= maxY; y++) {
                frameBlocks.add(start.getWorld().getBlockAt(x, y, minZ));
                frameBlocks.add(start.getWorld().getBlockAt(x, y, maxZ));
            }
        }

        for (int z = minZ; z <= maxZ; z++) {
            for (int y = minY; y <= maxY; y++) {
                frameBlocks.add(start.getWorld().getBlockAt(minX, y, z));
                frameBlocks.add(start.getWorld().getBlockAt(maxX, y, z));
            }
        }
    }

    private void findFrameRecursive(Block block, Set<Block> frameBlocks) {
        if (block == null || frameBlocks.contains(block) || block.getType() != Material.REINFORCED_DEEPSLATE) {
            return;
        }
        frameBlocks.add(block);

        findFrameRecursive(block.getRelative(1, 0, 0), frameBlocks);
        findFrameRecursive(block.getRelative(-1, 0, 0), frameBlocks);
        findFrameRecursive(block.getRelative(0, 1, 0), frameBlocks);
        findFrameRecursive(block.getRelative(0, -1, 0), frameBlocks);
        findFrameRecursive(block.getRelative(0, 0, 1), frameBlocks);
        findFrameRecursive(block.getRelative(0, 0, -1), frameBlocks);
    }

    private void fillFrameWithIce(Set<Block> frameBlocks) {
        int minX = frameBlocks.stream().mapToInt(Block::getX).min().orElse(0);
        int maxX = frameBlocks.stream().mapToInt(Block::getX).max().orElse(0);
        int minY = frameBlocks.stream().mapToInt(Block::getY).min().orElse(0);
        int maxY = frameBlocks.stream().mapToInt(Block::getY).max().orElse(0);
        int minZ = frameBlocks.stream().mapToInt(Block::getZ).min().orElse(0);
        int maxZ = frameBlocks.stream().mapToInt(Block::getZ).max().orElse(0);

        for (int x = minX + 1; x < maxX; x++) {
            for (int y = minY + 1; y < maxY; y++) {
                for (int z = minZ + 1; z < maxZ; z++) {
                    Block block = frameBlocks.iterator().next().getWorld().getBlockAt(x, y, z);
                    if (!frameBlocks.contains(block)) {
                        block.setType(Material.STONE);
                    }
                }
            }
        }
    }
    @Override
    public void onDisable() {
    }
}
1
  • Did you find a solution yet? The recursive idea seems good, but will cause potentially larger areas to be filled with Stone, than only the plane of the portal Commented Oct 1 at 21:32

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.