diff --git a/res/textures.png b/res/textures.png index 8a3adc8..c7a9111 100644 Binary files a/res/textures.png and b/res/textures.png differ diff --git a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java index 4ab30f1..56688bd 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java @@ -10,7 +10,11 @@ public class GameObject implements IRenderable, ITickable { } public boolean inScene() { - return scene.inScene(this); + return scene != null && scene.inScene(this); + } + + protected void dumpScene() { + scene.dump(); } protected T get(Class clazz) { @@ -22,11 +26,18 @@ public class GameObject implements IRenderable, ITickable { } protected final void add(GameObject obj) { + if(obj.inScene()) { + System.out.println(obj + " is already in the scene. not adding twice..."); + return; + } scene.add(obj); } @Override public void render() {} + + @Override + public void renderAlpha() {} @Override public void update(float dTime) {} diff --git a/src/main/java/xyz/valnet/engine/scenegraph/IRenderable.java b/src/main/java/xyz/valnet/engine/scenegraph/IRenderable.java index 0a39453..e776521 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/IRenderable.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/IRenderable.java @@ -2,4 +2,5 @@ package xyz.valnet.engine.scenegraph; public interface IRenderable { public void render(); + public void renderAlpha(); } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java b/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java index f4cafbe..c2a5726 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java @@ -43,10 +43,6 @@ public abstract class SceneGraph implements IScene { added.add(obj); } newObjects.clear(); - - for(GameObject obj : added) { - obj.start(); - } } // REMOVE OBJECTS @@ -110,6 +106,9 @@ public abstract class SceneGraph implements IScene { for(GameObject obj : objects) { obj.render(); } + for(GameObject obj : objects) { + obj.renderAlpha(); + } } protected abstract void construct(); @@ -123,6 +122,7 @@ public abstract class SceneGraph implements IScene { public void add(GameObject obj) { newObjects.add(obj); obj.link(this); + obj.start(); } public void remove(GameObject obj) { @@ -130,7 +130,12 @@ public abstract class SceneGraph implements IScene { } public boolean inScene(GameObject gameObject) { - return objects.contains(gameObject); + return objects.contains(gameObject) || newObjects.contains(gameObject); + } + + public void dump() { + for(GameObject go : objects) + System.out.println(go); } @Override diff --git a/src/main/java/xyz/valnet/engine/shaders/SimpleShader.java b/src/main/java/xyz/valnet/engine/shaders/SimpleShader.java index 7888428..156d518 100644 --- a/src/main/java/xyz/valnet/engine/shaders/SimpleShader.java +++ b/src/main/java/xyz/valnet/engine/shaders/SimpleShader.java @@ -27,6 +27,10 @@ public class SimpleShader extends Shader { popColor(); pushColor(color); } + + public void clearColorStack() { + colorStack.clear(); + } public void popColor() { colorStack.pop(); diff --git a/src/main/java/xyz/valnet/hadean/HadeanGame.java b/src/main/java/xyz/valnet/hadean/HadeanGame.java index 3b8b643..3f087d9 100644 --- a/src/main/java/xyz/valnet/hadean/HadeanGame.java +++ b/src/main/java/xyz/valnet/hadean/HadeanGame.java @@ -1,5 +1,12 @@ package xyz.valnet.hadean; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + import xyz.valnet.engine.App; import xyz.valnet.engine.Game; import xyz.valnet.engine.graphics.Drawing; diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/JobBoard.java b/src/main/java/xyz/valnet/hadean/gameobjects/JobBoard.java index 2a14164..ab01de6 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/JobBoard.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/JobBoard.java @@ -83,7 +83,7 @@ public class JobBoard extends GameObject { if(workables.size() > 0) { for(IJob job : workables) { if(!job.hasWork()) continue; - Vector2i[] workablePositions = job.getWorablePositions(); + Vector2i[] workablePositions = job.getWorkablePositions(); Path bestPathToJob = pathfinder.getBestPath( new Vector2i((int)Math.floor(workerLocation.x), (int)Math.floor(workerLocation.y)), workablePositions diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java b/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java index 8e1467c..1281512 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java @@ -173,12 +173,10 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener, @Override public void mouseEnter() { - } @Override public void mouseLeave() { - } @Override diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Stockpile.java b/src/main/java/xyz/valnet/hadean/gameobjects/Stockpile.java index 933fd9d..dc4387e 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Stockpile.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Stockpile.java @@ -12,11 +12,6 @@ public class Stockpile extends WorldObject implements ITileThing, ISelectable { private WorldObject thing; - public Stockpile(int x, int y) { - this.x = x; - this.y = y; - } - public boolean isFree() { return thing == null; } @@ -59,11 +54,5 @@ public class Stockpile extends WorldObject implements ITileThing, ISelectable { public String details() { return ""; } - - @Override - public void updatePosition(int x, int y) { - this.x = x; - this.y = y; - } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Tile.java b/src/main/java/xyz/valnet/hadean/gameobjects/Tile.java index ac45f52..7bde8ee 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Tile.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Tile.java @@ -35,7 +35,7 @@ public class Tile extends GameObject { public void start() { camera = get(Camera.class); - if(Math.random() > 0.9) { + if(Math.random() > 0.97) { Tree tree = new Tree(x, y); stuff.add(tree); add(tree); @@ -49,7 +49,6 @@ public class Tile extends GameObject { } public void placeThing(ITileThing thing) { - thing.updatePosition(x, y); stuff.add(thing); if(thing instanceof GameObject) { add((GameObject)thing); 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 7ba83fe..06a467d 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/BuildLayer.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/BuildLayer.java @@ -35,7 +35,6 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea { @Override public void render() { if(mouseDown && active) { - Assets.selectionFrame.draw(screenX, screenY, App.mouseX - screenX, App.mouseY - screenY); camera.screen2world(App.mouseX, App.mouseY); } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/tabs/BuildTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/tabs/BuildTab.java index 85d9c1e..b9e53ef 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/tabs/BuildTab.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/tabs/BuildTab.java @@ -2,11 +2,20 @@ package xyz.valnet.hadean.gameobjects.tabs; import static xyz.valnet.engine.util.Math.lerp; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.URL; import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; import java.util.List; +import java.util.Map; import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.IMouseCaptureArea; import xyz.valnet.hadean.gameobjects.BottomBar; import xyz.valnet.hadean.gameobjects.Camera; @@ -14,15 +23,21 @@ import xyz.valnet.hadean.gameobjects.Terrain; import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer; import xyz.valnet.hadean.gameobjects.inputlayer.Selection; import xyz.valnet.hadean.gameobjects.worldobjects.FarmPlot; +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; import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectionChangeListener; import xyz.valnet.hadean.interfaces.ITileThing; import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Layers; +import xyz.valnet.hadean.util.Pair; import xyz.valnet.hadean.util.SmartBoolean; -public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCaptureArea { +public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCaptureArea, IButtonListener { private Selection selection; private BuildLayer buildLayer; @@ -30,23 +45,70 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap private Terrain terrain; private SmartBoolean opened; - private float progress = 0f; - private float width = 200; + private int width = 200; private int padding = 10; private int x, y; private int w, h; + // private List categories = new ArrayList(); + + private String selectedCategory = "Zones"; + + private List> things = new ArrayList>(); + private Constructor selectedBuildable = null; + + private Map>>> buildables = new HashMap>>>(); + + private int height = 0; + + private void calculateBuildables() { + try { + Class[] maybeBuildables = getClasses("xyz.valnet.hadean"); + + for(Class clazz : maybeBuildables) { + if(clazz.isAnonymousClass()) continue; + if(!IBuildable.class.isAssignableFrom(clazz)) continue; + if(clazz.isInterface()) continue; + + Constructor constructor = clazz.getConstructor(); + if(constructor.getParameterCount() != 0) { + System.out.println(clazz + " has no default constructor (no params)"); + continue; + } + BuildableMetadata annotation = clazz.getAnnotation(BuildableMetadata.class); + if(annotation == null) { + System.out.println(clazz + " has no buildable data annotation"); + continue; + } + String category = annotation.category(); + String name = annotation.name(); + + if(!buildables.containsKey(category)) + buildables.put(category, new ArrayList>>()); + buildables.get(category).add(new Pair>(name, constructor)); + + selectedBuildable = constructor; + + System.out.println("Added " + category + " / " + name); + } + + } catch (Exception e) { + System.out.println(e); + } + + height = Math.max((int)Math.ceil(buildables.size() / 2f) * 24, 24*3); + } + @Override - public void render() { + public void renderAlpha () { 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); if(opened.value()) { + Assets.uiFrame.draw(padding, 576 - BottomBar.bottomBarHeight - padding - height, width, height); // draw the currently selected build item - Assets.flat.pushColor(new Vector4f(1f, 1f, 1f, 0.8f)); + Assets.flat.pushColor(new Vector4f(1f, 1f, 1f, 0.5f)); for(int i = 0; i < w; i ++) for(int j = 0; j < h; j ++) {{ camera.draw(Layers.BUILD_INTERACTABLE, Assets.stockpile, x + i, y + j); }} @@ -61,8 +123,32 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap selection = get(Selection.class); camera = get(Camera.class); terrain = get(Terrain.class); - - IBuildLayerListener buildListener = new IBuildLayerListener() { + + opened = new SmartBoolean(false, new SmartBoolean.IListener() { + + @Override + public void rise() { + activate(); + } + + @Override + public void fall() { + deactiveate(); + } + + }); + + if(selection != null) { + selection.subscribe(this); + } + + calculateBuildables(); + } + + private List