fAILS AT FONTS

This commit is contained in:
Daniel Mills 2020-08-31 15:33:51 -04:00
parent 0b583bcf80
commit 57cb8d5bda
11 changed files with 517 additions and 3 deletions

View File

@ -1,6 +1,7 @@
package com.volmit.iris; package com.volmit.iris;
import java.awt.Desktop; import java.awt.Desktop;
import java.awt.GraphicsEnvironment;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -62,6 +63,7 @@ import com.volmit.iris.util.MortarSender;
import com.volmit.iris.util.O; import com.volmit.iris.util.O;
import com.volmit.iris.util.RegistryListBiome; import com.volmit.iris.util.RegistryListBiome;
import com.volmit.iris.util.RegistryListDimension; import com.volmit.iris.util.RegistryListDimension;
import com.volmit.iris.util.RegistryListFont;
import com.volmit.iris.util.RegistryListGenerator; import com.volmit.iris.util.RegistryListGenerator;
import com.volmit.iris.util.RegistryListLoot; import com.volmit.iris.util.RegistryListLoot;
import com.volmit.iris.util.RegistryListObject; import com.volmit.iris.util.RegistryListObject;
@ -799,6 +801,11 @@ public class ProjectManager
prop.put("enum", new JSONArray(getBiomeList(dat))); prop.put("enum", new JSONArray(getBiomeList(dat)));
} }
if(k.isAnnotationPresent(RegistryListFont.class))
{
prop.put("enum", new JSONArray(getFontList()));
}
if(k.isAnnotationPresent(RegistryListLoot.class)) if(k.isAnnotationPresent(RegistryListLoot.class))
{ {
prop.put("enum", new JSONArray(getLootList(dat))); prop.put("enum", new JSONArray(getLootList(dat)));
@ -955,6 +962,26 @@ public class ProjectManager
continue; continue;
} }
if(k.isAnnotationPresent(RegistryListFont.class))
{
String name = "enfong" + t.type().getSimpleName().toLowerCase();
if(!def.containsKey(name))
{
JSONObject deff = new JSONObject();
deff.put("type", tx);
deff.put("enum", new JSONArray(getFontList()));
def.put(name, deff);
}
JSONObject items = new JSONObject();
items.put("$ref", "#/definitions/" + name);
prop.put("items", items);
prop.put("description", k.getAnnotation(Desc.class).value());
prop.put("type", tp);
properties.put(k.getName(), prop);
continue;
}
if(k.isAnnotationPresent(RegistryListLoot.class)) if(k.isAnnotationPresent(RegistryListLoot.class))
{ {
String name = "enloot" + t.type().getSimpleName().toLowerCase(); String name = "enloot" + t.type().getSimpleName().toLowerCase();
@ -1176,6 +1203,11 @@ public class ProjectManager
return schema; return schema;
} }
private String[] getFontList()
{
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
}
private String[] getBiomeList(IrisDataManager data) private String[] getBiomeList(IrisDataManager data)
{ {
return data.getBiomeLoader().getPossibleKeys(); return data.getBiomeLoader().getPossibleKeys();

View File

@ -18,6 +18,7 @@ import com.volmit.iris.object.IrisBiomeMutation;
import com.volmit.iris.object.IrisObjectPlacement; import com.volmit.iris.object.IrisObjectPlacement;
import com.volmit.iris.object.IrisRegion; import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.object.IrisStructurePlacement; import com.volmit.iris.object.IrisStructurePlacement;
import com.volmit.iris.object.IrisTextPlacement;
import com.volmit.iris.util.BiomeMap; import com.volmit.iris.util.BiomeMap;
import com.volmit.iris.util.CaveResult; import com.volmit.iris.util.CaveResult;
import com.volmit.iris.util.ChunkPosition; import com.volmit.iris.util.ChunkPosition;
@ -194,7 +195,6 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
@Override @Override
protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap, AtomicSliverMap map) protected void onPostGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid, HeightMap height, BiomeMap biomeMap, AtomicSliverMap map)
{ {
// flock.lock();
if(getSliverCache().size() > 20000) if(getSliverCache().size() > 20000)
{ {
getSliverCache().clear(); getSliverCache().clear();
@ -219,7 +219,6 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
super.onPostParallaxPostGenerate(random, x, z, data, grid, height, biomeMap, map); super.onPostParallaxPostGenerate(random, x, z, data, grid, height, biomeMap, map);
getParallaxMap().clean(ticks); getParallaxMap().clean(ticks);
getData().getObjectLoader().clean(); getData().getObjectLoader().clean();
// flock.unlock();
} }
public IrisStructureResult getStructure(int x, int y, int z) public IrisStructureResult getStructure(int x, int y, int z)
@ -229,7 +228,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
protected void onGenerateParallax(RNG random, int x, int z) protected void onGenerateParallax(RNG random, int x, int z)
{ {
String key = "par." + x + "." + "z"; String key = "par." + x + "." + z;
ChunkPosition rad = getDimension().getParallaxSize(this); ChunkPosition rad = getDimension().getParallaxSize(this);
KList<NastyRunnable> q = new KList<>(); KList<NastyRunnable> q = new KList<>();
@ -290,6 +289,36 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
IrisRegion r = sampleRegion((i * 16) + 7, (j * 16) + 7); IrisRegion r = sampleRegion((i * 16) + 7, (j * 16) + 7);
for(IrisTextPlacement k : getDimension().getText())
{
lockq.lock();
q.add(() ->
{
k.place(this, random.nextParallelRNG(-7228), i, j);
});
lockq.unlock();
}
for(IrisTextPlacement k : r.getText())
{
lockq.lock();
q.add(() ->
{
k.place(this, random.nextParallelRNG(-4228), i, j);
});
lockq.unlock();
}
for(IrisTextPlacement k : b.getText())
{
lockq.lock();
q.add(() ->
{
k.place(this, random.nextParallelRNG(-22228), i, j);
});
lockq.unlock();
}
for(IrisStructurePlacement k : r.getStructures()) for(IrisStructurePlacement k : r.getStructures())
{ {
lockq.lock(); lockq.lock();

View File

@ -10,6 +10,7 @@ import org.bukkit.block.data.BlockData;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.gen.DimensionChunkGenerator; import com.volmit.iris.gen.DimensionChunkGenerator;
import com.volmit.iris.gen.atomics.AtomicCache; import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.object.IrisMaterialPalette;
import com.volmit.iris.object.IrisObject; import com.volmit.iris.object.IrisObject;
import com.volmit.iris.util.B; import com.volmit.iris.util.B;
import com.volmit.iris.util.GenLayer; import com.volmit.iris.util.GenLayer;
@ -60,6 +61,29 @@ public class GenLayerText extends GenLayer
return o; return o;
} }
public IrisObject createTextObject(RNG rng, String text, int w, Font f, IrisMaterialPalette palette)
{
int h = f.getSize();
BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics gs = bufferedImage.getGraphics();
Graphics2D g = (Graphics2D) gs;
g.setFont(f);
g.drawString(text, 0, h);
IrisObject o = new IrisObject(w, 1, h);
for(int y = 0; y < h; y++)
{
for(int x = 0; x < w; x++)
{
if(bufferedImage.getRGB(x, y) != -16777216)
{
o.setUnsigned(x, 0, y, palette.get(rng, x, w, y));
}
}
}
return o;
}
@Override @Override
public double generate(double x, double z) public double generate(double x, double z)
{ {

View File

@ -0,0 +1,15 @@
package com.volmit.iris.object;
import com.volmit.iris.util.DontObfuscate;
public enum FontStyle
{
@DontObfuscate
PLAIN,
@DontObfuscate
ITALIC,
@DontObfuscate
BOLD,
}

View File

@ -37,6 +37,11 @@ public class IrisBiome extends IrisRegistrant implements IRare
@Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.") @Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.")
private String name = "A Biome"; private String name = "A Biome";
@DontObfuscate
@Desc("Place text on terrain")
@ArrayType(min = 1, type = IrisTextPlacement.class)
private KList<IrisTextPlacement> text = new KList<>();
@ArrayType(min = 1, type = IrisEffect.class) @ArrayType(min = 1, type = IrisEffect.class)
@DontObfuscate @DontObfuscate
@Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.") @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.")

View File

@ -46,6 +46,11 @@ public class IrisDimension extends IrisRegistrant
@Desc("The human readable name of this dimension") @Desc("The human readable name of this dimension")
private String name = "A Dimension"; private String name = "A Dimension";
@DontObfuscate
@Desc("Place text on terrain")
@ArrayType(min = 1, type = IrisTextPlacement.class)
private KList<IrisTextPlacement> text = new KList<>();
@DontObfuscate @DontObfuscate
@Desc("Reference loot tables in this area") @Desc("Reference loot tables in this area")
private IrisLootReference loot = new IrisLootReference(); private IrisLootReference loot = new IrisLootReference();
@ -679,6 +684,13 @@ public class IrisDimension extends IrisRegistrant
z = max > z ? max : z; z = max > z ? max : z;
} }
for(IrisTextPlacement i : getText())
{
int max = i.maxDimension();
x = max > x ? max : x;
z = max > z ? max : z;
}
for(IrisRegion v : r) for(IrisRegion v : r)
{ {
for(IrisDepositGenerator i : v.getDeposits()) for(IrisDepositGenerator i : v.getDeposits())
@ -687,6 +699,13 @@ public class IrisDimension extends IrisRegistrant
x = max > x ? max : x; x = max > x ? max : x;
z = max > z ? max : z; z = max > z ? max : z;
} }
for(IrisTextPlacement i : v.getText())
{
int max = i.maxDimension();
x = max > x ? max : x;
z = max > z ? max : z;
}
} }
for(IrisBiome v : b) for(IrisBiome v : b)
@ -697,6 +716,13 @@ public class IrisDimension extends IrisRegistrant
x = max > x ? max : x; x = max > x ? max : x;
z = max > z ? max : z; z = max > z ? max : z;
} }
for(IrisTextPlacement i : v.getText())
{
int max = i.maxDimension();
x = max > x ? max : x;
z = max > z ? max : z;
}
} }
x = (Math.max(x, 16) + 16) >> 4; x = (Math.max(x, 16) + 16) >> 4;

