Added chat icons for in-game items and blocks

This commit is contained in:
Anuken
2020-01-17 18:08:23 -05:00
parent d9e5dc8ba2
commit 8d61ddbbd4
11 changed files with 2272 additions and 2622 deletions

View File

@@ -18,6 +18,7 @@ import mindustry.graphics.*;
import mindustry.maps.*;
import mindustry.mod.*;
import mindustry.net.Net;
import mindustry.ui.*;
import static arc.Core.*;
import static mindustry.Vars.*;
@@ -55,15 +56,15 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
Vars.net = new Net(platform.getNet());
mods = new Mods();
UI.loadSystemCursors();
Fonts.loadSystemCursors();
assets.load(new Vars());
UI.loadDefaultFont();
Fonts.loadDefaultFont();
assets.load(new AssetDescriptor<>("sprites/sprites.atlas", TextureAtlas.class)).loaded = t -> {
atlas = (TextureAtlas)t;
UI.cleanAtlas(atlas);
Fonts.mergeFontAtlas(atlas);
};
assets.loadRun("maps", Map.class, () -> maps.loadPreviews());

View File

@@ -2,26 +2,13 @@ package mindustry.core;
import arc.*;
import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.Input.*;
import arc.assets.*;
import arc.assets.loaders.*;
import arc.assets.loaders.resolvers.*;
import arc.files.*;
import arc.freetype.*;
import arc.freetype.FreeTypeFontGenerator.*;
import arc.freetype.FreetypeFontLoader.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.Pixmap.*;
import arc.graphics.Texture.*;
import arc.graphics.g2d.*;
import arc.graphics.g2d.BitmapFont.*;
import arc.graphics.g2d.PixmapPacker.*;
import arc.graphics.g2d.TextureAtlas.*;
import arc.input.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.*;
import arc.scene.actions.*;
import arc.scene.event.*;
@@ -85,7 +72,7 @@ public class UI implements ApplicationListener, Loadable{
public Cursor drillCursor, unloadCursor;
public UI(){
setupFonts();
Fonts.loadFonts();
}
@Override
@@ -107,6 +94,7 @@ public class UI implements ApplicationListener, Loadable{
Icon.load();
Styles.load();
Tex.loadStyles();
Fonts.loadContentIcons();
Dialog.setShowAction(() -> sequence(alpha(0f), fadeIn(0.1f)));
Dialog.setHideAction(() -> sequence(fadeOut(0.1f)));
@@ -124,7 +112,9 @@ public class UI implements ApplicationListener, Loadable{
Colors.put("unlaunched", Color.valueOf("8982ed"));
Colors.put("highlight", Pal.accent.cpy().lerp(Color.white, 0.3f));
Colors.put("stat", Pal.stat);
loadExtraCursors();
drillCursor = Core.graphics.newCursor("drill");
unloadCursor = Core.graphics.newCursor("unload");
}
@Override
@@ -132,134 +122,6 @@ public class UI implements ApplicationListener, Loadable{
return Array.with(new AssetDescriptor<>(Control.class), new AssetDescriptor<>("outline", BitmapFont.class), new AssetDescriptor<>("default", BitmapFont.class), new AssetDescriptor<>("chat", BitmapFont.class));
}
/** Called from a static context to make the cursor appear immediately upon startup.*/
public static void loadSystemCursors(){
SystemCursor.arrow.set(Core.graphics.newCursor("cursor"));
SystemCursor.hand.set(Core.graphics.newCursor("hand"));
SystemCursor.ibeam.set(Core.graphics.newCursor("ibeam"));
Core.graphics.restoreCursor();
}
/** Called from a static context for use in the loading screen.*/
public static void loadDefaultFont(){
packer = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true);
FileHandleResolver resolver = new InternalFileHandleResolver();
Core.assets.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
Core.assets.setLoader(BitmapFont.class, null, new FreetypeFontLoader(resolver){
@Override
public BitmapFont loadSync(AssetManager manager, String fileName, Fi file, FreeTypeFontLoaderParameter parameter){
if(fileName.equals("outline")){
parameter.fontParameters.borderWidth = Scl.scl(2f);
parameter.fontParameters.spaceX -= parameter.fontParameters.borderWidth;
}
parameter.fontParameters.magFilter = TextureFilter.Linear;
parameter.fontParameters.minFilter = TextureFilter.Linear;
parameter.fontParameters.packer = packer;
return super.loadSync(manager, fileName, file, parameter);
}
});
FreeTypeFontParameter param = new FreeTypeFontParameter(){{
borderColor = Color.darkGray;
size = (int)(Scl.scl(18f));
incremental = true;
}};
Core.assets.load("outline", BitmapFont.class, new FreeTypeFontLoaderParameter("fonts/font.ttf", param)).loaded = t -> Fonts.outline = (BitmapFont)t;
}
public static void cleanAtlas(TextureAtlas atlas){
//grab all textures from the ui page, remove all the regions assigned to it, then copy them over to Fonts.packer and replace the texture in this atlas.
//grab old UI texture and regions...
Texture texture = atlas.find("logo").getTexture();
Page page = packer.getPages().first();
Array<AtlasRegion> regions = atlas.getRegions().select(t -> t.getTexture() == texture);
for(AtlasRegion region : regions){
//get new pack rect
page.setDirty(false);
Rect rect = packer.pack(region.name + (region.splits != null ? ".9" : ""), atlas.getPixmap(region));
//set new texture
region.setTexture(packer.getPages().first().getTexture());
//set its new position
region.set((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
//add old texture
atlas.getTextures().add(region.getTexture());
}
//remove old texture, it will no longer be used
atlas.getTextures().remove(texture);
texture.dispose();
atlas.disposePixmap(texture);
page.setDirty(true);
page.updateTexture(TextureFilter.Linear, TextureFilter.Linear, false);
}
void loadExtraCursors(){
drillCursor = Core.graphics.newCursor("drill");
unloadCursor = Core.graphics.newCursor("unload");
}
public TextureRegionDrawable getGlyph(BitmapFont font, char glyph){
Glyph g = font.getData().getGlyph(glyph);
if(g == null) throw new IllegalArgumentException("No glyph: " + glyph + " (" + (int)glyph + ")");
float size = Math.max(g.width, g.height);
float aspect = (float)g.height / g.width;
TextureRegionDrawable draw = new TextureRegionDrawable(new TextureRegion(font.getRegion().getTexture(), g.u, g.v2, g.u2, g.v)){
@Override
public void draw(float x, float y, float width, float height){
Draw.color(Tmp.c1.set(tint).mul(Draw.getColor()).toFloatBits());
float cx = x + width/2f - g.width/2f, cy = y + height/2f - g.height/2f;
cx = (int)cx;
cy = (int)cy;
Draw.rect(region, cx + g.width/2f, cy + g.height/2f, g.width, g.height);
}
@Override
public float imageSize(){
return size;
}
};
draw.setMinWidth(size);
draw.setMinHeight(size);
return draw;
}
public void setupFonts(){
String fontName = "fonts/font.ttf";
FreeTypeFontParameter param = fontParameter();
Core.assets.load("default", BitmapFont.class, new FreeTypeFontLoaderParameter(fontName, param)).loaded = f -> Fonts.def = (BitmapFont)f;
Core.assets.load("chat", BitmapFont.class, new FreeTypeFontLoaderParameter(fontName, param)).loaded = f -> Fonts.chat = (BitmapFont)f;
Core.assets.load("icon", BitmapFont.class, new FreeTypeFontLoaderParameter("fonts/icon.ttf", new FreeTypeFontParameter(){{
size = (int)(Scl.scl(30f));
incremental = true;
}})).loaded = f -> Fonts.icon = (BitmapFont)f;
}
public TextureRegionDrawable getIcon(String name){
if(Icon.icons.containsKey(name)){
return Icon.icons.get(name);
}
return Core.atlas.getDrawable("error");
}
static FreeTypeFontParameter fontParameter(){
return new FreeTypeFontParameter(){{
size = (int)(Scl.scl(18f));
shadowColor = Color.darkGray;
shadowOffsetY = 2;
incremental = true;
}};
}
@Override
public void update(){
if(disableUI || Core.scene == null) return;
@@ -355,6 +217,13 @@ public class UI implements ApplicationListener, Loadable{
}
}
public TextureRegionDrawable getIcon(String name){
if(Icon.icons.containsKey(name)){
return Icon.icons.get(name);
}
return Core.atlas.getDrawable("error");
}
public void loadAnd(Runnable call){
loadAnd("$loading", call);
}

View File

@@ -1,6 +1,29 @@
package mindustry.ui;
import arc.*;
import arc.Graphics.Cursor.*;
import arc.assets.*;
import arc.assets.loaders.*;
import arc.assets.loaders.resolvers.*;
import arc.files.*;
import arc.freetype.*;
import arc.freetype.FreeTypeFontGenerator.*;
import arc.freetype.FreetypeFontLoader.*;
import arc.graphics.*;
import arc.graphics.Pixmap.*;
import arc.graphics.Texture.*;
import arc.graphics.g2d.*;
import arc.graphics.g2d.BitmapFont.*;
import arc.graphics.g2d.PixmapPacker.*;
import arc.graphics.g2d.TextureAtlas.*;
import arc.math.geom.*;
import arc.scene.style.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.core.*;
import java.util.*;
public class Fonts{
public static BitmapFont def;
@@ -8,4 +31,156 @@ public class Fonts{
public static BitmapFont chat;
public static BitmapFont icon;
/** Called from a static context to make the cursor appear immediately upon startup.*/
public static void loadSystemCursors(){
SystemCursor.arrow.set(Core.graphics.newCursor("cursor"));
SystemCursor.hand.set(Core.graphics.newCursor("hand"));
SystemCursor.ibeam.set(Core.graphics.newCursor("ibeam"));
Core.graphics.restoreCursor();
}
public static void loadFonts(){
String fontName = "fonts/font.ttf";
FreeTypeFontParameter param = fontParameter();
Core.assets.load("default", BitmapFont.class, new FreeTypeFontLoaderParameter(fontName, param)).loaded = f -> Fonts.def = (BitmapFont)f;
Core.assets.load("chat", BitmapFont.class, new FreeTypeFontLoaderParameter(fontName, param)).loaded = f -> Fonts.chat = (BitmapFont)f;
Core.assets.load("icon", BitmapFont.class, new FreeTypeFontLoaderParameter("fonts/icon.ttf", new FreeTypeFontParameter(){{
size = (int)(Scl.scl(30f));
incremental = true;
}})).loaded = f -> Fonts.icon = (BitmapFont)f;
}
public static void loadContentIcons(){
Array<BitmapFont> fonts = Array.with(Fonts.chat, Fonts.def, Fonts.outline);
Texture uitex = Core.atlas.find("logo").getTexture();
int size = (int)(Fonts.def.getData().lineHeight/Fonts.def.getData().scaleY);
try(Scanner scan = new Scanner(Core.files.internal("icons/icons.properties").read(512))){
while(scan.hasNextLine()){
String line = scan.nextLine();
String[] split = line.split("=");
String character = split[0], texture = split[1].split("\\|")[1];
int ch = Integer.parseInt(character);
TextureRegion region = Core.atlas.find(texture);
if(region.getTexture() != uitex) throw new IllegalArgumentException("Font icon '" + texture + "' is not in the UI texture.");
Glyph glyph = new Glyph();
glyph.id = ch;
glyph.srcX = 0;
glyph.srcY = 0;
glyph.width = size;
glyph.height = size;
glyph.u = region.getU();
glyph.v = region.getV2();
glyph.u2 = region.getU2();
glyph.v2 = region.getV();
glyph.xoffset = 0;
glyph.yoffset = -size;
glyph.xadvance = size;
glyph.kerning = null;
glyph.fixedWidth = true;
glyph.page = 0;
fonts.each(f -> f.getData().setGlyph(ch, glyph));
}
}
}
/** Called from a static context for use in the loading screen.*/
public static void loadDefaultFont(){
UI.packer = new PixmapPacker(2048, 2048, Format.RGBA8888, 2, true);
FileHandleResolver resolver = new InternalFileHandleResolver();
Core.assets.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
Core.assets.setLoader(BitmapFont.class, null, new FreetypeFontLoader(resolver){
@Override
public BitmapFont loadSync(AssetManager manager, String fileName, Fi file, FreeTypeFontLoaderParameter parameter){
if(fileName.equals("outline")){
parameter.fontParameters.borderWidth = Scl.scl(2f);
parameter.fontParameters.spaceX -= parameter.fontParameters.borderWidth;
}
parameter.fontParameters.magFilter = TextureFilter.Linear;
parameter.fontParameters.minFilter = TextureFilter.Linear;
parameter.fontParameters.packer = UI.packer;
return super.loadSync(manager, fileName, file, parameter);
}
});
FreeTypeFontParameter param = new FreeTypeFontParameter(){{
borderColor = Color.darkGray;
size = (int)(Scl.scl(18f));
incremental = true;
}};
Core.assets.load("outline", BitmapFont.class, new FreeTypeFontLoaderParameter("fonts/font.ttf", param)).loaded = t -> Fonts.outline = (BitmapFont)t;
}
/** Merges the UI and font atlas together for better performance. */
public static void mergeFontAtlas(TextureAtlas atlas){
//grab all textures from the ui page, remove all the regions assigned to it, then copy them over to Fonts.packer and replace the texture in this atlas.
//grab old UI texture and regions...
Texture texture = atlas.find("logo").getTexture();
Page page = UI.packer.getPages().first();
Array<AtlasRegion> regions = atlas.getRegions().select(t -> t.getTexture() == texture);
for(AtlasRegion region : regions){
//get new pack rect
page.setDirty(false);
Rect rect = UI.packer.pack(region.name + (region.splits != null ? ".9" : ""), atlas.getPixmap(region));
//set new texture
region.setTexture(UI.packer.getPages().first().getTexture());
//set its new position
region.set((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
//add old texture
atlas.getTextures().add(region.getTexture());
}
//remove old texture, it will no longer be used
atlas.getTextures().remove(texture);
texture.dispose();
atlas.disposePixmap(texture);
page.setDirty(true);
page.updateTexture(TextureFilter.Linear, TextureFilter.Linear, false);
}
public static TextureRegionDrawable getGlyph(BitmapFont font, char glyph){
Glyph g = font.getData().getGlyph(glyph);
if(g == null) throw new IllegalArgumentException("No glyph: " + glyph + " (" + (int)glyph + ")");
float size = Math.max(g.width, g.height);
float aspect = (float)g.height / g.width;
TextureRegionDrawable draw = new TextureRegionDrawable(new TextureRegion(font.getRegion().getTexture(), g.u, g.v2, g.u2, g.v)){
@Override
public void draw(float x, float y, float width, float height){
Draw.color(Tmp.c1.set(tint).mul(Draw.getColor()).toFloatBits());
float cx = x + width/2f - g.width/2f, cy = y + height/2f - g.height/2f;
cx = (int)cx;
cy = (int)cy;
Draw.rect(region, cx + g.width/2f, cy + g.height/2f, g.width, g.height);
}
@Override
public float imageSize(){
return size;
}
};
draw.setMinWidth(size);
draw.setMinHeight(size);
return draw;
}
static FreeTypeFontParameter fontParameter(){
return new FreeTypeFontParameter(){{
size = (int)(Scl.scl(18f));
shadowColor = Color.darkGray;
shadowOffsetY = 2;
incremental = true;
}};
}
}