This commit is contained in:
Daniel Mills 2019-10-14 05:23:50 -04:00
parent 0a7214a39b
commit b29ad7ed0c
10 changed files with 608 additions and 82 deletions

View File

@ -7,29 +7,49 @@ import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.java.JavaPlugin;
import ninja.bytecode.shuriken.collections.GSet;
import ninja.bytecode.shuriken.execution.TaskExecutor;
public class Iris extends JavaPlugin implements Listener
{
public static TaskExecutor executor;
public static TaskExecutor noisePool;
public static IrisGenerator gen;
public void onEnable()
{
executor = new TaskExecutor(1, Thread.MIN_PRIORITY, "Iris Generator");
gen = new IrisGenerator();
noisePool = new TaskExecutor(4, Thread.MIN_PRIORITY, "Iris Generator");
getServer().getPluginManager().registerEvents((Listener) this, this);
// Debug world regens
GSet<String> ws = new GSet<>();
World w = createIrisWorld();
for(Player i : Bukkit.getOnlinePlayers())
{
ws.add(i.getWorld().getName());
i.teleport(new Location(w, 0, 256, 0));
i.setFlying(true);
i.setGameMode(GameMode.CREATIVE);
}
for(String i : ws)
{
Bukkit.unloadWorld(i, false);
}
}
public void onDisable()
{
executor.close();
noisePool.close();
}
@Override
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
{
@ -41,17 +61,24 @@ public class Iris extends JavaPlugin implements Listener
{
if(e.getMessage().toLowerCase().equals("/iris"))
{
World ww = Bukkit.createWorld(new WorldCreator("iris-worlds/" + UUID.randomUUID().toString())
.generator(new IrisGenerator())
.seed(0));
ww.setSpawnFlags(false, false);
ww.setAutoSave(false);
ww.setKeepSpawnInMemory(false);
ww.setSpawnLocation(0, 256, 0);
e.getPlayer().teleport(new Location(ww, 0, 256, 0));
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);
}
}
private World createIrisWorld()
{
World ww = Bukkit.createWorld(new WorldCreator("iris-worlds/" + UUID.randomUUID().toString()).generator(new IrisGenerator()).seed(0));
ww.setSpawnFlags(false, false);
ww.setAutoSave(false);
ww.setKeepSpawnInMemory(false);
ww.setSpawnLocation(0, 256, 0);
return ww;
}
}

View File

