diff --git a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java index 1b21415..c3a9578 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java @@ -3,6 +3,7 @@ package xyz.valnet.engine.scenegraph; import java.io.Serializable; import java.util.List; +import xyz.valnet.engine.scenegraph.SceneGraph.GameObjectCallback; import xyz.valnet.hadean.util.Pair; public class GameObject implements IRenderable, ITickable, Serializable { @@ -91,4 +92,12 @@ public class GameObject implements IRenderable, ITickable, Serializable { protected Pair getFPS() { return scene.getFPS(); } + + protected void onAddGameObject(GameObjectCallback listener) { + scene.registerAddListener(listener); + } + + protected void onRemoveGameObject(GameObjectCallback listener) { + scene.registerRemoveListener(listener); + } } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java b/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java index a1772a1..130f69b 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/SceneGraph.java @@ -4,6 +4,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.Serializable; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; @@ -17,7 +18,6 @@ import java.util.stream.Collectors; import xyz.valnet.engine.App; import xyz.valnet.engine.Game; import xyz.valnet.engine.math.Box; -import xyz.valnet.hadean.HadeanGame; import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; import xyz.valnet.hadean.util.Pair; @@ -31,6 +31,22 @@ public abstract class SceneGraph implements IScene { private boolean loadFlag = false; private boolean saveFlag = false; + @FunctionalInterface + public interface GameObjectCallback extends Serializable { + public void apply(GameObject obj); + } + + private Set onAddListeners = new HashSet<>(); + private Set onRemoveListeners = new HashSet<>(); + + public void registerAddListener(GameObjectCallback cb) { + onAddListeners.add(cb); + } + + public void registerRemoveListener(GameObjectCallback cb) { + onRemoveListeners.add(cb); + } + public T get(Class clazz) { for(GameObject obj : objects) { if(clazz.isInstance(obj)) { @@ -52,7 +68,7 @@ public abstract class SceneGraph implements IScene { @Override public void update(float dTime) { - dTime = 1; + dTime = Math.min(dTime, 6); // ADD OBJECTS if(!newObjects.isEmpty()) { List added = new ArrayList(); @@ -155,6 +171,12 @@ public abstract class SceneGraph implements IScene { for(GameObject obj : objects) { obj.addedToScene(); } + + for(GameObject obj : objects) { + for(GameObjectCallback listener : onAddListeners) { + listener.apply(obj); + } + } } @Override @@ -180,6 +202,9 @@ public abstract class SceneGraph implements IScene { newObjects.add(obj); obj.link(this); obj.addedToScene(); + for(GameObjectCallback listener : onAddListeners) { + listener.apply(obj); + } addObjectToCache(obj); } @@ -191,6 +216,9 @@ public abstract class SceneGraph implements IScene { public void remove(GameObject obj) { removeObjects.add(obj); + for(GameObjectCallback listener : onRemoveListeners) { + listener.apply(obj); + } } public boolean inScene(GameObject gameObject) { diff --git a/src/main/java/xyz/valnet/engine/util/ClassToInstanceSet.java b/src/main/java/xyz/valnet/engine/util/ClassToInstanceSet.java new file mode 100644 index 0000000..a89fd6f --- /dev/null +++ b/src/main/java/xyz/valnet/engine/util/ClassToInstanceSet.java @@ -0,0 +1,27 @@ +package xyz.valnet.engine.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class ClassToInstanceSet { + private Map, Set> map = new HashMap<>(); + + private final void ensure(Class clazz) { + if(!map.containsKey(clazz)) { + map.put(clazz, new HashSet<>()); + } + } + + public void add(Class clazz, T obj) { + ensure(clazz); + var set = map.get(clazz); + set.add(obj); + } + + @SuppressWarnings("unchecked") // it IS checked, by way of the add method. + public final Set get(Class clazz) { + return (Set) map.get(clazz); + } +} 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 7d115fb..08e4349 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/BuildLayer.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/BuildLayer.java @@ -60,8 +60,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi private void broadcastWorldCoords() { Vector2i worldcoords = camera.getWorldMouse().asInt(); if(mouseDown) { - Vector2i[] ords = orderCoords(startingPoint, worldcoords); - listener.update(new Box(ords[0].x, ords[0].y, ords[2].x + 1, ords[2].y + 1)); + listener.update(Box.fromPoints(startingPoint, camera.getWorldMouse())); return; } if(type == BuildType.SINGLE && dimensions != null) { diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/ui/WorkshopOrdersUI.java b/src/main/java/xyz/valnet/hadean/gameobjects/ui/WorkshopOrdersUI.java new file mode 100644 index 0000000..814359e --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/gameobjects/ui/WorkshopOrdersUI.java @@ -0,0 +1,46 @@ +package xyz.valnet.hadean.gameobjects.ui; + +import xyz.valnet.engine.graphics.ImmediateUI; +import xyz.valnet.engine.scenegraph.ITransient; +import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer; +import xyz.valnet.hadean.interfaces.IWorkshop; + +public class WorkshopOrdersUI extends ImmediateUI implements ITransient { + + private IWorkshop shop; + private SelectionLayer selectionLayer; + + public void open(IWorkshop shop) { + this.shop = shop; + } + + public void close() { + this.shop = null; + } + + @Override + protected void gui() { + if(shop == null) return; + + window(0, 0, 200, 300, () -> { + text("stuff"); + }); + } + + @Override + protected void connect() { + super.connect(); + this.selectionLayer = get(SelectionLayer.class); + } + + @Override + protected void start() { + super.start(); + this.selectionLayer.subscribe((selection) -> { + if(!selection.contains(shop)) { + close(); + } + }); + } + +} diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/MasonWorkshop.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/MasonWorkshop.java index 927edfe..a14d6a1 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/MasonWorkshop.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/MasonWorkshop.java @@ -2,11 +2,17 @@ package xyz.valnet.hadean.gameobjects.worldobjects.constructions; import xyz.valnet.engine.graphics.Sprite; import xyz.valnet.engine.math.Vector2i; +import xyz.valnet.hadean.gameobjects.ui.WorkshopOrdersUI; import xyz.valnet.hadean.gameobjects.worldobjects.items.Log; import xyz.valnet.hadean.interfaces.IItemPredicate; +import xyz.valnet.hadean.interfaces.IWorkshop; +import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Assets; -public class MasonWorkshop extends Construction { +public class MasonWorkshop extends Construction implements IWorkshop { + + private static Action OPEN_ORDERS = new Action("Orders"); + private transient WorkshopOrdersUI ordersWindow; @Override protected IItemPredicate getBuildingMaterial() { @@ -37,5 +43,23 @@ public class MasonWorkshop extends Construction { public Vector2i getDimensions() { return new Vector2i(3, 3); } + + @Override + public Action[] getActions() { + return new Action[] { OPEN_ORDERS }; + } + + @Override + public void runAction(Action action) { + if(action == OPEN_ORDERS) { + ordersWindow.open(this); + } + } + + @Override + protected void connect() { + super.connect(); + ordersWindow = get(WorkshopOrdersUI.class); + } } diff --git a/src/main/java/xyz/valnet/hadean/interfaces/IWorkshop.java b/src/main/java/xyz/valnet/hadean/interfaces/IWorkshop.java new file mode 100644 index 0000000..33c6d00 --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/interfaces/IWorkshop.java @@ -0,0 +1,5 @@ +package xyz.valnet.hadean.interfaces; + +public interface IWorkshop { + +} diff --git a/src/main/java/xyz/valnet/hadean/scenes/GameScene.java b/src/main/java/xyz/valnet/hadean/scenes/GameScene.java index bef4735..26e340c 100644 --- a/src/main/java/xyz/valnet/hadean/scenes/GameScene.java +++ b/src/main/java/xyz/valnet/hadean/scenes/GameScene.java @@ -7,6 +7,7 @@ import xyz.valnet.hadean.gameobjects.Camera; import xyz.valnet.hadean.gameobjects.Clock; import xyz.valnet.hadean.gameobjects.jobs.JobBoard; import xyz.valnet.hadean.gameobjects.ui.SelectionUI; +import xyz.valnet.hadean.gameobjects.ui.WorkshopOrdersUI; import xyz.valnet.hadean.gameobjects.terrain.Terrain; import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer; import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer; @@ -43,12 +44,12 @@ public class GameScene extends SceneGraph { objects.add(new Pawn()); } + objects.add(new WorkshopOrdersUI()); objects.add(new SelectionLayer()); objects.add(new SelectionUI()); objects.add(new BuildLayer()); - objects.add(new HoverQuery()); objects.add(new BottomBar());