Repackage utils

This commit is contained in:
Daniel Mills
2021-07-16 02:11:37 -04:00
parent b9b30f9f53
commit da53a7d469
471 changed files with 1043 additions and 601 deletions

View File

@@ -0,0 +1,37 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import com.volmit.iris.engine.object.IrisBiome;
public class BiomeMap {
private final IrisBiome[] height;
public BiomeMap() {
height = new IrisBiome[256];
}
public void setBiome(int x, int z, IrisBiome h) {
height[x * 16 + z] = h;
}
public IrisBiome getBiome(int x, int z) {
return height[x * 16 + z];
}
}

View File

@@ -0,0 +1,751 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import com.volmit.iris.util.Dimension;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.math.Direction;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* 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 KList<Entity> getEntities() {
KList<Entity> en = new KList<>();
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");
}
@NotNull
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<>();
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) {
return switch (dir) {
case North -> new Cuboid(worldName, x1 - amount, y1, z1, x2, y2, z2);
case South -> new Cuboid(worldName, x1, y1, z1, x2 + amount, y2, z2);
case East -> new Cuboid(worldName, x1, y1, z1 - amount, x2, y2, z2);
case West -> new Cuboid(worldName, x1, y1, z1, x2, y2, z2 + amount);
case Down -> new Cuboid(worldName, x1, y1 - amount, z1, x2, y2, z2);
case Up -> new Cuboid(worldName, x1, y1, z1, x2, y2 + amount, z2);
default -> throw new IllegalArgumentException("invalid direction " + dir);
};
}
public Cuboid expand(Direction dir, int amount) {
int ax = dir.toVector().getBlockX() == 1 ? amount : 0;
int sx = dir.toVector().getBlockX() == -1 ? -amount : 0;
int ay = dir.toVector().getBlockY() == 1 ? amount : 0;
int sy = dir.toVector().getBlockY() == -1 ? -amount : 0;
int az = dir.toVector().getBlockZ() == 1 ? amount : 0;
int sz = dir.toVector().getBlockZ() == -1 ? -amount : 0;
return new Cuboid(worldName, x1 + sx, y1 + sy, z1 + sz, x2 + ax, y2 + ay, z2 + az);
}
/**
* 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 -> expand(CuboidDirection.North, amount).expand(CuboidDirection.South, amount).expand(CuboidDirection.East, amount).expand(CuboidDirection.West, amount);
case Vertical -> expand(CuboidDirection.Down, amount).expand(CuboidDirection.Up, amount);
case Both -> outset(CuboidDirection.Horizontal, amount).outset(CuboidDirection.Vertical, amount);
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) {
return switch (dir) {
case Down -> new Cuboid(worldName, x1, y1, z1, x2, y1, z2);
case Up -> new Cuboid(worldName, x1, y2, z1, x2, y2, z2);
case North -> new Cuboid(worldName, x1, y1, z1, x1, y2, z2);
case South -> new Cuboid(worldName, x2, y1, z1, x2, y2, z2);
case East -> new Cuboid(worldName, x1, y1, z1, x2, y2, z1);
case West -> 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<>();
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 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()
*/
@SuppressWarnings("MethodDoesntCallSuperMethod")
@Override
public Cuboid clone() {
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 static class CuboidIterator implements Iterator<Block> {
private final World w;
private final int baseX;
private final int baseY;
private final int baseZ;
private int x, y, z;
private final int sizeX;
private final int sizeY;
private final int 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() {
return switch (this) {
case North -> South;
case East -> West;
case South -> North;
case West -> East;
case Horizontal -> Vertical;
case Vertical -> Horizontal;
case Up -> Down;
case Down -> Up;
case Both -> Both;
default -> Unknown;
};
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
/**
* Represents a cuboid exception
*
* @author cyberpwn
*/
public class CuboidException extends Exception {
public CuboidException(String string) {
super(string);
}
private static final long serialVersionUID = 1L;
}

View File

@@ -0,0 +1,124 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import com.volmit.iris.util.KList;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public abstract class DataPalette<T> implements Writable {
private static final int DEFAULT_BITS_PER_BLOCK = 4;
private static final int CAPACITY = 4096;
private int bpb;
private NibbleArray data;
private KList<T> palette;
public DataPalette(T defaultValue) {
palette = new KList<>();
bpb = DEFAULT_BITS_PER_BLOCK;
data = new NibbleArray(bpb, CAPACITY);
data.setAll(Byte.MIN_VALUE);
getPaletteId(defaultValue);
}
public abstract T readType(DataInputStream i);
public abstract void writeType(T t, DataOutputStream o);
@Override
public void write(DataOutputStream o) throws IOException {
o.writeByte(bpb + Byte.MIN_VALUE);
o.writeByte(palette.size() + Byte.MIN_VALUE);
for (T i : palette) {
writeType(i, o);
}
data.write(o);
}
@Override
public void read(DataInputStream i) throws IOException {
bpb = i.readByte() - Byte.MIN_VALUE;
palette = new KList<>();
int v = i.readByte() - Byte.MIN_VALUE;
for (int j = 0; j < v; j++) {
palette.add(readType(i));
}
data = new NibbleArray(CAPACITY, i);
}
private final void expand() {
if (bpb < 8) {
changeBitsPerBlock(bpb + 1);
} else {
throw new IndexOutOfBoundsException("The Data Palette can only handle at most 256 block types per 16x16x16 region. We cannot use more than 8 bits per block!");
}
}
public final void optimize() {
int targetBits = bpb;
int needed = palette.size();
for (int i = 1; i < bpb; i++) {
if (Math.pow(2, i) > needed) {
targetBits = i;
break;
}
}
changeBitsPerBlock(targetBits);
}
private final void changeBitsPerBlock(int bits) {
bpb = bits;
data = new NibbleArray(bpb, CAPACITY, data);
}
public final void set(int x, int y, int z, T d) {
data.set(getCoordinateIndex(x, y, z), getPaletteId(d));
}
public final T get(int x, int y, int z) {
return palette.get(data.get(getCoordinateIndex(x, y, z)));
}
private final int getPaletteId(T d) {
int index = palette.indexOf(d);
if (index == -1) {
index = palette.size();
palette.add(d);
if (palette.size() > Math.pow(2, bpb)) {
expand();
}
}
return index + Byte.MIN_VALUE;
}
private final int getCoordinateIndex(int x, int y, int z) {
return y << 8 | z << 4 | x;
}
}

View File

@@ -0,0 +1,89 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.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;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.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
}

View File

@@ -0,0 +1,48 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import com.google.common.util.concurrent.AtomicDoubleArray;
import java.util.Arrays;
public class DoubleArrayUtils {
public static void shiftRight(double[] values, double push) {
if (values.length - 2 + 1 >= 0) System.arraycopy(values, 0, values, 1, values.length - 2 + 1);
values[0] = push;
}
public static void wrapRight(double[] values) {
double last = values[values.length - 1];
shiftRight(values, last);
}
public static void fill(double[] values, double value) {
Arrays.fill(values, value);
}
public static void fill(AtomicDoubleArray values, double value) {
for (int i = 0; i < values.length(); i++) {
values.set(i, value);
}
}
}

View File

@@ -0,0 +1,38 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import java.util.Arrays;
public class HeightMap {
private final byte[] height;
public HeightMap() {
height = new byte[256];
Arrays.fill(height, Byte.MIN_VALUE);
}
public void setHeight(int x, int z, int h) {
height[x * 16 + z] = (byte) (h + Byte.MIN_VALUE);
}
public int getHeight(int x, int z) {
return height[x * 16 + z] - Byte.MIN_VALUE;
}
}

View File

@@ -0,0 +1,65 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util;
import com.volmit.iris.Iris;
import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.jetbrains.annotations.NotNull;
public class InvertedBiomeGrid implements BiomeGrid {
private final BiomeGrid grid;
public InvertedBiomeGrid(BiomeGrid real) {
this.grid = real;
}
@NotNull
@SuppressWarnings("deprecation")
@Override
public Biome getBiome(int arg0, int arg1) {
return grid.getBiome(arg0, arg1);
}
@NotNull
@Override
public Biome getBiome(int arg0, int arg1, int arg2) {
if (!Iris.biome3d) {
return getBiome(arg0, arg2);
}
return grid.getBiome(arg0, 255 - arg1, arg2);
}
@SuppressWarnings("deprecation")
@Override
public void setBiome(int arg0, int arg1, @NotNull Biome arg2) {
grid.setBiome(arg0, arg1, arg2);
}
@Override
public void setBiome(int arg0, int arg1, int arg2, @NotNull Biome arg3) {
if (!Iris.biome3d) {
setBiome(arg0, arg2, arg3);
return;
}
grid.setBiome(arg0, 255 - arg1, arg2, arg3);
}
}

View File

@@ -0,0 +1,83 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import com.volmit.iris.util.IrisMathHelper;
import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
public class IrisBiomeStorage {
private static final int e;
private static final int f;
public static final int a;
public static final int b;
public static final int c;
private final Biome[] g;
static {
e = (int) Math.round(Math.log(16.0) / Math.log(2.0)) - 2;
f = (int) Math.round(Math.log(256.0) / Math.log(2.0)) - 2; // TODO: WARNING HEIGHT
a = 1 << IrisBiomeStorage.e + IrisBiomeStorage.e + IrisBiomeStorage.f;
b = (1 << IrisBiomeStorage.e) - 1;
c = (1 << IrisBiomeStorage.f) - 1;
}
public IrisBiomeStorage(final Biome[] aBiome) {
this.g = aBiome;
}
public IrisBiomeStorage() {
this(new Biome[IrisBiomeStorage.a]);
}
public IrisBiomeStorage b() {
return new IrisBiomeStorage(this.g.clone());
}
public void inject(BiomeGrid grid) {
// TODO: WARNING HEIGHT
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 16; j++) {
for (int k = 0; k < 16; k++) {
Biome b = getBiome(j, i, k);
if (b == null || b.equals(Biome.THE_VOID)) {
continue;
}
grid.setBiome(j, i, k, b);
}
}
}
}
public Biome getBiome(final int x, final int y, final int z) {
final int l = x & IrisBiomeStorage.b;
final int i2 = IrisMathHelper.clamp(y, 0, IrisBiomeStorage.c);
final int j2 = z & IrisBiomeStorage.b;
return this.g[i2 << IrisBiomeStorage.e + IrisBiomeStorage.e | j2 << IrisBiomeStorage.e | l];
}
public void setBiome(final int x, final int y, final int z, final Biome biome) {
final int l = x & IrisBiomeStorage.b;
final int i2 = IrisMathHelper.clamp(y, 0, IrisBiomeStorage.c);
final int j2 = z & IrisBiomeStorage.b;
this.g[i2 << IrisBiomeStorage.e + IrisBiomeStorage.e | j2 << IrisBiomeStorage.e | l] = biome;
}
}