@ -4,64 +4,103 @@ import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import ninja.bytecode.iris.gen.GenLayerBase;
import ninja.bytecode.iris.gen.GenLayerBiome;
import ninja.bytecode.iris.gen.IGenLayer;
import ninja.bytecode.iris.util.RealBiome;
import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG;
public class IrisGenerator extends ParallelChunkGenerator
{
private static final MB water = new MB(Material.STATIONARY_WATER);
private static final MB bedrock = new MB(Material.BEDROCK);
private static final MB air = new MB(Material.AIR);
private static final MB grass = new MB(Material.GRASS);
private static final MB[] earth = {new MB(Material.DIRT), new MB(Material.DIRT, 1),
};
private static final MB[] sand = {new MB(Material.SAND), new MB(Material.SAND), new MB(Material.SAND, 1),
};
private static final MB[] sandygrass = {new MB(Material.GRASS), new MB(Material.SAND, 1),
};
private static final MB[] rock = {new MB(Material.STONE), new MB(Material.STONE, 5), new MB(Material.COBBLESTONE),
};
private GList<IGenLayer> genLayers;
private GenLayerBiome glBiome;
private GenLayerBase glBase;
private int waterLevel = 127;
@Override
public void onInit(World world, Random random)
{
RNG rng = new RNG(world.getSeed());
genLayers = new GList<>();
genLayers.add(new GenLayerBase(world, random, rng));
System.out.print("Gend");
genLayers.add(glBiome = new GenLayerBiome(world, random, rng));
genLayers.add(glBase = new GenLayerBase(world, random, rng));
}
public int getHeight(double dx, double dz)
{
double noise = 0.5;
for(IGenLayer i : genLayers)
{
noise = i.generateLayer(noise, dx, dz);
}
double n = noise * 250;
n = n > 255 ? 255 : n;
n = n > 254 ? 254 : n;
n = n < 0 ? 0 : n;
return (int) n;
}
@Override
public void genColumn(final int wx, final int wz)
public Biome genColumn(int wx, int wz, int x, int z)
{
int height = getHeight(wx, wz);
MB mb = rock[0];
for(int i = 0; i < height; i++)
RealBiome b = glBiome.getBiome(wx, wz);
boolean underwater = height < waterLevel;
for(int i = 0; i < Math.max(height, waterLevel); i++)
{
setBlock(wx, i, wz, mb.material, mb.data);
MB mb = underwater ? new MB(Material.STATIONARY_WATER) : new MB(Material.AIR);
if(i > height && underwater)
{
mb = new MB(Material.STATIONARY_WATER);
}
else if(i == 0 || (i == 1 && glBase.scatterChance(wx, i, wz, 0.45)))
{
mb = new MB(Material.BEDROCK);
}
else if(i == height - 1)
{
if(underwater)
{
mb = new MB(Material.SAND);
}
else
{
mb = b.surface(wx, i, wz, glBase);
}
}
else if(i > height - glBase.scatterInt(wx, i, wz, 12))
{
if(underwater)
{
mb = new MB(Material.SAND);
}
else
{
mb = b.dirt(wx, i, wz, glBase);
}
}
else
{
mb = b.rock(wx, i, wz, glBase);
}
setBlock(x, i, z, mb.material, mb.data);
}
return b.getBiome();
}
public int pick(int max, double noise)

View File

@ -4,14 +4,16 @@ import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator;
import ninja.bytecode.iris.atomics.AtomicChunkData;
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.math.RollingSequence;
public abstract class ParallelChunkGenerator extends ChunkGenerator
{
@ -23,12 +25,13 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
private TaskGroup tg;
private boolean ready = false;
private ChronoLatch cl = new ChronoLatch(1000);
private RollingSequence rs = new RollingSequence(512);
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
{
Shuriken.profiler.start("chunkgen-" + world.getName());
data = new AtomicChunkData(world);
try
{
if(!ready)
@ -37,7 +40,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
ready = true;
}
tg = Iris.executor.startWork();
tg = Iris.noisePool.startWork();
for(i = 0; i < 16; i++)
{
@ -48,16 +51,25 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
wz = (z * 16) + j;
int a = wx;
int b = wz;
tg.queue(() -> genColumn(a, b));
int c = i;
int d = j;
tg.queue(() ->
{
synchronized(biome)
{
biome.setBiome(c, d, genColumn(a, b, c, d));
}
});
}
}
tg.execute();
TaskResult r = tg.execute();
rs.put(r.timeElapsed);
Shuriken.profiler.stop("chunkgen-" + world.getName());
if(cl.flip())
{
J.a(() -> System.out.print("Gen: " + F.duration(Shuriken.profiler.getResult("chunkgen-" + world.getName()).getAverage(), 2)));
System.out.print("Avg: " + F.duration(rs.getAverage(), 2) + " " + F.duration(rs.getMax(), 2) + " / " + F.duration(rs.getMedian(), 2) + " / " + F.duration(rs.getMin(), 2));
}
}
@ -77,7 +89,7 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
public abstract void onInit(World world, Random random);
public abstract void genColumn(int wx, int wz);
public abstract Biome genColumn(int wx, int wz, int x, int z);
@SuppressWarnings("deprecation")
protected void setBlock(int x, int y, int z, Material b)
@ -98,6 +110,9 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
protected void setBlock(int x, int y, int z, int b, byte d)
{
data.setBlock(x, y, z, b, d);
synchronized(data)
{
data.setBlock(x, y, z, b, d);
}
}
}

