diff --git a/res/textures.png b/res/textures.png index e7b5641..311d258 100644 Binary files a/res/textures.png and b/res/textures.png differ diff --git a/src/main/java/xyz/valnet/engine/math/Vector2i.java b/src/main/java/xyz/valnet/engine/math/Vector2i.java index 80fe92d..9755b87 100644 --- a/src/main/java/xyz/valnet/engine/math/Vector2i.java +++ b/src/main/java/xyz/valnet/engine/math/Vector2i.java @@ -39,4 +39,20 @@ public class Vector2i implements Serializable { return new Vector2f(x, y); } + public Vector2i north() { + return new Vector2i(x, y - 1); + } + + public Vector2i east() { + return new Vector2i(x + 1, y); + } + + public Vector2i south() { + return new Vector2i(x, y + 1); + } + + public Vector2i west() { + return new Vector2i(x - 1, y); + } + } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java b/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java index 4cb7cc6..281757e 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java @@ -76,6 +76,10 @@ public class Camera extends GameObject { draw(layer, sprite, pos.x, pos.y, 1, 1); } + public void draw(float layer, Sprite sprite, Vector4i pos) { + draw(layer, sprite, pos.x, pos.y, pos.z, pos.w); + } + public void draw(float layer, Sprite sprite, float x, float y, float w, float h) { Vector2f screenPos = world2screen(x, y); Drawing.setLayer(layer + (((y + h) - minY) / (maxY - minY))); 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 417c6d8..75970ff 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/SelectionLayer.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/inputlayer/SelectionLayer.java @@ -115,6 +115,8 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr List selectables = getAll(ISelectable.class); + int prio = Integer.MIN_VALUE; + for(ISelectable thing : selectables) { Vector4f thingBox = thing.getWorldBox(); if(rectanglesIntersect( @@ -123,7 +125,18 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr thingBox.x, thingBox.y, thingBox.z, thingBox.w )) { - newSelection.add(thing); + System.out.println("Considering selecting " + thing); + int thingPrio = thing.getSelectPriority().toValue(); + if(thingPrio > prio) { + newSelection.clear(); + prio = thingPrio; + System.out.println("updated prio to " + prio); + System.out.println("List cleared"); + } + if(thingPrio >= prio) { + System.out.println("added " + thing); + newSelection.add(thing); + } } } 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 fb90606..acf356d 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 @@ -20,6 +20,7 @@ import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer; import xyz.valnet.hadean.gameobjects.worldobjects.FarmPlot; 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; @@ -62,6 +63,8 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap BuildTab.registerBuildable(Bed.class); BuildTab.registerBuildable(Wall.class); + + BuildTab.registerBuildable(Quarry.class); BuildTab.registerBuildable(FarmPlot.class); BuildTab.registerBuildable(Stockpile.class); diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Buildable.java b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Buildable.java index 4567862..009bc0e 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Buildable.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Buildable.java @@ -3,11 +3,14 @@ package xyz.valnet.hadean.gameobjects.worldobjects; import xyz.valnet.engine.math.Vector2i; import xyz.valnet.hadean.gameobjects.Tile; import xyz.valnet.hadean.interfaces.IBuildable; +import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ITileThing; +import xyz.valnet.hadean.util.Action; +import xyz.valnet.hadean.util.detail.Detail; -public abstract class Buildable extends WorldObject implements IBuildable, ITileThing { +public abstract class Buildable extends WorldObject implements IBuildable, ITileThing, ISelectable { - protected Vector2i getDefaultDimensions() { + protected Vector2i getDimensions() { return new Vector2i(1, 1); } @@ -18,10 +21,26 @@ public abstract class Buildable extends WorldObject implements IBuildable, ITile @Override public void buildAt(int x, int y) { - Vector2i dim = getDefaultDimensions(); + Vector2i dim = getDimensions(); setPosition(x, y, dim.x, dim.y); } @Override public void onPlaced(Tile tile) {} + + @Override + public Action[] getActions() { + // TODO Auto-generated method stub + return new Action[] {}; + } + + @Override + public void runAction(Action action) { + + } + + @Override + public Detail[] getDetails() { + return new Detail[] {}; + } } 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 ec318f2..1f40861 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Stockpile.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/Stockpile.java @@ -14,7 +14,7 @@ import xyz.valnet.hadean.util.Layers; import xyz.valnet.hadean.util.detail.Detail; @BuildableMetadata(category = "Zones", name = "Stockpile") -public class Stockpile extends Buildable implements ISelectable { +public class Stockpile extends Buildable { @Override public void render() { @@ -81,4 +81,8 @@ public class Stockpile extends Buildable implements ISelectable { @Override public void onPlaced(Tile tile) {} + @Override + public ISelectable.Priority getSelectPriority() { + return ISelectable.Priority.LOW; + } } 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 44e5d97..67b6653 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 @@ -203,6 +203,11 @@ public abstract class Agent extends WorldObject implements ISelectable { return new Action[0]; } + @Override + public ISelectable.Priority getSelectPriority() { + return ISelectable.Priority.HIGH; + } + public Vector2i getDestination() { if(nextPath != null) return nextPath.getDestination().getPosition(); if(path == null) return null; 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 15498d8..3c666fb 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 @@ -30,7 +30,7 @@ public class Bed extends Buildable implements IItemReceiver, IWorkable, ISelecta private Job job = null; @Override - protected Vector2i getDefaultDimensions() { + protected Vector2i getDimensions() { return new Vector2i(1, 2); } 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 new file mode 100644 index 0000000..ef74e1f --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/gameobjects/worldobjects/constructions/Quarry.java @@ -0,0 +1,143 @@ +package xyz.valnet.hadean.gameobjects.worldobjects.constructions; + +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; +import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder; +import xyz.valnet.hadean.interfaces.BuildableMetadata; +import xyz.valnet.hadean.interfaces.IWorkable; +import xyz.valnet.hadean.util.Assets; +import xyz.valnet.hadean.util.Layers; + +@BuildableMetadata(category = "Buildings", name = "Quarry", type = BuildableMetadata.Type.SINGLE) +public class Quarry extends Buildable { + + private float work = 0; + private static float MAX_WORK = 10000; + + private Job digJob = null; + + @Override + public void create() { + super.create(); + get(JobBoard.class).postSimpleWorkJob("Build Quarry", new IWorkable() { + @Override + public boolean doWork(float dTime) { + work += dTime; + return isBuilt(); + } + + @Override + public Vector2i[] getWorkablePositions() { + return new Vector2i[] { + getWorldPosition().xy().south().east() + }; + } + + @Override + public String getJobName() { + return "Build Quarry"; + } + }); + } + + @Override + public void render() { + if(isBuilt()) { + camera.draw(Layers.TILES, Assets.quarry, getWorldPosition()); + + if(digJob != null && !digJob.isCompleted()) { + camera.drawProgressBar(digProgress, getWorldBox()); + } + + } else { + float p = work / MAX_WORK; + float b = 4; + + Assets.flat.pushColor(new Vector4f(b, b, b, 0.5f)); + camera.draw(Layers.GROUND, Assets.quarry, getWorldPosition()); + Assets.flat.popColor(); + + camera.drawProgressBar(p, getWorldBox()); + } + } + + @Override + public Vector2i getDimensions() { + return new Vector2i(3, 3); + } + + private float digProgress = 0; + + private void tryCreateDigJob() { + if(!isBuilt()) return; + if (digJob != null) return; + if (terrain.getTile(getWorldPosition().xy().south().east()).has(Boulder.class)) return; + + digJob = get(JobBoard.class) + .postSimpleWorkJob("Mine at Quarry", new IWorkable() { + + private static float MAX_WORK = 5000; + private float work = 0; + + @Override + public boolean doWork(float dTime) { + work += dTime; + digProgress = work / MAX_WORK; + return work >= MAX_WORK; + } + + @Override + public Vector2i[] getWorkablePositions() { + return new Vector2i[] { + getWorldPosition().xy().south().east() + }; + } + + @Override + public String getJobName() { + return "Mine at Quarry"; + } + + }); + digJob.registerClosedListener(() -> { + digProgress = 0; + Vector2i dropPos = getWorldPosition().xy().south().east(); + Boulder boulder = new Boulder(dropPos.x, dropPos.y); + add(boulder); + boulder.runAction(Boulder.HAUL); + digJob = null; + }); + } + + @Override + public void update(float dTime) { + super.update(dTime); + tryCreateDigJob(); + } + + private boolean isBuilt() { + return work >= MAX_WORK; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public boolean shouldRemove() { + return false; + } + + @Override + public void onRemove() { + } + + @Override + public String getName() { + return "Quarry"; + } +} 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 a606a14..7d629ce 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 @@ -100,15 +100,10 @@ public class Wall extends Buildable implements IItemReceiver, IWorkable, ISelect private Vector2i[] getBorders() { Vector2i pos = getWorldPosition().xy(); return new Vector2i[] { - new Vector2i(pos.x, pos.y - 1), - - new Vector2i(pos.x - 1, pos.y), - new Vector2i(pos.x + 1, pos.y), - - new Vector2i(pos.x - 1, pos.y + 1), - new Vector2i(pos.x + 1, pos.y + 1), - - new Vector2i(pos.x, pos.y + 2), + pos.north(), + pos.east(), + pos.south(), + pos.west() }; } @@ -152,7 +147,7 @@ public class Wall extends Buildable implements IItemReceiver, IWorkable, ISelect @Override public boolean isWalkable() { - return false; + return isBuilt(); } @Override diff --git a/src/main/java/xyz/valnet/hadean/interfaces/ISelectable.java b/src/main/java/xyz/valnet/hadean/interfaces/ISelectable.java index aaaaff5..3a6bccd 100644 --- a/src/main/java/xyz/valnet/hadean/interfaces/ISelectable.java +++ b/src/main/java/xyz/valnet/hadean/interfaces/ISelectable.java @@ -5,9 +5,29 @@ import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.detail.Detail; public interface ISelectable { + + public enum Priority { + LOW(-10), + NORMAL(0), + HIGH(10); + + private int value; + + Priority(int value) { + this.value = value; + } + + public int toValue() { + return value; + } + } + public Vector4f getWorldBox(); public Action[] getActions(); public void runAction(Action action); public Detail[] getDetails(); public default void selectedRender() {} + public default Priority getSelectPriority() { + return Priority.NORMAL; + } } \ No newline at end of file diff --git a/src/main/java/xyz/valnet/hadean/interfaces/IWorkable.java b/src/main/java/xyz/valnet/hadean/interfaces/IWorkable.java index bdcef68..ae59cf4 100644 --- a/src/main/java/xyz/valnet/hadean/interfaces/IWorkable.java +++ b/src/main/java/xyz/valnet/hadean/interfaces/IWorkable.java @@ -1,8 +1,10 @@ package xyz.valnet.hadean.interfaces; +import java.io.Serializable; + import xyz.valnet.engine.math.Vector2i; -public interface IWorkable { +public interface IWorkable extends Serializable { public boolean doWork(float dTime); public Vector2i[] getWorkablePositions(); public String getJobName();