Skip to content

Commit

Permalink
Improved the wall generator.
Browse files Browse the repository at this point in the history
 - Two-blocks walls: one replaces air-like blocks, the other replaces solid blocks.
 - This avoid "light-gaps" with glass walls.
  • Loading branch information
AmauryCarrade committed Jul 18, 2014
1 parent bef1459 commit f47913f
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 55 deletions.
51 changes: 0 additions & 51 deletions src/main/java/me/azenet/UHPlugin/UHPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
import java.util.logging.Logger;

import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.SkullType;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
Expand Down Expand Up @@ -182,55 +180,6 @@ public Recipe getRecipe(String name) {
throw new IllegalArgumentException("Unknow recipe");
}


/**
* Generate the walls around the map.
*
* @throws Exception
*/
public boolean generateWalls(World w) {
Integer halfMapSize = (int) Math.floor(this.getConfig().getInt("map.size")/2);
Integer wallHeight = this.getConfig().getInt("map.wall.height");
Material wallBlock = Material.getMaterial(this.getConfig().getString("map.wall.block").toUpperCase());

if(wallBlock == null || !wallBlock.isSolid()) {
logger.severe("Unable to build the wall, the block set in the config file is invalid.");
return false;
}

Location spawn = w.getSpawnLocation();
Integer limitXInf = spawn.add(-halfMapSize, 0, 0).getBlockX();

spawn = w.getSpawnLocation();
Integer limitXSup = spawn.add(halfMapSize, 0, 0).getBlockX();

spawn = w.getSpawnLocation();
Integer limitZInf = spawn.add(0, 0, -halfMapSize).getBlockZ();

spawn = w.getSpawnLocation();
Integer limitZSup = spawn.add(0, 0, halfMapSize).getBlockZ();

for (Integer x = limitXInf; x <= limitXSup; x++) {
w.getBlockAt(x, 1, limitZInf).setType(Material.BEDROCK);
w.getBlockAt(x, 1, limitZSup).setType(Material.BEDROCK);
for (Integer y = 2; y <= wallHeight; y++) {
w.getBlockAt(x, y, limitZInf).setType(wallBlock);
w.getBlockAt(x, y, limitZSup).setType(wallBlock);
}
}

for (Integer z = limitZInf; z <= limitZSup; z++) {
w.getBlockAt(limitXInf, 1, z).setType(Material.BEDROCK);
w.getBlockAt(limitXSup, 1, z).setType(Material.BEDROCK);
for (Integer y = 2; y <= wallHeight; y++) {
w.getBlockAt(limitXInf, y, z).setType(wallBlock);
w.getBlockAt(limitXSup, y, z).setType(wallBlock);
}
}

return true;
}