View File

@ -174,6 +174,7 @@ public final class AtomicChunkData implements ChunkGenerator.ChunkData
{
s0 = new char[h];
}
return s0;
}
else if(s == 1)

View File

@ -12,7 +12,6 @@ public class GenLayerBase extends GenLayer
private double[][][] scatterCache;
private CNG gen;
private CNG fracture;
private CNG basegen;
public GenLayerBase(World world, Random random, RNG rng)
{
@ -21,27 +20,19 @@ public class GenLayerBase extends GenLayer
scatterCache = new double[16][][];
CNG scatter = new CNG(rng.nextRNG(), 1, 1)
.scale(10);
basegen = new CNG(rng.nextRNG(), 0.46, 3)
.scale(0.00295)
.fractureWith(new CNG(rng.nextRNG(), 1, 2)
.scale(0.025), 70);
gen = new CNG(rng.nextRNG(), 0.19D, 4)
gen = new CNG(rng.nextRNG(), 0.19D, 16)
.scale(0.012)
.amp(0.5)
.freq(1.1)
.fractureWith(new CNG(rng.nextRNG(), 1, 2)
.fractureWith(new CNG(rng.nextRNG(), 1, 6)
.scale(0.018)
.fractureWith(new CNG(rng.nextRNG(), 1, 1)
.injectWith(CNG.MULTIPLY)
.child(new CNG(rng.nextRNG(), 0.745, 2)
.scale(0.1))
.fractureWith(new CNG(rng.nextRNG(), 1, 3)
.scale(0.15), 24), 44);
fracture = new CNG(rng.nextRNG(), 0.6D, 4)
.scale(0.118);
// faultline = new CNG(rng.nextRNG(), 1D, 1)
// .scale(0.005)
// .child(new CNG(rng.nextRNG(), 1D, 1)
// .scale(0.012))
// .injectWith(CNG.MULTIPLY)
// .fractureWith(new CNG(rng.nextRNG(), 1, 1)
// .scale(0.07), 200);
//@done
for(int i = 0; i < 16; i++)
@ -60,13 +51,27 @@ public class GenLayerBase extends GenLayer
}
}
public int scatterInt(int x, int y, int z, int bound)
{
return (int) (scatter(x, y, z) * (double) (bound - 1));
}
public double scatter(int x, int y, int z)
{
return scatterCache[Math.abs(x) % 16][Math.abs(y) % 16][Math.abs(z) % 16];
}
public boolean scatterChance(int x, int y, int z, double chance)
{
return scatter(x, y, z) > chance;
}
@Override
public double generateLayer(double noise, double dx, double dz)
{
super.generateLayer(noise, dx, dz);
double fnoise = fracture.noise(dx, dz);
double fx = dx + (fnoise * 12);
double fz = dz - (fnoise * 12);
return basegen.noise(fx, fz) + gen.noise(fx, fz);
dx += (fnoise * 44);
dz -= (fnoise * 44);
return ((noise * 0.5) + (gen.noise(dx, dz) * (0.15 + (noise * 0.65)))) + 0.31;
}
}

View File

