mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-25 18:19:14 +00:00
Schematics
This commit is contained in:
@@ -4,29 +4,25 @@ import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.util.RealBiome;
|
||||
import ninja.bytecode.shuriken.bench.Profiler;
|
||||
import ninja.bytecode.shuriken.collections.GMap;
|
||||
import ninja.bytecode.shuriken.collections.GSet;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor;
|
||||
import ninja.bytecode.shuriken.format.F;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
|
||||
public class Iris extends JavaPlugin implements Listener
|
||||
{
|
||||
@@ -46,6 +42,7 @@ public class Iris extends JavaPlugin implements Listener
|
||||
gen = new IrisGenerator();
|
||||
genPool = new TaskExecutor(getTC(), settings.performance.threadPriority, "Iris Generator");
|
||||
getServer().getPluginManager().registerEvents((Listener) this, this);
|
||||
new WandManager();
|
||||
|
||||
// Debug world regens
|
||||
GSet<String> ws = new GSet<>();
|
||||
@@ -90,6 +87,7 @@ public class Iris extends JavaPlugin implements Listener
|
||||
public void onDisable()
|
||||
{
|
||||
genPool.close();
|
||||
HandlerList.unregisterAll((Plugin) this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,63 +99,17 @@ public class Iris extends JavaPlugin implements Listener
|
||||
@EventHandler
|
||||
public void on(PlayerCommandPreprocessEvent e)
|
||||
{
|
||||
if(e.getMessage().toLowerCase().equals("/iris"))
|
||||
if(e.getMessage().toLowerCase().equals("/iris gen"))
|
||||
{
|
||||
e.setCancelled(true);
|
||||
World wold = e.getPlayer().getWorld();
|
||||
World w = createIrisWorld();
|
||||
e.getPlayer().teleport(new Location(w, 0, 256, 0));
|
||||
e.getPlayer().setFlying(true);
|
||||
e.getPlayer().setGameMode(GameMode.CREATIVE);
|
||||
e.setCancelled(true);
|
||||
wold.setAutoSave(false);
|
||||
Bukkit.unloadWorld(wold, false);
|
||||
}
|
||||
|
||||
if(e.getMessage().toLowerCase().equals("/iris info"))
|
||||
{
|
||||
e.setCancelled(true);
|
||||
sendInfo(e.getPlayer());
|
||||
|
||||
for(Biome i : Biome.values())
|
||||
{
|
||||
J.attempt(() -> System.out.print(new RealBiome(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendInfo(Player player)
|
||||
{
|
||||
for(int i = 0; i < 18; i++)
|
||||
{
|
||||
player.sendMessage("");
|
||||
}
|
||||
|
||||
GMap<String, Function<Vector, Double>> w = values.get(player.getWorld().getName());
|
||||
for(String i : w.k())
|
||||
{
|
||||
double value = w.get(i).apply(player.getLocation().toVector());
|
||||
String p = i.substring(0, 2);
|
||||
String v = value + "";
|
||||
|
||||
if(p.startsWith("%"))
|
||||
{
|
||||
v = F.pc(value, Integer.valueOf(p.substring(1)));
|
||||
}
|
||||
|
||||
if(p.startsWith("D"))
|
||||
{
|
||||
v = F.f(value, Integer.valueOf(p.substring(1)));
|
||||
}
|
||||
|
||||
else if(p.startsWith("^"))
|
||||
{
|
||||
double c = M.lerpInverse(-11, 37, value);
|
||||
double f = 32 + (c * (1.8));
|
||||
v = F.f(c, Integer.valueOf(p.substring(1))) + " \u00B0C / " + F.f(f, Integer.valueOf(p.substring(1))) + " \u00B0F";
|
||||
}
|
||||
|
||||
player.sendMessage(ChatColor.GREEN + i.substring(2) + ": " + ChatColor.RESET + ChatColor.WHITE + ChatColor.BOLD + v);
|
||||
}
|
||||
}
|
||||
|
||||
private World createIrisWorld()
|
||||
|
||||
@@ -9,8 +9,8 @@ public class Settings
|
||||
|
||||
public static class PerformanceSettings
|
||||
{
|
||||
public PerformanceMode performanceMode = PerformanceMode.HALF_CPU;
|
||||
public int threadCount = 4;
|
||||
public PerformanceMode performanceMode = PerformanceMode.MATCH_CPU;
|
||||
public int threadCount = 12;
|
||||
public int threadPriority = Thread.MAX_PRIORITY;
|
||||
}
|
||||
|
||||
|
||||
101
src/main/java/ninja/bytecode/iris/WandManager.java
Normal file
101
src/main/java/ninja/bytecode/iris/WandManager.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package ninja.bytecode.iris;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
import ninja.bytecode.iris.schematic.Schematic;
|
||||
import ninja.bytecode.iris.util.WandUtil;
|
||||
|
||||
public class WandManager implements Listener
|
||||
{
|
||||
public WandManager()
|
||||
{
|
||||
Bukkit.getPluginManager().registerEvents(this, Iris.instance);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerCommandPreprocessEvent e)
|
||||
{
|
||||
if(e.getMessage().startsWith("/isave "))
|
||||
{
|
||||
e.setCancelled(true);
|
||||
Schematic s = WandUtil.createSchematic(e.getPlayer().getInventory().getItemInMainHand(), e.getPlayer().getLocation());
|
||||
File f = new File(Iris.instance.getDataFolder(), "schematics/" + e.getMessage().split("\\Q \\E")[1] + ".ish");
|
||||
f.getParentFile().mkdirs();
|
||||
try
|
||||
{
|
||||
FileOutputStream fos = new FileOutputStream(f);
|
||||
s.write(fos);
|
||||
e.getPlayer().sendMessage("Done!");
|
||||
}
|
||||
|
||||
catch(Throwable e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if(e.getMessage().startsWith("/iload "))
|
||||
{
|
||||
e.setCancelled(true);
|
||||
Schematic s = new Schematic(1, 1, 1, 1, 1, 1);
|
||||
File f = new File(Iris.instance.getDataFolder(), "schematics/" + e.getMessage().split("\\Q \\E")[1] + ".ish");
|
||||
if(!f.exists())
|
||||
{
|
||||
e.getPlayer().sendMessage("Not Found");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileInputStream fin = new FileInputStream(f);
|
||||
s.read(fin);
|
||||
WandUtil.pasteSchematic(s, e.getPlayer().getLocation());
|
||||
e.getPlayer().sendMessage("Done!");
|
||||
}
|
||||
|
||||
catch(Throwable e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if(e.getMessage().equals("/iris wand"))
|
||||
{
|
||||
e.setCancelled(true);
|
||||
e.getPlayer().getInventory().addItem(WandUtil.createWand());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerInteractEvent e)
|
||||
{
|
||||
if(e.getHand().equals(EquipmentSlot.HAND) && WandUtil.isWand(e.getPlayer().getInventory().getItemInMainHand()))
|
||||
{
|
||||
if(e.getAction().equals(Action.LEFT_CLICK_BLOCK))
|
||||
{
|
||||
e.setCancelled(true);
|
||||
e.getPlayer().getInventory().setItemInMainHand(WandUtil.update(true, e.getPlayer().getLocation(), e.getPlayer().getInventory().getItemInMainHand()));
|
||||
|
||||
e.getPlayer().updateInventory();
|
||||
}
|
||||
|
||||
else if(e.getAction().equals(Action.RIGHT_CLICK_BLOCK))
|
||||
{
|
||||
e.setCancelled(true);
|
||||
e.getPlayer().getInventory().setItemInMainHand(WandUtil.update(false, e.getPlayer().getLocation(), e.getPlayer().getInventory().getItemInMainHand()));
|
||||
|
||||
e.getPlayer().updateInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package ninja.bytecode.iris.generator;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -12,15 +13,19 @@ import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.biome.IrisBiome;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerBase;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerBiome;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerCaves;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise;
|
||||
import ninja.bytecode.iris.generator.layer.GenLayerRidge;
|
||||
import ninja.bytecode.iris.generator.populator.PopulatorTrees;
|
||||
import ninja.bytecode.iris.generator.populator.BiomeBiasSchematicPopulator;
|
||||
import ninja.bytecode.iris.schematic.Schematic;
|
||||
import ninja.bytecode.iris.util.AtomicChunkData;
|
||||
import ninja.bytecode.iris.util.ChunkPlan;
|
||||
import ninja.bytecode.iris.util.IrisInterpolation;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.iris.util.ParallelChunkGenerator;
|
||||
import ninja.bytecode.shuriken.collections.GList;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
@@ -32,8 +37,8 @@ public class IrisGenerator extends ParallelChunkGenerator
|
||||
private GenLayerLayeredNoise glLNoise;
|
||||
private GenLayerRidge glRidge;
|
||||
private GenLayerBiome glBiome;
|
||||
private GenLayerCaves glCaves;
|
||||
private RNG rTerrain;
|
||||
private RNG rScatter;
|
||||
private World world;
|
||||
|
||||
@Override
|
||||
@@ -45,11 +50,7 @@ public class IrisGenerator extends ParallelChunkGenerator
|
||||
glLNoise = new GenLayerLayeredNoise(this, world, random, rTerrain.nextParallelRNG(2));
|
||||
glRidge = new GenLayerRidge(this, world, random, rTerrain.nextParallelRNG(3));
|
||||
glBiome = new GenLayerBiome(this, world, random, rTerrain.nextParallelRNG(4));
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return world;
|
||||
glCaves = new GenLayerCaves(this, world, random, rTerrain.nextParallelRNG(-1));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,8 +70,10 @@ public class IrisGenerator extends ParallelChunkGenerator
|
||||
hv += glLNoise.generateLayer(hv, wxx, wzx);
|
||||
hv -= glRidge.generateLayer(hv, wxx, wzx);
|
||||
int height = (int) Math.round(M.clip(hv, 0D, 1D) * 253);
|
||||
int max = Math.max(height, seaLevel);
|
||||
IrisBiome override = null;
|
||||
|
||||
for(int i = 0; i < Math.max(height, seaLevel); i++)
|
||||
for(int i = 0; i < max; i++)
|
||||
{
|
||||
MB mb = new MB(Material.STONE);
|
||||
boolean underwater = i >= height && i < seaLevel;
|
||||
@@ -88,10 +91,43 @@ public class IrisGenerator extends ParallelChunkGenerator
|
||||
|
||||
if(i == height - 1)
|
||||
{
|
||||
if(height > 61 && height < glBase.scatterInt(x, i, z, 4) + 65)
|
||||
{
|
||||
override = IrisBiome.BEACH;
|
||||
}
|
||||
|
||||
else if(height < 63)
|
||||
{
|
||||
if(i < 36)
|
||||
{
|
||||
override = IrisBiome.DEEP_OCEAN;
|
||||
}
|
||||
|
||||
else if(i < 50)
|
||||
{
|
||||
override = IrisBiome.OCEAN;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
override = IrisBiome.LAKE;
|
||||
}
|
||||
}
|
||||
|
||||
if(override != null)
|
||||
{
|
||||
biome = override;
|
||||
}
|
||||
|
||||
mb = biome.getSurface(wx, wz, rTerrain);
|
||||
}
|
||||
|
||||
if(Iris.settings.gen.flatBedrock ? i == 0 : i < glBase.scatterInt(x, i, z, 3))
|
||||
if(i == 0)
|
||||
{
|
||||
mb = BEDROCK;
|
||||
}
|
||||
|
||||
if(Iris.settings.gen.flatBedrock ? i == 1 : i < glBase.scatterInt(x, i, z, 3))
|
||||
{
|
||||
mb = BEDROCK;
|
||||
}
|
||||
@@ -99,6 +135,13 @@ public class IrisGenerator extends ParallelChunkGenerator
|
||||
setBlock(x, i, z, mb.material, mb.data);
|
||||
}
|
||||
|
||||
glCaves.genCaves(wxx, wzx, x, z, height, this);
|
||||
|
||||
if(override != null)
|
||||
{
|
||||
return override.getRealBiome();
|
||||
}
|
||||
|
||||
return biome.getRealBiome();
|
||||
}
|
||||
|
||||
@@ -114,24 +157,73 @@ public class IrisGenerator extends ParallelChunkGenerator
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPopulator> getDefaultPopulators(World world)
|
||||
{
|
||||
GList<BlockPopulator> p = new GList<>();
|
||||
int b = 0;
|
||||
for(IrisBiome i : IrisBiome.getBiomes())
|
||||
{
|
||||
b++;
|
||||
L.i("Processing Populators for Biome " + i.getName());
|
||||
|
||||
for(String j : i.getSchematicGroups().keySet())
|
||||
{
|
||||
p.add(new BiomeBiasSchematicPopulator(i.getSchematicGroups().get(j), i, loadSchematics(j)));
|
||||
}
|
||||
}
|
||||
|
||||
J.attempt(() -> p.add(new BiomeBiasSchematicPopulator(5, IrisBiome.JUNGLE, loadSchematics(""))));
|
||||
|
||||
L.i("Initialized " + b + " Biomes and " + p.size() + " Populators");
|
||||
L.flush();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private Schematic[] loadSchematics(String folder)
|
||||
{
|
||||
File f = new File(Iris.instance.getDataFolder(), "objects/" + folder);
|
||||
GList<Schematic> s = new GList<>();
|
||||
|
||||
try
|
||||
{
|
||||
if(f.exists() && f.isDirectory())
|
||||
{
|
||||
for(File i : f.listFiles())
|
||||
{
|
||||
if(i.isFile() && i.getName().endsWith(".ish"))
|
||||
{
|
||||
s.add(Schematic.load(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return s.toArray(new Schematic[s.size()]);
|
||||
}
|
||||
|
||||
private double getBiomedHeight(int x, int z, ChunkPlan plan)
|
||||
{
|
||||
return plan.getHeight(x, z, () -> {
|
||||
return plan.getHeight(x, z, () ->
|
||||
{
|
||||
int wx = (int) Math.round((double) x * Iris.settings.gen.horizontalZoom);
|
||||
int wz = (int) Math.round((double) z * Iris.settings.gen.horizontalZoom);
|
||||
IrisBiome biome = glBiome.getBiome(wx * Iris.settings.gen.biomeScale, wz * Iris.settings.gen.biomeScale);
|
||||
double h = Iris.settings.gen.baseHeight + biome.getHeight();
|
||||
h += (glBase.getHeight(wx, wz) * biome.getAmp()) - (0.33 * biome.getAmp());
|
||||
|
||||
|
||||
return h;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPopulator> getDefaultPopulators(World world)
|
||||
public World getWorld()
|
||||
{
|
||||
GList<BlockPopulator> p = new GList<BlockPopulator>();
|
||||
p.add(new PopulatorTrees());
|
||||
return p;
|
||||
return world;
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@ public class IrisBiome
|
||||
.surface(MB.of(Material.SAND), MB.of(Material.SAND), MB.of(Material.SAND), MB.of(Material.CLAY), MB.of(Material.GRAVEL))
|
||||
.simplexSurface()
|
||||
.height(-0.03);
|
||||
public static final IrisBiome LAKE = new IrisBiome("Lake", Biome.OCEAN)
|
||||
.surface(MB.of(Material.SAND), MB.of(Material.SAND), MB.of(Material.SAND), MB.of(Material.GRAVEL), MB.of(Material.CLAY), MB.of(Material.GRAVEL))
|
||||
.simplexSurface()
|
||||
.height(-0.03);
|
||||
public static final IrisBiome DEEP_OCEAN = new IrisBiome("Deep Ocean", Biome.DEEP_OCEAN)
|
||||
.surface(MB.of(Material.SAND), MB.of(Material.CLAY), MB.of(Material.GRAVEL))
|
||||
.simplexSurface()
|
||||
@@ -237,7 +241,7 @@ public class IrisBiome
|
||||
simplexScatter = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public IrisBiome scatterSurface()
|
||||
{
|
||||
scatterSurface = true;
|
||||
@@ -312,9 +316,9 @@ public class IrisBiome
|
||||
});
|
||||
}
|
||||
|
||||
return poly.getChoice(wx * 0.2D, wz * 0.2D);
|
||||
return poly.getChoice(wx * 0.2D, wz * 0.2D);
|
||||
}
|
||||
|
||||
|
||||
if(scatterSurface)
|
||||
{
|
||||
if(poly == null)
|
||||
@@ -325,7 +329,7 @@ public class IrisBiome
|
||||
});
|
||||
}
|
||||
|
||||
return poly.getChoice(wx * 0.2D, wz * 0.2D);
|
||||
return poly.getChoice(wx * 0.2D, wz * 0.2D);
|
||||
}
|
||||
|
||||
return getSurface().getRandom();
|
||||
@@ -385,7 +389,12 @@ public class IrisBiome
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IrisBiome find(Biome biome)
|
||||
public static GList<IrisBiome> getBiomes()
|
||||
{
|
||||
return map.v().remove(IrisBiome.ROAD_GRASSY, IrisBiome.ROAD_GRAVEL, IrisBiome.BEACH, IrisBiome.LAKE, IrisBiome.RIVER);
|
||||
}
|
||||
|
||||
public static IrisBiome findByBiome(Biome biome)
|
||||
{
|
||||
if(map.containsKey(biome))
|
||||
{
|
||||
@@ -394,4 +403,9 @@ public class IrisBiome
|
||||
|
||||
return IrisBiome.PLAINS;
|
||||
}
|
||||
|
||||
public GMap<String, Double> getSchematicGroups()
|
||||
{
|
||||
return schematicGroups;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,38 +33,7 @@ public class GenLayerBiome extends GenLayer
|
||||
riverCheck = new CNG(rng.nextParallelRNG(30), 1D, 2).scale(0.00096);
|
||||
pathCheck = new CNG(rng.nextParallelRNG(31), 1D, 1).scale(0.00096);
|
||||
roads = new MaxingGenerator(rng.nextParallelRNG(32), 5, 0.00055, 8, factory);
|
||||
biomeGenerator = new EnumMaxingGenerator<IrisBiome>(rng.nextParallelRNG(33), 0.00755 * Iris.settings.gen.biomeScale, 1,
|
||||
new IrisBiome[] {
|
||||
IrisBiome.HAUNTED_FOREST,
|
||||
IrisBiome.FOREST_MOUNTAINS,
|
||||
IrisBiome.DESERT,
|
||||
IrisBiome.DESERT_HILLS,
|
||||
IrisBiome.MESA,
|
||||
IrisBiome.DESERT_COMBINED,
|
||||
IrisBiome.SAVANNA,
|
||||
IrisBiome.SAVANNA_HILLS,
|
||||
IrisBiome.DESERT_RED,
|
||||
IrisBiome.JUNGLE,
|
||||
IrisBiome.JUNGLE_HILLS,
|
||||
IrisBiome.SWAMP,
|
||||
IrisBiome.OCEAN,
|
||||
IrisBiome.PLAINS,
|
||||
IrisBiome.DECAYING_PLAINS,
|
||||
IrisBiome.FOREST,
|
||||
IrisBiome.FOREST_HILLS,
|
||||
IrisBiome.BIRCH_FOREST,
|
||||
IrisBiome.BIRCH_FOREST_HILLS,
|
||||
IrisBiome.ROOFED_FOREST,
|
||||
IrisBiome.TAIGA,
|
||||
IrisBiome.EXTREME_HILLS,
|
||||
IrisBiome.EXTREME_HILLS_TREES,
|
||||
IrisBiome.TAIGA_COLD,
|
||||
IrisBiome.TAIGA_COLD_HILLS,
|
||||
IrisBiome.ICE_FLATS,
|
||||
IrisBiome.ICE_MOUNTAINS,
|
||||
IrisBiome.REDWOOD_TAIGA,
|
||||
IrisBiome.REDWOOD_TAIGA_HILLS,
|
||||
}, factory);
|
||||
biomeGenerator = new EnumMaxingGenerator<IrisBiome>(rng.nextParallelRNG(33), 0.00755 * Iris.settings.gen.biomeScale, 1, IrisBiome.getBiomes().toArray(new IrisBiome[IrisBiome.getBiomes().size()]), factory);
|
||||
//@done
|
||||
}
|
||||
|
||||
@@ -72,7 +41,7 @@ public class GenLayerBiome extends GenLayer
|
||||
{
|
||||
double x = xx + (fracture.noise(zz, xx) * 1550D);
|
||||
double z = zz - (fracture.noise(xx, zz) * 1550D);
|
||||
|
||||
|
||||
if(riverCheck.noise(x, z) > 0.75)
|
||||
{
|
||||
if(biomeGenerator.hasBorder(3, 3 + Math.pow(riverCheck.noise(x, z), 1.25) * 16, x, z))
|
||||
@@ -80,24 +49,24 @@ public class GenLayerBiome extends GenLayer
|
||||
return IrisBiome.RIVER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IrisBiome cbi = biomeGenerator.getChoice(x, z);
|
||||
|
||||
|
||||
if(pathCheck.noise(x, z) > 0.33)
|
||||
{
|
||||
IrisBiome road = IrisBiome.ROAD_GRAVEL;
|
||||
|
||||
|
||||
if(cbi.getSurface().get(0).material.equals(Material.GRASS))
|
||||
{
|
||||
road = IrisBiome.ROAD_GRASSY;
|
||||
}
|
||||
|
||||
|
||||
if(Math.abs(road.getHeight() - cbi.getHeight()) < 0.0001 && roads.hasBorder(4, 3, xx, zz))
|
||||
{
|
||||
return road;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return cbi;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package ninja.bytecode.iris.generator.layer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.generator.IrisGenerator;
|
||||
import ninja.bytecode.iris.util.GenLayer;
|
||||
import ninja.bytecode.iris.util.MaxingGenerator;
|
||||
import ninja.bytecode.shuriken.math.CNG;
|
||||
import ninja.bytecode.shuriken.math.RNG;
|
||||
|
||||
public class GenLayerCaves extends GenLayer
|
||||
{
|
||||
private CNG caveHeight;
|
||||
private CNG caveGirth;
|
||||
private CNG caveClamp;
|
||||
private MaxingGenerator caveVeins;
|
||||
|
||||
public GenLayerCaves(IrisGenerator iris, World world, Random random, RNG rng)
|
||||
{
|
||||
super(iris, world, random, rng);
|
||||
caveHeight = new CNG(rng.nextParallelRNG(-100001), 1D, 7).scale(0.00222);
|
||||
caveGirth = new CNG(rng.nextParallelRNG(-100002), 1D, 12).scale(0.03);
|
||||
caveClamp = new CNG(rng.nextParallelRNG(-10000), 1D, 3).scale(0.1422);
|
||||
caveVeins = new MaxingGenerator(rng.nextParallelRNG(-99999), 22, 0.002, 1, (g) -> g.fractureWith(new CNG(rng.nextParallelRNG(-5555), 1D, 4).scale(0.02), 70));
|
||||
|
||||
}
|
||||
|
||||
public void genCaves(double wxx, double wzx, int x, int z, int s, IrisGenerator g)
|
||||
{
|
||||
for(double itr = 0; itr < 0.2; itr += 0.1)
|
||||
{
|
||||
double thickness = 0.25 + itr + (0.5 * caveClamp.noise(wxx, wzx));
|
||||
double size = 3.88D * thickness;
|
||||
double variance = 8.34D * thickness;
|
||||
double w = size + (variance * caveGirth.noise(wxx, wzx));
|
||||
double h = size + (variance * caveGirth.noise(wzx, wxx));
|
||||
double width = 0;
|
||||
double height = h;
|
||||
double elevation = (caveHeight.noise(wxx + (19949D * itr), wzx - (19949D * itr)) * (350)) - 80;
|
||||
while(width <= w && height > 1D)
|
||||
{
|
||||
width+=2;
|
||||
height-=2;
|
||||
|
||||
if(caveVeins.hasBorder(3, width, wxx - (19949D * itr), wzx + (19949D * itr)))
|
||||
{
|
||||
double r = (((caveGirth.noise(wxx, wzx, width)) * variance) + height) / 2D;
|
||||
|
||||
for(int i = (int) -r; i < r; i++)
|
||||
{
|
||||
if(i + height > s)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Material t = g.getType(x, (int) (elevation + i) - 55, z);
|
||||
if(t.equals(Material.BEDROCK) || t.equals(Material.WATER) || t.equals(Material.STATIONARY_WATER))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
g.setBlock(x, (int) (elevation + i) - 55, z, Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double generateLayer(double gnoise, double dx, double dz)
|
||||
{
|
||||
return gnoise;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package ninja.bytecode.iris.generator.populator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
||||
import ninja.bytecode.iris.generator.biome.IrisBiome;
|
||||
import ninja.bytecode.iris.schematic.Schematic;
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
|
||||
public class BiomeBiasSchematicPopulator extends SurfaceBiasSchematicPopulator
|
||||
{
|
||||
protected IrisBiome biome;
|
||||
public BiomeBiasSchematicPopulator(double chance, IrisBiome biome, Schematic... schematics)
|
||||
{
|
||||
super(chance, schematics);
|
||||
this.biome = biome;
|
||||
|
||||
for(MB i : biome.getSurface())
|
||||
{
|
||||
surface(i.material);
|
||||
}
|
||||
}
|
||||
|
||||
public void doPopulate(World world, Random random, Chunk source, int wx, int wz)
|
||||
{
|
||||
if(world.getBiome(wx, wz).equals(biome.getRealBiome()))
|
||||
{
|
||||
super.doPopulate(world, random, source, wx, wz);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package ninja.bytecode.iris.generator.populator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeType;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.biome.IrisBiome;
|
||||
import ninja.bytecode.shuriken.bench.PrecisionStopwatch;
|
||||
import ninja.bytecode.shuriken.math.RollingSequence;
|
||||
|
||||
public class PopulatorTrees extends BlockPopulator
|
||||
{
|
||||
public static RollingSequence timings = new RollingSequence(512);
|
||||
|
||||
@Override
|
||||
public void populate(World world, Random random, Chunk source)
|
||||
{
|
||||
if(!Iris.settings.gen.doTrees)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PrecisionStopwatch f = PrecisionStopwatch.start();
|
||||
int debuff = 0;
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(debuff > 0)
|
||||
{
|
||||
debuff--;
|
||||
continue;
|
||||
}
|
||||
|
||||
int x = random.nextInt(15) + (source.getX() * 16);
|
||||
int z = random.nextInt(15) + (source.getZ() * 16);
|
||||
int y = world.getHighestBlockYAt(x, z);
|
||||
Location l = new Location(world, x, y, z);
|
||||
|
||||
if(!l.getBlock().getType().isSolid())
|
||||
{
|
||||
l.getBlock().setType(Material.AIR, false);
|
||||
}
|
||||
|
||||
IrisBiome biome = IrisBiome.find(world.getBiome(x, z));
|
||||
TreeType tt = biome.getTreeChanceSingle();
|
||||
|
||||
if(tt != null)
|
||||
{
|
||||
world.generateTree(l, tt);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
debuff += 4;
|
||||
}
|
||||
}
|
||||
|
||||
f.end();
|
||||
timings.put(f.getMilliseconds());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package ninja.bytecode.iris.generator.populator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
import ninja.bytecode.iris.schematic.Schematic;
|
||||
import ninja.bytecode.iris.util.ChancedPopulator;
|
||||
|
||||
public class SchematicPopulator extends ChancedPopulator
|
||||
{
|
||||
protected final Schematic[] schematics;
|
||||
|
||||
public SchematicPopulator(double chance, Schematic... schematics)
|
||||
{
|
||||
super(chance);
|
||||
this.schematics = schematics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doPopulate(World world, Random random, Chunk source, int wx, int wz)
|
||||
{
|
||||
Block b = world.getHighestBlockAt(wx, wz);
|
||||
|
||||
if(!b.getRelative(BlockFace.DOWN).getType().isSolid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
schematics[random.nextInt(schematics.length)].place(world, wx, b.getY() - 1, wz);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package ninja.bytecode.iris.generator.populator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
import ninja.bytecode.iris.schematic.Schematic;
|
||||
import ninja.bytecode.shuriken.collections.GList;
|
||||
|
||||
public class SurfaceBiasSchematicPopulator extends SchematicPopulator
|
||||
{
|
||||
private GList<Material> bias;
|
||||
|
||||
public SurfaceBiasSchematicPopulator(double chance, Schematic... schematics)
|
||||
{
|
||||
super(chance, schematics);
|
||||
this.bias = new GList<>();
|
||||
}
|
||||
|
||||
public SurfaceBiasSchematicPopulator surface(Material mb)
|
||||
{
|
||||
bias.add(mb);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doPopulate(World world, Random random, Chunk source, int wx, int wz)
|
||||
{
|
||||
Block b = world.getHighestBlockAt(wx, wz);
|
||||
|
||||
for(Material i : bias)
|
||||
{
|
||||
if(b.getRelative(BlockFace.DOWN).getType().equals(i))
|
||||
{
|
||||
schematics[random.nextInt(schematics.length)].place(world, wx, b.getY() - 1, wz);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
210
src/main/java/ninja/bytecode/iris/schematic/Schematic.java
Normal file
210
src/main/java/ninja/bytecode/iris/schematic/Schematic.java
Normal file
@@ -0,0 +1,210 @@
|
||||
package ninja.bytecode.iris.schematic;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.BlockVector;
|
||||
|
||||
import ninja.bytecode.iris.util.MB;
|
||||
import ninja.bytecode.shuriken.collections.GMap;
|
||||
import ninja.bytecode.shuriken.io.CustomOutputStream;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
|
||||
public class Schematic
|
||||
{
|
||||
private int w;
|
||||
private int h;
|
||||
private int d;
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
private final GMap<BlockVector, MB> s;
|
||||
|
||||
public Schematic(int w, int h, int d, int x, int y, int z)
|
||||
{
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
this.d = d;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
s = new GMap<>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getW()
|
||||
{
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getH()
|
||||
{
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getD()
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getX()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getY()
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getZ()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public GMap<BlockVector, MB> getSchematic()
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void read(InputStream in) throws IOException
|
||||
{
|
||||
GZIPInputStream gzi = new GZIPInputStream(in);
|
||||
DataInputStream din = new DataInputStream(gzi);
|
||||
w = din.readInt();
|
||||
h = din.readInt();
|
||||
d = din.readInt();
|
||||
x = din.readInt();
|
||||
y = din.readInt();
|
||||
z = din.readInt();
|
||||
int l = din.readInt();
|
||||
clear();
|
||||
|
||||
for(int i = 0; i < l; i++)
|
||||
{
|
||||
s.put(new BlockVector(din.readInt(), din.readInt(), din.readInt()), new MB(Material.getMaterial((int)din.readByte()), din.readByte()));
|
||||
}
|
||||
|
||||
din.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void write(OutputStream out) throws IOException
|
||||
{
|
||||
CustomOutputStream cos = new CustomOutputStream(out, 9);
|
||||
DataOutputStream dos = new DataOutputStream(cos);
|
||||
dos.writeInt(w);
|
||||
dos.writeInt(h);
|
||||
dos.writeInt(d);
|
||||
dos.writeInt(x);
|
||||
dos.writeInt(y);
|
||||
dos.writeInt(z);
|
||||
dos.writeInt(s.size());
|
||||
|
||||
for(BlockVector i : s.keySet())
|
||||
{
|
||||
dos.writeInt(i.getBlockX());
|
||||
dos.writeInt(i.getBlockY());
|
||||
dos.writeInt(i.getBlockZ());
|
||||
dos.writeByte(s.get(i).material.getId());
|
||||
dos.writeByte(s.get(i).data);
|
||||
}
|
||||
|
||||
dos.close();
|
||||
}
|
||||
|
||||
public BlockVector getOffset()
|
||||
{
|
||||
return new BlockVector(x, y, z);
|
||||
}
|
||||
|
||||
public MB get(int x, int y, int z)
|
||||
{
|
||||
return s.get(new BlockVector(x, y, z));
|
||||
}
|
||||
|
||||
public boolean has(int x, int y, int z)
|
||||
{
|
||||
return s.contains(new BlockVector(x, y, z));
|
||||
}
|
||||
|
||||
public void put(int x, int y, int z, MB mb)
|
||||
{
|
||||
s.put(new BlockVector(x, y, z), mb);
|
||||
}
|
||||
|
||||
public Schematic copy()
|
||||
{
|
||||
Schematic s = new Schematic(w, h, d, x, y, z);
|
||||
s.fill(this.s);
|
||||
return s;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
s.clear();
|
||||
}
|
||||
|
||||
public void fill(GMap<BlockVector, MB> b)
|
||||
{
|
||||
clear();
|
||||
s.put(b);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void place(World source, int wx, int wy, int wz)
|
||||
{
|
||||
Location start = new Location(source, wx, wy, wz).clone().subtract(getOffset());
|
||||
|
||||
for(BlockVector i : getSchematic().keySet())
|
||||
{
|
||||
MB b = getSchematic().get(i);
|
||||
Block blk = start.clone().add(i).getBlock();
|
||||
|
||||
if(!blk.isEmpty() && !b.material.isOccluding())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
blk.setTypeIdAndData(b.material.getId(), b.data, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Schematic load(File f) throws IOException
|
||||
{
|
||||
L.i("Loading Schematic: " + f.getPath());
|
||||
Schematic s = new Schematic(1, 1, 1, 1, 1, 1);
|
||||
FileInputStream fin = new FileInputStream(f);
|
||||
s.read(fin);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
48
src/main/java/ninja/bytecode/iris/util/ChancedPopulator.java
Normal file
48
src/main/java/ninja/bytecode/iris/util/ChancedPopulator.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package ninja.bytecode.iris.util;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
|
||||
import ninja.bytecode.shuriken.math.M;
|
||||
|
||||
public abstract class ChancedPopulator extends BlockPopulator
|
||||
{
|
||||
private final double chance;
|
||||
|
||||
public ChancedPopulator(double chance)
|
||||
{
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(World world, Random random, Chunk source)
|
||||
{
|
||||
if(chance == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(chance > 0 && chance < 1 && M.r(chance))
|
||||
{
|
||||
doPopulate(world, random, source, (source.getX() << 4) + random.nextInt(16), (source.getZ() << 4) + random.nextInt(16));
|
||||
}
|
||||
|
||||
if(chance > 1)
|
||||
{
|
||||
for(int i = 0; i < (int) chance; i++)
|
||||
{
|
||||
doPopulate(world, random, source, (source.getX() << 4) + random.nextInt(16), (source.getZ() << 4) + random.nextInt(16));
|
||||
}
|
||||
|
||||
if(M.r(chance - ((int) chance)))
|
||||
{
|
||||
doPopulate(world, random, source, (source.getX() << 4) + random.nextInt(16), (source.getZ() << 4) + random.nextInt(16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void doPopulate(World world, Random random, Chunk source, int x, int z);
|
||||
}
|
||||
@@ -2,18 +2,28 @@ package ninja.bytecode.iris.util;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.bukkit.util.BlockVector;
|
||||
|
||||
import ninja.bytecode.iris.generator.biome.IrisBiome;
|
||||
import ninja.bytecode.iris.schematic.Schematic;
|
||||
import ninja.bytecode.shuriken.collections.GMap;
|
||||
|
||||
public class ChunkPlan
|
||||
{
|
||||
private final GMap<ChunkedVector, Double> heightCache;
|
||||
private final GMap<ChunkedVector, IrisBiome> biomeCache;
|
||||
private final GMap<BlockVector, Schematic> schematics;
|
||||
|
||||
public ChunkPlan()
|
||||
{
|
||||
this.heightCache = new GMap<ChunkedVector, Double>();
|
||||
this.biomeCache = new GMap<ChunkedVector, IrisBiome>();
|
||||
this.schematics = new GMap<>();
|
||||
this.heightCache = new GMap<>();
|
||||
this.biomeCache = new GMap<>();
|
||||
}
|
||||
|
||||
public void planSchematic(BlockVector b, Schematic s)
|
||||
{
|
||||
schematics.put(b, s);
|
||||
}
|
||||
|
||||
public IrisBiome getBiome(int x, int z)
|
||||
|
||||
910
src/main/java/ninja/bytecode/iris/util/Cuboid.java
Normal file
910
src/main/java/ninja/bytecode/iris/util/Cuboid.java
Normal file
@@ -0,0 +1,910 @@
|
||||
package ninja.bytecode.iris.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import ninja.bytecode.shuriken.collections.GList;
|
||||
|
||||
/**
|
||||
* Cuboids
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializable
|
||||
{
|
||||
protected final String worldName;
|
||||
protected int x1, y1, z1;
|
||||
protected int x2, y2, z2;
|
||||
|
||||
/**
|
||||
* Construct a Cuboid given two Location objects which represent any two corners
|
||||
* of the Cuboid.
|
||||
*
|
||||
* @param l1
|
||||
* one of the corners
|
||||
* @param l2
|
||||
* the other corner
|
||||
*/
|
||||
public Cuboid(Location l1, Location l2)
|
||||
{
|
||||
if(!l1.getWorld().equals(l2.getWorld()))
|
||||
{
|
||||
throw new IllegalArgumentException("locations must be on the same world");
|
||||
}
|
||||
|
||||
worldName = l1.getWorld().getName();
|
||||
x1 = Math.min(l1.getBlockX(), l2.getBlockX());
|
||||
y1 = Math.min(l1.getBlockY(), l2.getBlockY());
|
||||
z1 = Math.min(l1.getBlockZ(), l2.getBlockZ());
|
||||
x2 = Math.max(l1.getBlockX(), l2.getBlockX());
|
||||
y2 = Math.max(l1.getBlockY(), l2.getBlockY());
|
||||
z2 = Math.max(l1.getBlockZ(), l2.getBlockZ());
|
||||
}
|
||||
|
||||
public GList<LivingEntity> getLivingEntities()
|
||||
{
|
||||
return new GList<LivingEntity>(new GListAdapter<Entity, LivingEntity>()
|
||||
{
|
||||
@Override
|
||||
public LivingEntity onAdapt(Entity from)
|
||||
{
|
||||
if(from instanceof LivingEntity)
|
||||
{
|
||||
return (LivingEntity) from;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}.adapt(getEntities()));
|
||||
}
|
||||
|
||||
public GList<Entity> getEntities()
|
||||
{
|
||||
GList<Entity> en = new GList<Entity>();
|
||||
|
||||
for(Chunk i : getChunks())
|
||||
{
|
||||
for(Entity j : i.getEntities())
|
||||
{
|
||||
if(contains(j.getLocation()))
|
||||
{
|
||||
en.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return en;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locations
|
||||
*
|
||||
* @param l1
|
||||
* a
|
||||
* @param l2
|
||||
* b
|
||||
*/
|
||||
public void set(Location l1, Location l2)
|
||||
{
|
||||
x1 = Math.min(l1.getBlockX(), l2.getBlockX());
|
||||
y1 = Math.min(l1.getBlockY(), l2.getBlockY());
|
||||
z1 = Math.min(l1.getBlockZ(), l2.getBlockZ());
|
||||
x2 = Math.max(l1.getBlockX(), l2.getBlockX());
|
||||
y2 = Math.max(l1.getBlockY(), l2.getBlockY());
|
||||
z2 = Math.max(l1.getBlockZ(), l2.getBlockZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a one-block Cuboid at the given Location of the Cuboid.
|
||||
*
|
||||
* @param l1
|
||||
* location of the Cuboid
|
||||
*/
|
||||
public Cuboid(Location l1)
|
||||
{
|
||||
this(l1, l1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
* @param other
|
||||
* the Cuboid to copy
|
||||
*/
|
||||
public Cuboid(Cuboid other)
|
||||
{
|
||||
this(other.getWorld().getName(), other.x1, other.y1, other.z1, other.x2, other.y2, other.z2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Cuboid in the given World and xyz co-ordinates
|
||||
*
|
||||
* @param world
|
||||
* the Cuboid's world
|
||||
* @param x1
|
||||
* X co-ordinate of corner 1
|
||||
* @param y1
|
||||
* Y co-ordinate of corner 1
|
||||
* @param z1
|
||||
* Z co-ordinate of corner 1
|
||||
* @param x2
|
||||
* X co-ordinate of corner 2
|
||||
* @param y2
|
||||
* Y co-ordinate of corner 2
|
||||
* @param z2
|
||||
* Z co-ordinate of corner 2
|
||||
*/
|
||||
public Cuboid(World world, int x1, int y1, int z1, int x2, int y2, int z2)
|
||||
{
|
||||
this.worldName = world.getName();
|
||||
this.x1 = Math.min(x1, x2);
|
||||
this.x2 = Math.max(x1, x2);
|
||||
this.y1 = Math.min(y1, y2);
|
||||
this.y2 = Math.max(y1, y2);
|
||||
this.z1 = Math.min(z1, z2);
|
||||
this.z2 = Math.max(z1, z2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Cuboid in the given world name and xyz co-ordinates.
|
||||
*
|
||||
* @param worldName
|
||||
* the Cuboid's world name
|
||||
* @param x1
|
||||
* X co-ordinate of corner 1
|
||||
* @param y1
|
||||
* Y co-ordinate of corner 1
|
||||
* @param z1
|
||||
* Z co-ordinate of corner 1
|
||||
* @param x2
|
||||
* X co-ordinate of corner 2
|
||||
* @param y2
|
||||
* Y co-ordinate of corner 2
|
||||
* @param z2
|
||||
* Z co-ordinate of corner 2
|
||||
*/
|
||||
private Cuboid(String worldName, int x1, int y1, int z1, int x2, int y2, int z2)
|
||||
{
|
||||
this.worldName = worldName;
|
||||
this.x1 = Math.min(x1, x2);
|
||||
this.x2 = Math.max(x1, x2);
|
||||
this.y1 = Math.min(y1, y2);
|
||||
this.y2 = Math.max(y1, y2);
|
||||
this.z1 = Math.min(z1, z2);
|
||||
this.z2 = Math.max(z1, z2);
|
||||
}
|
||||
|
||||
public Cuboid(Map<String, Object> map)
|
||||
{
|
||||
worldName = (String) map.get("worldName");
|
||||
x1 = (Integer) map.get("x1");
|
||||
x2 = (Integer) map.get("x2");
|
||||
y1 = (Integer) map.get("y1");
|
||||
y2 = (Integer) map.get("y2");
|
||||
z1 = (Integer) map.get("z1");
|
||||
z2 = (Integer) map.get("z2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize()
|
||||
{
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("worldName", worldName);
|
||||
map.put("x1", x1);
|
||||
map.put("y1", y1);
|
||||
map.put("z1", z1);
|
||||
map.put("x2", x2);
|
||||
map.put("y2", y2);
|
||||
map.put("z2", z2);
|
||||
return map;
|
||||
}
|
||||
|
||||
public Cuboid flatten(int level)
|
||||
{
|
||||
return new Cuboid(getWorld(), x1, level, z1, x2, level, z2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Location of the lower northeast corner of the Cuboid (minimum XYZ
|
||||
* co-ordinates).
|
||||
*
|
||||
* @return Location of the lower northeast corner
|
||||
*/
|
||||
public Location getLowerNE()
|
||||
{
|
||||
return new Location(getWorld(), x1, y1, z1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Location of the upper southwest corner of the Cuboid (maximum XYZ
|
||||
* co-ordinates).
|
||||
*
|
||||
* @return Location of the upper southwest corner
|
||||
*/
|
||||
public Location getUpperSW()
|
||||
{
|
||||
return new Location(getWorld(), x2, y2, z2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the the centre of the Cuboid
|
||||
*
|
||||
* @return Location at the centre of the Cuboid
|
||||
*/
|
||||
public Location getCenter()
|
||||
{
|
||||
int x1 = getUpperX() + 1;
|
||||
int y1 = getUpperY() + 1;
|
||||
int z1 = getUpperZ() + 1;
|
||||
return new Location(getWorld(), getLowerX() + (x1 - getLowerX()) / 2.0, getLowerY() + (y1 - getLowerY()) / 2.0, getLowerZ() + (z1 - getLowerZ()) / 2.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Cuboid's world.
|
||||
*
|
||||
* @return the World object representing this Cuboid's world
|
||||
* @throws IllegalStateException
|
||||
* if the world is not loaded
|
||||
*/
|
||||
public World getWorld()
|
||||
{
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if(world == null)
|
||||
{
|
||||
throw new IllegalStateException("world '" + worldName + "' is not loaded");
|
||||
}
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of this Cuboid along the X axis
|
||||
*
|
||||
* @return Size of Cuboid along the X axis
|
||||
*/
|
||||
public int getSizeX()
|
||||
{
|
||||
return (x2 - x1) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of this Cuboid along the Y axis
|
||||
*
|
||||
* @return Size of Cuboid along the Y axis
|
||||
*/
|
||||
public int getSizeY()
|
||||
{
|
||||
return (y2 - y1) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of this Cuboid along the Z axis
|
||||
*
|
||||
* @return Size of Cuboid along the Z axis
|
||||
*/
|
||||
public int getSizeZ()
|
||||
{
|
||||
return (z2 - z1) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cuboid dimensions
|
||||
*
|
||||
* @return the dimensions
|
||||
*/
|
||||
public Dimension getDimension()
|
||||
{
|
||||
return new Dimension(getSizeX(), getSizeY(), getSizeZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum X co-ordinate of this Cuboid
|
||||
*
|
||||
* @return the minimum X co-ordinate
|
||||
*/
|
||||
public int getLowerX()
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum Y co-ordinate of this Cuboid
|
||||
*
|
||||
* @return the minimum Y co-ordinate
|
||||
*/
|
||||
public int getLowerY()
|
||||
{
|
||||
return y1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum Z co-ordinate of this Cuboid
|
||||
*
|
||||
* @return the minimum Z co-ordinate
|
||||
*/
|
||||
public int getLowerZ()
|
||||
{
|
||||
return z1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum X co-ordinate of this Cuboid
|
||||
*
|
||||
* @return the maximum X co-ordinate
|
||||
*/
|
||||
public int getUpperX()
|
||||
{
|
||||
return x2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum Y co-ordinate of this Cuboid
|
||||
*
|
||||
* @return the maximum Y co-ordinate
|
||||
*/
|
||||
public int getUpperY()
|
||||
{
|
||||
return y2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum Z co-ordinate of this Cuboid
|
||||
*
|
||||
* @return the maximum Z co-ordinate
|
||||
*/
|
||||
public int getUpperZ()
|
||||
{
|
||||
return z2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Blocks at the eight corners of the Cuboid.
|
||||
*
|
||||
* @return array of Block objects representing the Cuboid corners
|
||||
*/
|
||||
public Block[] corners()
|
||||
{
|
||||
Block[] res = new Block[8];
|
||||
World w = getWorld();
|
||||
res[0] = w.getBlockAt(x1, y1, z1);
|
||||
res[1] = w.getBlockAt(x1, y1, z2);
|
||||
res[2] = w.getBlockAt(x1, y2, z1);
|
||||
res[3] = w.getBlockAt(x1, y2, z2);
|
||||
res[4] = w.getBlockAt(x2, y1, z1);
|
||||
res[5] = w.getBlockAt(x2, y1, z2);
|
||||
res[6] = w.getBlockAt(x2, y2, z1);
|
||||
res[7] = w.getBlockAt(x2, y2, z2);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the Cuboid in the given direction by the given amount. Negative
|
||||
* amounts will shrink the Cuboid in the given direction. Shrinking a cuboid's
|
||||
* face past the opposite face is not an error and will return a valid Cuboid.
|
||||
*
|
||||
* @param dir
|
||||
* the direction in which to expand
|
||||
* @param amount
|
||||
* the number of blocks by which to expand
|
||||
* @return a new Cuboid expanded by the given direction and amount
|
||||
*/
|
||||
public Cuboid expand(CuboidDirection dir, int amount)
|
||||
{
|
||||
switch(dir)
|
||||
{
|
||||
case North:
|
||||
return new Cuboid(worldName, x1 - amount, y1, z1, x2, y2, z2);
|
||||
case South:
|
||||
return new Cuboid(worldName, x1, y1, z1, x2 + amount, y2, z2);
|
||||
case East:
|
||||
return new Cuboid(worldName, x1, y1, z1 - amount, x2, y2, z2);
|
||||
case West:
|
||||
return new Cuboid(worldName, x1, y1, z1, x2, y2, z2 + amount);
|
||||
case Down:
|
||||
return new Cuboid(worldName, x1, y1 - amount, z1, x2, y2, z2);
|
||||
case Up:
|
||||
return new Cuboid(worldName, x1, y1, z1, x2, y2 + amount, z2);
|
||||
default:
|
||||
throw new IllegalArgumentException("invalid direction " + dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift the Cuboid in the given direction by the given amount.
|
||||
*
|
||||
* @param dir
|
||||
* the direction in which to shift
|
||||
* @param amount
|
||||
* the number of blocks by which to shift
|
||||
* @return a new Cuboid shifted by the given direction and amount
|
||||
*/
|
||||
public Cuboid shift(CuboidDirection dir, int amount)
|
||||
{
|
||||
return expand(dir, amount).expand(dir.opposite(), -amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outset (grow) the Cuboid in the given direction by the given amount.
|
||||
*
|
||||
* @param dir
|
||||
* the direction in which to outset (must be Horizontal, Vertical, or
|
||||
* Both)
|
||||
* @param amount
|
||||
* the number of blocks by which to outset
|
||||
* @return a new Cuboid outset by the given direction and amount
|
||||
*/
|
||||
public Cuboid outset(CuboidDirection dir, int amount)
|
||||
{
|
||||
Cuboid c;
|
||||
switch(dir)
|
||||
{
|
||||
case Horizontal:
|
||||
c = expand(CuboidDirection.North, amount).expand(CuboidDirection.South, amount).expand(CuboidDirection.East, amount).expand(CuboidDirection.West, amount);
|
||||
break;
|
||||
case Vertical:
|
||||
c = expand(CuboidDirection.Down, amount).expand(CuboidDirection.Up, amount);
|
||||
break;
|
||||
case Both:
|
||||
c = outset(CuboidDirection.Horizontal, amount).outset(CuboidDirection.Vertical, amount);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("invalid direction " + dir);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inset (shrink) the Cuboid in the given direction by the given amount.
|
||||
* Equivalent to calling outset() with a negative amount.
|
||||
*
|
||||
* @param dir
|
||||
* the direction in which to inset (must be Horizontal, Vertical, or
|
||||
* Both)
|
||||
* @param amount
|
||||
* the number of blocks by which to inset
|
||||
* @return a new Cuboid inset by the given direction and amount
|
||||
*/
|
||||
public Cuboid inset(CuboidDirection dir, int amount)
|
||||
{
|
||||
return outset(dir, -amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the point at (x,y,z) is contained within this Cuboid.
|
||||
*
|
||||
* @param x
|
||||
* the X co-ordinate
|
||||
* @param y
|
||||
* the Y co-ordinate
|
||||
* @param z
|
||||
* the Z co-ordinate
|
||||
* @return true if the given point is within this Cuboid, false otherwise
|
||||
*/
|
||||
public boolean contains(int x, int y, int z)
|
||||
{
|
||||
return x >= x1 && x <= x2 && y >= y1 && y <= y2 && z >= z1 && z <= z2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given Block is contained within this Cuboid.
|
||||
*
|
||||
* @param b
|
||||
* the Block to check for
|
||||
* @return true if the Block is within this Cuboid, false otherwise
|
||||
*/
|
||||
public boolean contains(Block b)
|
||||
{
|
||||
return contains(b.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given Location is contained within this Cuboid.
|
||||
*
|
||||
* @param l
|
||||
* the Location to check for
|
||||
* @return true if the Location is within this Cuboid, false otherwise
|
||||
*/
|
||||
public boolean contains(Location l)
|
||||
{
|
||||
return worldName.equals(l.getWorld().getName()) && contains(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the volume of this Cuboid.
|
||||
*
|
||||
* @return the Cuboid volume, in blocks
|
||||
*/
|
||||
public int volume()
|
||||
{
|
||||
return getSizeX() * getSizeY() * getSizeZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the average light level of all empty (air) blocks in the Cuboid. Returns
|
||||
* 0 if there are no empty blocks.
|
||||
*
|
||||
* @return the average light level of this Cuboid
|
||||
*/
|
||||
public byte averageLightLevel()
|
||||
{
|
||||
long total = 0;
|
||||
int n = 0;
|
||||
for(Block b : this)
|
||||
{
|
||||
if(b.isEmpty())
|
||||
{
|
||||
total += b.getLightLevel();
|
||||
++n;
|
||||
}
|
||||
}
|
||||
return n > 0 ? (byte) (total / n) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contract the Cuboid, returning a Cuboid with any air around the edges
|
||||
* removed, just large enough to include all non-air blocks.
|
||||
*
|
||||
* @return a new Cuboid with no external air blocks
|
||||
*/
|
||||
public Cuboid contract()
|
||||
{
|
||||
return this.contract(CuboidDirection.Down).contract(CuboidDirection.South).contract(CuboidDirection.East).contract(CuboidDirection.Up).contract(CuboidDirection.North).contract(CuboidDirection.West);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contract the Cuboid in the given direction, returning a new Cuboid which has
|
||||
* no exterior empty space. E.g. a direction of Down will push the top face
|
||||
* downwards as much as possible.
|
||||
*
|
||||
* @param dir
|
||||
* the direction in which to contract
|
||||
* @return a new Cuboid contracted in the given direction
|
||||
*/
|
||||
public Cuboid contract(CuboidDirection dir)
|
||||
{
|
||||
Cuboid face = getFace(dir.opposite());
|
||||
switch(dir)
|
||||
{
|
||||
case Down:
|
||||
while(face.containsOnly(Material.AIR) && face.getLowerY() > this.getLowerY())
|
||||
{
|
||||
face = face.shift(CuboidDirection.Down, 1);
|
||||
}
|
||||
return new Cuboid(worldName, x1, y1, z1, x2, face.getUpperY(), z2);
|
||||
case Up:
|
||||
while(face.containsOnly(Material.AIR) && face.getUpperY() < this.getUpperY())
|
||||
{
|
||||
face = face.shift(CuboidDirection.Up, 1);
|
||||
}
|
||||
return new Cuboid(worldName, x1, face.getLowerY(), z1, x2, y2, z2);
|
||||
case North:
|
||||
while(face.containsOnly(Material.AIR) && face.getLowerX() > this.getLowerX())
|
||||
{
|
||||
face = face.shift(CuboidDirection.North, 1);
|
||||
}
|
||||
return new Cuboid(worldName, x1, y1, z1, face.getUpperX(), y2, z2);
|
||||
case South:
|
||||
while(face.containsOnly(Material.AIR) && face.getUpperX() < this.getUpperX())
|
||||
{
|
||||
face = face.shift(CuboidDirection.South, 1);
|
||||
}
|
||||
return new Cuboid(worldName, face.getLowerX(), y1, z1, x2, y2, z2);
|
||||
case East:
|
||||
while(face.containsOnly(Material.AIR) && face.getLowerZ() > this.getLowerZ())
|
||||
{
|
||||
face = face.shift(CuboidDirection.East, 1);
|
||||
}
|
||||
return new Cuboid(worldName, x1, y1, z1, x2, y2, face.getUpperZ());
|
||||
case West:
|
||||
while(face.containsOnly(Material.AIR) && face.getUpperZ() < this.getUpperZ())
|
||||
{
|
||||
face = face.shift(CuboidDirection.West, 1);
|
||||
}
|
||||
return new Cuboid(worldName, x1, y1, face.getLowerZ(), x2, y2, z2);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid direction " + dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Cuboid representing the face of this Cuboid. The resulting Cuboid
|
||||
* will be one block thick in the axis perpendicular to the requested face.
|
||||
*
|
||||
* @param dir
|
||||
* which face of the Cuboid to get
|
||||
* @return the Cuboid representing this Cuboid's requested face
|
||||
*/
|
||||
public Cuboid getFace(CuboidDirection dir)
|
||||
{
|
||||
switch(dir)
|
||||
{
|
||||
case Down:
|
||||
return new Cuboid(worldName, x1, y1, z1, x2, y1, z2);
|
||||
case Up:
|
||||
return new Cuboid(worldName, x1, y2, z1, x2, y2, z2);
|
||||
case North:
|
||||
return new Cuboid(worldName, x1, y1, z1, x1, y2, z2);
|
||||
case South:
|
||||
return new Cuboid(worldName, x2, y1, z1, x2, y2, z2);
|
||||
case East:
|
||||
return new Cuboid(worldName, x1, y1, z1, x2, y2, z1);
|
||||
case West:
|
||||
return new Cuboid(worldName, x1, y1, z2, x2, y2, z2);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid direction " + dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Cuboid contains only blocks of the given type
|
||||
*
|
||||
* @param material
|
||||
* the material to check for
|
||||
* @return true if this Cuboid contains only blocks of the given type
|
||||
*/
|
||||
public boolean containsOnly(Material material)
|
||||
{
|
||||
for(Block b : this)
|
||||
{
|
||||
if(b.getType() != material)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Cuboid big enough to hold both this Cuboid and the given one.
|
||||
*
|
||||
* @param other
|
||||
* the other Cuboid to include
|
||||
* @return a new Cuboid large enough to hold this Cuboid and the given Cuboid
|
||||
*/
|
||||
public Cuboid getBoundingCuboid(Cuboid other)
|
||||
{
|
||||
if(other == null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
int xMin = Math.min(getLowerX(), other.getLowerX());
|
||||
int yMin = Math.min(getLowerY(), other.getLowerY());
|
||||
int zMin = Math.min(getLowerZ(), other.getLowerZ());
|
||||
int xMax = Math.max(getUpperX(), other.getUpperX());
|
||||
int yMax = Math.max(getUpperY(), other.getUpperY());
|
||||
int zMax = Math.max(getUpperZ(), other.getUpperZ());
|
||||
|
||||
return new Cuboid(worldName, xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a block relative to the lower NE point of the Cuboid.
|
||||
*
|
||||
* @param x
|
||||
* the X co-ordinate
|
||||
* @param y
|
||||
* the Y co-ordinate
|
||||
* @param z
|
||||
* the Z co-ordinate
|
||||
* @return the block at the given position
|
||||
*/
|
||||
public Block getRelativeBlock(int x, int y, int z)
|
||||
{
|
||||
return getWorld().getBlockAt(x1 + x, y1 + y, z1 + z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a block relative to the lower NE point of the Cuboid in the given World.
|
||||
* This version of getRelativeBlock() should be used if being called many times,
|
||||
* to avoid excessive calls to getWorld().
|
||||
*
|
||||
* @param w
|
||||
* the World
|
||||
* @param x
|
||||
* the X co-ordinate
|
||||
* @param y
|
||||
* the Y co-ordinate
|
||||
* @param z
|
||||
* the Z co-ordinate
|
||||
* @return the block at the given position
|
||||
*/
|
||||
public Block getRelativeBlock(World w, int x, int y, int z)
|
||||
{
|
||||
return w.getBlockAt(x1 + x, y1 + y, z1 + z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of the chunks which are fully or partially contained in this
|
||||
* cuboid.
|
||||
*
|
||||
* @return a list of Chunk objects
|
||||
*/
|
||||
public List<Chunk> getChunks()
|
||||
{
|
||||
List<Chunk> res = new ArrayList<Chunk>();
|
||||
|
||||
World w = getWorld();
|
||||
int x1 = getLowerX() & ~0xf;
|
||||
int x2 = getUpperX() & ~0xf;
|
||||
int z1 = getLowerZ() & ~0xf;
|
||||
int z2 = getUpperZ() & ~0xf;
|
||||
for(int x = x1; x <= x2; x += 16)
|
||||
{
|
||||
for(int z = z1; z <= z2; z += 16)
|
||||
{
|
||||
res.add(w.getChunkAt(x >> 4, z >> 4));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all the blocks within the Cuboid to the given block ID and data byte.
|
||||
*
|
||||
* @param blockId
|
||||
* the block ID
|
||||
* @param data
|
||||
* the block data
|
||||
* @deprecated use {@link #fill(MaterialData, MassBlockUpdate)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void fill(int blockId, byte data)
|
||||
{
|
||||
for(Block b : this)
|
||||
{
|
||||
b.setTypeIdAndData(blockId, data, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all the blocks within the Cuboid to the given MaterialData, using a
|
||||
* MassBlockUpdate object for fast updates.
|
||||
*
|
||||
* @param mat
|
||||
* the MaterialData to set
|
||||
* @param mbu
|
||||
* the MassBlockUpdate object
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reset the light level of all blocks within this Cuboid.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
@Override
|
||||
public Iterator<Block> iterator()
|
||||
{
|
||||
return new CuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
public Cuboid clone() throws CloneNotSupportedException
|
||||
{
|
||||
return new Cuboid(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Cuboid: " + worldName + "," + x1 + "," + y1 + "," + z1 + "=>" + x2 + "," + y2 + "," + z2;
|
||||
}
|
||||
|
||||
public class CuboidIterator implements Iterator<Block>
|
||||
{
|
||||
private World w;
|
||||
private int baseX, baseY, baseZ;
|
||||
private int x, y, z;
|
||||
private int sizeX, sizeY, sizeZ;
|
||||
|
||||
public CuboidIterator(World w, int x1, int y1, int z1, int x2, int y2, int z2)
|
||||
{
|
||||
this.w = w;
|
||||
baseX = x1;
|
||||
baseY = y1;
|
||||
baseZ = z1;
|
||||
sizeX = Math.abs(x2 - x1) + 1;
|
||||
sizeY = Math.abs(y2 - y1) + 1;
|
||||
sizeZ = Math.abs(z2 - z1) + 1;
|
||||
x = y = z = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
return x < sizeX && y < sizeY && z < sizeZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block next()
|
||||
{
|
||||
Block b = w.getBlockAt(baseX + x, baseY + y, baseZ + z);
|
||||
if(++x >= sizeX)
|
||||
{
|
||||
x = 0;
|
||||
if(++y >= sizeY)
|
||||
{
|
||||
y = 0;
|
||||
++z;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
{
|
||||
// nop
|
||||
}
|
||||
}
|
||||
|
||||
public enum CuboidDirection
|
||||
{
|
||||
|
||||
North,
|
||||
East,
|
||||
South,
|
||||
West,
|
||||
Up,
|
||||
Down,
|
||||
Horizontal,
|
||||
Vertical,
|
||||
Both,
|
||||
Unknown;
|
||||
|
||||
public CuboidDirection opposite()
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case North:
|
||||
return South;
|
||||
case East:
|
||||
return West;
|
||||
case South:
|
||||
return North;
|
||||
case West:
|
||||
return East;
|
||||
case Horizontal:
|
||||
return Vertical;
|
||||
case Vertical:
|
||||
return Horizontal;
|
||||
case Up:
|
||||
return Down;
|
||||
case Down:
|
||||
return Up;
|
||||
case Both:
|
||||
return Both;
|
||||
default:
|
||||
return Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
16
src/main/java/ninja/bytecode/iris/util/CuboidException.java
Normal file
16
src/main/java/ninja/bytecode/iris/util/CuboidException.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package ninja.bytecode.iris.util;
|
||||
|
||||
/**
|
||||
* Represents a cuboid exception
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public class CuboidException extends Exception
|
||||
{
|
||||
public CuboidException(String string)
|
||||
{
|
||||
super(string);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
86
src/main/java/ninja/bytecode/iris/util/Dimension.java
Normal file
86
src/main/java/ninja/bytecode/iris/util/Dimension.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package ninja.bytecode.iris.util;
|
||||
|
||||
/**
|
||||
* Dimensions
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public class Dimension
|
||||
{
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final int depth;
|
||||
|
||||
/**
|
||||
* Make a dimension
|
||||
*
|
||||
* @param width
|
||||
* width of this (X)
|
||||
* @param height
|
||||
* the height (Y)
|
||||
* @param depth
|
||||
* the depth (Z)
|
||||
*/
|
||||
public Dimension(int width, int height, int depth)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.depth = depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a dimension
|
||||
*
|
||||
* @param width
|
||||
* width of this (X)
|
||||
* @param height
|
||||
* the height (Y)
|
||||
*/
|
||||
public Dimension(int width, int height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.depth = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the direction of the flat part of this dimension (null if no thin
|
||||
* face)
|
||||
*
|
||||
* @return the direction of the flat pane or null
|
||||
*/
|
||||
public DimensionFace getPane()
|
||||
{
|
||||
if(width == 1)
|
||||
{
|
||||
return DimensionFace.X;
|
||||
}
|
||||
|
||||
if(height == 1)
|
||||
{
|
||||
return DimensionFace.Y;
|
||||
}
|
||||
|
||||
if(depth == 1)
|
||||
{
|
||||
return DimensionFace.Z;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getDepth()
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
24
src/main/java/ninja/bytecode/iris/util/DimensionFace.java
Normal file
24
src/main/java/ninja/bytecode/iris/util/DimensionFace.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package ninja.bytecode.iris.util;
|
||||
|
||||
/**
|
||||
* Represents a dimension (coordinates not worlds)
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public enum DimensionFace
|
||||
{
|
||||
/**
|
||||
* The X dimension (width)
|
||||
*/
|
||||
X,
|
||||
|
||||
/**
|
||||
* The Y dimension (height)
|
||||
*/
|
||||
Y,
|
||||
|
||||
/**
|
||||
* The Z dimension (depth)
|
||||
*/
|
||||
Z
|
||||
}
|
||||
137
src/main/java/ninja/bytecode/iris/util/Direction.java
Normal file
137
src/main/java/ninja/bytecode/iris/util/Direction.java
Normal file
@@ -0,0 +1,137 @@
|
||||
package ninja.bytecode.iris.util;
|
||||
|
||||
import ninja.bytecode.iris.util.Cuboid.CuboidDirection;
|
||||
import ninja.bytecode.shuriken.collections.GList;
|
||||
|
||||
/**
|
||||
* Directions
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public enum Direction
|
||||
{
|
||||
U(0, 1, 0, CuboidDirection.Up),
|
||||
D(0, -1, 0, CuboidDirection.Down),
|
||||
N(0, 0, -1, CuboidDirection.North),
|
||||
S(0, 0, 1, CuboidDirection.South),
|
||||
E(1, 0, 0, CuboidDirection.East),
|
||||
W(-1, 0, 0, CuboidDirection.West);
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
private CuboidDirection f;
|
||||
|
||||
private Direction(int x, int y, int z, CuboidDirection f)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
public int x()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public int y()
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
public int z()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
|
||||
public CuboidDirection f()
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
public static GList<Direction> news()
|
||||
{
|
||||
return new GList<Direction>().add(N, E, W, S);
|
||||
}
|
||||
|
||||
public static GList<Direction> udnews()
|
||||
{
|
||||
return new GList<Direction>().add(U, D, N, E, W, S);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the directional value from the given byte from common directional blocks
|
||||
* (MUST BE BETWEEN 0 and 5 INCLUSIVE)
|
||||
*
|
||||
* @param b
|
||||
* the byte
|
||||
* @return the direction or null if the byte is outside of the inclusive range
|
||||
* 0-5
|
||||
*/
|
||||
public static Direction fromByte(byte b)
|
||||
{
|
||||
if(b > 5 || b < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if(b == 0)
|
||||
{
|
||||
return D;
|
||||
}
|
||||
|
||||
else if(b == 1)
|
||||
{
|
||||
return U;
|
||||
}
|
||||
|
||||
else if(b == 2)
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
else if(b == 3)
|
||||
{
|
||||
return S;
|
||||
}
|
||||
|
||||
else if(b == 4)
|
||||
{
|
||||
return W;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return E;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the byte value represented in some directional blocks
|
||||
*
|
||||
* @return the byte value
|
||||
*/
|
||||
public byte byteValue()
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case D:
|
||||
return 0;
|
||||
case E:
|
||||
return 5;
|
||||
case N:
|
||||
return 2;
|
||||
case S:
|
||||
return 3;
|
||||
case U:
|
||||
return 1;
|
||||
case W:
|
||||
return 4;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
51
src/main/java/ninja/bytecode/iris/util/GListAdapter.java
Normal file
51
src/main/java/ninja/bytecode/iris/util/GListAdapter.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package ninja.bytecode.iris.util;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ninja.bytecode.shuriken.collections.GList;
|
||||
|
||||
/**
|
||||
* Adapts a list of objects into a list of other objects
|
||||
*
|
||||
* @author cyberpwn
|
||||
* @param <FROM>
|
||||
* the from object in lists (the item INSIDE the list)
|
||||
* @param <TO>
|
||||
* the to object in lists (the item INSIDE the list)
|
||||
*/
|
||||
public abstract class GListAdapter<FROM, TO>
|
||||
{
|
||||
/**
|
||||
* Adapts a list of FROM to a list of TO
|
||||
*
|
||||
* @param from
|
||||
* the from list
|
||||
* @return the to list
|
||||
*/
|
||||
public List<TO> adapt(List<FROM> from)
|
||||
{
|
||||
List<TO> adapted = new GList<TO>();
|
||||
|
||||
for(FROM i : from)
|
||||
{
|
||||
TO t = onAdapt(i);
|
||||
|
||||
if(t != null)
|
||||
{
|
||||
adapted.add(onAdapt(i));
|
||||
}
|
||||
}
|
||||
|
||||
return adapted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts a list object FROM to TO for use with the adapt method
|
||||
*
|
||||
* @param from
|
||||
* the from object
|
||||
* @return the to object
|
||||
*/
|
||||
public abstract TO onAdapt(FROM from);
|
||||
}
|
||||
@@ -2,21 +2,16 @@ package ninja.bytecode.iris.util;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import ninja.bytecode.iris.Iris;
|
||||
import ninja.bytecode.iris.generator.populator.PopulatorTrees;
|
||||
import ninja.bytecode.shuriken.Shuriken;
|
||||
import ninja.bytecode.shuriken.execution.ChronoLatch;
|
||||
import ninja.bytecode.shuriken.execution.J;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
|
||||
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskResult;
|
||||
import ninja.bytecode.shuriken.format.F;
|
||||
import ninja.bytecode.shuriken.logging.L;
|
||||
import ninja.bytecode.shuriken.math.RollingSequence;
|
||||
import ninja.bytecode.shuriken.reaction.O;
|
||||
|
||||
@@ -31,42 +26,12 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
|
||||
private boolean ready = false;
|
||||
int cg = 0;
|
||||
private ChronoLatch cl = new ChronoLatch(1000);
|
||||
private ChronoLatch cs = new ChronoLatch(1000);
|
||||
private RollingSequence rs = new RollingSequence(512);
|
||||
private RollingSequence cps = new RollingSequence(3);
|
||||
private World world;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public ParallelChunkGenerator()
|
||||
public World getWorld()
|
||||
{
|
||||
Bukkit.getScheduler().scheduleAsyncRepeatingTask(Iris.instance, () ->
|
||||
{
|
||||
J.attempt(() ->
|
||||
{
|
||||
if(world.getPlayers().isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(cs.flip())
|
||||
{
|
||||
cps.put(cg);
|
||||
cg = 0;
|
||||
}
|
||||
|
||||
double total = rs.getAverage() + PopulatorTrees.timings.getAverage();
|
||||
double rcs = (1000D / total);
|
||||
double work = cps.getAverage() / (rcs + 1);
|
||||
L.i("Terrain Gen for " + world.getName());
|
||||
L.i("- Terrain (MLTC): " + F.duration(rs.getAverage(), 2));
|
||||
L.i("- Trees (SGLC): " + F.duration(PopulatorTrees.timings.getAverage(), 2));
|
||||
L.i("Total: " + F.duration(total, 3) + " Work: " + F.f(cps.getAverage(), 0) + "/s of " + F.f(rcs, 0) + "/s (" + F.pc(work, 0) + " utilization)");
|
||||
L.flush();
|
||||
|
||||
System.out.println("");
|
||||
});
|
||||
|
||||
}, 20, 5);
|
||||
return world;
|
||||
}
|
||||
|
||||
public void generateFullColumn(int a, int b, int c, int d, BiomeGrid g, ChunkPlan p)
|
||||
@@ -144,33 +109,33 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
|
||||
public abstract void decorateColumn(int wx, int wz, int x, int z, ChunkPlan plan);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void setBlock(int x, int y, int z, Material b)
|
||||
public void setBlock(int x, int y, int z, Material b)
|
||||
{
|
||||
setBlock(x, y, z, b.getId(), (byte) 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void setBlock(int x, int y, int z, Material b, byte d)
|
||||
public void setBlock(int x, int y, int z, Material b, byte d)
|
||||
{
|
||||
setBlock(x, y, z, b.getId(), d);
|
||||
}
|
||||
|
||||
protected void setBlock(int x, int y, int z, int b)
|
||||
public void setBlock(int x, int y, int z, int b)
|
||||
{
|
||||
setBlock(x, y, z, b, (byte) 0);
|
||||
}
|
||||
|
||||
protected void setBlock(int x, int y, int z, int b, byte d)
|
||||
public void setBlock(int x, int y, int z, int b, byte d)
|
||||
{
|
||||
data.setBlock(x, y, z, b, d);
|
||||
}
|
||||
|
||||
protected Material getType(int x, int y, int z)
|
||||
public Material getType(int x, int y, int z)
|
||||
{
|
||||
return data.getType(x, y, z);
|
||||
}
|
||||
|
||||
protected byte getData(int x, int y, int z)
|
||||
public byte getData(int x, int y, int z)
|
||||
{
|
||||
return data.getData(x, y, z);
|
||||
}
|
||||
|
||||
157
src/main/java/ninja/bytecode/iris/util/WandUtil.java
Normal file
157
src/main/java/ninja/bytecode/iris/util/WandUtil.java
Normal file
@@ -0,0 +1,157 @@
|
||||
package ninja.bytecode.iris.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.util.BlockVector;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import ninja.bytecode.iris.schematic.Schematic;
|
||||
import ninja.bytecode.shuriken.collections.GList;
|
||||
|
||||
public class WandUtil
|
||||
{
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void pasteSchematic(Schematic s, Location at)
|
||||
{
|
||||
Location start = at.clone().add(s.getOffset());
|
||||
|
||||
for(BlockVector i : s.getSchematic().keySet())
|
||||
{
|
||||
MB b = s.getSchematic().get(i);
|
||||
System.out.println("Pasted " + b.material + " @ " + start.clone().add(i));
|
||||
start.clone().add(i).getBlock().setTypeIdAndData(b.material.getId(), b.data, false);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static Schematic createSchematic(ItemStack wand, Location at)
|
||||
{
|
||||
if(!isWand(wand))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Location[] f = getCuboid(wand);
|
||||
Cuboid c = new Cuboid(f[0], f[1]);
|
||||
Vector v = at.clone().subtract(c.getLowerNE()).toVector();
|
||||
Schematic s = new Schematic(c.getSizeX(), c.getSizeY(), c.getSizeZ(), v.getBlockX(), v.getBlockY(), v.getBlockZ());
|
||||
Iterator<Block> bb = c.iterator();
|
||||
while(bb.hasNext())
|
||||
{
|
||||
Block b = bb.next();
|
||||
|
||||
if(b.getType().equals(Material.AIR))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockVector bv = b.getLocation().toVector().toBlockVector().subtract(c.getLowerNE().toVector().toBlockVector()).toBlockVector();
|
||||
System.out.println("Load " + bv + " " + b.getType());
|
||||
s.put(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), new MB(b.getType(), b.getData()));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Location stringToLocation(String s)
|
||||
{
|
||||
try
|
||||
{
|
||||
String[] f = s.split("\\Q in \\E");
|
||||
String[] g = f[0].split("\\Q,\\E");
|
||||
return new Location(Bukkit.getWorld(f[1]), Integer.valueOf(g[0]), Integer.valueOf(g[1]), Integer.valueOf(g[2]));
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String locationToString(Location s)
|
||||
{
|
||||
if(s == null)
|
||||
{
|
||||
return "<#>";
|
||||
}
|
||||
|
||||
return s.getBlockX() + "," + s.getBlockY() + "," + s.getBlockZ() + " in " + s.getWorld().getName();
|
||||
}
|
||||
|
||||
public static ItemStack createWand()
|
||||
{
|
||||
return createWand(null, null);
|
||||
}
|
||||
|
||||
public static ItemStack update(boolean left, Location a, ItemStack item)
|
||||
{
|
||||
if(!isWand(item))
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
Location[] f = getCuboid(item);
|
||||
Location other = left ? f[1] : f[0];
|
||||
|
||||
return createWand(left ? a : other, left ? other : a);
|
||||
}
|
||||
|
||||
public static ItemStack createWand(Location a, Location b)
|
||||
{
|
||||
ItemStack is = new ItemStack(Material.BLAZE_ROD);
|
||||
is.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 1);
|
||||
ItemMeta im = is.getItemMeta();
|
||||
im.setDisplayName(ChatColor.BOLD + "" + ChatColor.GOLD + "Wand of Iris");
|
||||
im.setUnbreakable(true);
|
||||
im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_PLACED_ON, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_DESTROYS, ItemFlag.HIDE_ENCHANTS);
|
||||
im.setLore(new GList<String>().add(locationToString(a), locationToString(b)));
|
||||
is.setItemMeta(im);
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
public static Location[] getCuboid(ItemStack is)
|
||||
{
|
||||
ItemMeta im = is.getItemMeta();
|
||||
return new Location[] {stringToLocation(im.getLore().get(0)), stringToLocation(im.getLore().get(1))};
|
||||
}
|
||||
|
||||
public static boolean isWand(ItemStack item)
|
||||
{
|
||||
if(!item.getType().equals(createWand().getType()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!item.getItemMeta().getEnchants().equals(createWand().getItemMeta().getEnchants()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!item.getItemMeta().getDisplayName().equals(createWand().getItemMeta().getDisplayName()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user