Added basic chat functionality, for server-side messages.
This commit is contained in:
parent
ec9153053c
commit
843ad028ad
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>ace-of-shades-2</artifactId>
|
<artifactId>ace-of-shades-2</artifactId>
|
||||||
<groupId>nl.andrewl</groupId>
|
<groupId>nl.andrewl</groupId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package nl.andrewl.aos2_client;
|
||||||
|
|
||||||
import nl.andrewl.aos2_client.config.ClientConfig;
|
import nl.andrewl.aos2_client.config.ClientConfig;
|
||||||
import nl.andrewl.aos2_client.control.*;
|
import nl.andrewl.aos2_client.control.*;
|
||||||
|
import nl.andrewl.aos2_client.model.Chat;
|
||||||
import nl.andrewl.aos2_client.model.ClientPlayer;
|
import nl.andrewl.aos2_client.model.ClientPlayer;
|
||||||
import nl.andrewl.aos2_client.model.OtherPlayer;
|
import nl.andrewl.aos2_client.model.OtherPlayer;
|
||||||
import nl.andrewl.aos2_client.render.GameRenderer;
|
import nl.andrewl.aos2_client.render.GameRenderer;
|
||||||
|
@ -41,6 +42,7 @@ public class Client implements Runnable {
|
||||||
private final Map<Integer, OtherPlayer> players;
|
private final Map<Integer, OtherPlayer> players;
|
||||||
private final Map<Integer, Projectile> projectiles;
|
private final Map<Integer, Projectile> projectiles;
|
||||||
private final Map<Integer, Team> teams;
|
private final Map<Integer, Team> teams;
|
||||||
|
private final Chat chat;
|
||||||
|
|
||||||
public Client(ClientConfig config) {
|
public Client(ClientConfig config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
@ -49,6 +51,7 @@ public class Client implements Runnable {
|
||||||
this.projectiles = new ConcurrentHashMap<>();
|
this.projectiles = new ConcurrentHashMap<>();
|
||||||
this.communicationHandler = new CommunicationHandler(this);
|
this.communicationHandler = new CommunicationHandler(this);
|
||||||
this.inputHandler = new InputHandler(this, communicationHandler);
|
this.inputHandler = new InputHandler(this, communicationHandler);
|
||||||
|
this.chat = new Chat();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientConfig getConfig() {
|
public ClientConfig getConfig() {
|
||||||
|
@ -182,6 +185,11 @@ public class Client implements Runnable {
|
||||||
}
|
}
|
||||||
} else if (msg instanceof ClientHealthMessage healthMessage) {
|
} else if (msg instanceof ClientHealthMessage healthMessage) {
|
||||||
myPlayer.setHealth(healthMessage.health());
|
myPlayer.setHealth(healthMessage.health());
|
||||||
|
} else if (msg instanceof ChatMessage chatMessage) {
|
||||||
|
chat.chatReceived(chatMessage);
|
||||||
|
if (soundManager != null) {
|
||||||
|
soundManager.play("chat", 1, myPlayer.getPosition(), myPlayer.getVelocity());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +213,10 @@ public class Client implements Runnable {
|
||||||
return projectiles;
|
return projectiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Chat getChat() {
|
||||||
|
return chat;
|
||||||
|
}
|
||||||
|
|
||||||
public void interpolatePlayers(long now, float dt) {
|
public void interpolatePlayers(long now, float dt) {
|
||||||
Vector3f movement = new Vector3f();
|
Vector3f movement = new Vector3f();
|
||||||
for (var player : players.values()) {
|
for (var player : players.values()) {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package nl.andrewl.aos2_client.model;
|
||||||
|
|
||||||
|
import nl.andrewl.aos_core.net.client.ChatMessage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the set of all chat messages that this client is aware of.
|
||||||
|
*/
|
||||||
|
public class Chat {
|
||||||
|
public static final int MAX_HISTORY = 20;
|
||||||
|
private final Deque<ChatMessage> messages = new ConcurrentLinkedDeque<>();
|
||||||
|
|
||||||
|
public void chatReceived(ChatMessage msg) {
|
||||||
|
messages.addFirst(msg);
|
||||||
|
while (messages.size() > MAX_HISTORY) {
|
||||||
|
messages.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ChatMessage> getMessages() {
|
||||||
|
return new ArrayList<>(messages);
|
||||||
|
}
|
||||||
|
}
|
|
@ -271,7 +271,7 @@ public class GameRenderer {
|
||||||
// GUI rendering
|
// GUI rendering
|
||||||
guiRenderer.start();
|
guiRenderer.start();
|
||||||
guiRenderer.drawNameplates(myPlayer, camera.getViewTransformData(), perspectiveTransform.get(new float[16]));
|
guiRenderer.drawNameplates(myPlayer, camera.getViewTransformData(), perspectiveTransform.get(new float[16]));
|
||||||
guiRenderer.drawNvg(screenWidth, screenHeight, myPlayer);
|
guiRenderer.drawNvg(screenWidth, screenHeight, myPlayer, client.getChat());
|
||||||
guiRenderer.end();
|
guiRenderer.end();
|
||||||
|
|
||||||
glfwSwapBuffers(windowHandle);
|
glfwSwapBuffers(windowHandle);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package nl.andrewl.aos2_client.render.gui;
|
package nl.andrewl.aos2_client.render.gui;
|
||||||
|
|
||||||
import nl.andrewl.aos2_client.Camera;
|
import nl.andrewl.aos2_client.Camera;
|
||||||
|
import nl.andrewl.aos2_client.model.Chat;
|
||||||
import nl.andrewl.aos2_client.model.ClientPlayer;
|
import nl.andrewl.aos2_client.model.ClientPlayer;
|
||||||
import nl.andrewl.aos2_client.model.OtherPlayer;
|
import nl.andrewl.aos2_client.model.OtherPlayer;
|
||||||
import nl.andrewl.aos2_client.render.ShaderProgram;
|
import nl.andrewl.aos2_client.render.ShaderProgram;
|
||||||
|
@ -59,7 +60,7 @@ public class GuiRenderer {
|
||||||
private final int namePlatePerspectiveTransformUniform;
|
private final int namePlatePerspectiveTransformUniform;
|
||||||
private final int namePlateTextureSamplerUniform;
|
private final int namePlateTextureSamplerUniform;
|
||||||
private final Font namePlateFont;
|
private final Font namePlateFont;
|
||||||
private final Map<OtherPlayer, GUITexture> playerNamePlates = new HashMap<>();
|
private final Map<OtherPlayer, GuiTexture> playerNamePlates = new HashMap<>();
|
||||||
|
|
||||||
public GuiRenderer() throws IOException {
|
public GuiRenderer() throws IOException {
|
||||||
vgId = nvgCreate(NVG_ANTIALIAS);
|
vgId = nvgCreate(NVG_ANTIALIAS);
|
||||||
|
@ -127,7 +128,7 @@ public class GuiRenderer {
|
||||||
glUniform1i(textureSamplerUniform, 0);
|
glUniform1i(textureSamplerUniform, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(GUITexture texture, float scaleX, float scaleY, float x, float y) {
|
public void draw(GuiTexture texture, float scaleX, float scaleY, float x, float y) {
|
||||||
glActiveTexture(0);
|
glActiveTexture(0);
|
||||||
transformMatrix.identity()
|
transformMatrix.identity()
|
||||||
.translate(x, y, 0)
|
.translate(x, y, 0)
|
||||||
|
@ -139,12 +140,12 @@ public class GuiRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addNamePlate(OtherPlayer player) {
|
private void addNamePlate(OtherPlayer player) {
|
||||||
GUITexture texture = new GUITexture(generateNameplateImage(player.getUsername()));
|
GuiTexture texture = new GuiTexture(generateNameplateImage(player.getUsername()));
|
||||||
playerNamePlates.put(player, texture);
|
playerNamePlates.put(player, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeNamePlate(OtherPlayer player) {
|
private void removeNamePlate(OtherPlayer player) {
|
||||||
GUITexture texture = playerNamePlates.remove(player);
|
GuiTexture texture = playerNamePlates.remove(player);
|
||||||
texture.free();
|
texture.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +198,7 @@ public class GuiRenderer {
|
||||||
OtherPlayer player = entry.getKey();
|
OtherPlayer player = entry.getKey();
|
||||||
// Skip rendering far-away nameplates.
|
// Skip rendering far-away nameplates.
|
||||||
if (player.getPosition().distance(myPlayer.getPosition()) > 50) continue;
|
if (player.getPosition().distance(myPlayer.getPosition()) > 50) continue;
|
||||||
GUITexture texture = entry.getValue();
|
GuiTexture texture = entry.getValue();
|
||||||
float aspectRatio = (float) texture.getHeight() / (float) texture.getWidth();
|
float aspectRatio = (float) texture.getHeight() / (float) texture.getWidth();
|
||||||
transformMatrix.identity()
|
transformMatrix.identity()
|
||||||
.translate(player.getPosition().x(), player.getPosition().y() + Player.HEIGHT + 1f, player.getPosition().z())
|
.translate(player.getPosition().x(), player.getPosition().y() + Player.HEIGHT + 1f, player.getPosition().z())
|
||||||
|
@ -215,11 +216,12 @@ public class GuiRenderer {
|
||||||
shaderProgram.use();
|
shaderProgram.use();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawNvg(float width, float height, ClientPlayer player) {
|
public void drawNvg(float width, float height, ClientPlayer player, Chat chat) {
|
||||||
nvgBeginFrame(vgId, width, height, width / height);
|
nvgBeginFrame(vgId, width, height, width / height);
|
||||||
nvgSave(vgId);
|
nvgSave(vgId);
|
||||||
|
|
||||||
drawCrosshair(width, height);
|
drawCrosshair(width, height);
|
||||||
|
drawChat(width, height, chat);
|
||||||
drawHealthBar(width, height, player);
|
drawHealthBar(width, height, player);
|
||||||
drawHeldItemStackInfo(width, height, player);
|
drawHeldItemStackInfo(width, height, player);
|
||||||
|
|
||||||
|
@ -315,4 +317,33 @@ public class GuiRenderer {
|
||||||
nvgTextAlign(vgId, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
|
nvgTextAlign(vgId, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
|
||||||
nvgText(vgId, w - 140, h - 30, String.format("%d / %d Blocks", stack.getAmount(), block.getMaxAmount()));
|
nvgText(vgId, w - 140, h - 30, String.format("%d / %d Blocks", stack.getAmount(), block.getMaxAmount()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void drawChat(float w, float h, Chat chat) {
|
||||||
|
float chatWidth = w / 3;
|
||||||
|
float chatHeight = h / 4;
|
||||||
|
|
||||||
|
nvgFillColor(vgId, GuiUtils.rgba(0, 0, 0, 0.25f, colorA));
|
||||||
|
nvgBeginPath(vgId);
|
||||||
|
nvgRect(vgId, 0, 0, chatWidth, chatHeight);
|
||||||
|
nvgFill(vgId);
|
||||||
|
|
||||||
|
nvgFontSize(vgId, 12f);
|
||||||
|
nvgFontFaceId(vgId, jetbrainsMonoFont);
|
||||||
|
nvgTextAlign(vgId, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
|
||||||
|
float y = chatHeight - 12;
|
||||||
|
for (var msg : chat.getMessages()) {
|
||||||
|
if (msg.author().equals("_ANNOUNCE")) {
|
||||||
|
nvgFillColor(vgId, GuiUtils.rgba(0.7f, 0, 0, 1, colorA));
|
||||||
|
nvgText(vgId, 5, y, msg.message());
|
||||||
|
} else if (msg.author().equals("_PRIVATE")) {
|
||||||
|
nvgFillColor(vgId, GuiUtils.rgba(0.3f, 0.3f, 0.3f, 1, colorA));
|
||||||
|
nvgText(vgId, 5, y, msg.message());
|
||||||
|
} else {
|
||||||
|
nvgFillColor(vgId, GuiUtils.rgba(1, 1, 1, 1, colorA));
|
||||||
|
nvgText(vgId, 5, y, msg.author() + ": " + msg.message());
|
||||||
|
}
|
||||||
|
|
||||||
|
y -= 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,7 @@ package nl.andrewl.aos2_client.render.gui;
|
||||||
|
|
||||||
import nl.andrewl.aos_core.FileUtils;
|
import nl.andrewl.aos_core.FileUtils;
|
||||||
import nl.andrewl.aos_core.ImageUtils;
|
import nl.andrewl.aos_core.ImageUtils;
|
||||||
import org.joml.Vector2f;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -13,7 +11,7 @@ import static org.lwjgl.opengl.GL46.*;
|
||||||
/**
|
/**
|
||||||
* Represents a texture loaded onto the GPU.
|
* Represents a texture loaded onto the GPU.
|
||||||
*/
|
*/
|
||||||
public class GUITexture {
|
public class GuiTexture {
|
||||||
private final int textureId;
|
private final int textureId;
|
||||||
/**
|
/**
|
||||||
* The original image's width.
|
* The original image's width.
|
||||||
|
@ -24,11 +22,11 @@ public class GUITexture {
|
||||||
*/
|
*/
|
||||||
private final int height;
|
private final int height;
|
||||||
|
|
||||||
public GUITexture(String location) throws IOException {
|
public GuiTexture(String location) throws IOException {
|
||||||
this(FileUtils.readClasspathImage(location));
|
this(FileUtils.readClasspathImage(location));
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUITexture(BufferedImage img) {
|
public GuiTexture(BufferedImage img) {
|
||||||
width = img.getWidth();
|
width = img.getWidth();
|
||||||
height = img.getHeight();
|
height = img.getHeight();
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple data structure class holding information about a certain glyph in the
|
|
||||||
* font texture atlas. All sizes are for a font-size of 1.
|
|
||||||
*
|
|
||||||
* @author Karl
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Character {
|
|
||||||
|
|
||||||
private int id;
|
|
||||||
private double xTextureCoord;
|
|
||||||
private double yTextureCoord;
|
|
||||||
private double xMaxTextureCoord;
|
|
||||||
private double yMaxTextureCoord;
|
|
||||||
private double xOffset;
|
|
||||||
private double yOffset;
|
|
||||||
private double sizeX;
|
|
||||||
private double sizeY;
|
|
||||||
private double xAdvance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param id
|
|
||||||
* - the ASCII value of the character.
|
|
||||||
* @param xTextureCoord
|
|
||||||
* - the x texture coordinate for the top left corner of the
|
|
||||||
* character in the texture atlas.
|
|
||||||
* @param yTextureCoord
|
|
||||||
* - the y texture coordinate for the top left corner of the
|
|
||||||
* character in the texture atlas.
|
|
||||||
* @param xTexSize
|
|
||||||
* - the width of the character in the texture atlas.
|
|
||||||
* @param yTexSize
|
|
||||||
* - the height of the character in the texture atlas.
|
|
||||||
* @param xOffset
|
|
||||||
* - the x distance from the curser to the left edge of the
|
|
||||||
* character's quad.
|
|
||||||
* @param yOffset
|
|
||||||
* - the y distance from the curser to the top edge of the
|
|
||||||
* character's quad.
|
|
||||||
* @param sizeX
|
|
||||||
* - the width of the character's quad in screen space.
|
|
||||||
* @param sizeY
|
|
||||||
* - the height of the character's quad in screen space.
|
|
||||||
* @param xAdvance
|
|
||||||
* - how far in pixels the cursor should advance after adding
|
|
||||||
* this character.
|
|
||||||
*/
|
|
||||||
protected Character(int id, double xTextureCoord, double yTextureCoord, double xTexSize, double yTexSize,
|
|
||||||
double xOffset, double yOffset, double sizeX, double sizeY, double xAdvance) {
|
|
||||||
this.id = id;
|
|
||||||
this.xTextureCoord = xTextureCoord;
|
|
||||||
this.yTextureCoord = yTextureCoord;
|
|
||||||
this.xOffset = xOffset;
|
|
||||||
this.yOffset = yOffset;
|
|
||||||
this.sizeX = sizeX;
|
|
||||||
this.sizeY = sizeY;
|
|
||||||
this.xMaxTextureCoord = xTexSize + xTextureCoord;
|
|
||||||
this.yMaxTextureCoord = yTexSize + yTextureCoord;
|
|
||||||
this.xAdvance = xAdvance;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getxTextureCoord() {
|
|
||||||
return xTextureCoord;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getyTextureCoord() {
|
|
||||||
return yTextureCoord;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getXMaxTextureCoord() {
|
|
||||||
return xMaxTextureCoord;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getYMaxTextureCoord() {
|
|
||||||
return yMaxTextureCoord;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getxOffset() {
|
|
||||||
return xOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getyOffset() {
|
|
||||||
return yOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getSizeX() {
|
|
||||||
return sizeX;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getSizeY() {
|
|
||||||
return sizeY;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getxAdvance() {
|
|
||||||
return xAdvance;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
import nl.andrewl.aos2_client.render.ShaderProgram;
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL46.*;
|
|
||||||
|
|
||||||
public class FontRenderer {
|
|
||||||
private final ShaderProgram shaderProgram;
|
|
||||||
|
|
||||||
public FontRenderer() {
|
|
||||||
shaderProgram = new ShaderProgram.Builder()
|
|
||||||
.withShader("/shader/text/vertex.glsl", GL_VERTEX_SHADER)
|
|
||||||
.withShader("/shader/text/fragment.glsl", GL_FRAGMENT_SHADER)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void free() {
|
|
||||||
shaderProgram.free();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a font. It holds the font's texture atlas as well as having the
|
|
||||||
* ability to create the quad vertices for any text using this font.
|
|
||||||
*
|
|
||||||
* @author Karl
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class FontType {
|
|
||||||
|
|
||||||
private final int textureAtlas;
|
|
||||||
private final TextMeshCreator loader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new font and loads up the data about each character from the
|
|
||||||
* font file.
|
|
||||||
*
|
|
||||||
* @param textureAtlas
|
|
||||||
* - the ID of the font atlas texture.
|
|
||||||
* @param fontFile
|
|
||||||
* - the font file containing information about each character in
|
|
||||||
* the texture atlas.
|
|
||||||
*/
|
|
||||||
public FontType(int textureAtlas, File fontFile, float aspectRatio) {
|
|
||||||
this.textureAtlas = textureAtlas;
|
|
||||||
this.loader = new TextMeshCreator(fontFile, aspectRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The font texture atlas.
|
|
||||||
*/
|
|
||||||
public int getTextureAtlas() {
|
|
||||||
return textureAtlas;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes in an unloaded text and calculate all of the vertices for the quads
|
|
||||||
* on which this text will be rendered. The vertex positions and texture
|
|
||||||
* coords and calculated based on the information from the font file.
|
|
||||||
*
|
|
||||||
* @param text
|
|
||||||
* - the unloaded text.
|
|
||||||
* @return Information about the vertices of all the quads.
|
|
||||||
*/
|
|
||||||
public TextMeshData loadText(GUIText text) {
|
|
||||||
return loader.createTextMesh(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,193 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
import org.joml.Vector2f;
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL46.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a piece of text in the game.
|
|
||||||
*
|
|
||||||
* @author Karl
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GUIText {
|
|
||||||
|
|
||||||
private final String textString;
|
|
||||||
private final float fontSize;
|
|
||||||
|
|
||||||
private int textMeshVao;
|
|
||||||
private int textMeshVbo;
|
|
||||||
private int vertexCount;
|
|
||||||
private final Vector3f colour = new Vector3f(0f, 0f, 0f);
|
|
||||||
|
|
||||||
private final Vector2f position;
|
|
||||||
private final float lineMaxSize;
|
|
||||||
private int numberOfLines;
|
|
||||||
|
|
||||||
private final FontType font;
|
|
||||||
|
|
||||||
private boolean centerText;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new text, loads the text's quads into a VAO, and adds the text
|
|
||||||
* to the screen.
|
|
||||||
*
|
|
||||||
* @param text
|
|
||||||
* - the text.
|
|
||||||
* @param fontSize
|
|
||||||
* - the font size of the text, where a font size of 1 is the
|
|
||||||
* default size.
|
|
||||||
* @param font
|
|
||||||
* - the font that this text should use.
|
|
||||||
* @param position
|
|
||||||
* - the position on the screen where the top left corner of the
|
|
||||||
* text should be rendered. The top left corner of the screen is
|
|
||||||
* (0, 0) and the bottom right is (1, 1).
|
|
||||||
* @param maxLineLength
|
|
||||||
* - basically the width of the virtual page in terms of screen
|
|
||||||
* width (1 is full screen width, 0.5 is half the width of the
|
|
||||||
* screen, etc.) Text cannot go off the edge of the page, so if
|
|
||||||
* the text is longer than this length it will go onto the next
|
|
||||||
* line. When text is centered it is centered into the middle of
|
|
||||||
* the line, based on this line length value.
|
|
||||||
* @param centered
|
|
||||||
* - whether the text should be centered or not.
|
|
||||||
*/
|
|
||||||
public GUIText(String text, float fontSize, FontType font, Vector2f position, float maxLineLength,
|
|
||||||
boolean centered) {
|
|
||||||
this.textString = text;
|
|
||||||
this.fontSize = fontSize;
|
|
||||||
this.font = font;
|
|
||||||
this.position = position;
|
|
||||||
this.lineMaxSize = maxLineLength;
|
|
||||||
this.centerText = centered;
|
|
||||||
// load text
|
|
||||||
TextMeshData meshData = font.loadText(this);
|
|
||||||
textMeshVao = glGenVertexArrays();
|
|
||||||
textMeshVbo = glGenBuffers();
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, textMeshVbo);
|
|
||||||
// FloatBuffer buffer1 = BufferUtils.createFloatBuffer(meshData)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the text from the screen.
|
|
||||||
*/
|
|
||||||
public void remove() {
|
|
||||||
// remove text
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The font used by this text.
|
|
||||||
*/
|
|
||||||
public FontType getFont() {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the colour of the text.
|
|
||||||
*
|
|
||||||
* @param r
|
|
||||||
* - red value, between 0 and 1.
|
|
||||||
* @param g
|
|
||||||
* - green value, between 0 and 1.
|
|
||||||
* @param b
|
|
||||||
* - blue value, between 0 and 1.
|
|
||||||
*/
|
|
||||||
public void setColour(float r, float g, float b) {
|
|
||||||
colour.set(r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the colour of the text.
|
|
||||||
*/
|
|
||||||
public Vector3f getColour() {
|
|
||||||
return colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The number of lines of text. This is determined when the text is
|
|
||||||
* loaded, based on the length of the text and the max line length
|
|
||||||
* that is set.
|
|
||||||
*/
|
|
||||||
public int getNumberOfLines() {
|
|
||||||
return numberOfLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The position of the top-left corner of the text in screen-space.
|
|
||||||
* (0, 0) is the top left corner of the screen, (1, 1) is the bottom
|
|
||||||
* right.
|
|
||||||
*/
|
|
||||||
public Vector2f getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the ID of the text's VAO, which contains all the vertex data for
|
|
||||||
* the quads on which the text will be rendered.
|
|
||||||
*/
|
|
||||||
public int getMesh() {
|
|
||||||
return textMeshVao;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the VAO and vertex count for this text.
|
|
||||||
*
|
|
||||||
* @param vao
|
|
||||||
* - the VAO containing all the vertex data for the quads on
|
|
||||||
* which the text will be rendered.
|
|
||||||
* @param verticesCount
|
|
||||||
* - the total number of vertices in all of the quads.
|
|
||||||
*/
|
|
||||||
public void setMeshInfo(int vao, int verticesCount) {
|
|
||||||
this.textMeshVao = vao;
|
|
||||||
this.vertexCount = verticesCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The total number of vertices of all the text's quads.
|
|
||||||
*/
|
|
||||||
public int getVertexCount() {
|
|
||||||
return this.vertexCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the font size of the text (a font size of 1 is normal).
|
|
||||||
*/
|
|
||||||
protected float getFontSize() {
|
|
||||||
return fontSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the number of lines that this text covers (method used only in
|
|
||||||
* loading).
|
|
||||||
*
|
|
||||||
* @param number
|
|
||||||
*/
|
|
||||||
protected void setNumberOfLines(int number) {
|
|
||||||
this.numberOfLines = number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code true} if the text should be centered.
|
|
||||||
*/
|
|
||||||
protected boolean isCentered() {
|
|
||||||
return centerText;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The maximum length of a line of this text.
|
|
||||||
*/
|
|
||||||
protected float getMaxLineSize() {
|
|
||||||
return lineMaxSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The string of text.
|
|
||||||
*/
|
|
||||||
protected String getTextString() {
|
|
||||||
return textString;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a line of text during the loading of a text.
|
|
||||||
*
|
|
||||||
* @author Karl
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Line {
|
|
||||||
|
|
||||||
private final double maxLength;
|
|
||||||
private final double spaceSize;
|
|
||||||
|
|
||||||
private final List<Word> words = new ArrayList<Word>();
|
|
||||||
private double currentLineLength = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an empty line.
|
|
||||||
*
|
|
||||||
* @param spaceWidth
|
|
||||||
* - the screen-space width of a space character.
|
|
||||||
* @param fontSize
|
|
||||||
* - the size of font being used.
|
|
||||||
* @param maxLength
|
|
||||||
* - the screen-space maximum length of a line.
|
|
||||||
*/
|
|
||||||
protected Line(double spaceWidth, double fontSize, double maxLength) {
|
|
||||||
this.spaceSize = spaceWidth * fontSize;
|
|
||||||
this.maxLength = maxLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to add a word to the line. If the line can fit the word in
|
|
||||||
* without reaching the maximum line length then the word is added and the
|
|
||||||
* line length increased.
|
|
||||||
*
|
|
||||||
* @param word
|
|
||||||
* - the word to try to add.
|
|
||||||
* @return {@code true} if the word has successfully been added to the line.
|
|
||||||
*/
|
|
||||||
protected boolean attemptToAddWord(Word word) {
|
|
||||||
double additionalLength = word.getWordWidth();
|
|
||||||
additionalLength += !words.isEmpty() ? spaceSize : 0;
|
|
||||||
if (currentLineLength + additionalLength <= maxLength) {
|
|
||||||
words.add(word);
|
|
||||||
currentLineLength += additionalLength;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The max length of the line.
|
|
||||||
*/
|
|
||||||
protected double getMaxLength() {
|
|
||||||
return maxLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The current screen-space length of the line.
|
|
||||||
*/
|
|
||||||
protected double getLineLength() {
|
|
||||||
return currentLineLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The list of words in the line.
|
|
||||||
*/
|
|
||||||
protected List<Word> getWords() {
|
|
||||||
return words;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,213 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides functionality for getting the values from a font file.
|
|
||||||
*
|
|
||||||
* @author Karl
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MetaFile {
|
|
||||||
|
|
||||||
private static final int PAD_TOP = 0;
|
|
||||||
private static final int PAD_LEFT = 1;
|
|
||||||
private static final int PAD_BOTTOM = 2;
|
|
||||||
private static final int PAD_RIGHT = 3;
|
|
||||||
|
|
||||||
private static final int DESIRED_PADDING = 3;
|
|
||||||
|
|
||||||
private static final String SPLITTER = " ";
|
|
||||||
private static final String NUMBER_SEPARATOR = ",";
|
|
||||||
|
|
||||||
private final double aspectRatio;
|
|
||||||
|
|
||||||
private double verticalPerPixelSize;
|
|
||||||
private double horizontalPerPixelSize;
|
|
||||||
private double spaceWidth;
|
|
||||||
private int[] padding;
|
|
||||||
private int paddingWidth;
|
|
||||||
private int paddingHeight;
|
|
||||||
|
|
||||||
private final Map<Integer, Character> metaData = new HashMap<>();
|
|
||||||
|
|
||||||
private BufferedReader reader;
|
|
||||||
private final Map<String, String> values = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens a font file in preparation for reading.
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* - the font file.
|
|
||||||
*/
|
|
||||||
protected MetaFile(File file, float aspectRatio) {
|
|
||||||
this.aspectRatio = aspectRatio;
|
|
||||||
openFile(file);
|
|
||||||
loadPaddingData();
|
|
||||||
loadLineSizes();
|
|
||||||
int imageWidth = getValueOfVariable("scaleW");
|
|
||||||
loadCharacterData(imageWidth);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getSpaceWidth() {
|
|
||||||
return spaceWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Character getCharacter(int ascii) {
|
|
||||||
return metaData.get(ascii);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read in the next line and store the variable values.
|
|
||||||
*
|
|
||||||
* @return {@code true} if the end of the file hasn't been reached.
|
|
||||||
*/
|
|
||||||
private boolean processNextLine() {
|
|
||||||
values.clear();
|
|
||||||
String line = null;
|
|
||||||
try {
|
|
||||||
line = reader.readLine();
|
|
||||||
} catch (IOException e1) {
|
|
||||||
}
|
|
||||||
if (line == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (String part : line.split(SPLITTER)) {
|
|
||||||
String[] valuePairs = part.split("=");
|
|
||||||
if (valuePairs.length == 2) {
|
|
||||||
values.put(valuePairs[0], valuePairs[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@code int} value of the variable with a certain name on the
|
|
||||||
* current line.
|
|
||||||
*
|
|
||||||
* @param variable
|
|
||||||
* - the name of the variable.
|
|
||||||
* @return The value of the variable.
|
|
||||||
*/
|
|
||||||
private int getValueOfVariable(String variable) {
|
|
||||||
return Integer.parseInt(values.get(variable));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the array of ints associated with a variable on the current line.
|
|
||||||
*
|
|
||||||
* @param variable
|
|
||||||
* - the name of the variable.
|
|
||||||
* @return The int array of values associated with the variable.
|
|
||||||
*/
|
|
||||||
private int[] getValuesOfVariable(String variable) {
|
|
||||||
String[] numbers = values.get(variable).split(NUMBER_SEPARATOR);
|
|
||||||
int[] actualValues = new int[numbers.length];
|
|
||||||
for (int i = 0; i < actualValues.length; i++) {
|
|
||||||
actualValues[i] = Integer.parseInt(numbers[i]);
|
|
||||||
}
|
|
||||||
return actualValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the font file after finishing reading.
|
|
||||||
*/
|
|
||||||
private void close() {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens the font file, ready for reading.
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* - the font file.
|
|
||||||
*/
|
|
||||||
private void openFile(File file) {
|
|
||||||
try {
|
|
||||||
reader = new BufferedReader(new FileReader(file));
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.err.println("Couldn't read font meta file!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the data about how much padding is used around each character in
|
|
||||||
* the texture atlas.
|
|
||||||
*/
|
|
||||||
private void loadPaddingData() {
|
|
||||||
processNextLine();
|
|
||||||
this.padding = getValuesOfVariable("padding");
|
|
||||||
this.paddingWidth = padding[PAD_LEFT] + padding[PAD_RIGHT];
|
|
||||||
this.paddingHeight = padding[PAD_TOP] + padding[PAD_BOTTOM];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads information about the line height for this font in pixels, and uses
|
|
||||||
* this as a way to find the conversion rate between pixels in the texture
|
|
||||||
* atlas and screen-space.
|
|
||||||
*/
|
|
||||||
private void loadLineSizes() {
|
|
||||||
processNextLine();
|
|
||||||
int lineHeightPixels = getValueOfVariable("lineHeight") - paddingHeight;
|
|
||||||
verticalPerPixelSize = TextMeshCreator.LINE_HEIGHT / (double) lineHeightPixels;
|
|
||||||
horizontalPerPixelSize = verticalPerPixelSize / aspectRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads in data about each character and stores the data in the
|
|
||||||
* {@link Character} class.
|
|
||||||
*
|
|
||||||
* @param imageWidth
|
|
||||||
* - the width of the texture atlas in pixels.
|
|
||||||
*/
|
|
||||||
private void loadCharacterData(int imageWidth) {
|
|
||||||
processNextLine();
|
|
||||||
processNextLine();
|
|
||||||
while (processNextLine()) {
|
|
||||||
Character c = loadCharacter(imageWidth);
|
|
||||||
if (c != null) {
|
|
||||||
metaData.put(c.getId(), c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads all the data about one character in the texture atlas and converts
|
|
||||||
* it all from 'pixels' to 'screen-space' before storing. The effects of
|
|
||||||
* padding are also removed from the data.
|
|
||||||
*
|
|
||||||
* @param imageSize
|
|
||||||
* - the size of the texture atlas in pixels.
|
|
||||||
* @return The data about the character.
|
|
||||||
*/
|
|
||||||
private Character loadCharacter(int imageSize) {
|
|
||||||
int id = getValueOfVariable("id");
|
|
||||||
if (id == TextMeshCreator.SPACE_ASCII) {
|
|
||||||
this.spaceWidth = (getValueOfVariable("xadvance") - paddingWidth) * horizontalPerPixelSize;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
double xTex = ((double) getValueOfVariable("x") + (padding[PAD_LEFT] - DESIRED_PADDING)) / imageSize;
|
|
||||||
double yTex = ((double) getValueOfVariable("y") + (padding[PAD_TOP] - DESIRED_PADDING)) / imageSize;
|
|
||||||
int width = getValueOfVariable("width") - (paddingWidth - (2 * DESIRED_PADDING));
|
|
||||||
int height = getValueOfVariable("height") - ((paddingHeight) - (2 * DESIRED_PADDING));
|
|
||||||
double quadWidth = width * horizontalPerPixelSize;
|
|
||||||
double quadHeight = height * verticalPerPixelSize;
|
|
||||||
double xTexSize = (double) width / imageSize;
|
|
||||||
double yTexSize = (double) height / imageSize;
|
|
||||||
double xOff = (getValueOfVariable("xoffset") + padding[PAD_LEFT] - DESIRED_PADDING) * horizontalPerPixelSize;
|
|
||||||
double yOff = (getValueOfVariable("yoffset") + (padding[PAD_TOP] - DESIRED_PADDING)) * verticalPerPixelSize;
|
|
||||||
double xAdvance = (getValueOfVariable("xadvance") - paddingWidth) * horizontalPerPixelSize;
|
|
||||||
return new Character(id, xTex, yTex, xTexSize, yTexSize, xOff, yOff, quadWidth, quadHeight, xAdvance);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
import org.joml.Vector2f;
|
|
||||||
import org.lwjgl.BufferUtils;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL46.*;
|
|
||||||
import static org.lwjgl.stb.STBEasyFont.stb_easy_font_print;
|
|
||||||
|
|
||||||
public class TextMesh {
|
|
||||||
private final int vbo;
|
|
||||||
private final int vao;
|
|
||||||
private int quadCount;
|
|
||||||
|
|
||||||
private String text;
|
|
||||||
private final Vector2f position;
|
|
||||||
|
|
||||||
public TextMesh() {
|
|
||||||
this.vbo = glGenBuffers();
|
|
||||||
this.vao = glGenVertexArrays();
|
|
||||||
this.position = new Vector2f();
|
|
||||||
this.text = "Hello world";
|
|
||||||
|
|
||||||
glBindVertexArray(vao);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, false, 7, 0);
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, false, 7, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateMesh() {
|
|
||||||
ByteBuffer colorBuffer = ByteBuffer.allocate(4);
|
|
||||||
colorBuffer.putInt(Color.WHITE.getRGB());
|
|
||||||
colorBuffer.flip();
|
|
||||||
ByteBuffer vertexBuffer = BufferUtils.createByteBuffer(text.length() * 500);
|
|
||||||
quadCount = stb_easy_font_print(position.x, position.y, text, colorBuffer, vertexBuffer);
|
|
||||||
vertexBuffer.flip();
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw() {
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBindVertexArray(vao);
|
|
||||||
|
|
||||||
glDrawArrays(GL_QUADS, 0, quadCount);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TextMeshCreator {
|
|
||||||
|
|
||||||
protected static final double LINE_HEIGHT = 0.03f;
|
|
||||||
protected static final int SPACE_ASCII = 32;
|
|
||||||
|
|
||||||
private final MetaFile metaData;
|
|
||||||
|
|
||||||
protected TextMeshCreator(File metaFile, float aspectRatio) {
|
|
||||||
metaData = new MetaFile(metaFile, aspectRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TextMeshData createTextMesh(GUIText text) {
|
|
||||||
List<Line> lines = createStructure(text);
|
|
||||||
return createQuadVertices(text, lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Line> createStructure(GUIText text) {
|
|
||||||
char[] chars = text.getTextString().toCharArray();
|
|
||||||
List<Line> lines = new ArrayList<Line>();
|
|
||||||
Line currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize());
|
|
||||||
Word currentWord = new Word(text.getFontSize());
|
|
||||||
for (char c : chars) {
|
|
||||||
if ((int) c == SPACE_ASCII) {
|
|
||||||
boolean added = currentLine.attemptToAddWord(currentWord);
|
|
||||||
if (!added) {
|
|
||||||
lines.add(currentLine);
|
|
||||||
currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize());
|
|
||||||
currentLine.attemptToAddWord(currentWord);
|
|
||||||
}
|
|
||||||
currentWord = new Word(text.getFontSize());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Character character = metaData.getCharacter(c);
|
|
||||||
currentWord.addCharacter(character);
|
|
||||||
}
|
|
||||||
completeStructure(lines, currentLine, currentWord, text);
|
|
||||||
return lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void completeStructure(List<Line> lines, Line currentLine, Word currentWord, GUIText text) {
|
|
||||||
boolean added = currentLine.attemptToAddWord(currentWord);
|
|
||||||
if (!added) {
|
|
||||||
lines.add(currentLine);
|
|
||||||
currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize());
|
|
||||||
currentLine.attemptToAddWord(currentWord);
|
|
||||||
}
|
|
||||||
lines.add(currentLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextMeshData createQuadVertices(GUIText text, List<Line> lines) {
|
|
||||||
text.setNumberOfLines(lines.size());
|
|
||||||
double curserX = 0f;
|
|
||||||
double curserY = 0f;
|
|
||||||
List<Float> vertices = new ArrayList<Float>();
|
|
||||||
List<Float> textureCoords = new ArrayList<Float>();
|
|
||||||
for (Line line : lines) {
|
|
||||||
if (text.isCentered()) {
|
|
||||||
curserX = (line.getMaxLength() - line.getLineLength()) / 2;
|
|
||||||
}
|
|
||||||
for (Word word : line.getWords()) {
|
|
||||||
for (Character letter : word.getCharacters()) {
|
|
||||||
addVerticesForCharacter(curserX, curserY, letter, text.getFontSize(), vertices);
|
|
||||||
addTexCoords(textureCoords, letter.getxTextureCoord(), letter.getyTextureCoord(),
|
|
||||||
letter.getXMaxTextureCoord(), letter.getYMaxTextureCoord());
|
|
||||||
curserX += letter.getxAdvance() * text.getFontSize();
|
|
||||||
}
|
|
||||||
curserX += metaData.getSpaceWidth() * text.getFontSize();
|
|
||||||
}
|
|
||||||
curserX = 0;
|
|
||||||
curserY += LINE_HEIGHT * text.getFontSize();
|
|
||||||
}
|
|
||||||
return new TextMeshData(listToArray(vertices), listToArray(textureCoords));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addVerticesForCharacter(double curserX, double curserY, Character character, double fontSize,
|
|
||||||
List<Float> vertices) {
|
|
||||||
double x = curserX + (character.getxOffset() * fontSize);
|
|
||||||
double y = curserY + (character.getyOffset() * fontSize);
|
|
||||||
double maxX = x + (character.getSizeX() * fontSize);
|
|
||||||
double maxY = y + (character.getSizeY() * fontSize);
|
|
||||||
double properX = (2 * x) - 1;
|
|
||||||
double properY = (-2 * y) + 1;
|
|
||||||
double properMaxX = (2 * maxX) - 1;
|
|
||||||
double properMaxY = (-2 * maxY) + 1;
|
|
||||||
addVertices(vertices, properX, properY, properMaxX, properMaxY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addVertices(List<Float> vertices, double x, double y, double maxX, double maxY) {
|
|
||||||
vertices.add((float) x);
|
|
||||||
vertices.add((float) y);
|
|
||||||
vertices.add((float) x);
|
|
||||||
vertices.add((float) maxY);
|
|
||||||
vertices.add((float) maxX);
|
|
||||||
vertices.add((float) maxY);
|
|
||||||
vertices.add((float) maxX);
|
|
||||||
vertices.add((float) maxY);
|
|
||||||
vertices.add((float) maxX);
|
|
||||||
vertices.add((float) y);
|
|
||||||
vertices.add((float) x);
|
|
||||||
vertices.add((float) y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addTexCoords(List<Float> texCoords, double x, double y, double maxX, double maxY) {
|
|
||||||
texCoords.add((float) x);
|
|
||||||
texCoords.add((float) y);
|
|
||||||
texCoords.add((float) x);
|
|
||||||
texCoords.add((float) maxY);
|
|
||||||
texCoords.add((float) maxX);
|
|
||||||
texCoords.add((float) maxY);
|
|
||||||
texCoords.add((float) maxX);
|
|
||||||
texCoords.add((float) maxY);
|
|
||||||
texCoords.add((float) maxX);
|
|
||||||
texCoords.add((float) y);
|
|
||||||
texCoords.add((float) x);
|
|
||||||
texCoords.add((float) y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static float[] listToArray(List<Float> listOfFloats) {
|
|
||||||
float[] array = new float[listOfFloats.size()];
|
|
||||||
for (int i = 0; i < array.length; i++) {
|
|
||||||
array[i] = listOfFloats.get(i);
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the vertex data for all the quads on which a text will be rendered.
|
|
||||||
* @author Karl
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class TextMeshData {
|
|
||||||
|
|
||||||
private final float[] vertexPositions;
|
|
||||||
private final float[] textureCoords;
|
|
||||||
|
|
||||||
protected TextMeshData(float[] vertexPositions, float[] textureCoords){
|
|
||||||
this.vertexPositions = vertexPositions;
|
|
||||||
this.textureCoords = textureCoords;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float[] getVertexPositions() {
|
|
||||||
return vertexPositions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float[] getTextureCoords() {
|
|
||||||
return textureCoords;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVertexCount() {
|
|
||||||
return vertexPositions.length/2;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package nl.andrewl.aos2_client.render.gui.font;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* During the loading of a text this represents one word in the text.
|
|
||||||
* @author Karl
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Word {
|
|
||||||
|
|
||||||
private final List<Character> characters = new ArrayList<>();
|
|
||||||
private double width = 0;
|
|
||||||
private final double fontSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new empty word.
|
|
||||||
* @param fontSize - the font size of the text which this word is in.
|
|
||||||
*/
|
|
||||||
protected Word(double fontSize){
|
|
||||||
this.fontSize = fontSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a character to the end of the current word and increases the screen-space width of the word.
|
|
||||||
* @param character - the character to be added.
|
|
||||||
*/
|
|
||||||
protected void addCharacter(Character character){
|
|
||||||
characters.add(character);
|
|
||||||
width += character.getxAdvance() * fontSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The list of characters in the word.
|
|
||||||
*/
|
|
||||||
protected List<Character> getCharacters(){
|
|
||||||
return characters;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The width of the word in terms of screen size.
|
|
||||||
*/
|
|
||||||
protected double getWordWidth(){
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -79,6 +79,7 @@ public class SoundManager {
|
||||||
load("hurt_3", "sound/m_hurt_3.wav");
|
load("hurt_3", "sound/m_hurt_3.wav");
|
||||||
load("block_break_1", "sound/m_block_break_1.wav");
|
load("block_break_1", "sound/m_block_break_1.wav");
|
||||||
load("block_place_1", "sound/m_block_place_1.wav");
|
load("block_place_1", "sound/m_block_place_1.wav");
|
||||||
|
load("chat", "sound/chat.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(String name, String resource) {
|
public void load(String name, String resource) {
|
||||||
|
|
Binary file not shown.
|
@ -1,102 +0,0 @@
|
||||||
info face="JetBrains Mono Regular" size=74 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=3,3,3,3 spacing=0,0
|
|
||||||
common lineHeight=105 base=76 scaleW=512 scaleH=512 pages=1 packed=0
|
|
||||||
page id=0 file="jetbrains-mono.png"
|
|
||||||
chars count=97
|
|
||||||
char id=0 x=0 y=444 width=48 height=26 xoffset=-1 yoffset=36 xadvance=50 page=0 chnl=0
|
|
||||||
char id=10 x=0 y=0 width=0 height=0 xoffset=-3 yoffset=0 xadvance=6 page=0 chnl=0
|
|
||||||
char id=32 x=0 y=0 width=0 height=0 xoffset=-3 yoffset=0 xadvance=50 page=0 chnl=0
|
|
||||||
char id=33 x=490 y=82 width=18 height=62 xoffset=13 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=34 x=457 y=396 width=29 height=29 xoffset=8 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=36 x=0 y=0 width=41 height=82 xoffset=2 yoffset=7 xadvance=50 page=0 chnl=0
|
|
||||||
char id=37 x=312 y=151 width=49 height=62 xoffset=-2 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=38 x=368 y=82 width=44 height=63 xoffset=1 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=39 x=486 y=396 width=14 height=29 xoffset=15 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=40 x=77 y=0 width=29 height=78 xoffset=10 yoffset=10 xadvance=50 page=0 chnl=0
|
|
||||||
char id=41 x=106 y=0 width=29 height=78 xoffset=5 yoffset=10 xadvance=50 page=0 chnl=0
|
|
||||||
char id=42 x=290 y=396 width=46 height=45 xoffset=-1 yoffset=27 xadvance=50 page=0 chnl=0
|
|
||||||
char id=43 x=336 y=396 width=42 height=41 xoffset=1 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=44 x=483 y=0 width=22 height=30 xoffset=9 yoffset=61 xadvance=50 page=0 chnl=0
|
|
||||||
char id=45 x=179 y=444 width=31 height=12 xoffset=7 yoffset=45 xadvance=50 page=0 chnl=0
|
|
||||||
char id=46 x=137 y=444 width=19 height=19 xoffset=13 yoffset=61 xadvance=50 page=0 chnl=0
|
|
||||||
char id=47 x=149 y=0 width=40 height=77 xoffset=2 yoffset=10 xadvance=50 page=0 chnl=0
|
|
||||||
char id=48 x=328 y=82 width=40 height=63 xoffset=2 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=49 x=460 y=274 width=40 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=50 x=77 y=151 width=40 height=62 xoffset=2 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=51 x=117 y=151 width=39 height=62 xoffset=2 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=52 x=0 y=335 width=38 height=61 xoffset=2 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=53 x=156 y=151 width=39 height=62 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=54 x=195 y=151 width=42 height=62 xoffset=1 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=55 x=38 y=335 width=42 height=61 xoffset=2 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=56 x=286 y=82 width=42 height=63 xoffset=1 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=57 x=237 y=151 width=42 height=62 xoffset=1 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=58 x=483 y=151 width=19 height=49 xoffset=13 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=59 x=477 y=213 width=23 height=60 xoffset=9 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=60 x=0 y=0 width=0 height=0 xoffset=3 yoffset=0 xadvance=50 page=0 chnl=0
|
|
||||||
char id=61 x=418 y=396 width=39 height=30 xoffset=3 yoffset=36 xadvance=50 page=0 chnl=0
|
|
||||||
char id=62 x=165 y=335 width=110 height=50 xoffset=3 yoffset=27 xadvance=50 page=0 chnl=0
|
|
||||||
char id=63 x=279 y=151 width=33 height=62 xoffset=6 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=64 x=396 y=0 width=45 height=75 xoffset=0 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=65 x=361 y=151 width=44 height=61 xoffset=0 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=66 x=405 y=151 width=40 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=67 x=129 y=82 width=39 height=63 xoffset=3 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=68 x=445 y=151 width=38 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=69 x=0 y=213 width=38 height=61 xoffset=4 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=70 x=38 y=213 width=38 height=61 xoffset=4 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=71 x=168 y=82 width=39 height=63 xoffset=3 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=72 x=76 y=213 width=38 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=73 x=114 y=213 width=36 height=61 xoffset=4 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=74 x=412 y=82 width=40 height=62 xoffset=0 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=75 x=150 y=213 width=42 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=76 x=192 y=213 width=38 height=61 xoffset=6 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=77 x=230 y=213 width=40 height=61 xoffset=2 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=78 x=270 y=213 width=38 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=79 x=207 y=82 width=38 height=63 xoffset=3 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=80 x=308 y=213 width=41 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=81 x=356 y=0 width=40 height=75 xoffset=2 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=82 x=349 y=213 width=41 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=83 x=245 y=82 width=41 height=63 xoffset=2 yoffset=17 xadvance=50 page=0 chnl=0
|
|
||||||
char id=84 x=390 y=213 width=43 height=61 xoffset=1 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=85 x=452 y=82 width=38 height=62 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=86 x=433 y=213 width=44 height=61 xoffset=0 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=87 x=0 y=274 width=48 height=61 xoffset=-2 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=88 x=48 y=274 width=46 height=61 xoffset=-1 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=89 x=94 y=274 width=46 height=61 xoffset=-1 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=90 x=140 y=274 width=39 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=91 x=229 y=0 width=25 height=76 xoffset=12 yoffset=11 xadvance=50 page=0 chnl=0
|
|
||||||
char id=92 x=189 y=0 width=40 height=77 xoffset=2 yoffset=10 xadvance=50 page=0 chnl=0
|
|
||||||
char id=93 x=254 y=0 width=25 height=76 xoffset=8 yoffset=11 xadvance=50 page=0 chnl=0
|
|
||||||
char id=94 x=378 y=396 width=40 height=36 xoffset=2 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=95 x=0 y=82 width=129 height=69 xoffset=1 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=96 x=156 y=444 width=23 height=17 xoffset=8 yoffset=14 xadvance=50 page=0 chnl=0
|
|
||||||
char id=97 x=275 y=335 width=40 height=49 xoffset=1 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=98 x=0 y=151 width=39 height=62 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=99 x=315 y=335 width=39 height=49 xoffset=3 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=100 x=39 y=151 width=38 height=62 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=101 x=354 y=335 width=39 height=49 xoffset=3 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=102 x=179 y=274 width=42 height=61 xoffset=1 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=103 x=221 y=274 width=38 height=61 xoffset=3 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=104 x=259 y=274 width=38 height=61 xoffset=3 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=105 x=441 y=0 width=42 height=65 xoffset=3 yoffset=14 xadvance=50 page=0 chnl=0
|
|
||||||
char id=106 x=41 y=0 width=36 height=78 xoffset=2 yoffset=14 xadvance=50 page=0 chnl=0
|
|
||||||
char id=107 x=297 y=274 width=41 height=61 xoffset=4 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=108 x=338 y=274 width=45 height=61 xoffset=-1 yoffset=18 xadvance=50 page=0 chnl=0
|
|
||||||
char id=109 x=0 y=396 width=42 height=48 xoffset=1 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=110 x=471 y=335 width=38 height=48 xoffset=3 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=111 x=393 y=335 width=39 height=49 xoffset=3 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=112 x=383 y=274 width=39 height=61 xoffset=3 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=113 x=422 y=274 width=38 height=61 xoffset=3 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=114 x=42 y=396 width=38 height=48 xoffset=5 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=115 x=432 y=335 width=39 height=49 xoffset=3 yoffset=31 xadvance=50 page=0 chnl=0
|
|
||||||
char id=116 x=124 y=335 width=41 height=59 xoffset=1 yoffset=20 xadvance=50 page=0 chnl=0
|
|
||||||
char id=117 x=80 y=396 width=38 height=48 xoffset=3 yoffset=32 xadvance=50 page=0 chnl=0
|
|
||||||
char id=118 x=118 y=396 width=44 height=47 xoffset=0 yoffset=32 xadvance=50 page=0 chnl=0
|
|
||||||
char id=119 x=162 y=396 width=46 height=47 xoffset=-1 yoffset=32 xadvance=50 page=0 chnl=0
|
|
||||||
char id=120 x=208 y=396 width=44 height=47 xoffset=0 yoffset=32 xadvance=50 page=0 chnl=0
|
|
||||||
char id=121 x=80 y=335 width=44 height=60 xoffset=0 yoffset=32 xadvance=50 page=0 chnl=0
|
|
||||||
char id=122 x=252 y=396 width=38 height=47 xoffset=3 yoffset=32 xadvance=50 page=0 chnl=0
|
|
||||||
char id=123 x=279 y=0 width=39 height=76 xoffset=2 yoffset=11 xadvance=50 page=0 chnl=0
|
|
||||||
char id=124 x=135 y=0 width=14 height=77 xoffset=15 yoffset=10 xadvance=50 page=0 chnl=0
|
|
||||||
char id=125 x=318 y=0 width=38 height=76 xoffset=4 yoffset=11 xadvance=50 page=0 chnl=0
|
|
||||||
char id=126 x=96 y=444 width=41 height=22 xoffset=2 yoffset=38 xadvance=50 page=0 chnl=0
|
|
||||||
char id=127 x=48 y=444 width=48 height=25 xoffset=-1 yoffset=36 xadvance=50 page=0 chnl=0
|
|
||||||
kernings count=0
|
|
Binary file not shown.
Before Width: | Height: | Size: 34 KiB |
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>ace-of-shades-2</artifactId>
|
<artifactId>ace-of-shades-2</artifactId>
|
||||||
<groupId>nl.andrewl</groupId>
|
<groupId>nl.andrewl</groupId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,8 @@ public final class Net {
|
||||||
serializer.registerType(17, ProjectileMessage.class);
|
serializer.registerType(17, ProjectileMessage.class);
|
||||||
serializer.registerType(18, ClientHealthMessage.class);
|
serializer.registerType(18, ClientHealthMessage.class);
|
||||||
serializer.registerType(19, BlockColorMessage.class);
|
serializer.registerType(19, BlockColorMessage.class);
|
||||||
|
serializer.registerType(20, ChatMessage.class);
|
||||||
|
serializer.registerType(21, ChatWrittenMessage.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExtendedDataInputStream getInputStream(InputStream in) {
|
public static ExtendedDataInputStream getInputStream(InputStream in) {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package nl.andrewl.aos_core.net.client;
|
||||||
|
|
||||||
|
import nl.andrewl.record_net.Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A message that's sent from the server to clients about a message that has
|
||||||
|
* appeared in chat.
|
||||||
|
*/
|
||||||
|
public record ChatMessage(
|
||||||
|
long sentAt,
|
||||||
|
String author,
|
||||||
|
String message
|
||||||
|
) implements Message {
|
||||||
|
public static ChatMessage announce(String message) {
|
||||||
|
return new ChatMessage(System.currentTimeMillis(), "_ANNOUNCE", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatMessage privateMessage(String message) {
|
||||||
|
return new ChatMessage(System.currentTimeMillis(), "_PRIVATE", message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.andrewl.aos_core.net.client;
|
||||||
|
|
||||||
|
import nl.andrewl.record_net.Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A message sent by clients when they write a chat message for others to see.
|
||||||
|
*/
|
||||||
|
public record ChatWrittenMessage(
|
||||||
|
String message
|
||||||
|
) implements Message {}
|
2
pom.xml
2
pom.xml
|
@ -7,7 +7,7 @@
|
||||||
<groupId>nl.andrewl</groupId>
|
<groupId>nl.andrewl</groupId>
|
||||||
<artifactId>ace-of-shades-2</artifactId>
|
<artifactId>ace-of-shades-2</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
<modules>
|
<modules>
|
||||||
<module>core</module>
|
<module>core</module>
|
||||||
<module>server</module>
|
<module>server</module>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>ace-of-shades-2</artifactId>
|
<artifactId>ace-of-shades-2</artifactId>
|
||||||
<groupId>nl.andrewl</groupId>
|
<groupId>nl.andrewl</groupId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,10 @@ package nl.andrewl.aos2_server;
|
||||||
import nl.andrewl.aos2_server.model.ServerPlayer;
|
import nl.andrewl.aos2_server.model.ServerPlayer;
|
||||||
import nl.andrewl.aos_core.Net;
|
import nl.andrewl.aos_core.Net;
|
||||||
import nl.andrewl.aos_core.model.Team;
|
import nl.andrewl.aos_core.model.Team;
|
||||||
import nl.andrewl.aos_core.model.item.*;
|
import nl.andrewl.aos_core.model.item.BlockItemStack;
|
||||||
|
import nl.andrewl.aos_core.model.item.Gun;
|
||||||
|
import nl.andrewl.aos_core.model.item.GunItemStack;
|
||||||
|
import nl.andrewl.aos_core.model.item.ItemStack;
|
||||||
import nl.andrewl.aos_core.net.client.*;
|
import nl.andrewl.aos_core.net.client.*;
|
||||||
import nl.andrewl.aos_core.net.connect.DatagramInit;
|
import nl.andrewl.aos_core.net.connect.DatagramInit;
|
||||||
import nl.andrewl.record_net.Message;
|
import nl.andrewl.record_net.Message;
|
||||||
|
@ -37,10 +40,14 @@ public class PlayerManager {
|
||||||
log.info("Registered player \"{}\" with id {}", player.getUsername(), player.getId());
|
log.info("Registered player \"{}\" with id {}", player.getUsername(), player.getId());
|
||||||
players.put(player.getId(), player);
|
players.put(player.getId(), player);
|
||||||
clientHandlers.put(player.getId(), handler);
|
clientHandlers.put(player.getId(), handler);
|
||||||
|
String joinMessage;
|
||||||
Team team = findBestTeamForNewPlayer();
|
Team team = findBestTeamForNewPlayer();
|
||||||
if (team != null) {
|
if (team != null) {
|
||||||
player.setTeam(team);
|
player.setTeam(team);
|
||||||
log.info("Player \"{}\" joined the \"{}\" team.", player.getUsername(), team.getName());
|
log.info("Player \"{}\" joined the \"{}\" team.", player.getUsername(), team.getName());
|
||||||
|
joinMessage = String.format("%s joined the %s team.", username, team.getName());
|
||||||
|
} else {
|
||||||
|
joinMessage = username + " joined the game.";
|
||||||
}
|
}
|
||||||
player.setPosition(getBestSpawnPoint(player));
|
player.setPosition(getBestSpawnPoint(player));
|
||||||
// Tell all other players that this one has joined.
|
// Tell all other players that this one has joined.
|
||||||
|
@ -53,6 +60,7 @@ public class PlayerManager {
|
||||||
player.getInventory().getSelectedItemStack().getType().getId(),
|
player.getInventory().getSelectedItemStack().getType().getId(),
|
||||||
player.getInventory().getSelectedBlockValue()
|
player.getInventory().getSelectedBlockValue()
|
||||||
), player);
|
), player);
|
||||||
|
broadcastTcpMessageToAllBut(ChatMessage.announce(joinMessage), player);
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +71,7 @@ public class PlayerManager {
|
||||||
clientHandlers.remove(player.getId());
|
clientHandlers.remove(player.getId());
|
||||||
broadcastTcpMessage(new PlayerLeaveMessage(player.getId()));
|
broadcastTcpMessage(new PlayerLeaveMessage(player.getId()));
|
||||||
log.info("Deregistered player \"{}\" with id {}", player.getUsername(), player.getId());
|
log.info("Deregistered player \"{}\" with id {}", player.getUsername(), player.getId());
|
||||||
|
broadcastTcpMessage(ChatMessage.announce(player.getUsername() + " left the game."));
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void deregisterAll() {
|
public synchronized void deregisterAll() {
|
||||||
|
@ -163,6 +172,13 @@ public class PlayerManager {
|
||||||
resupply(player);
|
resupply(player);
|
||||||
broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis()));
|
broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis()));
|
||||||
broadcastUdpMessage(new SoundMessage("death", 1, deathPosition));
|
broadcastUdpMessage(new SoundMessage("death", 1, deathPosition));
|
||||||
|
String deathMessage;
|
||||||
|
if (killedBy != null) {
|
||||||
|
deathMessage = player.getUsername() + " was killed by " + killedBy.getUsername() + ".";
|
||||||
|
} else {
|
||||||
|
deathMessage = player.getUsername() + " died.";
|
||||||
|
}
|
||||||
|
broadcastTcpMessage(ChatMessage.announce(deathMessage));
|
||||||
// TODO: Team points or something.
|
// TODO: Team points or something.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +197,7 @@ public class PlayerManager {
|
||||||
handler.sendTcpMessage(new ItemStackMessage(i, stack));
|
handler.sendTcpMessage(new ItemStackMessage(i, stack));
|
||||||
}
|
}
|
||||||
handler.sendDatagramPacket(new ClientHealthMessage(player.getHealth()));
|
handler.sendDatagramPacket(new ClientHealthMessage(player.getHealth()));
|
||||||
|
handler.sendTcpMessage(ChatMessage.privateMessage("You've been resupplied at your team base."));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleUdpInit(DatagramInit init, DatagramPacket packet) {
|
public void handleUdpInit(DatagramInit init, DatagramPacket packet) {
|
||||||
|
|
Loading…
Reference in New Issue