@ -0,0 +1,78 @@
package ninja.bytecode.iris.gen;
import java.util.Random;
import org.bukkit.World;
import ninja.bytecode.iris.util.RealBiome;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.M;
import ninja.bytecode.shuriken.math.RNG;
public class GenLayerBiome extends GenLayer
{
private CNG temperature;
private CNG humidity;
private CNG hfracture;
private CNG alt;
private CNG height;
private CNG ocean;
public GenLayerBiome(World world, Random random, RNG rng)
{
super(world, random, rng);
//@builder
temperature = new CNG(rng.nextRNG(), 1, 2)
.scale(0.0018)
.fractureWith(new CNG(rng.nextRNG(), 1, 1).scale(0.06), 23);
hfracture = new CNG(rng.nextRNG(), 1, 2)
.scale(0.0124);
humidity = new CNG(rng.nextRNG(), 1, 2)
.scale(0.0024)
.fractureWith(new CNG(rng.nextRNG(), 1, 1).scale(0.06), 12);
height = new CNG(rng.nextRNG(), 1, 8)
.scale(0.0017601)
.fractureWith(new CNG(rng.nextRNG(), 1, 6)
.scale(0.0574)
.fractureWith(new CNG(rng.nextRNG(), 1, 1), 30)
.scale(0.116), 3);
ocean = new CNG(rng.nextRNG(), 1, 3)
.scale(0.0004601)
.fractureWith(new CNG(rng.nextRNG(), 1, 4).scale(0.016), 499);
alt = new CNG(rng.nextRNG(), 1, 1)
.scale(0.0008)
.fractureWith(new CNG(rng.nextRNG(), 1, 1).scale(0.3), 100);
//@done
}
public RealBiome getBiome(double x, double z)
{
return RealBiome.match(getTemperature(x, z) * 2, getHumidity(x, z), getHeight(x, z), getAlt(x, z));
}
private double getAlt(double x, double z)
{
return alt.noise(x, z);
}
public double getTemperature(double x, double z)
{
return M.clip(temperature.noise(x, z) - (getHeight(x, z) * 0.45), 0D, 1D);
}
public double getHumidity(double x, double z)
{
return humidity.noise(x, z);
}
public double getHeight(double x, double z)
{
return M.clip(Math.pow(height.noise(x + (hfracture.noise(x, z) * 180), z + (hfracture.noise(z, x) * 180)), 3) * 2.654, 0D, 1D);
}
@Override
public double generateLayer(double noise, double dx, double dz)
{
return getHeight(dx, dz);
}
}

View File

@ -0,0 +1,28 @@
package ninja.bytecode.iris.gen;
import java.util.Random;
import org.bukkit.World;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.RNG;
public class GenLayerDeppOcean extends GenLayer
{
private CNG gen;
public GenLayerDeppOcean(World world, Random random, RNG rng)
{
//@builder
super(world, random, rng);
gen = new CNG(rng.nextRNG(), 1D, 4)
.scale(0.012);
//@done
}
@Override
public double generateLayer(double noise, double dx, double dz)
{
double deeper = gen.noise(dx, dz);
}
}

View File

@ -1,18 +0,0 @@
package ninja.bytecode.iris.gen;
import java.util.Random;
import org.bukkit.World;
import ninja.bytecode.shuriken.math.RNG;
public class GenLayerFracture extends GenLayer
{
public GenLayerFracture(World world, Random random, RNG rng)
{
super(world, random, rng);
// TODO Auto-generated constructor stub
}
}

View File

@ -0,0 +1,37 @@
package ninja.bytecode.iris.gen;
import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import ninja.bytecode.iris.MB;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.RNG;
public class GenLayerSnow extends GenLayer
{
private CNG snow;
public GenLayerSnow(World world, Random random, RNG rng)
{
super(world, random, rng);
//@builder
snow = new CNG(rng.nextRNG(), 1, 1)
.scale(0.1);
//@done
}
public MB getSnow(double dx, double dz, double snowChance)
{
int m = (int) ((snowChance * 14) * snow.noise(dx, dz));
m = m > 7 ? 7 : m;
return new MB(Material.SNOW, m);
}
@Override
public double generateLayer(double noise, double dx, double dz)
{
return noise;
}
}

View File

