package de._82grfl1bif.kpiVisualizer.structures; import de._82grfl1bif.kpiVisualizer.data.Klasse; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import java.time.Duration; import java.util.Objects; import java.util.Random; import java.util.logging.Level; public class Builder { Server server; public Builder(Server server) { this.server = server; } public void setFoundation(Location startLocation, int x, int z, Material material) { for (int cx = 0; cx < x; cx++) { for (int cz = 0; cz < z; cz++) { Block block = server.getWorlds().get(0).getBlockAt(startLocation.clone().add(cx, 0, cz)); block.setType(material); } } } public void fillQube(Location startLocation, int x, int y, int z, Material material) { for (int cy = 0; cy < y; cy++) { setFoundation(startLocation.clone().add(0, cy, 0), x, z, material); } } private void setWalls(Location startLocation, int x, int y, int z, Material innerMaterial, Material glassMaterial) { Location temp = startLocation.clone().add(0, 0, 1); for (int cz = 0; cz < z - 2; cz++) {//00-0Z for (int cy = 0; cy < y; cy++) { server.getWorlds().get(0).getBlockAt(temp.clone().add(1, cy, cz)).setType(innerMaterial); server.getWorlds().get(0).getBlockAt(temp.clone().add(0, cy, cz)).setType(glassMaterial); } } temp = startLocation.clone().add(1, 0, 0); for (int cx = 0; cx < x - 2; cx++) {//00-0X for (int cy = 0; cy < y; cy++) { server.getWorlds().get(0).getBlockAt(temp.clone().add(cx, cy, 1)).setType(innerMaterial); server.getWorlds().get(0).getBlockAt(temp.clone().add(cx, cy, 0)).setType(glassMaterial); } } temp = startLocation.clone().add(1, 0, z - 1); for (int cx = 0; cx < x - 2; cx++) {//0Z-ZX for (int cy = 0; cy < y; cy++) { server.getWorlds().get(0).getBlockAt(temp.clone().add(cx, cy, -1)).setType(innerMaterial); server.getWorlds().get(0).getBlockAt(temp.clone().add(cx, cy, 0)).setType(glassMaterial); } } temp = startLocation.clone().add(x - 1, 0, 1); for (int cz = 0; cz < z - 2; cz++) {//0X-XZ for (int cy = 0; cy < y; cy++) { server.getWorlds().get(0).getBlockAt(temp.clone().add(-1, cy, cz)).setType(innerMaterial); server.getWorlds().get(0).getBlockAt(temp.clone().add(0, cy, cz)).setType(glassMaterial); } } } private void setCorners(Location startLocation, int x, int y, int z, Material facade) { Location temp = startLocation.clone(); for (int cy = 0; cy < y; cy++) { server.getWorlds().get(0).getBlockAt(temp.clone().add(0, cy, 0)).setType(facade); } temp = startLocation.clone().add(x - 1, 0, 0); for (int cy = 0; cy < y; cy++) { server.getWorlds().get(0).getBlockAt(temp.clone().add(0, cy, 0)).setType(facade); } temp = startLocation.clone().add(0, 0, z - 1); for (int cy = 0; cy < y; cy++) { server.getWorlds().get(0).getBlockAt(temp.clone().add(0, cy, 0)).setType(facade); } temp = startLocation.clone().add(x - 1, 0, z - 1); for (int cy = 0; cy < y; cy++) { server.getWorlds().get(0).getBlockAt(temp.clone().add(0, cy, 0)).setType(facade); } } public void buildBuilding(Location startLocation, int x, int y,int craneHeight,int antennaHeight, int z, Material facadeMaterial, Material glassMaterial, Material innerMaterial) { setWalls(startLocation, x, y, z, innerMaterial, glassMaterial); setCorners(startLocation, x, y, z, facadeMaterial); setFoundation(startLocation.clone().add(0, y, 0), x, z, facadeMaterial);//roof fillQube(startLocation.clone().add(Math.round(x/2f),y+1,Math.round(x/2f)),1,antennaHeight,1,Material.COBBLESTONE_WALL); Random rm = new Random(); switch (rm.nextInt(3)+1){ case 1: setCrane(startLocation,x,y,z,craneHeight,BlockFace.NORTH); break; case 2: setCrane(startLocation,x,y,z,craneHeight,BlockFace.WEST); break; case 3: setCrane(startLocation,x,y,z,craneHeight,BlockFace.EAST); break; case 4: setCrane(startLocation,x,y,z,craneHeight,BlockFace.SOUTH); break; } } public void setAllChildren(Foundation foundation) { for (Structure s : foundation.getChildren()) { if (s.getClass() == Foundation.class) {//TODO must be revisited to draw rectangular Foundations this.setFoundation(s.getLocation().clone().add(0, s.getDepth(), 0), s.getWidth().x, s.getWidth().x, s.getMaterial()); addDescription(s.getLocation().clone().add(0, s.getDepth(), 0), s); setAllChildren((Foundation) s); } else {//TODO must be revisited to draw rectangular Buildings float firstCommit = ((Building) s).klasse.firstCommitTime.toDays(); float scaleFirstCommit; if((float)Klasse.firstCommitTimeMin.toDays() == (float)Klasse.firstCommitTimeMax.toDays()){ scaleFirstCommit = 0f; }else { scaleFirstCommit = ((firstCommit - (float)Klasse.firstCommitTimeMin.toDays()) / ((float) Klasse.firstCommitTimeMax.toDays() - (float)Klasse.firstCommitTimeMin.toDays())); } Duration d = ((Building) s).klasse.lastEditingTime; float lastCommit = d.toDays(); float scaleLastCommit; if((float)Klasse.lastEditingTimeMin.toDays() == (float)Klasse.lastEditingTimeMax.toDays()){ scaleLastCommit = 0f; }else { scaleLastCommit = ((lastCommit - (float)Klasse.lastEditingTimeMin.toDays()) / ((float)Klasse.lastEditingTimeMax.toDays() - (float)Klasse.lastEditingTimeMin.toDays())); } Material facadeMaterial; if(scaleFirstCommit < 0.10){ facadeMaterial = Material.WAXED_COPPER_BLOCK; }else if(scaleFirstCommit < 0.5){ facadeMaterial = Material.WAXED_EXPOSED_COPPER; }else if(scaleFirstCommit < 0.90){ facadeMaterial = Material.WAXED_WEATHERED_COPPER; }else { facadeMaterial = Material.WAXED_OXIDIZED_COPPER; } Material facadeInnerMaterial; if(scaleLastCommit< 0.10){ facadeInnerMaterial = Material.WHITE_STAINED_GLASS; }else if(scaleLastCommit < 0.5){ facadeInnerMaterial = Material.GLASS; }else if(scaleLastCommit < 0.90){ facadeInnerMaterial = Material.BLUE_STAINED_GLASS; }else { facadeInnerMaterial = Material.IRON_BARS; } this.buildBuilding(s.getLocation().clone().add(1, s.getDepth() + 1,1), s.getWidth().x - 2, ((Building) s).getHeight()+1, ((Building)s).klasse.commits, Math.round(((Building)s).klasse.complexity/100f), s.getWidth().x - 2, facadeMaterial, facadeInnerMaterial, s.getMaterial()); addDescription(s.getLocation().clone().add(1, s.getDepth() + 1, 1), s); } } } public void setCrane(Location startLocation ,int x ,int y ,int z ,int height ,BlockFace orientation){ switch (orientation) { case NORTH: for(int cy = y+1; cy < (height+y+2); cy++){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,cy,z-2)).setType(Material.YELLOW_CONCRETE); } for(int cz = 0; cz < z; cz++){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,y+height,cz)).setType(Material.YELLOW_CONCRETE); } break; case WEST: for(int cy = y+1; cy < (height+y+2); cy++){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(x-2,cy,0)).setType(Material.YELLOW_CONCRETE); } for(int cx = 0; cx < z; cx++){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(cx,y+height,0)).setType(Material.YELLOW_CONCRETE); } break; case EAST: for(int cy = y+1; cy < (height+y+2); cy++){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(2,cy,z-1)).setType(Material.YELLOW_CONCRETE); } for(int cx = 0; cx < z; cx++){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(cx,y+height,z-1)).setType(Material.YELLOW_CONCRETE); } break; case SOUTH: for(int cy = y+1; cy < (height+y+2); cy++){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(x-1,cy,2)).setType(Material.YELLOW_CONCRETE); } for(int cz = 0; cz < z; cz++){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(x-1,y+height,cz)).setType(Material.YELLOW_CONCRETE); } break; default: Bukkit.getLogger().log(Level.SEVERE, "fehlerhafte Orientierung"); break; } } private void addDescription(Location startLocation, Structure structure) { if (structure.getClass() == Foundation.class) { setFoundationSing(startLocation,(Foundation) structure); } else { setWallSing(startLocation, (Building) structure, BlockFace.NORTH); setWallSing(startLocation, (Building) structure, BlockFace.EAST); setWallSing(startLocation, (Building) structure, BlockFace.WEST); setWallSing(startLocation, (Building) structure, BlockFace.SOUTH); } } private void setWallSing(Location startLocation, Building building, BlockFace orientation) { org.bukkit.block.Sign sign1 = null; org.bukkit.block.Sign sign2 = null; org.bukkit.block.Sign sign1o = null; org.bukkit.block.Sign sign2o = null; org.bukkit.material.Sign matSign = new org.bukkit.material.Sign(Material.OAK_WALL_SIGN); switch (orientation) { case NORTH: server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 1, -1)).setType(Material.OAK_WALL_SIGN); sign1 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 1, -1)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 3, 1, -1)).setType(Material.OAK_WALL_SIGN); sign2 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 3, 1, -1)).getState(); matSign.setFacingDirection(BlockFace.NORTH); if (building.name.length() > 60) { server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 2, -1)).setType(Material.OAK_WALL_SIGN); sign1o = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 2, -1)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 3, 2, -1)).setType(Material.OAK_WALL_SIGN); sign2o = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 3, 2, -1)).getState(); } break; case EAST: server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 2, 1, 0)).setType(Material.OAK_WALL_SIGN); sign1 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 2, 1, 0)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 2, 1, building.width.y - 3)).setType(Material.OAK_WALL_SIGN); sign2 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 2, 1, building.width.y - 3)).getState(); matSign.setFacingDirection(BlockFace.WEST_NORTH_WEST);//Don't have a clue why this works but getting it made me go mad if (building.name.length() > 60) { server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 2, 2, 0)).setType(Material.OAK_WALL_SIGN); sign1o = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 2, 2, 0)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 2, 2, building.width.y - 3)).setType(Material.OAK_WALL_SIGN); sign2o = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 2, 2, building.width.y - 3)).getState(); } break; case SOUTH: server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 1, building.width.y - 2)).setType(Material.OAK_WALL_SIGN); sign1 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 1, building.width.y - 2)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 3, 1, building.width.y - 2)).setType(Material.OAK_WALL_SIGN); sign2 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 3, 1, building.width.y - 2)).getState(); matSign.setFacingDirection(BlockFace.WEST_SOUTH_WEST);//Same here ;( if (building.name.length() > 60) { server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 2, building.width.y - 2)).setType(Material.OAK_WALL_SIGN); sign1o = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 2, building.width.y - 2)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 3, 2, building.width.y - 2)).setType(Material.OAK_WALL_SIGN); sign2o = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(building.width.x - 3, 2, building.width.y - 2)).getState(); } break; case WEST: server.getWorlds().get(0).getBlockAt(startLocation.clone().add(-1, 1, 0)).setType(Material.OAK_WALL_SIGN); sign1 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(-1, 1, 0)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(-1, 1, building.width.y - 3)).setType(Material.OAK_WALL_SIGN); sign2 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(-1, 1, building.width.y - 3)).getState(); matSign.setFacingDirection(BlockFace.WEST); if (building.name.length() > 60) { server.getWorlds().get(0).getBlockAt(startLocation.clone().add(-1, 2, 0)).setType(Material.OAK_WALL_SIGN); sign1o = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(-1, 2, 0)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(-1, 2, building.width.y - 3)).setType(Material.OAK_WALL_SIGN); sign2o = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(-1, 2, building.width.y - 3)).getState(); } break; default: Bukkit.getLogger().log(Level.SEVERE, "falsche Orientierung übergeben!"); } Objects.requireNonNull(sign1).setData(matSign); Objects.requireNonNull(sign2o).setData(matSign); sign1.setGlowingText(true); sign2.setGlowingText(true); if (building.name.length() > 60) { Objects.requireNonNull(sign1o).setData(matSign); Objects.requireNonNull(sign2o).setData(matSign); sign1o.setGlowingText(true); sign2o.setGlowingText(true); setTextToSign(sign1, sign1o, building.name); setTextToSign(sign2, sign2o, building.name); }else{ setTextToSign(sign1, building.name); setTextToSign(sign2, building.name); } } private void setTextToSign(Sign sign, String text) { int i = (text.length() > 15) ? text.length() - 15 : 0; sign.setLine(3, text.substring(i)); int i1 = (text.length() > 30) ? text.length() - 30 : 0; sign.setLine(2, text.substring(i1, i)); int i2 = (text.length() > 45) ? text.length() - 45 : 0; sign.setLine(1, text.substring(i2, i1)); sign.setLine(0, text.substring(Math.max(text.length() - 60 , 0), i2)); sign.update(); } private void setTextToSign(Sign sign, Sign oSign, String text) { setTextToSign(sign, text); int i = Math.max(text.length() - 75 , 0); oSign.setLine(3, text.substring(i, Math.max(text.length() - 60 , 0))); int i1 = Math.max(text.length() - 90 , 0); oSign.setLine(2, text.substring(i1, i)); int i2 = Math.max(text.length() - 105 , 0); oSign.setLine(1, text.substring(i2, i1)); oSign.setLine(0, text.substring(Math.max(text.length() - 120 , 0), i2)); oSign.update(); } private void setFoundationSing(Location startLocation, Foundation foundation) { server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 0, 0)).setType(Material.OAK_SIGN); org.bukkit.block.Sign sign = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 0, 0)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(foundation.width.x-1, 0, 0)).setType(Material.OAK_SIGN); org.bukkit.block.Sign sign1 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(foundation.width.x-1, 0, 0)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 0, (foundation.getWidth().y==0)?foundation.getWidth().x-1:foundation.getWidth().y-1)).setType(Material.OAK_SIGN); org.bukkit.block.Sign sign2 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0, 0, (foundation.getWidth().y==0)?foundation.getWidth().x-1:foundation.getWidth().y-1)).getState(); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(foundation.getWidth().x-1, 0, (foundation.getWidth().y==0)?foundation.getWidth().x-1:foundation.getWidth().y-1)).setType(Material.OAK_SIGN); org.bukkit.block.Sign sign3 = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation.clone().add(foundation.getWidth().x-1, 0, (foundation.getWidth().y==0)?foundation.getWidth().x-1:foundation.getWidth().y-1)).getState(); org.bukkit.material.Sign matSign = new org.bukkit.material.Sign(Material.OAK_SIGN); matSign.setFacingDirection(BlockFace.NORTH_WEST); sign.setData(matSign); matSign.setFacingDirection(BlockFace.NORTH_EAST); sign1.setData(matSign); matSign.setFacingDirection(BlockFace.SOUTH_WEST); sign2.setData(matSign); matSign.setFacingDirection(BlockFace.SOUTH_EAST); sign3.setData(matSign); sign.setGlowingText(true); sign1.setGlowingText(true); sign2.setGlowingText(true); sign3.setGlowingText(true); setTextToSign(sign,foundation.name.split("/")[foundation.name.split("/").length-1]); setTextToSign(sign1,foundation.name.split("/")[foundation.name.split("/").length-1]); setTextToSign(sign2,foundation.name.split("/")[foundation.name.split("/").length-1]); setTextToSign(sign3,foundation.name.split("/")[foundation.name.split("/").length-1]); } public void setLegend(Location startLocation){ server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,0,-6)).setType(Material.WAXED_COPPER_BLOCK); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,1,-6)).setType(Material.WAXED_EXPOSED_COPPER); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,2,-6)).setType(Material.WAXED_WEATHERED_COPPER); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,3,-6)).setType(Material.WAXED_OXIDIZED_COPPER); setLegendBlock(startLocation.clone().add(-1,0,-6),"1. Quartal","Zeit seit dem","Erstem Commit"); setLegendBlock(startLocation.clone().add(-1,1,-6),"2. Quartal","Zeit seit dem","Erstem Commit"); setLegendBlock(startLocation.clone().add(-1,2,-6),"3. Quartal","Zeit seit dem","Erstem Commit"); setLegendBlock(startLocation.clone().add(-1,3,-6),"4. Quartal","Zeit seit dem","Erstem Commit"); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,0,-5)).setType(Material.WHITE_STAINED_GLASS); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,1,-5)).setType(Material.GLASS); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,2,-5)).setType(Material.BLUE_STAINED_GLASS); server.getWorlds().get(0).getBlockAt(startLocation.clone().add(0,3,-5)).setType(Material.IRON_BARS); setLegendBlock(startLocation.clone().add(-1,0,-5),"1. Quartal","Zeit seit dem","Letzten Commit"); setLegendBlock(startLocation.clone().add(-1,1,-5),"2. Quartal","Zeit seit dem","Letzten Commit"); setLegendBlock(startLocation.clone().add(-1,2,-5),"3. Quartal","Zeit seit dem","Letzten Commit"); setLegendBlock(startLocation.clone().add(-1,3,-5),"4. Quartal","Zeit seit dem","Letzten Commit"); setLegendBlock(startLocation.clone().add(-1,0,-4),"Breite der","Gebäude = ","#Variablen-3"); setLegendBlock(startLocation.clone().add(-1,1,-4),"Höhe der ","Gebäude =","#Methoden"); setLegendBlock(startLocation.clone().add(-1,2,-4),"Höhe der ","Antenne ≈","Komplexität"); setLegendBlock(startLocation.clone().add(-1,3,-4),"Höhe der ","Kräne =","#Commits"); } private void setLegendBlock(Location startLocation,String s1,String s2,String s3){ org.bukkit.material.Sign matSign = new org.bukkit.material.Sign(Material.OAK_WALL_SIGN); org.bukkit.block.Sign sign; server.getWorlds().get(0).getBlockAt(startLocation).setType(Material.OAK_WALL_SIGN); sign = (org.bukkit.block.Sign) server.getWorlds().get(0).getBlockAt(startLocation).getState(); sign.setGlowingText(true); sign.setGlowingText(true); sign.setLine(1,s1); sign.setLine(2,s2); sign.setLine(3,s3); matSign.setFacingDirection(BlockFace.WEST); sign.setData(matSign); sign.update(); } }