View File

@ -0,0 +1,95 @@
package com.volmit.iris.object;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.noise.CNG;
import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.B;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.Required;
import lombok.Data;
@Desc("A palette of materials")
@Data
public class IrisMaterialPalette
{
@DontObfuscate
@Desc("The style of noise")
private IrisGeneratorStyle style = NoiseStyle.STATIC.style();
@MinNumber(0.0001)
@DontObfuscate
@Desc("The terrain zoom mostly for zooming in on a wispy palette")
private double zoom = 5;
@Required
@ArrayType(min = 1, type = String.class)
@DontObfuscate
@Desc("The palette of blocks to be used in this layer")
private KList<String> palette = new KList<String>().qadd("STONE");
private transient AtomicCache<KList<BlockData>> blockData = new AtomicCache<>();
private transient AtomicCache<CNG> layerGenerator = new AtomicCache<>();
private transient AtomicCache<CNG> heightGenerator = new AtomicCache<>();
public BlockData get(RNG rng, double x, double y, double z)
{
if(getBlockData().isEmpty())
{
return null;
}
if(getBlockData().size() == 1)
{
return getBlockData().get(0);
}
return getLayerGenerator(rng).fit(getBlockData(), x / zoom, y / zoom, z / zoom);
}
public CNG getLayerGenerator(RNG rng)
{
return layerGenerator.aquire(() ->
{
RNG rngx = rng.nextParallelRNG(-23498896 + getBlockData().size());
return style.create(rngx);
});
}
public KList<String> add(String b)
{
palette.add(b);
return palette;
}
public KList<BlockData> getBlockData()
{
return blockData.aquire(() ->
{
KList<BlockData> blockData = new KList<>();
for(String ix : palette)
{
BlockData bx = B.getBlockData(ix);
if(bx != null)
{
blockData.add(bx);
}
}
return blockData;
});
}
public IrisMaterialPalette zero()
{
palette.clear();
return this;
}
}