@ -0,0 +1,314 @@
package ninja.bytecode.iris.util;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import ninja.bytecode.iris.MB;
import ninja.bytecode.iris.gen.GenLayerBase;
import ninja.bytecode.shuriken.collections.GList;
public class RealBiome
{
public static final double a = 0;
public static final double h = 0.5;
public static final double t = 0.5;
//@builder
public static final RealBiome[] biomes = {
new RealBiome(0, 0.5, h, -1).water(), // Ocean
new RealBiome(1, 0.6, 0.4, 0.125), // Plains
new RealBiome(2, 2, 0, 0.125) // Desert
.surface(new MB(Material.SAND))
.dirt(new MB(Material.SAND), new MB(Material.SAND, 1))
.rock(new MB(Material.SANDSTONE)),
new RealBiome(3, 0.2, 0.3, 0.56), // Extreme Hills
new RealBiome(4, 0.5, 0.8, a), // Forest
new RealBiome(5, 0.25, 0.8, 0.2), // Taiga
new RealBiome(6, 0.8, 0.9, -0.2), // Swampland
new RealBiome(7, t, h, -0.5).river(), // River
new RealBiome(8, 2, 0, a).dimensional(), // Hell
new RealBiome(9, t, h, a).dimensional(), // The End
new RealBiome(10, 0, 0.5, -1).water(), // Frozen Ocean
new RealBiome(11, 0, 0.5, -0.5).river(), // Frozen River
new RealBiome(12, 0, 0.5, 0.125).surface(new MB(Material.SNOW_BLOCK)), // Ice Plains
new RealBiome(13, 0, 0.5, 0.765) // Ice Mountains
.surface(new MB(Material.SNOW_BLOCK))
.dirt(new MB(Material.PACKED_ICE)),
new RealBiome(14, 0.9, 1, 0.2).modifier() // Mushroom Island
.surface(new MB(Material.MYCEL)),
new RealBiome(15, 0, 1, 0).modifier() // Mushroom Island Shore
.surface(new MB(Material.MYCEL)),
new RealBiome(16, 0.8, 0.4, 0).beach(), // Beaches
new RealBiome(17, 2, 0, 0.75) // Desert Hills
.surface(new MB(Material.SAND))
.dirt(new MB(Material.SAND), new MB(Material.SAND, 1))
.rock(new MB(Material.SANDSTONE)),
new RealBiome(18, 0.6, 0.8, 0.75), // Forest Hills
new RealBiome(19, 0.25, 0.8, 0.75), // Taiga Hills
new RealBiome(20, 0.2, 0.3, 0.8), // Extreme Hills Edge
new RealBiome(21, 0.95, 0.9, a), // Jungle
new RealBiome(22, 0.95, 0.9, 0.75), // Jungle
new RealBiome(23, 0.9, 0.9, 0.15), // Jungle Edge
new RealBiome(24, t, h, -1.8).water(), // Deep Ocean
new RealBiome(25, 0.2, 0.3, 0.1).beach(), // Stone Beach
new RealBiome(26, 0.2, 0.3, 0).beach(), // Cold Beach
new RealBiome(27, 0.5, 0.5, a), // Birch Forest
new RealBiome(28, 0.4, 0.4, 0.25), // Birch Forest Hills
new RealBiome(29, 0.7, 0.8, a), // Roofed Forest
new RealBiome(30, -0.5, 0.4, 0.2), // Cold Taiga
new RealBiome(31, -0.5, 0.4, 0.75), // Cold Taiga Hills
new RealBiome(32, 0.4, 0.8, 0.2), // Redwood Taiga
new RealBiome(33, 0.3, 0.8, 0.75), // Redwood Taiga Hills
new RealBiome(34, 0.2, 0.3, 1), // Extra Hills with Trees
new RealBiome(35, 1.2, 0, 0.125), // Savanna
new RealBiome(36, 1, 0, 0.28), // Savanna Plateau
new RealBiome(37, 2, 0, a), // Mesa
new RealBiome(38, 2, 0, 0.28), // Mesa Plateau F
new RealBiome(39, 2, 0, 0.31), // Mesa Plateau
};
//@done
private int biomeId;
private double temperature;
private double humidity;
private double height;
private boolean modifier;
private boolean river;
private boolean water;
private boolean beach;
private boolean dimensional;
private GList<MB> surface;
private GList<MB> dirt;
private GList<MB> rock;
private boolean defs;
private boolean defd;
private boolean defr;
public RealBiome(int biomeId, double temperature, double humidity, double height)
{
defs = true;
defd = true;
defr = true;
this.biomeId = biomeId;
this.temperature = temperature;
this.humidity = humidity;
this.height = height;
surface = new GList<>();
dirt = new GList<>();
rock = new GList<>();
surface.add(new MB(Material.GRASS));
dirt.add(new MB(Material.DIRT), new MB(Material.DIRT, 1));
rock.add(new MB(Material.STONE), new MB(Material.STONE, 5), new MB(Material.COBBLESTONE));
temperature = temperature > 1 ? 1 : temperature < 0 ? 0 : temperature;
humidity = humidity > 1 ? 1 : humidity < 0 ? 0 : humidity;
height = height > 1 ? 1 : height < 0 ? 0 : height;
}
public static RealBiome match(double temperature, double humidity, double height, double d)
{
GList<RealBiome> b = new GList<>();
double distance = Double.MAX_VALUE;
for(RealBiome i : biomes)
{
if(i.modifier)
{
continue;
}
double dist = i.getDistance(temperature, humidity, height);
if(dist < distance)
{
distance = dist;
b.add(i);
}
}
return b.get((int) (d * Math.min(b.size(), 3)));
}
public double getDistance(double temperature, double humidity, double height)
{
return Math.abs((temperature - this.temperature) * 3.5) + Math.abs((humidity - this.humidity) * 2.5) + Math.abs((height - this.height) * 4.8);
}
public Biome getBiome()
{
return Biome.values()[biomeId];
}
public RealBiome surface(MB... mb)
{
if(defs)
{
defs = false;
surface.clear();
}
this.surface.add(mb);
return this;
}
public RealBiome dirt(MB... mb)
{
if(defd)
{
defd = false;
dirt.clear();
}
this.dirt.add(mb);
return this;
}
public RealBiome rock(MB... mb)
{
if(defr)
{
defr = false;
rock.clear();
}
this.rock.add(mb);
return this;
}
public RealBiome modifier()
{
modifier = true;
return this;
}
public RealBiome river()
{
river = true;
return this.modifier();
}
public RealBiome water()
{
water = true;
return this.modifier();
}
public RealBiome beach()
{
beach = true;
return this.modifier();
}
public RealBiome dimensional()
{
dimensional = true;
return this.modifier();
}
public MB surface(int x, int y, int z, GenLayerBase glBase)
{
return surface.get(glBase.scatterInt(x, y, z, surface.size()));
}
public MB dirt(int x, int y, int z, GenLayerBase glBase)
{
return dirt.get(glBase.scatterInt(x, y, z, dirt.size()));
}
public MB rock(int x, int y, int z, GenLayerBase glBase)
{
return rock.get(glBase.scatterInt(x, y, z, rock.size()));
}
public static double getA()
{
return a;
}
public static double getH()
{
return h;
}
public static double getT()
{
return t;
}
public static RealBiome[] getBiomes()
{
return biomes;
}
public int getBiomeId()
{
return biomeId;
}
public double getTemperature()
{
return temperature;
}
public double getHumidity()
{
return humidity;
}
public double getHeight()
{
return height;
}
public boolean isModifier()
{
return modifier;
}
public boolean isRiver()
{
return river;
}
public boolean isWater()
{
return water;
}
public boolean isBeach()
{
return beach;
}
public boolean isDimensional()
{
return dimensional;
}
public GList<MB> getSurface()
{
return surface;
}
public GList<MB> getDirt()
{
return dirt;
}
public GList<MB> getRock()
{
return rock;
}
public boolean isDefs()
{
return defs;
}
public boolean isDefd()
{
return defd;
}
public boolean isDefr()
{
return defr;
}
}