diff --git a/.gitignore b/.gitignore index 3bd11db..bee96e5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ out output SAVE_DATA.TXT .DS_Store +.vscode/graalvm \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index a82eed7..89874d1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,20 +1,25 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "java", - "name": "Launch App", - "request": "launch", - "mainClass": "xyz.valnet.hadean.HadeanGame", - "projectName": "hadean", - "console": "internalConsole", - "internalConsoleOptions": "neverOpen", - "osx": { - "vmArgs": "-XstartOnFirstThread" - } - } - ] + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Launch App", + "request": "launch", + "mainClass": "xyz.valnet.hadean.HadeanGame", + "projectName": "hadean", + "console": "internalConsole", + "internalConsoleOptions": "neverOpen", + + "osx": { + "type": "java", + "name": "Launch App", + "request": "launch", + "mainClass": "xyz.valnet.hadean.HadeanGame", + "vmArgs": "-XstartOnFirstThread" + } + } + ] } \ No newline at end of file diff --git a/src/main/java/xyz/valnet/engine/App.java b/src/main/java/xyz/valnet/engine/App.java index 5e2c3c6..8fbbcf7 100644 --- a/src/main/java/xyz/valnet/engine/App.java +++ b/src/main/java/xyz/valnet/engine/App.java @@ -9,9 +9,7 @@ import static org.lwjgl.system.MemoryUtil.*; import java.nio.IntBuffer; -import org.lwjgl.glfw.GLFWCursorPosCallback; import org.lwjgl.glfw.GLFWErrorCallback; -import org.lwjgl.glfw.GLFWMouseButtonCallback; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.openal.AL; import org.lwjgl.openal.ALC; @@ -21,6 +19,7 @@ import org.lwjgl.opengl.GL; import org.lwjgl.system.MemoryStack; import xyz.valnet.engine.math.Matrix4f; +import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; public class App { @@ -91,7 +90,6 @@ public class App { }); glfwSetScrollCallback(window, (long window, double xOffset, double yOffset) -> { - System.out.println("Scroll " + yOffset); if(yOffset > 0) game.scrollUp(); else if(yOffset < 0) @@ -113,7 +111,8 @@ public class App { if(button == GLFW_MOUSE_BUTTON_LEFT) { mouseLeft = action == 1; return; } if(button == GLFW_MOUSE_BUTTON_RIGHT) { mouseRight = action == 1; return; } if(button == GLFW_MOUSE_BUTTON_MIDDLE) { mouseMiddle = action == 1; return ; } - System.out.println("Mouse: action " + action + " : button " + button); + + DebugTab.log("Mouse: action " + action + " : button " + button); }); // Get the thread stack and push a new frame diff --git a/src/main/java/xyz/valnet/engine/graphics/Color.java b/src/main/java/xyz/valnet/engine/graphics/Color.java new file mode 100644 index 0000000..caafa8e --- /dev/null +++ b/src/main/java/xyz/valnet/engine/graphics/Color.java @@ -0,0 +1,62 @@ +package xyz.valnet.engine.graphics; + +import java.io.Serializable; + +public class Color implements Serializable { + public final float r, g, b, a; + + public static Color black = new Color(0, 0, 0); + public static Color white = new Color(1, 1, 1); + + public static Color red = new Color(1, 0, 0); + public static Color green = new Color(0, 1, 0); + public static Color blue = new Color(0, 0, 1); + + public static Color yellow = new Color(1, 1, 0); + public static Color cyan = new Color(0, 1, 1); + public static Color magenta = new Color(1, 0, 1); + + public static Color orange = new Color(1, 0.5f, 0); + public static Color lime = new Color(0.5f, 1, 0); + public static Color aqua = new Color(0, 1, 0.5f); + public static Color indigo = new Color(0, 0.5f, 1); + public static Color purple = new Color(0.5f, 0, 1); + public static Color hotpink = new Color(1, 0, 0.5f); + + public Color(float r, float g, float b) { + this(r, g, b, 1.0f); + } + + public Color(float r, float g, float b, float a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + public Color withAlpha(float a) { + return new Color(r, g, b, a); + } + + public Color brighter() { + return new Color( + (float) Math.sqrt(r), + (float) Math.sqrt(g), + (float) Math.sqrt(b), + a + ); + } + + public Color darker() { + return new Color( + (float) Math.pow(r, 2), + (float) Math.pow(g, 2), + (float) Math.pow(b, 2), + a + ); + } + + public static Color grey(float f) { + return new Color(f, f, f); + } +} diff --git a/src/main/java/xyz/valnet/engine/graphics/Font.java b/src/main/java/xyz/valnet/engine/graphics/Font.java index 6c453fc..3322d59 100644 --- a/src/main/java/xyz/valnet/engine/graphics/Font.java +++ b/src/main/java/xyz/valnet/engine/graphics/Font.java @@ -2,7 +2,6 @@ package xyz.valnet.engine.graphics; import java.util.Map; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.math.Vector4i; import xyz.valnet.hadean.util.Assets; @@ -21,7 +20,7 @@ public class Font { } public void drawStringOutlined(String str, int x, int y) { - Assets.flat.pushColor(Vector4f.black); + Assets.flat.pushColor(Color.black); drawString(str, x - scale, y - scale); drawString(str, x, y - scale); drawString(str, x + scale, y - scale); diff --git a/src/main/java/xyz/valnet/engine/graphics/IModalUI.java b/src/main/java/xyz/valnet/engine/graphics/IModalUI.java new file mode 100644 index 0000000..7e10260 --- /dev/null +++ b/src/main/java/xyz/valnet/engine/graphics/IModalUI.java @@ -0,0 +1,12 @@ +package xyz.valnet.engine.graphics; + +// TODO there is some shared logic for these in tabs & selection ui. +// combine them into a base class, probably extending immediateUI... + +public interface IModalUI { + public void open(); + public void close(); + public default void back() { + close(); + } +} diff --git a/src/main/java/xyz/valnet/engine/graphics/ImmediateUI.java b/src/main/java/xyz/valnet/engine/graphics/ImmediateUI.java index 34ffcdd..a9f89d6 100644 --- a/src/main/java/xyz/valnet/engine/graphics/ImmediateUI.java +++ b/src/main/java/xyz/valnet/engine/graphics/ImmediateUI.java @@ -8,7 +8,8 @@ import java.util.Map; import java.util.Set; import java.util.Stack; -import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.engine.math.Box; +import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector4i; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.IMouseCaptureArea; @@ -29,16 +30,6 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre end(); } - public void renderAlpha() { - // float f = 99; - // Assets.flat.pushColor(new Vector4f(1, 0, 0, 0.3f)); - // for(Vector4f box : guiAreas) { - // Drawing.setLayer(f += 0.001f); - // Assets.fillColor.draw(box); - // } - // Assets.flat.popColor(); - } - @Override public void mouseEnter() { active = true; @@ -68,8 +59,8 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre private record StackingContext( boolean fixedSize, - Vector4f box, - Vector4f occlusionBox, + Box box, + Box occlusionBox, boolean hasRegisteredGuiArea, boolean horizontal // layout manager? @@ -99,7 +90,6 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre private Button getButton(String id) { if(hasButton(id)) return buttons.get(id); - System.out.println("Created new Button"); Button btn = new Button(Assets.uiFrame, "", 0, 0, 0, 0, 0); btn.registerClickListener((target) -> { if(!clicks.containsKey(target)) clicks.put(target, 0); @@ -120,31 +110,42 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre return false; } + private void modifyBox(float x, float y, float w, float h) { + context = new StackingContext( + context.fixedSize, + new Box(context.box.x + x, context.box.y + y, context.box.w + w, context.box.h + h), + context.occlusionBox, + context.hasRegisteredGuiArea, + context.horizontal + ); + } + private void adjustBox(float w, float h) { if(context.vertical()) { if(context.fixedSize) { - context.box.y += h; - context.box.w -= h; + modifyBox(0, h, 0, -h); } else { - context.box.w += h; + modifyBox(0, 0, 0, h); + if (w - context.box.w > 0) + modifyBox(0, 0, w - context.box.w, 0); } } else { if(context.fixedSize) { - context.box.x += w; - context.box.z -= w; + modifyBox(w, 0, -w, 0); } else { - context.box.z += w; - context.box.w = Math.max(context.box.w, h); + modifyBox(0, 0, w, 0); + if (h - context.box.h > 0) + modifyBox(0, 0, 0, h - context.box.h); } } } @Override - public final List getGuiBoxes() { + public final List getGuiBoxes() { return guiAreas; } - private transient List guiAreas = new ArrayList(); + private transient List guiAreas = new ArrayList(); @FunctionalInterface public interface RenderCallback { @@ -159,6 +160,19 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre return getLayer() + contextStack.size() * 0.001f; } + // PLEASE PLEASE INLINE THIS DOGWATER CALL + private final Vector2i getNextBoxLocation() { + if(context.fixedSize) { + return context.box.a.asInt(); + } else { + if(context.horizontal) { + return new Vector2i((int) context.box.x2, (int) context.box.y); + } else { + return new Vector2i((int) context.box.x, (int) context.box.y2); + } + } + } + // === ELEMENTS === // @@ -187,7 +201,7 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre protected void root(int x, int y, int w, int h) { assert context == null : "root can only be a root element"; - Vector4f box = new Vector4f(x, y, w, h); + Box box = new Box(x, y, w, h); context = new StackingContext(true, box, box, false, false); } @@ -200,7 +214,7 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre contextStack.push(context); context = new StackingContext( true, - new Vector4f(context.box.x, context.box.y, w, h), + new Box(context.box.x, context.box.y, w, h), context.occlusionBox.copy(), true, context.horizontal @@ -211,7 +225,7 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre contextStack.push(context); context = new StackingContext( false, - new Vector4f(context.box.x, context.box.y, context.box.z, 0), + new Box(context.box.x, context.box.y, context.box.w, 0), context.occlusionBox.copy(), true, context.horizontal @@ -245,11 +259,11 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre } protected boolean button(String id, String text, boolean expand) { - float h = 32; + int h = 32; if(expand && context.fixedSize) { - h = context.box.w; + h = (int) context.box.h; } - float w = context.box.z; + int w = (int) context.box.w; if(context.horizontal && !context.fixedSize) { w = 100; } @@ -259,13 +273,13 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre if(!context.fixedSize) { if(context.vertical()) { - y += (int) context.box.w; + y += (int) context.box.h; } else { - x += (int) context.box.z; + x += (int) context.box.w; } } - Vector4f buttonBox = new Vector4f(x, y, w, h); + Box buttonBox = new Box(x, y, w, h); Button btn = getButton(id); if(!context.hasRegisteredGuiArea) { @@ -274,10 +288,10 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre btn.setText(text); btn.setPosition(x, y); - btn.setSize((int) buttonBox.z, (int) buttonBox.w); + btn.setSize(w, h); btn.setLayer(getCurrentLayer()); - adjustBox(buttonBox.z, buttonBox.w); + adjustBox(buttonBox.w, buttonBox.h); return getClick(btn); } @@ -291,8 +305,8 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre protected void group() { contextStack.push(context); context = new StackingContext(false, - new Vector4f( - context.box.x, context.box.y, context.box.z, 0 + new Box( + context.box.x, context.box.y, context.box.w, 0 ), context.occlusionBox.copy(), context.hasRegisteredGuiArea, @@ -303,19 +317,19 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre protected void groupEnd() { padEnd(); - Drawing.setLayer(getPreviousLayer()); - float h = context.box.w; - Assets.uiFrame.draw(context.box); + Box inner = context.box; context = contextStack.pop(); - adjustBox(context.box.z, h); + Drawing.setLayer(getCurrentLayer()); + Assets.uiFrame.draw(inner); + adjustBox(inner.w, inner.h); } protected void pad() { contextStack.push(context); if(context.fixedSize) { context = new StackingContext(true, - new Vector4f( - context.box.x + 8, context.box.y + 8, context.box.z - 16, context.box.w - 16 + new Box( + context.box.x + 8, context.box.y + 8, context.box.w - 16, context.box.h - 16 ), context.occlusionBox.copy(), context.hasRegisteredGuiArea, @@ -323,8 +337,8 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre ); } else { context = new StackingContext(false, - new Vector4f( - context.box.x + 8, context.box.y + 8, context.box.z - 16, 0 + new Box( + context.box.x + 8, context.box.y + 8, context.box.w - 16, 0 ), context.occlusionBox.copy(), context.hasRegisteredGuiArea, @@ -334,23 +348,39 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre } protected void padEnd() { - float h = context.box.w + 16; + Box inner = context.box; context = contextStack.pop(); - adjustBox(context.box.z + 16, h); + adjustBox(inner.w + 16, inner.h + 16); } protected void horizontal(RenderCallback cb) { contextStack.push(context); context = new StackingContext( false, - new Vector4f(context.box.x, context.box.y, 0, 0), + new Box(getNextBoxLocation(), 0, 0), context.occlusionBox, context.hasRegisteredGuiArea, true ); cb.apply(); - float w = context.box.z; - float h = context.box.w; + float w = context.box.w; + float h = context.box.h; + context = contextStack.pop(); + adjustBox(w, h); + } + + protected void vertical(RenderCallback cb) { + contextStack.push(context); + context = new StackingContext( + false, + new Box(getNextBoxLocation(), 0, 0), + context.occlusionBox, + context.hasRegisteredGuiArea, + false + ); + cb.apply(); + float w = context.box.w; + float h = context.box.h; context = contextStack.pop(); adjustBox(w, h); } @@ -398,9 +428,9 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre if(!context.fixedSize) { if(context.vertical()) { - y += (int) context.box.w; + y += (int) context.box.h; } else { - x += (int) context.box.z; + x += (int) context.box.w; } } diff --git a/src/main/java/xyz/valnet/engine/graphics/Tile9.java b/src/main/java/xyz/valnet/engine/graphics/Tile9.java index f41fb63..c3125c8 100644 --- a/src/main/java/xyz/valnet/engine/graphics/Tile9.java +++ b/src/main/java/xyz/valnet/engine/graphics/Tile9.java @@ -1,7 +1,6 @@ package xyz.valnet.engine.graphics; -import xyz.valnet.engine.math.Vector4f; -import xyz.valnet.engine.math.Vector4i; +import xyz.valnet.engine.math.Box; public class Tile9 { @@ -37,12 +36,8 @@ public class Tile9 { this.bottomRight = bottomRight; } - public void draw(Vector4f box) { - draw(box.asInt()); - } - - public void draw(Vector4i box) { - draw(box.x, box.y, box.z, box.w); + public void draw(Box box) { + draw((int) box.x, (int) box.y, (int) box.w, (int) box.h); } public void draw(int x, int y, int w, int h) { diff --git a/src/main/java/xyz/valnet/engine/math/Box.java b/src/main/java/xyz/valnet/engine/math/Box.java new file mode 100644 index 0000000..bf3a778 --- /dev/null +++ b/src/main/java/xyz/valnet/engine/math/Box.java @@ -0,0 +1,95 @@ +package xyz.valnet.engine.math; + +import java.io.Serializable; + +public class Box implements Serializable { + + public final float x, y, w, h, x2, y2; + public final Vector2f a, b; + public final Vector2f pos, dim; + + public static final Box none = new Box(0, 0, 0, 0); + + public Box(float x, float y, float w, float h) { + if(w < 0) { + this.w = Math.abs(w); + this.x = x + w; + } else { + this.x = x; + this.w = w; + } + if(h < 0) { + this.h = Math.abs(h); + this.y = y + h; + } else { + this.y = y; + this.h = h; + } + this.x2 = this.x + this.w; + this.y2 = this.y + this.h; + this.a = new Vector2f(this.x, this.y); + this.b = new Vector2f(this.x2, this.y2); + this.pos = this.a; + this.dim = new Vector2f(this.w, this.h); + } + + public Box(Vector2f pos, float w, float h) { + this(pos.x, pos.y, w, h); + } + + public Box(float x, float y, Vector2f dim) { + this(x, y, dim.x, dim.y); + } + + public Box(Vector2f pos, Vector2f dim) { + this(pos.x, pos.y, dim.x, dim.y); + } + + public Box(Vector2i pos, float w, float h) { + this(pos.x, pos.y, w, h); + } + + public Box(float x, float y, Vector2i dim) { + this(x, y, dim.x, dim.y); + } + + public Box(Vector2i pos, Vector2i dim) { + this(pos.x, pos.y, dim.x, dim.y); + } + + public static Box fromPoints(Vector2i a, Vector2i b) { + return new Box(a.x, a.y, b.x - a.x, b.y - a.y); + } + + public static Box fromPoints(Vector2i a, float x2, float y2) { + return new Box(a.x, a.y, x2 - a.x, y2 - a.y); + } + + public static Box fromPoints(float x, float y, Vector2i b) { + return new Box(x, y, b.x - x, b.y - y); + } + + public static Box fromPoints(Vector2f a, Vector2f b) { + return new Box(a.x, a.y, b.x - a.x, b.y - a.y); + } + + public static Box fromPoints(Vector2f a, float x2, float y2) { + return new Box(a.x, a.y, x2 - a.x, y2 - a.y); + } + + public static Box fromPoints(float x, float y, Vector2f b) { + return new Box(x, y, b.x - x, b.y - y); + } + + public static Box fromPoints(float x, float y, float x2, float y2) { + return new Box(x, y, x2 - x, y2 - y); + } + + public Box copy() { + return new Box(x, y, w, h); + } + + public boolean contains(float x, float y) { + return x >= this.x && x < this.x2 && y >= this.y && y < this.y2; + } +} diff --git a/src/main/java/xyz/valnet/engine/math/Vector2i.java b/src/main/java/xyz/valnet/engine/math/Vector2i.java index 9755b87..9e25a0f 100644 --- a/src/main/java/xyz/valnet/engine/math/Vector2i.java +++ b/src/main/java/xyz/valnet/engine/math/Vector2i.java @@ -55,4 +55,8 @@ public class Vector2i implements Serializable { return new Vector2i(x - 1, y); } + public Box getTileBox() { + return new Box(x, y, 1, 1); + } + } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/CustomObjectDeserializer.java b/src/main/java/xyz/valnet/engine/scenegraph/CustomObjectDeserializer.java index 9fdb1eb..36d7a70 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/CustomObjectDeserializer.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/CustomObjectDeserializer.java @@ -5,6 +5,8 @@ import java.io.InputStream; import java.io.InvalidClassException; import java.io.ObjectInputStream; import java.io.ObjectStreamClass; + +import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; public class CustomObjectDeserializer extends ObjectInputStream { @@ -20,8 +22,8 @@ public class CustomObjectDeserializer extends ObjectInputStream { try { localClass = Class.forName(resultClassDescriptor.getName()); } catch (ClassNotFoundException e) { - System.out.println("No local class for " + resultClassDescriptor.getName()); - System.out.println(e); + DebugTab.log("No local class for " + resultClassDescriptor.getName()); + DebugTab.log(e); return resultClassDescriptor; } ObjectStreamClass localClassDescriptor = ObjectStreamClass.lookup(localClass); @@ -33,8 +35,8 @@ public class CustomObjectDeserializer extends ObjectInputStream { s.append("local serialVersionUID = ").append(localSUID); s.append(" stream serialVersionUID = ").append(streamSUID); Exception e = new InvalidClassException(s.toString()); - System.out.println("Potentially Fatal Deserialization Operation."); - System.out.println(e); + DebugTab.log("Potentially Fatal Deserialization Operation."); + DebugTab.log(e); resultClassDescriptor = localClassDescriptor; // Use local class descriptor for deserialization } } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java index 81401b6..cf7bcb2 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java @@ -81,4 +81,8 @@ public class GameObject implements IRenderable, ITickable, Serializable { protected boolean getKey(int key) { return scene.getKey(key); } + + protected boolean isPaused() { + return scene.isPaused(); + } } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/IKeyboardListener.java b/src/main/java/xyz/valnet/engine/scenegraph/IKeyboardListener.java new file mode 100644 index 0000000..e1019e0 --- /dev/null +++ b/src/main/java/xyz/valnet/engine/scenegraph/IKeyboardListener.java @@ -0,0 +1,7 @@ +package xyz.valnet.engine.scenegraph; + +public interface IKeyboardListener { + public void keyPress(int code); + public void keyRelease(int code); + // public default void keyPress(int code) {} +} diff --git a/src/main/java/xyz/valnet/engine/scenegraph/IMouseCaptureArea.java b/src/main/java/xyz/valnet/engine/scenegraph/IMouseCaptureArea.java index 5967131..05ba4f2 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/IMouseCaptureArea.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/IMouseCaptureArea.java @@ -2,16 +2,18 @@ package xyz.valnet.engine.scenegraph; import java.util.List; -import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.engine.math.Box; public interface IMouseCaptureArea { - public void mouseEnter(); - public void mouseLeave(); + + public default void mouseEnter() {} + public default void mouseLeave() {} + public List getGuiBoxes(); + public float getLayer(); + public void mouseDown(int button); public void mouseUp(int button); public default void scrollUp() {} public default void scrollDown() {} - public List getGuiBoxes(); - public float getLayer(); } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/IPauser.java b/src/main/java/xyz/valnet/engine/scenegraph/IPauser.java new file mode 100644 index 0000000..88e2cbb --- /dev/null +++ b/src/main/java/xyz/valnet/engine/scenegraph/IPauser.java @@ -0,0 +1,5 @@ +package xyz.valnet.engine.scenegraph; + +public interface IPauser { + public boolean isPaused(); +} diff --git a/src/main/java/xyz/valnet/engine/scenegraph/ITickable.java b/src/main/java/xyz/valnet/engine/scenegraph/ITickable.java index fbbc58d..7da5b51 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/ITickable.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/ITickable.java @@ -2,4 +2,5 @@ package xyz.valnet.engine.scenegraph; public interface ITickable { public void update(float dTime); + public default void fixedUpdate(float dTime) {} } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java b/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java index 06c4761..d811d80 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java @@ -15,7 +15,8 @@ import java.util.Set; import java.util.stream.Collectors; import xyz.valnet.engine.App; -import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.engine.math.Box; +import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; public abstract class SceneGraph implements IScene { protected final List objects = new ArrayList(); @@ -70,9 +71,24 @@ public abstract class SceneGraph implements IScene { if(saveFlag) save(); if(loadFlag) load(); - // TICK OBJECTS + paused = false; + for(IPauser pauser : pausers) { + if(pauser.isPaused()) { + paused = true; + break; + } + } + + if(!paused) { + // TICK OBJECTS + for(GameObject obj : objects) { + obj.update(dTime); + } + } + + // fixed TICK OBJECTS for(GameObject obj : objects) { - obj.update(dTime); + obj.fixedUpdate(dTime); } mouseUpdate(); @@ -91,7 +107,7 @@ public abstract class SceneGraph implements IScene { }); for(IMouseCaptureArea listener : mouseListeners) { - for(Vector4f guiBox : listener.getGuiBoxes()) { + for(Box guiBox : listener.getGuiBoxes()) { boolean currentlyEntered = guiBox.contains(App.mouseX, App.mouseY); if(currentlyEntered) { if(listener != hoveredMouseListener) { @@ -112,10 +128,20 @@ public abstract class SceneGraph implements IScene { } } + private boolean paused = false; + + public boolean isPaused() { + return paused; + } + @Override public void enable() { this.construct(); + for(GameObject obj : objects) { + addObjectToCache(obj); + } + for(GameObject obj : objects) { obj.link(this); } @@ -142,10 +168,19 @@ public abstract class SceneGraph implements IScene { objects.clear(); } + private Set pausers = new HashSet(); + public void add(GameObject obj) { newObjects.add(obj); obj.link(this); obj.addedToScene(); + addObjectToCache(obj); + } + + private void addObjectToCache(GameObject obj) { + if(obj instanceof IPauser) { + pausers.add((IPauser) obj); + } } public void remove(GameObject obj) { @@ -158,7 +193,7 @@ public abstract class SceneGraph implements IScene { public void dump() { for(GameObject go : objects) - System.out.println(go); + DebugTab.log(go); } private void dump(List objects) { @@ -170,7 +205,7 @@ public abstract class SceneGraph implements IScene { count.put(clazz, count.get(clazz) + 1); } for(Entry, Integer> entry : count.entrySet()) { - System.out.println("" + entry.getValue() + "x " + entry.getKey().getSimpleName()); + DebugTab.log("" + entry.getValue() + "x " + entry.getKey().getSimpleName()); } } @@ -185,15 +220,15 @@ public abstract class SceneGraph implements IScene { FileOutputStream file = new FileOutputStream("SAVE_DATA.TXT"); ObjectOutputStream out = new ObjectOutputStream(file); ArrayList toSave = getNonTransientObjects(); - System.out.println("=== [ SAVING ] ==="); + DebugTab.log("=== [ SAVING ] ==="); dump(toSave); out.writeObject(toSave); out.close(); file.close(); - System.out.println("=== [ SAVED ] ==="); + DebugTab.log("=== [ SAVED ] ==="); } catch (Exception e) { e.printStackTrace(); - System.out.println("=== [ FAILED ] ==="); + DebugTab.log("=== [ FAILED ] ==="); } saveFlag = false; } @@ -206,7 +241,7 @@ public abstract class SceneGraph implements IScene { List newObjects = (List) input.readObject(); input.close(); file.close(); - System.out.println("imported " + newObjects.size() + " objects"); + DebugTab.log("imported " + newObjects.size() + " objects"); ArrayList toRemove = getNonTransientObjects(); for(GameObject obj : toRemove) { @@ -250,13 +285,19 @@ public abstract class SceneGraph implements IScene { @Override public final void keyPress(int key) { + DebugTab.log("keyCode: " + key); keys.add(key); - System.out.println("keyCode: " + key); + for(IKeyboardListener ikbl : getAll(IKeyboardListener.class)) { + ikbl.keyPress(key); + } } @Override public final void keyRelease(int key) { if(keys.contains(key)) keys.remove(key); + for(IKeyboardListener ikbl : getAll(IKeyboardListener.class)) { + ikbl.keyRelease(key); + } } @Override diff --git a/src/main/java/xyz/valnet/engine/shaders/Shader.java b/src/main/java/xyz/valnet/engine/shaders/Shader.java index 377d2c9..a6c8f90 100644 --- a/src/main/java/xyz/valnet/engine/shaders/Shader.java +++ b/src/main/java/xyz/valnet/engine/shaders/Shader.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Matrix4f; import xyz.valnet.engine.math.Vector3f; import xyz.valnet.engine.math.Vector4f; @@ -123,6 +124,11 @@ public class Shader { glUniform4f(getUniform(name), vector.x, vector.y, vector.z, vector.w); } + public void setUniform4f(String name, Color c) { + if (!enabled) enable(); + glUniform4f(getUniform(name), c.r, c.g, c.b, c.a); + } + public void setUniformMat4f(String name, Matrix4f matrix) { if (!enabled) enable(); glUniformMatrix4fv(getUniform(name), false, matrix.toFloatBuffer()); diff --git a/src/main/java/xyz/valnet/engine/shaders/SimpleShader.java b/src/main/java/xyz/valnet/engine/shaders/SimpleShader.java index dc5f8c2..4131b3a 100644 --- a/src/main/java/xyz/valnet/engine/shaders/SimpleShader.java +++ b/src/main/java/xyz/valnet/engine/shaders/SimpleShader.java @@ -1,14 +1,14 @@ package xyz.valnet.engine.shaders; -import java.util.Stack; - import static org.lwjgl.opengl.GL20.*; -import xyz.valnet.engine.math.Vector4f; +import java.util.Stack; + +import xyz.valnet.engine.graphics.Color; public class SimpleShader extends Shader { - private Stack colorStack = new Stack(); + private Stack colorStack = new Stack(); public final static int COLOR = 1; public final static int TEX_COORD = 2; @@ -17,12 +17,12 @@ public class SimpleShader extends Shader { super(vertPath, fragPath); } - public void pushColor(Vector4f color) { + public void pushColor(Color color) { colorStack.push(color); setUniform4f("uColor", color); } - public void swapColor(Vector4f color) { + public void swapColor(Color color) { popColor(); pushColor(color); } @@ -33,10 +33,10 @@ public class SimpleShader extends Shader { public void popColor() { colorStack.pop(); - Vector4f newColor = colorStack.peek(); + Color newColor = colorStack.peek(); if(newColor == null) { - setUniform4f("uColor", Vector4f.one); + setUniform4f("uColor", Color.white); return; } setUniform4f("uColor", newColor); diff --git a/src/main/java/xyz/valnet/hadean/Constants.java b/src/main/java/xyz/valnet/hadean/Constants.java new file mode 100644 index 0000000..acca217 --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/Constants.java @@ -0,0 +1,5 @@ +package xyz.valnet.hadean; + +public class Constants { + public static final float animationSpeed = 20; +} diff --git a/src/main/java/xyz/valnet/hadean/HadeanGame.java b/src/main/java/xyz/valnet/hadean/HadeanGame.java index 8070cb8..761972e 100644 --- a/src/main/java/xyz/valnet/hadean/HadeanGame.java +++ b/src/main/java/xyz/valnet/hadean/HadeanGame.java @@ -1,13 +1,10 @@ package xyz.valnet.hadean; -import java.util.ArrayList; -import java.util.List; - import xyz.valnet.engine.App; import xyz.valnet.engine.Game; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.math.Matrix4f; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.hadean.scenes.GameScene; import xyz.valnet.hadean.util.Assets; @@ -22,7 +19,7 @@ public class HadeanGame extends Game { @Override public void start() { - Assets.flat.pushColor(Vector4f.one); + Assets.flat.pushColor(Color.white); changeScene(new GameScene()); } @@ -32,35 +29,14 @@ public class HadeanGame extends Game { super.render(); if(!debugView) return; - Drawing.setLayer(99); - renderDebugInfo(); } - private static Runtime runtime = Runtime.getRuntime(); - private static Vector4f fontColor = new Vector4f(1, 0, 0, 1); + public float getAverageFPS() { + return averageFPS; + } - private void renderDebugInfo() { - - long allocated = runtime.totalMemory(); - long max = runtime.maxMemory(); - int left = 770; - int top = 10; - - List strings = new ArrayList(); - strings.add(" === [ DEBUG ] ==="); - strings.add("FPS: " + Math.round(averageFPS) + "/" + measuredFPS + " | AVG/MEASURED"); - strings.add("Mouse: <" + App.mouseX + ", " + App.mouseY + ">"); - strings.add("MEMORY: " + (int)((allocated / (double)max) * 100) + "% (" + (allocated / (1024 * 1024)) + "/" + (max / (1024 * 1024)) + "MB)"); - strings.add("dTime: " + dTime); - - for(String str : strings) { - Assets.flat.pushColor(Vector4f.black); - Assets.font.drawString(str, left + 1, top + 1); - Assets.flat.swapColor(fontColor); - Assets.font.drawString(str, left, top); - Assets.flat.popColor(); - top += 16; - } + public int getMeasuredFPS() { + return measuredFPS; } // receive the updated matrix every frame for the actual window. diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java b/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java index 5635b5a..615dbde 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java @@ -1,13 +1,13 @@ package xyz.valnet.hadean.gameobjects; -import static xyz.valnet.engine.util.Math.*; - import java.util.List; import xyz.valnet.engine.App; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.graphics.Sprite; import xyz.valnet.engine.graphics.Tile9; +import xyz.valnet.engine.math.Box; import xyz.valnet.engine.math.Vector2f; import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector4f; @@ -19,6 +19,8 @@ import xyz.valnet.hadean.interfaces.IWorldBoundsAdapter; import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Layers; +import static xyz.valnet.engine.util.Math.lerp; + public class Camera extends GameObject implements ITransient, IMouseCaptureArea { private int tileWidth = 16; @@ -37,6 +39,11 @@ public class Camera extends GameObject implements ITransient, IMouseCaptureArea maxY = bounds.w; } + public Vector2f getWorldMouse() { + return screen2world(App.mouseX, App.mouseY); + } + + @Override public void update(float dTime) { Vector2f direction = Vector2f.zero; if(dragOrigin == null) { @@ -54,8 +61,7 @@ public class Camera extends GameObject implements ITransient, IMouseCaptureArea } Vector2f move = direction.normalize().multiply(dTime / 5f); - // move = Vector2f.east; - // System.out.println(move); + focus = focus.add(move); } else { Vector2f dragDifference = screen2world(App.mouseX, App.mouseY).subtract(focus); @@ -124,6 +130,10 @@ public class Camera extends GameObject implements ITransient, IMouseCaptureArea Drawing.drawSprite(sprite, (int)(screenPos.x), (int)(screenPos.y), (int)(tileWidth * w), (int)(tileWidth * h)); } + public void draw(float layer, Tile9 sprite, Box box) { + draw(layer, sprite, box.x, box.y, box.w, box.h); + } + public void draw(float layer, Tile9 sprite, float x, float y, float w, float h) { Vector2i screenPos = world2screen(x, y); Drawing.setLayer(layer + (((y + h) - minY) / (maxY - minY))); @@ -134,9 +144,9 @@ public class Camera extends GameObject implements ITransient, IMouseCaptureArea int h = 6; Vector4i box = world2screen(worldBox).toXYWH().asInt(); Drawing.setLayer(Layers.GENERAL_UI); - Assets.flat.pushColor(new Vector4f(0, 0, 0, 1)); + Assets.flat.pushColor(Color.black); Assets.uiFrame.draw(box.x - h, box.y + box.w / 2 - h / 2, box.z + h * 2, h); - Assets.flat.swapColor(new Vector4f(1, 1, 0, 1)); + Assets.flat.swapColor(Color.yellow); Assets.fillColor.draw(box.x + 1 - h, box.y + 1 + box.w / 2 - h / 2, (int)Math.round(lerp(0, box.z - 3 + h * 2, progress)) + 1, h - 2); Assets.flat.popColor(); } @@ -164,8 +174,8 @@ public class Camera extends GameObject implements ITransient, IMouseCaptureArea } @Override - public List getGuiBoxes() { - return List.of(Vector4f.zero); + public List getGuiBoxes() { + return List.of(Box.none); } @Override diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Clock.java b/src/main/java/xyz/valnet/hadean/gameobjects/Clock.java index 750de9d..3885039 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Clock.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Clock.java @@ -1,7 +1,6 @@ package xyz.valnet.hadean.gameobjects; import xyz.valnet.engine.graphics.Drawing; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Layers; diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/JobBoard.java b/src/main/java/xyz/valnet/hadean/gameobjects/JobBoard.java index 0278b80..44a69d2 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/JobBoard.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/JobBoard.java @@ -9,8 +9,8 @@ import java.util.Map.Entry; import java.util.Set; import java.util.stream.Stream; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.hadean.HadeanGame; import xyz.valnet.hadean.gameobjects.worldobjects.pawn.Pawn; @@ -46,18 +46,18 @@ public class JobBoard extends GameObject { super.render(); if(HadeanGame.debugView) { float opacity = 0.6f; - Assets.flat.pushColor(new Vector4f(1, 0.8f, 0, opacity)); + Assets.flat.pushColor(Color.orange.withAlpha(opacity)); for(Job job : availableJobs) { for(Vector2i position : job.getLocations()) { if(job.isValid()) { - Assets.flat.swapColor(new Vector4f(1, 0.8f, 0, opacity)); + Assets.flat.swapColor(Color.orange.withAlpha(opacity)); } else { - Assets.flat.swapColor(new Vector4f(1.0f, 0.2f, 0, opacity)); + Assets.flat.swapColor(Color.red.withAlpha(opacity)); } camera.draw(Layers.GROUND_MARKERS, Assets.fillTile, position.asFloat()); } } - Assets.flat.swapColor(new Vector4f(0.2f, 1.0f, 0, opacity)); + Assets.flat.swapColor(Color.lime.withAlpha(opacity)); for(Job job : allocations.values()) { for(Vector2i position : job.getLocations()) { camera.draw(Layers.GROUND_MARKERS, Assets.fillTile, position.asFloat()); @@ -173,6 +173,40 @@ public class JobBoard extends GameObject { // } else return null; // } + public String getValidJobs() { + Map jobs = new HashMap(); + for(Job job : availableJobs) { + if(!job.isValid()) continue; + String name = job.getJobName(); + if(!jobs.containsKey(name)) jobs.put(name, 0); + jobs.put(name, jobs.get(name) + 1); + } + String str = ""; + for(Entry entry : jobs.entrySet()) { + // int num = entry.getValue(); + // if(num == 1) str += " " + str += entry.getValue() + "x " + entry.getKey() + "\n"; + } + return str.trim(); + } + + public String getInvalidJobs() { + String str = ""; + for(Job job : availableJobs) { + if(job.isValid()) continue; + str += " " + job.getJobName() + "\n"; + } + return str; + } + + public String getTakenJobs() { + String str = ""; + for(Entry allocation : allocations.entrySet()) { + str += " " + allocation.getKey().getName() + ": " + allocation.getValue().getJobName() + "\n"; + } + return str; + } + public String details() { String takenJobsString = ""; diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java b/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java index 90673b1..4cdccf0 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java @@ -1,21 +1,27 @@ package xyz.valnet.hadean.gameobjects; +import static xyz.valnet.engine.util.Math.*; + import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; +import xyz.valnet.engine.graphics.IModalUI; import xyz.valnet.engine.graphics.ImmediateUI; import xyz.valnet.engine.scenegraph.ITransient; +import xyz.valnet.hadean.Constants; import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer; +import xyz.valnet.hadean.gameobjects.ui.ExclusivityManager; import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectionChangeListener; import xyz.valnet.hadean.util.Action; +import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Layers; import xyz.valnet.hadean.util.detail.Detail; -public class SelectionUI extends ImmediateUI implements ISelectionChangeListener, ITransient { +public class SelectionUI extends ImmediateUI implements ISelectionChangeListener, ITransient, IModalUI { private class SelectedByType extends HashMap, List> {} @@ -29,8 +35,11 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener private SelectionLayer selectionManager; private final int width = 300, height = 200; - private final int padding = 10; - private final int actionButtonSize = 100; + + private boolean opened = false; + private float openness = 0f; + + private ExclusivityManager exclusivityManager; // this will be null normally, but set if // a button has been pressed to update the selection. @@ -46,20 +55,39 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener } @Override - public void update(float dTime) { + public void fixedUpdate(float dTime) { + openness = lerp(openness, opened ? 1 : 0, dTime / Constants.animationSpeed); if(newSelection != null) { selectionManager.updateSelection(newSelection); newSelection = null; } + if(!opened && openness < 0.0001f && selected.size() > 0) { + resetCache(); + } + } + + private void resetCache() { + selected = new ArrayList(); + selectedByType.clear(); + selectedCount = selected.size(); + actions.clear(); } @Override public void selectionChanged(List newSelection) { + if(selected.size() != 0 && newSelection.size() != 0) { + Assets.sndBubble.play(); + } + + if(newSelection.size() == 0) { + close(); + return; + } + + resetCache(); selected = newSelection; - selectedByType.clear(); - selectedCount = newSelection.size(); - actions.clear(); + selectedCount = selected.size(); for(ISelectable selectable : newSelection) { Class clazz = selectable.getClass(); @@ -70,13 +98,14 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener actions.add(action); } - if(!selectedByType.containsKey(clazz)) { selectedByType.put(clazz, new ArrayList()); } selectedByType.get(clazz).add(selectable); } + + open(); } @Override @@ -84,11 +113,17 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener return Layers.GENERAL_UI; } + private int animate(int a, int b) { + return (int) Math.round(lerp(a, b, openness)); + } + @Override protected void gui() { - if(selected.isEmpty()) return; + // if(selected.isEmpty()) return; + if(!opened && openness <= 0.0001f) return; - window(padding, 576 - padding - height - BottomBar.bottomBarHeight, width, height, () -> { + // main window + window(animate(-width - 50, 0), 576 - height - BottomBar.bottomBarHeight + 1, width, height, () -> { if(selectedByType.size() == 1) { if(selectedCount == 1) { text(properName); @@ -121,8 +156,9 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener } }); - if(selectedByType.size() == 1) { - root(padding * 2 + width, 576 - 32 - padding - BottomBar.bottomBarHeight, 1000, 32, () -> { + // actions + window(width - 1, animate(576 + 50, 576 - 48 - BottomBar.bottomBarHeight + 1), 1024 - width + 1, 48, () -> { + if(selectedByType.size() == 1) { horizontal(() -> { for(Action action : actions) { if(button(action.name)) { @@ -133,8 +169,32 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener space(8); } }); - }); - } + } else { + space(8); + text(" Select an Item Type"); + } + }); } + + @Override + public void open() { + if(opened) return; + opened = true; + exclusivityManager.switchTo(this); + } + + @Override + public void close() { + if(!opened) return; + opened = false; + exclusivityManager.closeCurrent(); + selectionManager.clearSelection(); + } + + @Override + protected void connect() { + super.connect(); + exclusivityManager = get(ExclusivityManager.class); + } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Tile.java b/src/main/java/xyz/valnet/hadean/gameobjects/Tile.java index 1f16f5e..2746d83 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Tile.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Tile.java @@ -5,8 +5,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.math.Vector4i; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.hadean.gameobjects.worldobjects.FarmPlot; @@ -27,7 +27,7 @@ public class Tile extends WorldObject implements IWorkable { private static int greenSeed = (int)(Math.random() * 10000); private static int blueSeed = (int)(Math.random() * 10000); - private Vector4f color; + private Color color; private final int tileSelector = (int)Math.floor(Math.random() * 4); private boolean rocks = false; @@ -55,7 +55,7 @@ public class Tile extends WorldObject implements IWorkable { float green = (float) terrain.getNoise(greenSeed, pos.x * scale, pos.y * scale); float blue = (float) terrain.getNoise(blueSeed, pos.x * scale, pos.y * scale); - if(color == null) color = new Vector4f(red * 0.1f, 0.4f + green * 0.15f, blue * 0.05f, 1f); + if(color == null) color = new Color(red * 0.1f, 0.4f + green * 0.15f, blue * 0.05f, 1f); } @Override @@ -166,7 +166,7 @@ public class Tile extends WorldObject implements IWorkable { if(rocks) camera.draw(Layers.TILES, Assets.rocks, pos.x, pos.y); } if(tillLevel > 0f) { - Assets.flat.pushColor(Vector4f.opacity(tillLevel)); + Assets.flat.pushColor(Color.white.withAlpha(tillLevel)); camera.draw(Layers.TILES, Assets.farmPlot[tileSelector], pos.x, pos.y); Assets.flat.popColor(); } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/BuildLayer.java b/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/BuildLayer.java index a1bb684..4bf75b9 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/BuildLayer.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/BuildLayer.java @@ -3,8 +3,8 @@ package xyz.valnet.hadean.gameobjects.inputlayer; import java.util.List; import xyz.valnet.engine.App; +import xyz.valnet.engine.math.Box; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.IMouseCaptureArea; import xyz.valnet.engine.scenegraph.ITransient; @@ -121,8 +121,6 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi } } - - private Vector2i[] orderCoords(Vector2i a, Vector2i b) { return new Vector2i[] { new Vector2i(Math.min(a.x, b.x), Math.min(a.y, b.y)), @@ -132,8 +130,8 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi } @Override - public List getGuiBoxes() { - return List.of(active ? new Vector4f(0, 0, 1024, 576) : Vector4f.zero); + public List getGuiBoxes() { + return List.of(active ? new Box(0, 0, 1024, 576) : Box.none); } @Override diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/SelectionLayer.java b/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/SelectionLayer.java index 3e5509e..e40aa0d 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/SelectionLayer.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/SelectionLayer.java @@ -7,15 +7,15 @@ import java.util.List; import xyz.valnet.engine.App; import xyz.valnet.engine.graphics.Drawing; +import xyz.valnet.engine.math.Box; import xyz.valnet.engine.math.Vector2f; import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector4f; -import xyz.valnet.engine.math.Vector4i; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.IMouseCaptureArea; import xyz.valnet.engine.scenegraph.ITransient; import xyz.valnet.hadean.gameobjects.Camera; -import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab; +import xyz.valnet.hadean.gameobjects.ui.ExclusivityManager; import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectionChangeListener; import xyz.valnet.hadean.util.Assets; @@ -30,12 +30,9 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr private float animationAmplitude = 0.2f; private List listeners = new ArrayList(); - private BuildTab buildTab; - @Override public void start() { camera = get(Camera.class); - buildTab = get(BuildTab.class); } public void subscribe(ISelectionChangeListener listener) { @@ -92,13 +89,10 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr } if(initialCoords != null) { - Vector2i screenPos = camera.world2screen(initialCoords); - Assets.selectionFrame.draw(new Vector4i( - screenPos.x, - screenPos.y, - App.mouseX, - App.mouseY - ).toXYWH()); + camera.draw(Layers.AREA_SELECT_BOX, Assets.selectionFrame, Box.fromPoints( + initialCoords, + camera.getWorldMouse() + )); } } @@ -150,9 +144,6 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr } private void broadcastSelectionChanged() { - // Assets.sndSelectionChanged.play(); - if(selected.size() > 0) Assets.sndBubble.play(); - if(selected.size() == 0) Assets.sndCancel.play(); for(ISelectionChangeListener listener : listeners) { listener.selectionChanged(selected); @@ -189,8 +180,8 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr } @Override - public List getGuiBoxes() { - return List.of(new Vector4f(0, 0, 1000, 1000)); + public List getGuiBoxes() { + return List.of(new Box(0, 0, 10000, 10000)); } @Override @@ -201,6 +192,7 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr @Override public void mouseDown(int button) { if(!active) return; + if(isPaused()) return; if(button == 0) { if(initialCoords == null) { @@ -208,7 +200,7 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr } } else if (button == 1) { if(selected.size() == 0) { - buildTab.rightClickOnWorld(); + get(ExclusivityManager.class).backOrDefault(); } else { clearSelection(); } @@ -217,7 +209,7 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr public void clearSelection() { if(selected.size() == 0) return; - selected.clear(); + selected = new ArrayList(); broadcastSelectionChanged(); } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/ExclusivityManager.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/ExclusivityManager.java new file mode 100644 index 0000000..3e7771f --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/ExclusivityManager.java @@ -0,0 +1,67 @@ +package xyz.valnet.hadean.gameobjects.ui; + +import xyz.valnet.engine.graphics.IModalUI; +import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.engine.scenegraph.IKeyboardListener; +import xyz.valnet.engine.scenegraph.ITransient; +import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab; +import xyz.valnet.hadean.gameobjects.ui.tabs.MenuTab; +import xyz.valnet.hadean.util.Assets; + +public class ExclusivityManager extends GameObject implements ITransient, IKeyboardListener { + private IModalUI current = null; + + private boolean switching = false; + + private IModalUI defaultTab = null; + private IModalUI menuTab = null; + + public void switchTo(IModalUI tab) { + if(tab == current) return; + if(tab == null) { + closeCurrent(); + return; + } + Assets.sndBubble.play(); + switching = true; + if(current != null) current.close(); + current = tab; + current.open(); + switching = false; + } + + public void closeCurrent() { + if(switching) return; + if(current == null) return; + Assets.sndCancel.play(); + current.close(); + current = null; + } + + public void backOrDefault() { + if(current == null) switchTo(defaultTab); + else current.back(); + } + + private void backOrMenu() { + if(current == null) switchTo(menuTab); + else current.back(); + } + + @Override + protected void connect() { + defaultTab = get(BuildTab.class); + menuTab = get(MenuTab.class); + } + + @Override + public void keyPress(int code) { + if(code == 256) { // ESCAPE + backOrMenu(); + } + } + + @Override + public void keyRelease(int code) {} + +} diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/Popup.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/Popup.java index 7b6302a..4127be6 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/Popup.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/Popup.java @@ -1,6 +1,7 @@ package xyz.valnet.hadean.gameobjects.ui; import xyz.valnet.engine.graphics.ImmediateUI; +import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; public class Popup extends ImmediateUI { @@ -24,7 +25,7 @@ public class Popup extends ImmediateUI { text("But not this..."); if(button("Click Me!")) { - System.out.println("The Event!"); + DebugTab.log("The Event!"); } text("This after button..."); diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/BuildTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/BuildTab.java index 14e95f1..4d54b5a 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/BuildTab.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/BuildTab.java @@ -6,11 +6,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.GameObject; -import xyz.valnet.engine.scenegraph.IMouseCaptureArea; import xyz.valnet.hadean.designation.CutTreesDesignation; import xyz.valnet.hadean.designation.HaulItemDesignation; import xyz.valnet.hadean.gameobjects.BottomBar; @@ -22,9 +21,6 @@ import xyz.valnet.hadean.gameobjects.worldobjects.Stockpile; import xyz.valnet.hadean.gameobjects.worldobjects.constructions.Bed; import xyz.valnet.hadean.gameobjects.worldobjects.constructions.Quarry; import xyz.valnet.hadean.gameobjects.worldobjects.constructions.Wall; -import xyz.valnet.hadean.input.Button; -import xyz.valnet.hadean.input.IButtonListener; -import xyz.valnet.hadean.input.SimpleButton; import xyz.valnet.hadean.interfaces.BuildableMetadata; import xyz.valnet.hadean.interfaces.IBuildLayerListener; import xyz.valnet.hadean.interfaces.IBuildable; @@ -32,9 +28,6 @@ import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectionChangeListener; import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Layers; -import xyz.valnet.hadean.util.SmartBoolean; - -import static xyz.valnet.engine.util.Math.lerp; public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLayerListener { @@ -42,8 +35,6 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay private BuildLayer buildLayer; private Camera camera; - private boolean opened; - private int x, y; private int w, h; @@ -52,8 +43,6 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay private static transient Map> buildables = new HashMap>(); private transient BuildableRecord selectedBuildable = null; - private float openness = 0; - static { BuildTab.registerBuildable(HaulItemDesignation.class); BuildTab.registerBuildable(CutTreesDesignation.class); @@ -78,13 +67,13 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay try { BuildableMetadata annotation = clazz.getAnnotation(BuildableMetadata.class); if(annotation == null) { - System.out.println(clazz + " has no buildable data annotation"); + DebugTab.log(clazz + " has no buildable data annotation"); return; } Constructor constructor = (Constructor) clazz.getConstructor(); if(constructor.getParameterCount() != 0) { - System.out.println(clazz + " has no default constructor (no params)"); + DebugTab.log(clazz + " has no default constructor (no params)"); return; } @@ -92,7 +81,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay String name = annotation.name(); BuildableMetadata.Type type = annotation.type(); - System.out.println("Added " + category + " / " + name); + DebugTab.log("Added " + category + " / " + name); if(!buildables.containsKey(category)) buildables.put(category, new ArrayList()); @@ -109,12 +98,12 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay if(!opened || selectedBuildable == null) return; // draw the currently selected build item - Assets.flat.pushColor(new Vector4f(1f, 1f, 1f, 1.0f)); + Assets.flat.pushColor(Color.white); Vector2i topLeft = camera.world2screen(x, y); Assets.font.drawString(selectedBuildable.name, topLeft.x, topLeft.y - 20); - Assets.flat.swapColor(new Vector4f(1f, 1f, 1f, 0.6f)); + Assets.flat.swapColor(Color.white.withAlpha(0.6f)); camera.draw(Layers.BUILD_INTERACTABLE, Assets.selectionFrame, x, y, w, h); - Assets.flat.swapColor(new Vector4f(1f, 1f, 1f, 0.35f)); + Assets.flat.swapColor(Color.white.withAlpha(0.35f)); for(int i = 0; i < w; i ++) for(int j = 0; j < h; j ++) {{ camera.draw(Layers.BUILD_INTERACTABLE, Assets.checkerBoard, x + i, y + j); }} @@ -138,15 +127,11 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay } @Override - public void update(float dTime) { - openness = lerp(openness, opened ? 1 : 0, dTime / 20); - } - - public void rightClickOnWorld() { + public void back() { if(selectedBuildable != null) { selectBuildable(null); } else { - evoke(); + close(); } } @@ -179,7 +164,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay } building.buildAt(x1, y1, x2 - x1 + 1, y2 - y1 + 1); } catch (Exception e) { - System.out.println(e); + DebugTab.log(e); } } @@ -193,7 +178,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay } building.buildAt(x1, y1); } catch (Exception e) { - System.out.println(e); + DebugTab.log(e); } } @@ -209,30 +194,10 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay @Override public void selectionChanged(List selected) { if(selected.isEmpty()) return; - opened = false; + close(); } - @Override - public void evoke() { - if(opened) close(); - else open(); - } - - public void open() { - if(opened) return; - Assets.sndBubble.play(); - opened = true; - reset(); - } - - public void close() { - if(!opened) return; - Assets.sndCancel.play(); - opened = false; - buildLayer.deactiveate(); - } - - public void reset() { + private void reset() { selectBuildable(null); } @@ -246,22 +211,12 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay return "Build"; } - @Override - public float getLayer() { - return Layers.GENERAL_UI; - } - - @Override - public boolean isButtonClickSilent() { - return true; - } - public void gui() { - if(openness < 0.0001f) return; + if(!shouldRender()) return; int height = 8 + 16 + 8 + buildables.size() * (32 + 8); - window((int) lerp(-180, 0, openness), 576 - BottomBar.bottomBarHeight - height + 1, 150, height, () -> { + window(animate(-180, 0), 576 - BottomBar.bottomBarHeight - height + 1, 150, height, () -> { text("Build"); for(String category : buildables.keySet()) { @@ -276,7 +231,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay } }); - window(149, (int) lerp(576 + 50, 576 - BottomBar.bottomBarHeight - 16 - 32 + 1 - 24, openness), 875, 48 + 24, () -> { + window(149, animate(576 + 50, 576 - BottomBar.bottomBarHeight - 16 - 32 + 1 - 24), 875, 48 + 24, () -> { if(selectedCategory == null) { space(20); text(" Select a Category..."); @@ -294,4 +249,14 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IBuildLay }); }); } + + @Override + protected void onClose() { + buildLayer.deactiveate(); + } + + @Override + protected void onOpen() { + reset(); + } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/DebugTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/DebugTab.java index d2c118a..3f82522 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/DebugTab.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/DebugTab.java @@ -1,17 +1,84 @@ package xyz.valnet.hadean.gameobjects.ui.tabs; +import java.util.LinkedList; +import java.util.List; + +import xyz.valnet.engine.scenegraph.IKeyboardListener; import xyz.valnet.hadean.HadeanGame; +import xyz.valnet.hadean.gameobjects.BottomBar; -public class DebugTab extends Tab { +public class DebugTab extends Tab implements IKeyboardListener { - @Override - public void evoke() { - HadeanGame.debugView = !HadeanGame.debugView; - } + private int width = 250; + private static Runtime runtime = Runtime.getRuntime(); @Override public String getTabName() { - return "Toggle Debug"; + return "Debug"; } + @Override + protected void onClose() {} + + @Override + protected void onOpen() {} + + @Override + protected void gui() { + if(!shouldRender()) return; + + window(0, animate(-200, 0), 1024 - width + 1, 176, () -> { + for(int i = 10; i > logs.size(); i --) { + text(" "); + } + for(String str : logs) { + text(str); + } + }); + + window(animate(1050, 1024 - width), 0, width, 576 - BottomBar.bottomBarHeight + 1, () -> { + text("Debug"); + space(8); + + text(System.getProperty("java.runtime.name")); + space(8); + text(System.getProperty("java.version")); + space(8); + + long allocated = runtime.totalMemory(); + long max = runtime.maxMemory(); + + text("MEMORY: " + (int)((allocated / (double)max) * 100) + "% (" + (allocated / (1024 * 1024)) + "/" + (max / (1024 * 1024)) + "MB)"); + space(8); + + if(button("Debug: " + (HadeanGame.debugView ? "on" : "off"))) { + HadeanGame.debugView = !HadeanGame.debugView; + } + }); + + } + + private static List logs = new LinkedList(); + + public static void log(String str) { + logs.add(str); + while(logs.size() > 10) { + logs.remove(0); + } + } + + public static void log(Object obj) { + log(obj.toString()); + } + + @Override + public void keyPress(int code) { + if(code == 96) { // tilde + evoke(); + } + } + + @Override + public void keyRelease(int code) {} + } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/JobBoardTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/JobBoardTab.java index 818922b..f67a2e0 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/JobBoardTab.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/JobBoardTab.java @@ -1,75 +1,53 @@ package xyz.valnet.hadean.gameobjects.ui.tabs; -import static xyz.valnet.engine.util.Math.lerp; - -import java.util.ArrayList; -import java.util.List; - -import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.hadean.gameobjects.BottomBar; import xyz.valnet.hadean.gameobjects.JobBoard; -import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer; -import xyz.valnet.hadean.interfaces.ISelectable; -import xyz.valnet.hadean.interfaces.ISelectionChangeListener; -import xyz.valnet.hadean.util.Assets; -import xyz.valnet.hadean.util.Layers; -public class JobBoardTab extends Tab implements ISelectionChangeListener { +public class JobBoardTab extends Tab { - private SelectionLayer selection; private JobBoard jobBoard; - private boolean opened; - private float progress = 0f; - private float width = 200; - - private int padding = 10; + private int height = 200; @Override - public void render() { - Drawing.setLayer(Layers.GENERAL_UI); - float left = lerp(-width - padding, padding, progress); - Assets.uiFrame.draw((int) left, padding, (int) width, 576 - padding * 2 - BottomBar.bottomBarHeight); - Assets.font.drawString(jobBoard.details(), (int) left + padding, padding * 2); + protected void gui() { + if(!shouldRender()) return; + + window(0, animate(576 + 50, 576 - BottomBar.bottomBarHeight - height + 1), 1024, height, () -> { + horizontal(() -> { + vertical(() -> { + text("Valid"); + text(jobBoard.getValidJobs()); + }); + space(32); + vertical(() -> { + text("Invalid"); + text(jobBoard.getInvalidJobs()); + }); + space(32); + vertical(() -> { + text("Taken"); + text(jobBoard.getTakenJobs()); + }); + }); + + }); } @Override protected void connect() { super.connect(); - selection = get(SelectionLayer.class); jobBoard = get(JobBoard.class); } - @Override - public void start() { - super.start(); - opened = false; - if(selection != null) selection.subscribe(this); - - } - - @Override - public void update(float dTime) { - progress = lerp(progress, opened ? 1 : 0, 0.05f); - } - - @Override - public void selectionChanged(List selected) { - if(selected.isEmpty()) return; - opened = false; - } - - @Override - public void evoke() { - opened = !opened; - - if(opened) { - selection.updateSelection(new ArrayList()); - } - } - @Override public String getTabName() { - return "Jobs"; + return "Work"; } + + @Override + protected void onClose() { } + + @Override + protected void onOpen() { } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/LoadTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/LoadTab.java deleted file mode 100644 index 4b38cde..0000000 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/LoadTab.java +++ /dev/null @@ -1,15 +0,0 @@ -package xyz.valnet.hadean.gameobjects.ui.tabs; - -public class LoadTab extends Tab { - - @Override - public void evoke() { - load(); - } - - @Override - public String getTabName() { - return "Load"; - } - -} diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/MenuTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/MenuTab.java new file mode 100644 index 0000000..c773171 --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/MenuTab.java @@ -0,0 +1,63 @@ +package xyz.valnet.hadean.gameobjects.ui.tabs; + +import xyz.valnet.engine.scenegraph.IPauser; + +public class MenuTab extends Tab implements IPauser { + + private int width = 300; + private int height = 6 * 32 + 1 * 16 + 6 * 8 + 2 * 24; + + @Override + protected void onClose() { + + } + + @Override + protected void onOpen() { + + } + + @Override + protected void gui() { + window(1024 / 2 - width / 2, animate(-height - 50, 576 / 2 - height / 2), width, height, () -> { + text(" === Paused ==="); + space(8); + if(button("Resume")) { + close(); + } + space(24); + if(button("Options")) { + + } + space(8); + if(button("Save")) { + save(); + close(); + } + space(8); + if(button("Load")) { + load(); + close(); + } + space(24); + if(button("Quit to Menu")) { + + } + space(8); + if(button("Quit to Desktop")) { + + } + }); + } + + @Override + public String getTabName() { + return "Menu"; + } + + @Override + public boolean isPaused() { + return opened; + } + +} \ No newline at end of file diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/SaveTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/SaveTab.java deleted file mode 100644 index 52b5ec1..0000000 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/SaveTab.java +++ /dev/null @@ -1,15 +0,0 @@ -package xyz.valnet.hadean.gameobjects.ui.tabs; - -public class SaveTab extends Tab { - - @Override - public void evoke() { - save(); - } - - @Override - public String getTabName() { - return "Save"; - } - -} diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/Tab.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/Tab.java index 27b533c..ca705b7 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/Tab.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/tabs/Tab.java @@ -1,17 +1,34 @@ package xyz.valnet.hadean.gameobjects.ui.tabs; +import static xyz.valnet.engine.util.Math.lerp; + +import xyz.valnet.engine.graphics.IModalUI; import xyz.valnet.engine.graphics.ImmediateUI; import xyz.valnet.engine.scenegraph.ITransient; +import xyz.valnet.hadean.Constants; import xyz.valnet.hadean.gameobjects.BottomBar; +import xyz.valnet.hadean.gameobjects.ui.ExclusivityManager; import xyz.valnet.hadean.interfaces.IBottomBarItem; +import xyz.valnet.hadean.util.Layers; -public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransient { +public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransient, IModalUI { private BottomBar bottombar; + protected boolean opened = false; + private float animation = 0f; + + private ExclusivityManager exclusivityManager; + + @Override + public void fixedUpdate(float dTime) { + animation = lerp(animation, opened ? 1 : 0, dTime / Constants.animationSpeed); + } + @Override protected void connect() { bottombar = get(BottomBar.class); + exclusivityManager = get(ExclusivityManager.class); } @Override @@ -20,9 +37,45 @@ public abstract class Tab extends ImmediateUI implements IBottomBarItem, ITransi } @Override - public boolean isButtonClickSilent() { - return false; + public final boolean isButtonClickSilent() { + return true; } - public void gui() {} + @Override + public final float getLayer() { + return Layers.GENERAL_UI; + } + + protected final boolean shouldRender() { + return opened || animation > 0.0001f; + } + + protected final int animate(float a, float b) { + return (int) Math.round(lerp(a, b, animation)); + } + + @Override + public final void evoke() { + if(opened) close(); + else open(); + } + + @Override + public final void open() { + if(opened) return; + opened = true; + exclusivityManager.switchTo(this); + onOpen(); + } + + @Override + public final void close() { + if(!opened) return; + opened = false; + exclusivityManager.closeCurrent(); + onClose(); + } + + protected abstract void onClose(); + protected abstract void onOpen(); } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/FarmPlot.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/FarmPlot.java index 93c732b..d2f1245 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/FarmPlot.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/FarmPlot.java @@ -1,6 +1,6 @@ package xyz.valnet.hadean.gameobjects.worldobjects; -import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Vector4i; import xyz.valnet.hadean.gameobjects.Tile; import xyz.valnet.hadean.interfaces.BuildableMetadata; @@ -16,7 +16,7 @@ public class FarmPlot extends Buildable { public void renderAlpha() { if(!visible) return; Vector4i pos = getWorldPosition(); - Assets.flat.pushColor(new Vector4f(0.4f, 1f, 0.3f, 0.2f)); + Assets.flat.pushColor(new Color(0.4f, 1f, 0.3f, 0.2f)); camera.draw(Layers.GROUND, Assets.whiteBox, pos.x, pos.y, pos.z, pos.w); Assets.flat.popColor(); } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Rice.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Rice.java index a88d872..491bbe3 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Rice.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Rice.java @@ -1,7 +1,7 @@ package xyz.valnet.hadean.gameobjects.worldobjects; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.hadean.gameobjects.worldobjects.items.Item; import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Assets; @@ -20,7 +20,7 @@ public class Rice extends Item { Vector2i pos = getWorldPosition().xy(); camera.draw(Layers.AIR, Assets.riceBag, pos.x, pos.y); - Assets.flat.pushColor(Vector4f.black); + Assets.flat.pushColor(Color.black); Vector2i screeCoords = camera.world2screen(pos.x, pos.y); Assets.miniFont.drawString("123", (int)screeCoords.x, (int)screeCoords.y); Assets.flat.popColor(); diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Stockpile.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Stockpile.java index 1f40861..dec3f8a 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Stockpile.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Stockpile.java @@ -2,8 +2,8 @@ package xyz.valnet.hadean.gameobjects.worldobjects; import java.util.Set; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.math.Vector4i; import xyz.valnet.hadean.gameobjects.Tile; import xyz.valnet.hadean.interfaces.BuildableMetadata; @@ -24,7 +24,7 @@ public class Stockpile extends Buildable { public void renderAlpha() { if(!visible) return; Vector4i pos = getWorldPosition(); - Assets.flat.pushColor(new Vector4f(1f, 0.2f, 0.1f, 0.3f)); + Assets.flat.pushColor(new Color(1f, 0.2f, 0.1f, 0.3f)); camera.draw(Layers.TILES, Assets.whiteBox, pos.x, pos.y, pos.z, pos.w); Assets.flat.popColor(); } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/agents/Agent.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/agents/Agent.java index 0b594e2..31f2b29 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/agents/Agent.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/agents/Agent.java @@ -6,10 +6,10 @@ import static org.lwjgl.opengl.GL11.glEnd; import static org.lwjgl.opengl.GL11.glVertex3f; import static org.lwjgl.opengl.GL20.glVertexAttrib2f; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.math.Vector2f; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.shaders.SimpleShader; import xyz.valnet.hadean.HadeanGame; import xyz.valnet.hadean.gameobjects.Terrain; @@ -160,7 +160,7 @@ public abstract class Agent extends WorldObject implements ISelectable { public void renderAlpha() { if(!HadeanGame.debugView) return; Drawing.setLayer(Layers.GROUND_MARKERS); - Assets.flat.pushColor(Vector4f.opacity(0.6f)); + Assets.flat.pushColor(Color.white.withAlpha(0.6f)); if(path != null) { int count = 0; for(Node node : path) { @@ -184,15 +184,7 @@ public abstract class Agent extends WorldObject implements ISelectable { count ++; } - Assets.selectionFrame.draw( - camera.world2screen( - terrain.getTile( - path.getDestination().getPosition() - ) - .getWorldBox() - ) - .toXYWH() - ); + camera.draw(Layers.GROUND_MARKERS, Assets.selectionFrame, path.getDestination().getPosition().getTileBox()); } Assets.flat.popColor(); } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Bed.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Bed.java index 2ee2aa7..ac14300 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Bed.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Bed.java @@ -1,7 +1,7 @@ package xyz.valnet.hadean.gameobjects.worldobjects.constructions; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.hadean.gameobjects.Job; import xyz.valnet.hadean.gameobjects.JobBoard; import xyz.valnet.hadean.gameobjects.worldobjects.Buildable; @@ -53,7 +53,7 @@ public class Bed extends Buildable implements IItemReceiver, IWorkable { float p = work / maxWork; float b = 4; - Assets.flat.pushColor(new Vector4f(b, b, b, 0.5f)); + Assets.flat.pushColor(Color.grey(b).withAlpha(0.5f)); camera.draw(Layers.GROUND, Assets.bed, pos.x, pos.y, 1, 2); Assets.flat.popColor(); diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Quarry.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Quarry.java index 601421a..7989a0f 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Quarry.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Quarry.java @@ -1,7 +1,7 @@ package xyz.valnet.hadean.gameobjects.worldobjects.constructions; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.hadean.gameobjects.Job; import xyz.valnet.hadean.gameobjects.JobBoard; import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder; @@ -14,7 +14,6 @@ import xyz.valnet.hadean.util.Layers; @BuildableMetadata(category = "Buildings", name = "Quarry", type = BuildableMetadata.Type.SINGLE) public class Quarry extends Construction { - private float work = 0; private Job digJob = null; @Override @@ -29,7 +28,7 @@ public class Quarry extends Construction { } else { float b = 4; - Assets.flat.pushColor(new Vector4f(b, b, b, 0.5f)); + Assets.flat.pushColor(Color.grey(b).withAlpha(0.5f)); camera.draw(Layers.GROUND, Assets.quarry, getWorldPosition()); Assets.flat.popColor(); @@ -49,9 +48,6 @@ public class Quarry extends Construction { if (digJob != null) return; if (terrain.getTile(getWorldPosition().xy().south().east()).has(Boulder.class)) return; - - System.out.println("Dig job?"); - digJob = get(JobBoard.class) .postSimpleWorkJob("Mine at Quarry", new IWorkable() { diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Wall.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Wall.java index 75f1aa5..25dc9c8 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Wall.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Wall.java @@ -2,9 +2,9 @@ package xyz.valnet.hadean.gameobjects.worldobjects.constructions; import java.util.EnumSet; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.graphics.Tile16.Direction; import xyz.valnet.engine.math.Vector2i; -import xyz.valnet.engine.math.Vector4f; import xyz.valnet.hadean.HadeanGame; import xyz.valnet.hadean.gameobjects.Job; import xyz.valnet.hadean.gameobjects.JobBoard; @@ -58,14 +58,14 @@ public class Wall extends Buildable implements IItemReceiver, IWorkable, IPingab if(isBuilt()) { float b = 0.7f; - Assets.flat.pushColor(new Vector4f(b, b, b, 1f)); + Assets.flat.pushColor(Color.grey(b)); camera.draw(Layers.GROUND, Assets.wall.getTextureFor(wallSides), pos.x, pos.y); Assets.flat.popColor(); } else { float p = work / maxWork; float b = 4; - Assets.flat.pushColor(new Vector4f(b, b, b, 0.5f)); + Assets.flat.pushColor(Color.grey(b).withAlpha(0.5f)); camera.draw(Layers.GROUND, Assets.wall.getTextureFor(wallSides), pos.x, pos.y); Assets.flat.popColor(); diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/pawn/Pawn.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/pawn/Pawn.java index 94195f5..644ea43 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/pawn/Pawn.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/pawn/Pawn.java @@ -5,6 +5,7 @@ import static xyz.valnet.hadean.util.detail.Detail.*; import java.util.ArrayList; import java.util.List; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.math.Vector2f; import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector4f; @@ -111,9 +112,9 @@ public class Pawn extends Agent { public void render() { super.render(); if(currentActivity instanceof SleepActivity) { - Assets.flat.pushColor(new Vector4f(0.5f, 0.5f, 0.5f, 1.0f)); + Assets.flat.pushColor(Color.grey(0.5f)); } else { - Assets.flat.pushColor(Vector4f.one); + Assets.flat.pushColor(Color.white); } camera.draw(Layers.PAWNS, Assets.pawn, getCalculatedPosition()); Assets.flat.popColor(); diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/pawn/SleepActivity.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/pawn/SleepActivity.java index ef83ffc..166a511 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/pawn/SleepActivity.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/pawn/SleepActivity.java @@ -29,7 +29,7 @@ public class SleepActivity extends Activity { // as it will induce oversleep WeightedAverage average = new WeightedAverage(); average.add(needs.getSleepNeed(), 1); - // System.out.println(1 - 2 * clock.getSunlight()); + average.add(1 - 2 * clock.getSunlight(), circadianStrength); return average.calculate(); } diff --git a/src/main/java/xyz/valnet/hadean/input/Button.java b/src/main/java/xyz/valnet/hadean/input/Button.java index 445bf62..2f30861 100644 --- a/src/main/java/xyz/valnet/hadean/input/Button.java +++ b/src/main/java/xyz/valnet/hadean/input/Button.java @@ -4,9 +4,10 @@ import static xyz.valnet.engine.util.Math.*; import java.util.List; +import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.graphics.Tile9; -import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.engine.math.Box; import xyz.valnet.engine.math.Vector4i; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.IMouseCaptureArea; @@ -80,10 +81,10 @@ public class Button extends GameObject implements IMouseCaptureArea, ITransient Assets.uiFrame.draw(box.x, box.y, box.z, box.w); } - Assets.flat.pushColor(Vector4f.black); + Assets.flat.pushColor(Color.black); Assets.font.drawString(text, 1 + x + (width - textWidth) / 2, 1 + y + (height - textHeight) / 2); - Assets.flat.swapColor(Vector4f.one); + Assets.flat.swapColor(Color.white); Assets.font.drawString(text, x + (width - textWidth) / 2, y + (height - textHeight) / 2); Assets.flat.popColor(); @@ -123,12 +124,8 @@ public class Button extends GameObject implements IMouseCaptureArea, ITransient private IButtonListener listener = null; - public void update() { - update(1); - } - @Override - public void update(float dTime) { + public void fixedUpdate(float dTime) { box.x = x - (int)hPad; box.y = y - (int)vPad; box.z = width + ((int)hPad) * 2; @@ -224,8 +221,8 @@ public class Button extends GameObject implements IMouseCaptureArea, ITransient } @Override - public List getGuiBoxes() { - return List.of(new Vector4f(x, y, width, height)); + public List getGuiBoxes() { + return List.of(new Box(x, y, width, height)); } @Override diff --git a/src/main/java/xyz/valnet/hadean/scenes/GameScene.java b/src/main/java/xyz/valnet/hadean/scenes/GameScene.java index 5a5cdbe..b65f14d 100644 --- a/src/main/java/xyz/valnet/hadean/scenes/GameScene.java +++ b/src/main/java/xyz/valnet/hadean/scenes/GameScene.java @@ -10,13 +10,12 @@ import xyz.valnet.hadean.gameobjects.SelectionUI; import xyz.valnet.hadean.gameobjects.Terrain; import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer; import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer; +import xyz.valnet.hadean.gameobjects.ui.ExclusivityManager; import xyz.valnet.hadean.gameobjects.ui.HoverQuery; -import xyz.valnet.hadean.gameobjects.ui.Popup; import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab; -import xyz.valnet.hadean.gameobjects.ui.tabs.JobBoardTab; -import xyz.valnet.hadean.gameobjects.ui.tabs.LoadTab; import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; -import xyz.valnet.hadean.gameobjects.ui.tabs.SaveTab; +import xyz.valnet.hadean.gameobjects.ui.tabs.JobBoardTab; +import xyz.valnet.hadean.gameobjects.ui.tabs.MenuTab; import xyz.valnet.hadean.gameobjects.worldobjects.pawn.Pawn; // TODO BIG IDEAS @@ -53,11 +52,11 @@ public class GameScene extends SceneGraph { objects.add(new HoverQuery()); objects.add(new BottomBar()); + objects.add(new ExclusivityManager()); objects.add(new BuildTab()); objects.add(new JobBoardTab()); objects.add(new DebugTab()); - objects.add(new SaveTab()); - objects.add(new LoadTab()); + objects.add(new MenuTab()); // objects.add(new Popup()); diff --git a/src/main/java/xyz/valnet/hadean/scenes/MenuScene.java b/src/main/java/xyz/valnet/hadean/scenes/MenuScene.java deleted file mode 100644 index 6c56576..0000000 --- a/src/main/java/xyz/valnet/hadean/scenes/MenuScene.java +++ /dev/null @@ -1,100 +0,0 @@ -package xyz.valnet.hadean.scenes; - -import xyz.valnet.engine.math.Vector4f; -import xyz.valnet.engine.scenegraph.IScene; -import xyz.valnet.hadean.input.Button; -import xyz.valnet.hadean.input.IButtonListener; -import xyz.valnet.hadean.util.Assets; -import xyz.valnet.hadean.util.Layers; - -import static xyz.valnet.hadean.HadeanGame.Hadean; - -// TODO convert this to a scenegraph -public class MenuScene implements IScene, IButtonListener { - - private Button btnNewGame = new Button(Assets.frame, "New Game", 50, 200, 128, 32, Layers.GENERAL_UI); - private Button btnLoadGame = new Button(Assets.frame, "Load Game", 50, 240, 128, 32, Layers.GENERAL_UI); - private Button btnOptions = new Button(Assets.frame, "Options", 50, 280, 128, 32, Layers.GENERAL_UI); - private Button btnQuit = new Button(Assets.frame, "Quit", 50, 320, 128, 32, Layers.GENERAL_UI); - - public MenuScene() { - btnNewGame.registerClickListener(this); - btnLoadGame.registerClickListener(this); - btnOptions.registerClickListener(this); - btnQuit.registerClickListener(this); - } - - public Vector4f green = new Vector4f(0.0f, 1.0f, 0.2f, 1.0f); - public Vector4f cyan = new Vector4f(0.1f, 0.7f, 1.0f, 1.0f); - public Vector4f yellow = new Vector4f(1.0f, 1.0f, 0.0f, 1.0f); - public Vector4f red = new Vector4f(1.0f, 0.1f, 0.1f, 1.0f); - - @Override - public void render() { - Assets.flat.pushColor(green); - btnNewGame.render(); - Assets.flat.swapColor(cyan); - btnLoadGame.render(); - Assets.flat.swapColor(yellow); - btnOptions.render(); - Assets.flat.swapColor(red); - btnQuit.render(); - Assets.flat.popColor(); - } - - @Override - public void update(float dTime) { - // btnNewGame.setMouseCoords(App.mouseX, App.mouseY); - // btnLoadGame.setMouseCoords(App.mouseX, App.mouseY); - // btnOptions.setMouseCoords(App.mouseX, App.mouseY); - // btnQuit.setMouseCoords(App.mouseX, App.mouseY); - btnNewGame.update(); - btnLoadGame.update(); - btnOptions.update(); - btnQuit.update(); - } - - @Override - public void click(Button target) { - if(target == btnNewGame) { - newGame(); - } else if(target == btnQuit) { - quit(); - } - } - - private void newGame() { - Hadean.changeScene(new GameScene()); - } - - private void quit() { - - } - - @Override - public void enable() { - - } - - @Override - public void disable() { - - } - - @Override - public void mouseDown(int button) { - btnNewGame.mouseDown(button); - btnLoadGame.mouseDown(button); - btnOptions.mouseDown(button); - btnQuit.mouseDown(button); - } - - @Override - public void mouseUp(int button) { - btnNewGame.mouseUp(button); - btnLoadGame.mouseUp(button); - btnOptions.mouseUp(button); - btnQuit.mouseUp(button); - } - -} diff --git a/src/main/java/xyz/valnet/hadean/util/Assets.java b/src/main/java/xyz/valnet/hadean/util/Assets.java index d952e28..81d290a 100644 --- a/src/main/java/xyz/valnet/hadean/util/Assets.java +++ b/src/main/java/xyz/valnet/hadean/util/Assets.java @@ -11,13 +11,13 @@ import xyz.valnet.engine.graphics.Tile9; import xyz.valnet.engine.math.Vector4i; import xyz.valnet.engine.shaders.SimpleShader; import xyz.valnet.engine.sound.Sound; +import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; public class Assets { public static final Sound sndBubble; public static final Sound sndCancel; public static final Sound sndGlassTap; - public static final Sound sndSelectionChanged; public static final Texture atlas; public static final Font font; @@ -59,7 +59,7 @@ public class Assets { public static final SimpleShader flat; static { - System.out.println("=== [ LOADING ASSETS ] ==="); + DebugTab.log("=== [ LOADING ASSETS ] ==="); flat = new SimpleShader("res/shaders/flat.vert", "res/shaders/flat.frag"); atlas = new Texture("res/textures.png"); @@ -316,12 +316,11 @@ public class Assets { wall = new Tile16(atlas, new Vector4i(0, 17 * 8, 32, 32)); - sndSelectionChanged = new Sound("res/sounds/leohpaz/retro-rpg-menu-sounds/079_Buy_sell_01.ogg"); sndBubble = new Sound("res/sounds/p0ss/interface-sounds/appear-online.ogg"); // sndCancel = new Sound("res/sounds/Listener/botton-sound-pack/cancel.ogg").setVolume(2f); sndCancel = new Sound("res/sounds/leohpaz/retro-rpg-menu-sounds/098_Unpause_04.ogg").setVolume(0.8f); sndGlassTap = new Sound("res/sounds/p0ss/interface-sounds/click5.ogg").setVolume(0.2f); - System.out.println("=== [ ASSETS LOADED ] ==="); + DebugTab.log("=== [ ASSETS LOADED ] ==="); } } diff --git a/src/main/java/xyz/valnet/hadean/util/Layers.java b/src/main/java/xyz/valnet/hadean/util/Layers.java index c522492..207971e 100644 --- a/src/main/java/xyz/valnet/hadean/util/Layers.java +++ b/src/main/java/xyz/valnet/hadean/util/Layers.java @@ -20,5 +20,6 @@ public class Layers { public static final float GENERAL_UI = current ++; public static final float GENERAL_UI_INTERACTABLE = current ++; public static final float BOTTOM_BAR = current ++; - + public static final float PAUSE_MENU = current ++; + public static final float CONSOLE = current ++; }