Flora rotation options

This commit is contained in:
dfsek
2020-12-09 14:07:33 -07:00
parent 47438b7db9
commit aea2b23fc3
4 changed files with 56 additions and 3 deletions

View File

@@ -16,6 +16,6 @@ public class FloraFactory implements TerraFactory<FloraTemplate, Flora> {
for(PaletteLayer layer : config.getFloraPalette()) {
palette.add(layer.getLayer(), layer.getSize());
}
return new TerraFlora(palette, config.doPhysics(), config.isCeiling(), config.getIrrigable(), config.getSpawnable(), config.getReplaceable(), config.getMaxPlacements(), config.getSearch(), config.isSpawnBlacklist(), config.getIrrigableOffset());
return new TerraFlora(palette, config.doPhysics(), config.isCeiling(), config.getIrrigable(), config.getSpawnable(), config.getReplaceable(), config.getRotatable(), config.getMaxPlacements(), config.getSearch(), config.isSpawnBlacklist(), config.getIrrigableOffset());
}
}

View File

@@ -35,6 +35,11 @@ public class FloraTemplate extends AbstractableTemplate {
@Default
private MaterialSet irrigable = null;
@Value("rotatable")
@Abstractable
@Default
private MaterialSet rotatable = new MaterialSet();
@Value("layers")
@Abstractable
private List<PaletteLayer> palette;
@@ -107,4 +112,8 @@ public class FloraTemplate extends AbstractableTemplate {
public boolean isSpawnBlacklist() {
return spawnBlacklist;
}
public MaterialSet getRotatable() {
return rotatable;
}
}

View File

@@ -7,7 +7,12 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.MultipleFacing;
import org.bukkit.block.data.Rotatable;
import org.polydev.gaea.math.Range;
import org.polydev.gaea.util.FastRandom;
import org.polydev.gaea.util.GlueList;
import org.polydev.gaea.world.Flora;
import org.polydev.gaea.world.palette.Palette;
@@ -24,6 +29,8 @@ public class TerraFlora implements Flora {
private final MaterialSet spawnable;
private final MaterialSet replaceable;
private final MaterialSet testRotation;
private final int maxPlacements;
private final Search search;
@@ -32,9 +39,10 @@ public class TerraFlora implements Flora {
private final int irrigableOffset;
public TerraFlora(Palette<BlockData> floraPalette, boolean physics, boolean ceiling, MaterialSet irrigable, MaterialSet spawnable, MaterialSet replaceable, int maxPlacements, Search search, boolean spawnBlacklist, int irrigableOffset) {
public TerraFlora(Palette<BlockData> floraPalette, boolean physics, boolean ceiling, MaterialSet irrigable, MaterialSet spawnable, MaterialSet replaceable, MaterialSet testRotation, int maxPlacements, Search search, boolean spawnBlacklist, int irrigableOffset) {
this.floraPalette = floraPalette;
this.physics = physics;
this.testRotation = testRotation;
this.spawnBlacklist = spawnBlacklist;
this.ceiling = ceiling;
this.irrigable = irrigable;
@@ -81,15 +89,47 @@ public class TerraFlora implements Flora {
@Override
public boolean plant(Location location) {
boolean doRotation = testRotation.size() > 0;
int size = floraPalette.getSize();
int c = ceiling ? -1 : 1;
List<BlockFace> faces = doRotation ? getFaces(location.clone().add(0, c, 0).getBlock()) : new GlueList<>();
if(doRotation && faces.size() == 0) return false; // Don't plant if no faces are valid.
BlockFace oneFace = doRotation ? faces.get(new FastRandom(location.getBlockX() ^ location.getBlockZ()).nextInt(faces.size())) : null; // Get random face.
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
int lvl = (FastMath.abs(i));
location.clone().add(0, i + c, 0).getBlock().setBlockData(floraPalette.get((ceiling ? lvl : size - lvl - 1), location.getBlockX(), location.getBlockZ()), physics);
BlockData data = floraPalette.get((ceiling ? lvl : size - lvl - 1), location.getBlockX(), location.getBlockZ()).clone();
if(doRotation) {
if(data instanceof Directional) {
((Directional) data).setFacing(oneFace);
} else if(data instanceof MultipleFacing) {
MultipleFacing o = (MultipleFacing) data;
for(BlockFace face : o.getFaces()) o.setFace(face, false);
for(BlockFace face : faces) o.setFace(face, true);
} else if(data instanceof Rotatable) {
((Rotatable) data).setRotation(oneFace);
}
}
location.clone().add(0, i + c, 0).getBlock().setBlockData(data, physics);
}
return true;
}
private List<BlockFace> getFaces(Block b) {
List<BlockFace> faces = new GlueList<>();
test(faces, BlockFace.NORTH, b);
test(faces, BlockFace.SOUTH, b);
test(faces, BlockFace.EAST, b);
test(faces, BlockFace.WEST, b);
return faces;
}
private void test(List<BlockFace> faces, BlockFace f, Block b) {
if(testRotation.contains(b.getRelative(f).getType())) faces.add(f);
}
public enum Search {
UP,
DOWN

View File

@@ -39,7 +39,9 @@ public final class TagUtil {
putCustomSet("minecraft:base_stone_overworld", Material.STONE, Material.GRANITE, Material.DIORITE, Material.ANDESITE);
Set<Material> snow = new HashSet<>();
Set<Material> solid = new HashSet<>();
for(Material m : Material.values()) {
if(m.isSolid()) solid.add(m);
String name = m.toString().toLowerCase();
if(name.contains("slab")
|| name.contains("stair")
@@ -55,7 +57,9 @@ public final class TagUtil {
|| !m.isSolid()) snow.add(m);
}
tagMap.put("terra:snow_blacklist", snow);
tagMap.put("terra:solid", solid);
Debug.info("Added " + snow.size() + " materials to snow blacklist");
Debug.info("Added " + solid.size() + " materials to solid list");
Debug.info("Loaded " + tagMap.size() + " tags.");
}