View File

@@ -0,0 +1,126 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
/**
* Material blocks
*
* @author cyberpwn
*/
@SuppressWarnings("deprecation")
public class MaterialBlock {
private Material material;
private Byte data;
/**
* Create a materialblock
*
* @param material the material
* @param data the data
*/
public MaterialBlock(Material material, Byte data) {
this.material = material;
this.data = data;
}
public MaterialBlock(Material material) {
this.material = material;
data = 0;
}
public MaterialBlock(Location location) {
this(location.getBlock());
}
public MaterialBlock(BlockState state) {
material = state.getType();
data = state.getData().getData();
}
public MaterialBlock(Block block) {
material = block.getType();
data = block.getData();
}
public MaterialBlock() {
material = Material.AIR;
data = 0;
}
public Material getMaterial() {
return material;
}
public void setMaterial(Material material) {
this.material = material;
}
public Byte getData() {
return data;
}
public void setData(Byte data) {
this.data = data;
}
@Override
public String toString() {
if (getData() == 0) {
return getMaterial().toString();
}
return getMaterial().toString() + ":" + getData();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((material == null) ? 0 : material.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
MaterialBlock other = (MaterialBlock) obj;
if (data == null) {
if (other.data != null) {
return false;
}
} else if (!data.equals(other.data)) {
return false;
}
return material == other.material;
}
}

View File

@@ -0,0 +1,196 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.StringJoiner;
public class NibbleArray implements Writable {
private byte[] data;
private int depth;
private final int size;
private byte mask;
private final Object lock = new Object();
public NibbleArray(int capacity, DataInputStream in) throws IOException {
size = capacity;
read(in);
}
public NibbleArray(int nibbleDepth, int capacity) {
if (nibbleDepth > 8 || nibbleDepth < 1) {
throw new IllegalArgumentException();
}
int neededBits = nibbleDepth * capacity;
size = capacity;
depth = nibbleDepth;
data = new byte[(neededBits + neededBits % 8) / 8];
mask = (byte) maskFor(nibbleDepth);
}
public NibbleArray(int nibbleDepth, int capacity, NibbleArray existing) {
if (nibbleDepth > 8 || nibbleDepth < 1) {
throw new IllegalArgumentException();
}
int neededBits = nibbleDepth * capacity;
size = capacity;
depth = nibbleDepth;
data = new byte[(neededBits + neededBits % 8) / 8];
mask = (byte) maskFor(nibbleDepth);
for (int i = 0; i < Math.min(size, existing.size()); i++) {
set(i, existing.get(i));
}
}
@Override
public void write(DataOutputStream o) throws IOException {
o.writeByte(depth + Byte.MIN_VALUE);
o.write(data);
}
@Override
public void read(DataInputStream i) throws IOException {
depth = i.readByte() - Byte.MIN_VALUE;
int neededBits = depth * size;
data = new byte[(neededBits + neededBits % 8) / 8];
mask = (byte) maskFor(depth);
i.read(data);
}
public int size() {
return size;
}
public byte get(int index) {
synchronized (lock) {
bitIndex = index * depth;
byteIndex = bitIndex >> 3;
bitInByte = bitIndex & 7;
int value = data[byteIndex] >> bitInByte;
if (bitInByte + depth > 8) {
value |= data[byteIndex + 1] << bitInByte;
}
return (byte) (value & mask);
}
}
public byte getAsync(int index) {
int bitIndex = index * depth;
int byteIndex = bitIndex >> 3;
int bitInByte = bitIndex & 7;
int value = data[byteIndex] >> bitInByte;
if (bitInByte + depth > 8) {
value |= data[byteIndex + 1] << bitInByte;
}
return (byte) (value & mask);
}
private transient int bitIndex, byteIndex, bitInByte;
public void set(int index, int nibble) {
set(index, (byte) nibble);
}
public void set(int index, byte nybble) {
synchronized (lock) {
bitIndex = index * depth;
byteIndex = bitIndex >> 3;
bitInByte = bitIndex & 7;
data[byteIndex] = (byte) (((~(data[byteIndex] & (mask << bitInByte)) & data[byteIndex]) | ((nybble & mask) << bitInByte)) & 0xff);
if (bitInByte + depth > 8) {
data[byteIndex + 1] = (byte) (((~(data[byteIndex + 1] & MASKS[bitInByte + depth - 8]) & data[byteIndex + 1]) | ((nybble & mask) >> (8 - bitInByte))) & 0xff);
}
}
}
public String toBitsString() {
return toBitsString(ByteOrder.BIG_ENDIAN);
}
public String toBitsString(ByteOrder byteOrder) {
StringJoiner joiner = new StringJoiner(" ");
for (byte datum : data) {
joiner.add(binaryString(datum, byteOrder));
}
return joiner.toString();
}
public void clear() {
Arrays.fill(data, (byte) 0);
}
public void setAll(byte nibble) {
for (int i = 0; i < size; i++) {
set(i, nibble);
}
}
public void setAll(int nibble) {
for (int i = 0; i < size; i++) {
set(i, (byte) nibble);
}
}
public static int maskFor(int amountOfBits) {
return powerOfTwo(amountOfBits) - 1;
}
public static int powerOfTwo(int power) {
int result = 1;
for (int i = 0; i < power; i++) {
result *= 2;
}
return result;
}
private static final int[] MASKS = new int[8];
static {
for (int i = 0; i < MASKS.length; i++) {
MASKS[i] = maskFor(i);
}
}
public static String binaryString(byte b, ByteOrder byteOrder) {
String str = String.format("%8s", Integer.toBinaryString(b & 0xff)).replace(' ', '0');
return byteOrder.equals(ByteOrder.BIG_ENDIAN) ? str : reverse(str);
}
public static String reverse(String str) {
return new StringBuilder(str).reverse().toString();
}
}

View File

@@ -0,0 +1,39 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util;
public class Shrinkwrap<T> {
private T t;
public Shrinkwrap(T t) {
set(t);
}
public Shrinkwrap() {
this(null);
}
public T get() {
return t;
}
public void set(T t) {
this.t = t;
}
}

View File

@@ -0,0 +1,126 @@
package com.volmit.iris.util;
import org.bukkit.block.Biome;
import com.volmit.iris.util.inventorygui.RandomColor.*;
public class VanillaBiomeMap {
private static KMap<Biome, Integer> BIOME_HEX = new KMap<>();
private static KMap<Biome, Color> BIOME_COLOR = new KMap<>();
private static KMap<Biome, Luminosity> BIOME_LUMINOSITY = new KMap<>();
private static KMap<Biome, SaturationType> BIOME_SATURATION = new KMap<>();
private static KMap<Biome, Short> BIOME_IDs = new KMap<>();
private static void add(Biome biome, int color, short id, Color randomColor, Luminosity luminosity, SaturationType saturation) {
BIOME_HEX.put(biome, color);
BIOME_COLOR.put(biome, randomColor);
if (luminosity != null) BIOME_LUMINOSITY.put(biome, luminosity);
if (saturation != null) BIOME_SATURATION.put(biome, saturation);
BIOME_IDs.put(biome, id);
}
private static void add(Biome biome, int color, short id, Color randomColor, Luminosity luminosity) {
add(biome, color, id, randomColor, luminosity, null);
}
public static int getColor(Biome biome) {
return BIOME_HEX.get(biome);
}
public static Color getColorType(Biome biome) {
return BIOME_COLOR.get(biome);
}
public static Luminosity getColorLuminosity(Biome biome) {
return BIOME_LUMINOSITY.get(biome);
}
public static SaturationType getColorSaturatiom(Biome biome) {
return BIOME_SATURATION.get(biome);
}
public static short getId(Biome biome) {
return BIOME_IDs.get(biome);
}
static {
add(Biome.OCEAN, 0x000070, (short) 0, Color.BLUE, Luminosity.BRIGHT, SaturationType.MEDIUM);
add(Biome.PLAINS, 0x8DB360, (short) 1, Color.GREEN, Luminosity.LIGHT, SaturationType.MEDIUM);
add(Biome.DESERT, 0xFA9418, (short) 2, Color.YELLOW, Luminosity.LIGHT, SaturationType.MEDIUM);
add(Biome.MOUNTAINS, 0x606060, (short) 3, Color.MONOCHROME, Luminosity.BRIGHT, null);
add(Biome.FOREST, 0x056621, (short) 4, Color.GREEN, Luminosity.BRIGHT);
add(Biome.TAIGA, 0x0B6659, (short) 5, Color.GREEN, Luminosity.BRIGHT, SaturationType.MEDIUM);
add(Biome.SWAMP, 0x07F9B2, (short) 6, Color.ORANGE, Luminosity.DARK, SaturationType.MEDIUM);
add(Biome.RIVER, 0x0000FF, (short) 7, Color.BLUE, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.NETHER_WASTES, 0xBF3B3B, (short) 8, Color.RED, Luminosity.LIGHT, SaturationType.MEDIUM);
add(Biome.THE_END, 0x8080FF, (short) 9, Color.PURPLE, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.FROZEN_OCEAN, 0x7070D6, (short) 10, Color.BLUE, Luminosity.BRIGHT, SaturationType.MEDIUM);
add(Biome.FROZEN_RIVER, 0xA0A0FF, (short) 11, Color.BLUE, Luminosity.BRIGHT, SaturationType.MEDIUM);
add(Biome.SNOWY_TUNDRA, 0xFFFFFF, (short) 12, Color.MONOCHROME, Luminosity.LIGHT);
add(Biome.SNOWY_MOUNTAINS, 0xA0A0A0, (short) 13, Color.MONOCHROME, Luminosity.LIGHT);
add(Biome.MUSHROOM_FIELDS, 0xFF00FF, (short) 14, Color.PURPLE, Luminosity.BRIGHT);
add(Biome.MUSHROOM_FIELD_SHORE, 0xA000FF, (short) 15, Color.PURPLE, Luminosity.BRIGHT);
add(Biome.BEACH, 0xFADE55, (short) 16, Color.YELLOW, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.DESERT_HILLS, 0xD25F12, (short) 17, Color.YELLOW, Luminosity.LIGHT, SaturationType.MEDIUM);
add(Biome.WOODED_HILLS, 0x22551C, (short) 18, Color.GREEN, Luminosity.LIGHT);
add(Biome.TAIGA_HILLS, 0x163933, (short) 19, Color.GREEN, Luminosity.BRIGHT, SaturationType.MEDIUM);
add(Biome.MOUNTAIN_EDGE, 0x72789A, (short) 20, Color.MONOCHROME, Luminosity.BRIGHT);
add(Biome.JUNGLE, 0x537B09, (short) 21, Color.GREEN, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.JUNGLE_HILLS, 0x2C4205, (short) 22, Color.GREEN, Luminosity.DARK, SaturationType.HIGH);
add(Biome.JUNGLE_EDGE, 0x628B17, (short) 23, Color.GREEN, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.DEEP_OCEAN, 0x000030, (short) 24, Color.BLUE, Luminosity.DARK);
add(Biome.STONE_SHORE, 0xA2A284, (short) 25, Color.GREEN, Luminosity.DARK);
add(Biome.SNOWY_BEACH, 0xFAF0C0, (short) 26, Color.YELLOW, Luminosity.LIGHT);
add(Biome.BIRCH_FOREST, 0x307444, (short) 27, Color.GREEN, Luminosity.LIGHT);
add(Biome.BIRCH_FOREST_HILLS, 0x1F5F32, (short) 28, Color.GREEN, Luminosity.LIGHT);
add(Biome.DARK_FOREST, 0x40511A, (short) 29, Color.GREEN, Luminosity.DARK);
add(Biome.SNOWY_TAIGA, 0x31554A, (short) 30, Color.BLUE, Luminosity.LIGHT);
add(Biome.SNOWY_TAIGA_HILLS, 0x243F36, (short) 31, Color.BLUE, Luminosity.LIGHT);
add(Biome.GIANT_TREE_TAIGA, 0x596651, (short) 32, Color.ORANGE, Luminosity.LIGHT);
add(Biome.GIANT_TREE_TAIGA_HILLS, 0x454F3E, (short) 33, Color.ORANGE, Luminosity.LIGHT);
add(Biome.WOODED_MOUNTAINS, 0x507050, (short) 34, Color.MONOCHROME, Luminosity.BRIGHT);
add(Biome.SAVANNA, 0xBDB25F, (short) 35, Color.GREEN, Luminosity.LIGHT);
add(Biome.SAVANNA_PLATEAU, 0xA79D64, (short) 36, Color.GREEN, Luminosity.LIGHT);
add(Biome.BADLANDS, 0xD94515, (short) 37, Color.ORANGE, Luminosity.BRIGHT, SaturationType.MEDIUM);
add(Biome.WOODED_BADLANDS_PLATEAU, 0xB09765, (short) 38, Color.ORANGE, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.BADLANDS_PLATEAU, 0xCA8C65, (short) 39, Color.ORANGE, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.END_MIDLANDS, 0x8080FF, (short) 41, Color.YELLOW, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.END_HIGHLANDS, 0x8080FF, (short) 42, Color.PURPLE, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.END_BARRENS, 0x8080FF, (short) 43, Color.PURPLE, Luminosity.LIGHT, SaturationType.MEDIUM);
add(Biome.WARM_OCEAN, 0x0000AC, (short) 44, Color.BLUE, Luminosity.BRIGHT, SaturationType.LOW);
add(Biome.LUKEWARM_OCEAN, 0x000090, (short) 45, Color.BLUE, Luminosity.BRIGHT, SaturationType.MEDIUM);
add(Biome.COLD_OCEAN, 0x202070, (short) 46, Color.BLUE, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.DEEP_WARM_OCEAN, 0x000050, (short) 47, Color.BLUE, Luminosity.DARK, SaturationType.LOW);
add(Biome.DEEP_LUKEWARM_OCEAN, 0x000040, (short) 48, Color.BLUE, Luminosity.DARK, SaturationType.MEDIUM);
add(Biome.DEEP_COLD_OCEAN, 0x202038, (short) 49, Color.BLUE, Luminosity.DARK, SaturationType.HIGH);
add(Biome.DEEP_FROZEN_OCEAN, 0x404090, (short) 50, Color.BLUE, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.THE_VOID, 0x000000, (short) 127, Color.MONOCHROME, Luminosity.DARK);
add(Biome.SUNFLOWER_PLAINS, 0xB5DB88, (short) 129, Color.GREEN, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.DESERT_LAKES, 0xFFBC40, (short) 130, Color.BLUE, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.GRAVELLY_MOUNTAINS, 0x888888, (short) 131, Color.MONOCHROME, Luminosity.LIGHT);
add(Biome.FLOWER_FOREST, 0x2D8E49, (short) 132, Color.RED, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.TAIGA_MOUNTAINS, 0x338E81, (short) 133, Color.GREEN, Luminosity.DARK, SaturationType.MEDIUM);
add(Biome.SWAMP_HILLS, 0x2FFFDA, (short) 134, Color.ORANGE, Luminosity.DARK, SaturationType.MEDIUM);
add(Biome.ICE_SPIKES, 0xB4DCDC, (short) 140, Color.BLUE, Luminosity.LIGHT, SaturationType.LOW);
add(Biome.MODIFIED_JUNGLE, 0x7BA331, (short) 149, Color.GREEN, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.MODIFIED_JUNGLE_EDGE, 0x8AB33F, (short) 151, Color.GREEN, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.TALL_BIRCH_FOREST, 0x589C6C, (short) 155, Color.GREEN, Luminosity.LIGHT);
add(Biome.TALL_BIRCH_HILLS, 0x47875A, (short) 156, Color.GREEN, Luminosity.LIGHT);
add(Biome.DARK_FOREST_HILLS, 0x687942, (short) 157, Color.GREEN, Luminosity.DARK);
add(Biome.SNOWY_TAIGA_MOUNTAINS, 0x597D72, (short) 158, Color.BLUE, Luminosity.LIGHT);
add(Biome.GIANT_SPRUCE_TAIGA, 0x818E79, (short) 160, Color.ORANGE, Luminosity.DARK, SaturationType.HIGH);
add(Biome.GIANT_SPRUCE_TAIGA_HILLS, 0x6D7766, (short) 161, Color.ORANGE, Luminosity.DARK, SaturationType.HIGH);
add(Biome.GRAVELLY_MOUNTAINS, 0x789878, (short) 162, Color.MONOCHROME, Luminosity.LIGHT);
add(Biome.SHATTERED_SAVANNA, 0xE5DA87, (short) 163, Color.ORANGE, Luminosity.LIGHT, SaturationType.HIGH);
add(Biome.SHATTERED_SAVANNA_PLATEAU, 0xCFC58C, (short) 164, Color.ORANGE, Luminosity.LIGHT, SaturationType.HIGH);
add(Biome.ERODED_BADLANDS, 0xFF6D3D, (short) 165, Color.ORANGE, Luminosity.LIGHT, SaturationType.HIGH);
add(Biome.MODIFIED_WOODED_BADLANDS_PLATEAU, 0xD8BF8D, (short) 166, Color.ORANGE, Luminosity.BRIGHT);
add(Biome.MODIFIED_BADLANDS_PLATEAU, 0xF2B48D, (short) 167, Color.ORANGE, Luminosity.BRIGHT);
add(Biome.BAMBOO_JUNGLE, 0x768E14, (short) 168, Color.GREEN, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.BAMBOO_JUNGLE_HILLS, 0x3B470A, (short) 169, Color.GREEN, Luminosity.BRIGHT, SaturationType.HIGH);
add(Biome.SOUL_SAND_VALLEY, 0x5E3830, (short) 170, Color.BLUE, Luminosity.BRIGHT, SaturationType.MEDIUM);
add(Biome.CRIMSON_FOREST, 0xDD0808, (short) 171, Color.RED, Luminosity.DARK, SaturationType.HIGH);
add(Biome.WARPED_FOREST, 0x49907B, (short) 172, Color.BLUE, Luminosity.BRIGHT);
add(Biome.BASALT_DELTAS, 0x403636, (short) 173, Color.MONOCHROME, Luminosity.DARK);
}
}

View File

@@ -0,0 +1,64 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.Shrinkwrap;
public class WeightMap<T> extends KMap<T, Double> {
private static final long serialVersionUID = 87558033900969389L;
private boolean modified = false;
private double lastWeight = 0;
public double getPercentChance(T t) {
if (totalWeight() <= 0) {
return 0;
}
return getWeight(t) / totalWeight();
}
public void clear() {
modified = true;
}
public WeightMap<T> setWeight(T t, double weight) {
modified = true;
put(t, weight);
return this;
}
public double getWeight(T t) {
return get(t);
}
public double totalWeight() {
if (!modified) {
return lastWeight;
}
modified = false;
Shrinkwrap<Double> s = new Shrinkwrap<>(0D);
forEachKey(Integer.MAX_VALUE, (d) -> s.set(s.get() + 1));
lastWeight = s.get();
return lastWeight;
}
}

View File

@@ -0,0 +1,62 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KeyPair;
import java.util.Random;
public class WeightedRandom<T> {
private final KList<KeyPair<T, Integer>> weightedObjects = new KList<>();
private final Random random;
private int totalWeight = 0;
public WeightedRandom(Random random) {
this.random = random;
}
public WeightedRandom() {
this.random = new Random();
}
public void put(T object, int weight) {
weightedObjects.add(new KeyPair<>(object, weight));
totalWeight += weight;
}
public T pullRandom() {
int pull = random.nextInt(totalWeight);
int index = 0;
while (pull > 0) {
pull -= weightedObjects.get(index).getV();
index++;
}
return weightedObjects.get(index).getK();
}
public int getSize() {
return weightedObjects.size();
}
public void shuffle() {
weightedObjects.shuffle(random);
}
}

View File

@@ -0,0 +1,29 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.data;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public interface Writable {
void write(DataOutputStream o) throws IOException;
void read(DataInputStream i) throws IOException;
}