View File

@ -41,6 +41,11 @@ public class IrisRegion extends IrisRegistrant implements IRare
@DontObfuscate @DontObfuscate
@Desc("The rarity of the region") @Desc("The rarity of the region")
private int rarity = 1; private int rarity = 1;
@DontObfuscate
@Desc("Place text on terrain")
@ArrayType(min = 1, type = IrisTextPlacement.class)
private KList<IrisTextPlacement> text = new KList<>();
@ArrayType(min = 1, type = IrisBlockDrops.class) @ArrayType(min = 1, type = IrisBlockDrops.class)
@DontObfuscate @DontObfuscate

View File

@ -0,0 +1,122 @@
package com.volmit.iris.object;
import com.volmit.iris.Iris;
import com.volmit.iris.gen.ParallaxChunkGenerator;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.Required;
import lombok.Data;
@Desc("A text renderer to place text on terrain")
@Data
public class IrisTextPlacement
{
@MinNumber(0)
@MaxNumber(1)
@DontObfuscate
@Desc("The chance to place this font per chunk")
private double chance = 0.1;
@MinNumber(0)
@DontObfuscate
@Desc("The amount of times to place randomly in a chunk if the chance passes")
private int density = 1;
@DontObfuscate
@Desc("The rotation for this text placement")
private IrisObjectRotation rotation = new IrisObjectRotation();
@DontObfuscate
@Desc("The mode to place this text")
private ObjectPlaceMode mode = ObjectPlaceMode.PAINT;
@DontObfuscate
@Desc("The translation for this text placement")
private IrisObjectTranslate translate = new IrisObjectTranslate();
@DontObfuscate
@Desc("The clamp for this text placement")
private IrisObjectLimit clamp = new IrisObjectLimit();
@Required
@DontObfuscate
@Desc("The text renderers to pick from")
@ArrayType(min = 1, type = IrisTextRenderer.class)
private KList<IrisTextRenderer> render = new KList<>();
@DontObfuscate
@Desc("If set to true, objects will place on the terrain height, ignoring the water surface.")
private boolean underwater = false;
@DontObfuscate
@Desc("If set to true, Blocks placed underwater that could be waterlogged are waterlogged.")
private boolean waterloggable = true;
@DontObfuscate
@Desc("If set to true, objects will place on the fluid height level Such as boats.")
private boolean onwater = false;
private AtomicCache<IrisObjectPlacement> config = new AtomicCache<>();
public IrisObjectPlacement getConfig()
{
return config.aquire(() ->
{
IrisObjectPlacement p = new IrisObjectPlacement();
p.setRotation(getRotation());
p.setBore(false);
p.setDensity(getDensity());
p.setChance(getChance());
p.setTranslate(getTranslate());
p.setClamp(getClamp());
p.setOnwater(isOnwater());
p.setUnderwater(isUnderwater());
p.setWaterloggable(isWaterloggable());
return p;
});
}
public IrisTextPlacement()
{
}
public int maxDimension()
{
int m = 0;
for(IrisTextRenderer i : getRender())
{
int g = (int) Math.ceil(i.getMaxLength());
if(g > m)
{
m = g;
}
}
return m;
}
public void place(ParallaxChunkGenerator g, RNG rngf, int x, int z)
{
RNG rngg = rngf.nextParallelRNG(x).nextParallelRNG(z);
for(int i = 0; i < getConfig().getTriesForChunk(rngg); i++)
{
RNG rng = rngg.nextParallelRNG((i * 3 + 8) - 23040);
int xb = (x * 16) + rng.nextInt(16);
int zb = (z * 16) + rng.nextInt(16);
Iris.info("Placing at " + xb + " " + zb);
getRender().get(rng.nextInt(getRender().size())).place(g, rngg, getConfig(), xb, zb);
}
}
}

