Search in sources :

Example 1 with StructureMaterial

use of eelfloat.replcraft.StructureMaterial in project replcraft by LeeFlemingRepl.

the class StructureUtil method verifyStructure.

/**
 * Verifies the structure attached to a sign
 * @param starting_block A block on the frame of the structure
 * @throws InvalidStructure if the structure is invalid
 * @return a partially validated structure, missing its sign field
 */
public static Structure verifyStructure(Block starting_block) throws InvalidStructure {
    // A list of all seen frame blocks, attached chests, and signs.
    HashSet<Location> seen = new HashSet<>();
    Stack<Location> to_explore = new Stack<>();
    int min_x = starting_block.getX();
    int min_y = starting_block.getY();
    int min_z = starting_block.getZ();
    int max_x = starting_block.getX();
    int max_y = starting_block.getY();
    int max_z = starting_block.getZ();
    List<Block> chests = new ArrayList<>();
    to_explore.push(starting_block.getLocation());
    StructureMaterial material = null;
    int explored = 0;
    while (!to_explore.isEmpty()) {
        explored += 1;
        if (material == null && explored > 100) {
            throw new InvalidStructure("Too many connected blocks before finding any valid structure material.");
        }
        if (material != null && explored > material.max_size) {
            throw new InvalidStructure(String.format("Too many connected %s blocks. The limit is %d for this material type.", material.name, material.max_size));
        }
        Block block = to_explore.pop().getBlock();
        for (BlockFace face : BlockFace.values()) {
            if (!face.isCartesian())
                continue;
            Block relative = block.getRelative(face);
            Location location = relative.getLocation();
            if (relative.getType() == Material.CHEST) {
                seen.add(location);
                chests.add(relative);
            }
            boolean isValidStructureMaterial = material == null ? ReplCraft.plugin.frame_materials.stream().flatMap(mats -> mats.validMaterials.stream()).anyMatch(mat -> relative.getType() == mat) : material.validMaterials.contains(relative.getType());
            if (isValidStructureMaterial && !seen.contains(location)) {
                if (material == null) {
                    material = ReplCraft.plugin.frame_materials.stream().filter(mats -> mats.validMaterials.contains(relative.getType())).findFirst().orElseThrow(() -> new RuntimeException("unreachable"));
                    ReplCraft.plugin.logger.info("Structure type determined to be " + material.name);
                }
                seen.add(location);
                to_explore.push(location);
                min_x = Math.min(min_x, location.getBlockX());
                min_y = Math.min(min_y, location.getBlockY());
                min_z = Math.min(min_z, location.getBlockZ());
                max_x = Math.max(max_x, location.getBlockX());
                max_y = Math.max(max_y, location.getBlockY());
                max_z = Math.max(max_z, location.getBlockZ());
            }
        }
    }
    ReplCraft.plugin.logger.info(String.format("Structure min [%s %s %s] max [%s %s %s]", min_x, min_y, min_z, max_x, max_y, max_z));
    if (material == null) {
        throw new InvalidStructure("Structure must contain at least one valid structure block from any structure type.");
    }
    // Top edges
    // 1
    check_axis(material, new Location(starting_block.getWorld(), min_x, max_y, max_z), 1, 0, 0, max_x - min_x);
    // 2
    check_axis(material, new Location(starting_block.getWorld(), max_x, max_y, max_z), 0, 0, -1, max_z - min_z);
    // 3
    check_axis(material, new Location(starting_block.getWorld(), max_x, max_y, min_z), -1, 0, 0, max_x - min_x);
    // 4
    check_axis(material, new Location(starting_block.getWorld(), min_x, max_y, min_z), 0, 0, 1, max_z - min_z);
    // Side edges
    // 5
    check_axis(material, new Location(starting_block.getWorld(), max_x, min_y, max_z), 0, 1, 0, max_y - min_y);
    // 6
    check_axis(material, new Location(starting_block.getWorld(), max_x, min_y, min_z), 0, 1, 0, max_y - min_y);
    // 7
    check_axis(material, new Location(starting_block.getWorld(), min_x, min_y, min_z), 0, 1, 0, max_y - min_y);
    // 8
    check_axis(material, new Location(starting_block.getWorld(), min_x, min_y, max_z), 0, 1, 0, max_y - min_y);
    // Bottom edges
    // 9
    check_axis(material, new Location(starting_block.getWorld(), min_x, min_y, max_z), 1, 0, 0, max_x - min_x);
    // 10
    check_axis(material, new Location(starting_block.getWorld(), max_x, min_y, max_z), 0, 0, -1, max_z - min_z);
    // 11
    check_axis(material, new Location(starting_block.getWorld(), max_x, min_y, min_z), -1, 0, 0, max_x - min_x);
    // 12
    check_axis(material, new Location(starting_block.getWorld(), min_x, min_y, min_z), 0, 0, 1, max_z - min_z);
    Structure structure = new Structure(material, null, null, null, null, null, seen, chests, min_x, min_y, min_z, max_x, max_y, max_z);
    if (structure.inner_size_x() < 1 || structure.inner_size_y() < 1 || structure.inner_size_z() < 1) {
        throw new InvalidStructure("Structure must have a nonzero interior size.");
    }
    return structure;
}
Also used : java.util(java.util) BlockData(org.bukkit.block.data.BlockData) Predicate(java.util.function.Predicate) Structure(eelfloat.replcraft.Structure) BlockState(org.bukkit.block.BlockState) ApiError(eelfloat.replcraft.exceptions.ApiError) WallSign(org.bukkit.block.data.type.WallSign) BlockFace(org.bukkit.block.BlockFace) StructureMaterial(eelfloat.replcraft.StructureMaterial) Collectors(java.util.stream.Collectors) org.bukkit(org.bukkit) Claims(io.jsonwebtoken.Claims) Jwts(io.jsonwebtoken.Jwts) Block(org.bukkit.block.Block) InvalidStructure(eelfloat.replcraft.exceptions.InvalidStructure) ReplCraft(eelfloat.replcraft.ReplCraft) JwtException(io.jsonwebtoken.JwtException) InvalidStructure(eelfloat.replcraft.exceptions.InvalidStructure) BlockFace(org.bukkit.block.BlockFace) StructureMaterial(eelfloat.replcraft.StructureMaterial) Block(org.bukkit.block.Block) Structure(eelfloat.replcraft.Structure) InvalidStructure(eelfloat.replcraft.exceptions.InvalidStructure)

Aggregations

ReplCraft (eelfloat.replcraft.ReplCraft)1 Structure (eelfloat.replcraft.Structure)1 StructureMaterial (eelfloat.replcraft.StructureMaterial)1 ApiError (eelfloat.replcraft.exceptions.ApiError)1 InvalidStructure (eelfloat.replcraft.exceptions.InvalidStructure)1 Claims (io.jsonwebtoken.Claims)1 JwtException (io.jsonwebtoken.JwtException)1 Jwts (io.jsonwebtoken.Jwts)1 java.util (java.util)1 Predicate (java.util.function.Predicate)1 Collectors (java.util.stream.Collectors)1 org.bukkit (org.bukkit)1 Block (org.bukkit.block.Block)1 BlockFace (org.bukkit.block.BlockFace)1 BlockState (org.bukkit.block.BlockState)1 BlockData (org.bukkit.block.data.BlockData)1 WallSign (org.bukkit.block.data.type.WallSign)1