public UHTeamManager getTeamManager() {
return teamManager;
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/me/azenet/UHPlugin/UHPluginCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,12 @@ private void doGeneratewalls(CommandSender sender, Command command, String label
sender.sendMessage(ci + "From the console, generating the walls of the default world, " + world.getName());
}


try {
Boolean success = p.generateWalls(world);
UHWallGenerator wallGenerator = new UHWallGenerator(this.p, world);
Boolean success = wallGenerator.build();

if(!success) {
sender.sendMessage(ce + "Unable to generate the wall: the block set in the config is not valid.");
sender.sendMessage(ce + "Unable to generate the wall: see logs for details. The blocks set in the config are probably invalid.");
}
}
catch(Exception e) {
Expand Down
160 changes: 160 additions & 0 deletions src/main/java/me/azenet/UHPlugin/UHWallGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package me.azenet.UHPlugin;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;

public class UHWallGenerator {

private UHPlugin p = null;
private World w = null;

Material wallBlockAir = null;
Material wallBlockSolid = null;

public UHWallGenerator(UHPlugin p, World w) {
this.p = p;
this.w = w;
}

/**
* Generate the walls around the map.
*
* @throws Exception
*/
public boolean build() {
Integer halfMapSize = (int) Math.floor(p.getConfig().getInt("map.size")/2);
Integer wallHeight = p.getConfig().getInt("map.wall.height");

this.wallBlockAir = Material.matchMaterial(p.getConfig().getString("map.wall.block.replaceAir"));
this.wallBlockSolid = Material.matchMaterial(p.getConfig().getString("map.wall.block.replaceSolid"));

if(wallBlockAir == null || !wallBlockAir.isSolid() || wallBlockSolid == null || !wallBlockSolid.isSolid()) {
p.getLogger().severe("Unable to build the wall, the blocks set in the config file are invalid.");
return false;
}

Location spawn = w.getSpawnLocation();
Integer limitXInf = spawn.add(-halfMapSize, 0, 0).getBlockX();

spawn = w.getSpawnLocation();
Integer limitXSup = spawn.add(halfMapSize, 0, 0).getBlockX();

spawn = w.getSpawnLocation();
Integer limitZInf = spawn.add(0, 0, -halfMapSize).getBlockZ();

spawn = w.getSpawnLocation();
Integer limitZSup = spawn.add(0, 0, halfMapSize).getBlockZ();

for (Integer x = limitXInf; x <= limitXSup; x++) {
w.getBlockAt(x, 1, limitZInf).setType(Material.BEDROCK);
w.getBlockAt(x, 1, limitZSup).setType(Material.BEDROCK);

for (Integer y = 2; y <= wallHeight; y++) {
setBlock(w.getBlockAt(x, y, limitZInf), WallPosition.NORTH);
setBlock(w.getBlockAt(x, y, limitZSup), WallPosition.SOUTH);
}
}

for (Integer z = limitZInf; z <= limitZSup; z++) {
w.getBlockAt(limitXInf, 1, z).setType(Material.BEDROCK);
w.getBlockAt(limitXSup, 1, z).setType(Material.BEDROCK);
for (Integer y = 2; y <= wallHeight; y++) {
setBlock(w.getBlockAt(limitXInf, y, z), WallPosition.WEST);
setBlock(w.getBlockAt(limitXSup, y, z), WallPosition.EAST);
}
}

return true;
}

/**
* Set a block according to his environment.
* If the block replaces a "air/tree" block, or if it is next to a transparent block, it needs to be a
* "wall.block.replaceAir" block.
* In all other cases, it needs to be a "wall.block.replaceSolid" one.
*
* @param block The block to set.
* @param position The position of the current wall in the world
*/
private void setBlock(Block block, WallPosition position) {
// The block is a transparent block or a tree
if(isBlockTransparentOrTree(block.getType())) {
block.setType(wallBlockAir);
}
// We set the block according to the block near it inside the border.
else {
Material innerMaterial = getInnerBlock(block, position).getType();
if(innerMaterial.isTransparent() || innerMaterial.equals(Material.WATER)) {
block.setType(wallBlockAir);
}
else {
block.setType(wallBlockSolid);
}
}
}

/**
* Checks if a block is transparent or is par of a tree.
* Used to generate the wall.
*
* @return bool True if the block is transparent, or part of a tree.
*/
private Boolean isBlockTransparentOrTree(Material blockType) {
if(blockType.isTransparent()
|| blockType.equals(Material.LEAVES) || blockType.equals(Material.LEAVES_2)
|| blockType.equals(Material.LOG) || blockType.equals(Material.LOG_2)
|| blockType.equals(Material.CHEST) || blockType.equals(Material.TRAPPED_CHEST)
|| blockType.equals(Material.WATER)) {
return true;
}
return false;
}

/**
* Gets the block left to the given block inside the border.
*
* @param block The reference block.
* @param position The position of the wall currently build.
*/
private Block getInnerBlock(Block block, WallPosition position) {
// Just for readability.
Integer x = block.getX();
Integer y = block.getY();
Integer z = block.getZ();

switch(position) {
case EAST:
return w.getBlockAt(x - 1, y, z);
case NORTH:
return w.getBlockAt(x, y, z + 1);
case SOUTH:
return w.getBlockAt(x, y, z - 1);
case WEST:
return w.getBlockAt(x + 1, y, z);
default: // wait what?
return null;
}
}

/**
* Used to determine in witch wall we are, to get the "inner" block.
*
* North: small Z
* South: big Z
* East: big X
* West: small X
*/
public enum WallPosition {
NORTH("N"),
SOUTH("S"),
EAST("E"),
WEST("W"),
;

WallPosition(String position) {

}
}
}
6 changes: 5 additions & 1 deletion src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ map:
size: 2000
wall:
height: 128
block: BEDROCK
block:
# The replaceAir block will be placed where there where some transparent blocks or trees before.
# The replaceSolid one, where there was an other kind of block.
replaceAir: GLASS
replaceSolid: BEDROCK

daylightCycle:
do: false
Expand Down

0 comments on commit f47913f

Please sign in to comment.