diff --git a/client/pom.xml b/client/pom.xml index e146b39..0e209db 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -5,7 +5,7 @@ ace-of-shades-2 nl.andrewl - 1.0.0 + 1.1.0 4.0.0 diff --git a/client/src/main/java/nl/andrewl/aos2_client/Client.java b/client/src/main/java/nl/andrewl/aos2_client/Client.java index 855308c..7e5eeeb 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/Client.java +++ b/client/src/main/java/nl/andrewl/aos2_client/Client.java @@ -2,6 +2,7 @@ package nl.andrewl.aos2_client; import nl.andrewl.aos2_client.config.ClientConfig; 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.OtherPlayer; import nl.andrewl.aos2_client.render.GameRenderer; @@ -41,6 +42,7 @@ public class Client implements Runnable { private final Map players; private final Map projectiles; private final Map teams; + private final Chat chat; public Client(ClientConfig config) { this.config = config; @@ -49,6 +51,7 @@ public class Client implements Runnable { this.projectiles = new ConcurrentHashMap<>(); this.communicationHandler = new CommunicationHandler(this); this.inputHandler = new InputHandler(this, communicationHandler); + this.chat = new Chat(); } public ClientConfig getConfig() { @@ -182,6 +185,11 @@ public class Client implements Runnable { } } else if (msg instanceof ClientHealthMessage healthMessage) { 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; } + public Chat getChat() { + return chat; + } + public void interpolatePlayers(long now, float dt) { Vector3f movement = new Vector3f(); for (var player : players.values()) { diff --git a/client/src/main/java/nl/andrewl/aos2_client/model/Chat.java b/client/src/main/java/nl/andrewl/aos2_client/model/Chat.java new file mode 100644 index 0000000..89d439c --- /dev/null +++ b/client/src/main/java/nl/andrewl/aos2_client/model/Chat.java @@ -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 messages = new ConcurrentLinkedDeque<>(); + + public void chatReceived(ChatMessage msg) { + messages.addFirst(msg); + while (messages.size() > MAX_HISTORY) { + messages.removeLast(); + } + } + + public List getMessages() { + return new ArrayList<>(messages); + } +} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/GameRenderer.java b/client/src/main/java/nl/andrewl/aos2_client/render/GameRenderer.java index 019898f..40e26ab 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/render/GameRenderer.java +++ b/client/src/main/java/nl/andrewl/aos2_client/render/GameRenderer.java @@ -271,7 +271,7 @@ public class GameRenderer { // GUI rendering guiRenderer.start(); guiRenderer.drawNameplates(myPlayer, camera.getViewTransformData(), perspectiveTransform.get(new float[16])); - guiRenderer.drawNvg(screenWidth, screenHeight, myPlayer); + guiRenderer.drawNvg(screenWidth, screenHeight, myPlayer, client.getChat()); guiRenderer.end(); glfwSwapBuffers(windowHandle); diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/GuiRenderer.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/GuiRenderer.java index 416372d..63ca69e 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/GuiRenderer.java +++ b/client/src/main/java/nl/andrewl/aos2_client/render/gui/GuiRenderer.java @@ -1,6 +1,7 @@ package nl.andrewl.aos2_client.render.gui; 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.OtherPlayer; import nl.andrewl.aos2_client.render.ShaderProgram; @@ -59,7 +60,7 @@ public class GuiRenderer { private final int namePlatePerspectiveTransformUniform; private final int namePlateTextureSamplerUniform; private final Font namePlateFont; - private final Map playerNamePlates = new HashMap<>(); + private final Map playerNamePlates = new HashMap<>(); public GuiRenderer() throws IOException { vgId = nvgCreate(NVG_ANTIALIAS); @@ -127,7 +128,7 @@ public class GuiRenderer { 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); transformMatrix.identity() .translate(x, y, 0) @@ -139,12 +140,12 @@ public class GuiRenderer { } private void addNamePlate(OtherPlayer player) { - GUITexture texture = new GUITexture(generateNameplateImage(player.getUsername())); + GuiTexture texture = new GuiTexture(generateNameplateImage(player.getUsername())); playerNamePlates.put(player, texture); } private void removeNamePlate(OtherPlayer player) { - GUITexture texture = playerNamePlates.remove(player); + GuiTexture texture = playerNamePlates.remove(player); texture.free(); } @@ -197,7 +198,7 @@ public class GuiRenderer { OtherPlayer player = entry.getKey(); // Skip rendering far-away nameplates. if (player.getPosition().distance(myPlayer.getPosition()) > 50) continue; - GUITexture texture = entry.getValue(); + GuiTexture texture = entry.getValue(); float aspectRatio = (float) texture.getHeight() / (float) texture.getWidth(); transformMatrix.identity() .translate(player.getPosition().x(), player.getPosition().y() + Player.HEIGHT + 1f, player.getPosition().z()) @@ -215,11 +216,12 @@ public class GuiRenderer { 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); nvgSave(vgId); drawCrosshair(width, height); + drawChat(width, height, chat); drawHealthBar(width, height, player); drawHeldItemStackInfo(width, height, player); @@ -315,4 +317,33 @@ public class GuiRenderer { nvgTextAlign(vgId, NVG_ALIGN_LEFT | NVG_ALIGN_TOP); 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; + } + } } diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/GUITexture.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/GuiTexture.java similarity index 90% rename from client/src/main/java/nl/andrewl/aos2_client/render/gui/GUITexture.java rename to client/src/main/java/nl/andrewl/aos2_client/render/gui/GuiTexture.java index 91cf40b..5e0457e 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/GUITexture.java +++ b/client/src/main/java/nl/andrewl/aos2_client/render/gui/GuiTexture.java @@ -2,9 +2,7 @@ package nl.andrewl.aos2_client.render.gui; import nl.andrewl.aos_core.FileUtils; import nl.andrewl.aos_core.ImageUtils; -import org.joml.Vector2f; -import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.IOException; @@ -13,7 +11,7 @@ import static org.lwjgl.opengl.GL46.*; /** * Represents a texture loaded onto the GPU. */ -public class GUITexture { +public class GuiTexture { private final int textureId; /** * The original image's width. @@ -24,11 +22,11 @@ public class GUITexture { */ private final int height; - public GUITexture(String location) throws IOException { + public GuiTexture(String location) throws IOException { this(FileUtils.readClasspathImage(location)); } - public GUITexture(BufferedImage img) { + public GuiTexture(BufferedImage img) { width = img.getWidth(); height = img.getHeight(); diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Character.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Character.java deleted file mode 100644 index 57e2f19..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Character.java +++ /dev/null @@ -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; - } - -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/FontRenderer.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/FontRenderer.java deleted file mode 100644 index 4e28da0..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/FontRenderer.java +++ /dev/null @@ -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(); - } -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/FontType.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/FontType.java deleted file mode 100644 index e6ed200..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/FontType.java +++ /dev/null @@ -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); - } - -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/GUIText.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/GUIText.java deleted file mode 100644 index 4ca0fee..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/GUIText.java +++ /dev/null @@ -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; - } - -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Line.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Line.java deleted file mode 100644 index 5e3ae3e..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Line.java +++ /dev/null @@ -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 words = new ArrayList(); - 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 getWords() { - return words; - } - -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/MetaFile.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/MetaFile.java deleted file mode 100644 index 92d2725..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/MetaFile.java +++ /dev/null @@ -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 metaData = new HashMap<>(); - - private BufferedReader reader; - private final Map 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); - } -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMesh.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMesh.java deleted file mode 100644 index dac8061..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMesh.java +++ /dev/null @@ -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); - } -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMeshCreator.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMeshCreator.java deleted file mode 100644 index 940dee7..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMeshCreator.java +++ /dev/null @@ -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 lines = createStructure(text); - return createQuadVertices(text, lines); - } - - private List createStructure(GUIText text) { - char[] chars = text.getTextString().toCharArray(); - List lines = new ArrayList(); - 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 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 lines) { - text.setNumberOfLines(lines.size()); - double curserX = 0f; - double curserY = 0f; - List vertices = new ArrayList(); - List textureCoords = new ArrayList(); - 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 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 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 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 listOfFloats) { - float[] array = new float[listOfFloats.size()]; - for (int i = 0; i < array.length; i++) { - array[i] = listOfFloats.get(i); - } - return array; - } - -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMeshData.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMeshData.java deleted file mode 100644 index 54412b2..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/TextMeshData.java +++ /dev/null @@ -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; - } - -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Word.java b/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Word.java deleted file mode 100644 index 46d88b3..0000000 --- a/client/src/main/java/nl/andrewl/aos2_client/render/gui/font/Word.java +++ /dev/null @@ -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 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 getCharacters(){ - return characters; - } - - /** - * @return The width of the word in terms of screen size. - */ - protected double getWordWidth(){ - return width; - } - -} diff --git a/client/src/main/java/nl/andrewl/aos2_client/sound/SoundManager.java b/client/src/main/java/nl/andrewl/aos2_client/sound/SoundManager.java index dea7f47..60a19e3 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/sound/SoundManager.java +++ b/client/src/main/java/nl/andrewl/aos2_client/sound/SoundManager.java @@ -79,6 +79,7 @@ public class SoundManager { load("hurt_3", "sound/m_hurt_3.wav"); load("block_break_1", "sound/m_block_break_1.wav"); load("block_place_1", "sound/m_block_place_1.wav"); + load("chat", "sound/chat.wav"); } public void load(String name, String resource) { diff --git a/client/src/main/resources/sound/chat.wav b/client/src/main/resources/sound/chat.wav new file mode 100644 index 0000000..7b6c766 Binary files /dev/null and b/client/src/main/resources/sound/chat.wav differ diff --git a/client/src/main/resources/text/jetbrains-mono.fnt b/client/src/main/resources/text/jetbrains-mono.fnt deleted file mode 100644 index 0a7414b..0000000 --- a/client/src/main/resources/text/jetbrains-mono.fnt +++ /dev/null @@ -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 diff --git a/client/src/main/resources/text/jetbrains-mono.png b/client/src/main/resources/text/jetbrains-mono.png deleted file mode 100644 index 816b567..0000000 Binary files a/client/src/main/resources/text/jetbrains-mono.png and /dev/null differ diff --git a/core/pom.xml b/core/pom.xml index aca274b..c80d185 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ ace-of-shades-2 nl.andrewl - 1.0.0 + 1.1.0 4.0.0 diff --git a/core/src/main/java/nl/andrewl/aos_core/Net.java b/core/src/main/java/nl/andrewl/aos_core/Net.java index 2c5c0b4..1be6b3c 100644 --- a/core/src/main/java/nl/andrewl/aos_core/Net.java +++ b/core/src/main/java/nl/andrewl/aos_core/Net.java @@ -46,6 +46,8 @@ public final class Net { serializer.registerType(17, ProjectileMessage.class); serializer.registerType(18, ClientHealthMessage.class); serializer.registerType(19, BlockColorMessage.class); + serializer.registerType(20, ChatMessage.class); + serializer.registerType(21, ChatWrittenMessage.class); } public static ExtendedDataInputStream getInputStream(InputStream in) { diff --git a/core/src/main/java/nl/andrewl/aos_core/net/client/ChatMessage.java b/core/src/main/java/nl/andrewl/aos_core/net/client/ChatMessage.java new file mode 100644 index 0000000..a29140c --- /dev/null +++ b/core/src/main/java/nl/andrewl/aos_core/net/client/ChatMessage.java @@ -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); + } +} diff --git a/core/src/main/java/nl/andrewl/aos_core/net/client/ChatWrittenMessage.java b/core/src/main/java/nl/andrewl/aos_core/net/client/ChatWrittenMessage.java new file mode 100644 index 0000000..edde8b0 --- /dev/null +++ b/core/src/main/java/nl/andrewl/aos_core/net/client/ChatWrittenMessage.java @@ -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 {} diff --git a/pom.xml b/pom.xml index 85024e0..a3543c7 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ nl.andrewl ace-of-shades-2 pom - 1.0.0 + 1.1.0 core server diff --git a/server/pom.xml b/server/pom.xml index dbb974e..2f7b82b 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -5,7 +5,7 @@ ace-of-shades-2 nl.andrewl - 1.0.0 + 1.1.0 4.0.0 diff --git a/server/src/main/java/nl/andrewl/aos2_server/PlayerManager.java b/server/src/main/java/nl/andrewl/aos2_server/PlayerManager.java index 5dbe282..1f9f1c6 100644 --- a/server/src/main/java/nl/andrewl/aos2_server/PlayerManager.java +++ b/server/src/main/java/nl/andrewl/aos2_server/PlayerManager.java @@ -3,7 +3,10 @@ package nl.andrewl.aos2_server; import nl.andrewl.aos2_server.model.ServerPlayer; import nl.andrewl.aos_core.Net; 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.connect.DatagramInit; import nl.andrewl.record_net.Message; @@ -37,10 +40,14 @@ public class PlayerManager { log.info("Registered player \"{}\" with id {}", player.getUsername(), player.getId()); players.put(player.getId(), player); clientHandlers.put(player.getId(), handler); + String joinMessage; Team team = findBestTeamForNewPlayer(); if (team != null) { player.setTeam(team); 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)); // Tell all other players that this one has joined. @@ -53,6 +60,7 @@ public class PlayerManager { player.getInventory().getSelectedItemStack().getType().getId(), player.getInventory().getSelectedBlockValue() ), player); + broadcastTcpMessageToAllBut(ChatMessage.announce(joinMessage), player); return player; } @@ -63,6 +71,7 @@ public class PlayerManager { clientHandlers.remove(player.getId()); broadcastTcpMessage(new PlayerLeaveMessage(player.getId())); log.info("Deregistered player \"{}\" with id {}", player.getUsername(), player.getId()); + broadcastTcpMessage(ChatMessage.announce(player.getUsername() + " left the game.")); } public synchronized void deregisterAll() { @@ -163,6 +172,13 @@ public class PlayerManager { resupply(player); broadcastUdpMessage(player.getUpdateMessage(System.currentTimeMillis())); 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. } @@ -181,6 +197,7 @@ public class PlayerManager { handler.sendTcpMessage(new ItemStackMessage(i, stack)); } 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) {