From 57cb8d5bdae880eedbf19b26970a181f38b78b4b Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 31 Aug 2020 15:33:51 -0400 Subject: [PATCH] fAILS AT FONTS --- .../java/com/volmit/iris/ProjectManager.java | 32 ++++ .../iris/gen/ParallaxChunkGenerator.java | 35 ++++- .../volmit/iris/gen/layer/GenLayerText.java | 24 +++ .../com/volmit/iris/object/FontStyle.java | 15 ++ .../com/volmit/iris/object/IrisBiome.java | 5 + .../com/volmit/iris/object/IrisDimension.java | 26 ++++ .../iris/object/IrisMaterialPalette.java | 95 +++++++++++ .../com/volmit/iris/object/IrisRegion.java | 5 + .../volmit/iris/object/IrisTextPlacement.java | 122 +++++++++++++++ .../volmit/iris/object/IrisTextRenderer.java | 147 ++++++++++++++++++ .../volmit/iris/util/RegistryListFont.java | 14 ++ 11 files changed, 517 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/volmit/iris/object/FontStyle.java create mode 100644 src/main/java/com/volmit/iris/object/IrisMaterialPalette.java create mode 100644 src/main/java/com/volmit/iris/object/IrisTextPlacement.java create mode 100644 src/main/java/com/volmit/iris/object/IrisTextRenderer.java create mode 100644 src/main/java/com/volmit/iris/util/RegistryListFont.java diff --git a/src/main/java/com/volmit/iris/ProjectManager.java b/src/main/java/com/volmit/iris/ProjectManager.java index ee0eb10a4..4a80fdabf 100644 --- a/src/main/java/com/volmit/iris/ProjectManager.java +++ b/src/main/java/com/volmit/iris/ProjectManager.java @@ -1,6 +1,7 @@ package com.volmit.iris; import java.awt.Desktop; +import java.awt.GraphicsEnvironment; import java.io.File; import java.io.IOException; 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.RegistryListBiome; import com.volmit.iris.util.RegistryListDimension; +import com.volmit.iris.util.RegistryListFont; import com.volmit.iris.util.RegistryListGenerator; import com.volmit.iris.util.RegistryListLoot; import com.volmit.iris.util.RegistryListObject; @@ -799,6 +801,11 @@ public class ProjectManager prop.put("enum", new JSONArray(getBiomeList(dat))); } + if(k.isAnnotationPresent(RegistryListFont.class)) + { + prop.put("enum", new JSONArray(getFontList())); + } + if(k.isAnnotationPresent(RegistryListLoot.class)) { prop.put("enum", new JSONArray(getLootList(dat))); @@ -955,6 +962,26 @@ public class ProjectManager 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)) { String name = "enloot" + t.type().getSimpleName().toLowerCase(); @@ -1176,6 +1203,11 @@ public class ProjectManager return schema; } + private String[] getFontList() + { + return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); + } + private String[] getBiomeList(IrisDataManager data) { return data.getBiomeLoader().getPossibleKeys(); diff --git a/src/main/java/com/volmit/iris/gen/ParallaxChunkGenerator.java b/src/main/java/com/volmit/iris/gen/ParallaxChunkGenerator.java index 1ea07e29f..a97c95662 100644 --- a/src/main/java/com/volmit/iris/gen/ParallaxChunkGenerator.java +++ b/src/main/java/com/volmit/iris/gen/ParallaxChunkGenerator.java @@ -18,6 +18,7 @@ import com.volmit.iris.object.IrisBiomeMutation; import com.volmit.iris.object.IrisObjectPlacement; import com.volmit.iris.object.IrisRegion; import com.volmit.iris.object.IrisStructurePlacement; +import com.volmit.iris.object.IrisTextPlacement; import com.volmit.iris.util.BiomeMap; import com.volmit.iris.util.CaveResult; import com.volmit.iris.util.ChunkPosition; @@ -194,7 +195,6 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple @Override 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) { getSliverCache().clear(); @@ -219,7 +219,6 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple super.onPostParallaxPostGenerate(random, x, z, data, grid, height, biomeMap, map); getParallaxMap().clean(ticks); getData().getObjectLoader().clean(); - // flock.unlock(); } 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) { - String key = "par." + x + "." + "z"; + String key = "par." + x + "." + z; ChunkPosition rad = getDimension().getParallaxSize(this); KList q = new KList<>(); @@ -290,6 +289,36 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple 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()) { lockq.lock(); diff --git a/src/main/java/com/volmit/iris/gen/layer/GenLayerText.java b/src/main/java/com/volmit/iris/gen/layer/GenLayerText.java index 03902c29b..64c418f2a 100644 --- a/src/main/java/com/volmit/iris/gen/layer/GenLayerText.java +++ b/src/main/java/com/volmit/iris/gen/layer/GenLayerText.java @@ -10,6 +10,7 @@ import org.bukkit.block.data.BlockData; import com.volmit.iris.Iris; import com.volmit.iris.gen.DimensionChunkGenerator; import com.volmit.iris.gen.atomics.AtomicCache; +import com.volmit.iris.object.IrisMaterialPalette; import com.volmit.iris.object.IrisObject; import com.volmit.iris.util.B; import com.volmit.iris.util.GenLayer; @@ -60,6 +61,29 @@ public class GenLayerText extends GenLayer 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 public double generate(double x, double z) { diff --git a/src/main/java/com/volmit/iris/object/FontStyle.java b/src/main/java/com/volmit/iris/object/FontStyle.java new file mode 100644 index 000000000..433cbb169 --- /dev/null +++ b/src/main/java/com/volmit/iris/object/FontStyle.java @@ -0,0 +1,15 @@ +package com.volmit.iris.object; + +import com.volmit.iris.util.DontObfuscate; + +public enum FontStyle +{ + @DontObfuscate + PLAIN, + + @DontObfuscate + ITALIC, + + @DontObfuscate + BOLD, +} diff --git a/src/main/java/com/volmit/iris/object/IrisBiome.java b/src/main/java/com/volmit/iris/object/IrisBiome.java index 065cd8005..1d0e0f61d 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/object/IrisBiome.java @@ -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.") private String name = "A Biome"; + @DontObfuscate + @Desc("Place text on terrain") + @ArrayType(min = 1, type = IrisTextPlacement.class) + private KList text = new KList<>(); + @ArrayType(min = 1, type = IrisEffect.class) @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.") diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index 20cd28f9e..356fb789f 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -46,6 +46,11 @@ public class IrisDimension extends IrisRegistrant @Desc("The human readable name of this dimension") private String name = "A Dimension"; + @DontObfuscate + @Desc("Place text on terrain") + @ArrayType(min = 1, type = IrisTextPlacement.class) + private KList text = new KList<>(); + @DontObfuscate @Desc("Reference loot tables in this area") private IrisLootReference loot = new IrisLootReference(); @@ -679,6 +684,13 @@ public class IrisDimension extends IrisRegistrant 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(IrisDepositGenerator i : v.getDeposits()) @@ -687,6 +699,13 @@ public class IrisDimension extends IrisRegistrant x = max > x ? max : x; 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) @@ -697,6 +716,13 @@ public class IrisDimension extends IrisRegistrant x = max > x ? max : x; 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; diff --git a/src/main/java/com/volmit/iris/object/IrisMaterialPalette.java b/src/main/java/com/volmit/iris/object/IrisMaterialPalette.java new file mode 100644 index 000000000..b791706cf --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisMaterialPalette.java @@ -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 palette = new KList().qadd("STONE"); + + private transient AtomicCache> blockData = new AtomicCache<>(); + private transient AtomicCache layerGenerator = new AtomicCache<>(); + private transient AtomicCache 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 add(String b) + { + palette.add(b); + + return palette; + } + + public KList getBlockData() + { + return blockData.aquire(() -> + { + KList 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; + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisRegion.java b/src/main/java/com/volmit/iris/object/IrisRegion.java index 7a3c69231..95a41436c 100644 --- a/src/main/java/com/volmit/iris/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/object/IrisRegion.java @@ -41,6 +41,11 @@ public class IrisRegion extends IrisRegistrant implements IRare @DontObfuscate @Desc("The rarity of the region") private int rarity = 1; + + @DontObfuscate + @Desc("Place text on terrain") + @ArrayType(min = 1, type = IrisTextPlacement.class) + private KList text = new KList<>(); @ArrayType(min = 1, type = IrisBlockDrops.class) @DontObfuscate diff --git a/src/main/java/com/volmit/iris/object/IrisTextPlacement.java b/src/main/java/com/volmit/iris/object/IrisTextPlacement.java new file mode 100644 index 000000000..54f8b608c --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisTextPlacement.java @@ -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 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 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); + } + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisTextRenderer.java b/src/main/java/com/volmit/iris/object/IrisTextRenderer.java new file mode 100644 index 000000000..5d3f93915 --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisTextRenderer.java @@ -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 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> objects = new AtomicCache<>(); + private transient AtomicCache fontData = new AtomicCache<>(); + private transient AtomicCache fontMetrics = new AtomicCache<>(); + private transient AtomicCache maxLength = new AtomicCache<>(); + private transient AtomicCache fontStyleData = new AtomicCache<>(); + + public IrisTextRenderer() + { + + } + + public KList getObjects(ParallaxChunkGenerator g, RNG rng) + { + return objects.aquire(() -> + { + KList 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); + } +} diff --git a/src/main/java/com/volmit/iris/util/RegistryListFont.java b/src/main/java/com/volmit/iris/util/RegistryListFont.java new file mode 100644 index 000000000..bd0bbb8e0 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/RegistryListFont.java @@ -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 +{ + +}