View File

@ -0,0 +1,147 @@
package com.volmit.iris.object;
import java.awt.Canvas;
import java.awt.Font;
import java.awt.FontMetrics;
import com.volmit.iris.gen.ParallaxChunkGenerator;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.Required;
import lombok.Data;
@Desc("A text renderer to place text on terrain")
@Data
public class IrisTextRenderer
{
@Required
@DontObfuscate
@Desc("The font to use for this renderer")
private String font;
@MinNumber(4)
@MaxNumber(48)
@DontObfuscate
@Desc("The font scale 1 = 1pt = ~1-2 blocks high per character")
private int size = 18;
@DontObfuscate
@Desc("The font style to use while rendering text")
private FontStyle fontStyle = FontStyle.PLAIN;
@Required
@DontObfuscate
@Desc("The lines of text to randomly pick from")
@ArrayType(min = 1, type = String.class)
private KList<String> text = new KList<>();
@Required
@DontObfuscate
@Desc("The palette of blocks to use when drawing text")
private IrisMaterialPalette palette = new IrisMaterialPalette();
@DontObfuscate
@Desc("Use a generator to shuffle the surface field of coordinates. Using simplex for example would make the text rendered wavy. Use the multiplier to stretch further.")
private IrisGeneratorStyle surfaceField = new IrisGeneratorStyle(NoiseStyle.FLAT);
private transient AtomicCache<KList<IrisObject>> objects = new AtomicCache<>();
private transient AtomicCache<Font> fontData = new AtomicCache<>();
private transient AtomicCache<FontMetrics> fontMetrics = new AtomicCache<>();
private transient AtomicCache<Double> maxLength = new AtomicCache<>();
private transient AtomicCache<Integer> fontStyleData = new AtomicCache<>();
public IrisTextRenderer()
{
}
public KList<IrisObject> getObjects(ParallaxChunkGenerator g, RNG rng)
{
return objects.aquire(() ->
{
KList<IrisObject> o = new KList<>();
for(String i : text)
{
o.add(g.getGlText().createTextObject(rng, i, (int) getLength(i), getFontData(), getPalette()));
}
return o;
});
}
public String getText(RNG rng)
{
return text.get(rng.nextInt(text.size()));
}
public double getMaxLength()
{
return maxLength.aquire(() ->
{
String l = "";
for(String i : text)
{
if(i.length() > l.length())
{
l = i;
}
}
return getLength(l);
});
}
public double getLength(String str)
{
return getFontMetrics().stringWidth(str);
}
public double getHeight(String str)
{
return getSize() * 1.2;
}
public Font getFontData()
{
return fontData.aquire(() ->
{
return new Font(getFont(), fontStyleData.aquire(() ->
{
if(getFontStyle().equals(FontStyle.ITALIC))
{
return Font.ITALIC;
}
if(getFontStyle().equals(FontStyle.BOLD))
{
return Font.BOLD;
}
return Font.PLAIN;
}), getSize());
});
}
public FontMetrics getFontMetrics()
{
return fontMetrics.aquire(() ->
{
Canvas c = new Canvas();
return c.getFontMetrics(getFontData());
});
}
public void place(ParallaxChunkGenerator g, RNG rng, IrisObjectPlacement config, int xb, int zb)
{
getObjects(g, rng).get(rng.nextInt(getObjects(g, rng).size())).place(xb, zb, g, config, rng);
}
}

View File

@ -0,0 +1,14 @@
package com.volmit.iris.util;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({PARAMETER, TYPE, FIELD})
public @interface RegistryListFont
{
}