pawns now do work at work locations

shops
Ivory 2023-07-06 02:13:43 -04:00
parent 496ecd9796
commit f2f46acbb5
29 changed files with 193 additions and 198 deletions

10
pom.xml
View File

@ -14,8 +14,8 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>16</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<lwjgl.version>3.3.1</lwjgl.version> <lwjgl.version>3.3.1</lwjgl.version>
<jar.finalName>${project.name}</jar.finalName> <jar.finalName>${project.name}</jar.finalName>
</properties> </properties>
@ -143,6 +143,7 @@
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<configuration> <configuration>
<outputDirectory>output/${platform.name}/raw</outputDirectory> <outputDirectory>output/${platform.name}/raw</outputDirectory>
<archive> <archive>
<manifest> <manifest>
<addClasspath>true</addClasspath> <addClasspath>true</addClasspath>
@ -207,7 +208,10 @@
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version> <version>3.10.1</version>
<configuration>
<enablePreview>true</enablePreview>
</configuration>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-install-plugin</artifactId> <artifactId>maven-install-plugin</artifactId>

View File

@ -1,4 +1,4 @@
package xyz.valnet.hadean.designation; package xyz.valnet.hadean.designations;
import xyz.valnet.hadean.gameobjects.worldobjects.Tree; import xyz.valnet.hadean.gameobjects.worldobjects.Tree;

View File

@ -1,11 +1,11 @@
package xyz.valnet.hadean.designation; package xyz.valnet.hadean.designations;
import java.util.List; import java.util.List;
import xyz.valnet.engine.math.Box; import xyz.valnet.engine.math.Box;
import xyz.valnet.engine.math.TileBox; import xyz.valnet.engine.math.TileBox;
import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.interfaces.BuildType; import xyz.valnet.hadean.enums.BuildType;
import xyz.valnet.hadean.interfaces.IBuildable; import xyz.valnet.hadean.interfaces.IBuildable;
import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectable;

View File

@ -1,4 +1,4 @@
package xyz.valnet.hadean.designation; package xyz.valnet.hadean.designations;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item; import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;

View File

@ -1,4 +1,4 @@
package xyz.valnet.hadean.interfaces; package xyz.valnet.hadean.enums;
public enum BuildType { public enum BuildType {
AREA, AREA,

View File

@ -0,0 +1,13 @@
package xyz.valnet.hadean.enums;
public enum WorkType {
Construct("Construct"),
Farm("Till"),
Chop("Chop");
public final String verb;
private WorkType(String verb) {
this.verb = verb;
}
}

View File

@ -9,8 +9,8 @@ import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.engine.scenegraph.IMouseCaptureArea; import xyz.valnet.engine.scenegraph.IMouseCaptureArea;
import xyz.valnet.engine.scenegraph.ITransient; import xyz.valnet.engine.scenegraph.ITransient;
import xyz.valnet.hadean.enums.BuildType;
import xyz.valnet.hadean.gameobjects.Camera; import xyz.valnet.hadean.gameobjects.Camera;
import xyz.valnet.hadean.interfaces.BuildType;
import xyz.valnet.hadean.interfaces.IBuildLayerListener; import xyz.valnet.hadean.interfaces.IBuildLayerListener;
import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Assets;
import xyz.valnet.hadean.util.Layers; import xyz.valnet.hadean.util.Layers;

View File

@ -4,13 +4,16 @@ import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
import xyz.valnet.hadean.interfaces.IItemReceiver; import xyz.valnet.hadean.interfaces.IItemReceiver;
import xyz.valnet.hadean.interfaces.IWorkable; import xyz.valnet.hadean.interfaces.IWorkable;
public interface Job { // TODO create a subtype of job for jobs with
// locations so pawn can generically path to it
public sealed interface Job {
record Work( record Work(
IWorkable workable IWorkable workable
) implements Job { ) implements Job {
@Override @Override
public String getShortDescription() { public String getShortDescription() {
return workable.getWorkType().verb + " " + workable.getName(); return workable.getWorkType().verb + " " + workable.getWorkableName();
} }
} }

View File

@ -9,6 +9,7 @@ import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab;
import xyz.valnet.hadean.gameobjects.worldobjects.agents.pawn.Pawn; import xyz.valnet.hadean.gameobjects.worldobjects.agents.pawn.Pawn;
import xyz.valnet.hadean.interfaces.IWorkable; import xyz.valnet.hadean.interfaces.IWorkable;
@ -25,8 +26,7 @@ public class JobBoard extends GameObject {
public Job post(IWorkable workable) { public Job post(IWorkable workable) {
var job = new Job.Work(workable); var job = new Job.Work(workable);
availableJobs.add(job); return postJob(job);
return job;
} }
@ -81,6 +81,21 @@ public class JobBoard extends GameObject {
} }
} }
public class ENoJobsAvailable extends Error {}
public Job takeJob(Pawn worker) {
if(availableJobs.size() == 0) return null;
Job[] jobs = new Job[availableJobs.size()];
availableJobs.toArray(jobs);
Job job = jobs[(int) (Math.floor(Math.random() * jobs.length))];
DebugTab.log("" + worker.getName() + " took job: " + job.getShortDescription());
allocations.put(worker, job);
availableJobs.remove(job);
return job;
}
} }

View File

@ -12,6 +12,7 @@ public class SimpleWorkable implements IWorkable {
private float MAX_WORK = 0; private float MAX_WORK = 0;
private IProgressUpdateCallback callback; private IProgressUpdateCallback callback;
private IGetPositionsFunction positions; private IGetPositionsFunction positions;
private final WorkType workType;
@FunctionalInterface @FunctionalInterface
public interface IGetPositionsFunction extends Serializable { public interface IGetPositionsFunction extends Serializable {
@ -23,11 +24,12 @@ public class SimpleWorkable implements IWorkable {
public void progress(float progress); public void progress(float progress);
} }
public SimpleWorkable(String name, float maxWork, IGetPositionsFunction positionsFunction, IProgressUpdateCallback callback) { public SimpleWorkable(String name, float maxWork, WorkType type, IGetPositionsFunction positionsFunction, IProgressUpdateCallback callback) {
this.name = name; this.name = name;
this.MAX_WORK = maxWork; this.MAX_WORK = maxWork;
this.positions = positionsFunction; this.positions = positionsFunction;
this.callback = callback; this.callback = callback;
this.workType = type;
} }
@Override @Override
@ -43,8 +45,13 @@ public class SimpleWorkable implements IWorkable {
} }
@Override @Override
public final String getJobName() { public final String getWorkableName() {
return name; return name;
} }
@Override
public WorkType getWorkType() {
return workType;
}
} }

View File

@ -4,7 +4,6 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.graphics.Color;
import xyz.valnet.engine.math.TileBox;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.math.Vector4i; import xyz.valnet.engine.math.Vector4i;
import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
@ -61,7 +60,7 @@ public class Tile extends WorldObject implements IWorkable {
rocks = true; rocks = true;
} }
if(Math.random() > 0.97) { if(Math.random() > 0.97) {
// add(new Tree(pos.x, pos.y)); add(new Tree(pos.x, pos.y));
} else if(Math.random() > 0.98) { } else if(Math.random() > 0.98) {
rocks = false; rocks = false;
add(new Boulder(pos.x, pos.y)); add(new Boulder(pos.x, pos.y));
@ -89,7 +88,7 @@ public class Tile extends WorldObject implements IWorkable {
} }
public void pingThings() { public void pingThings() {
// TODO this is a quick lil workaround for a concurerncy issue. // this is a quick lil workaround for a concurerncy issue.
// just clone the items // just clone the items
for(var thing : new HashSet<IWorldObject>(stuff)) { for(var thing : new HashSet<IWorldObject>(stuff)) {
if(thing instanceof IPingable) { if(thing instanceof IPingable) {
@ -239,4 +238,9 @@ public class Tile extends WorldObject implements IWorkable {
public WorkType getWorkType() { public WorkType getWorkType() {
return WorkType.Farm; return WorkType.Farm;
} }
@Override
public String getWorkableName() {
return "Soil";
}
} }

View File

@ -77,11 +77,12 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener
private void updateActions() { private void updateActions() {
actions.clear(); actions.clear();
updateActionsFlag = false; updateActionsFlag = false;
for(ISelectable selectable : selected) for(ISelectable selectable : selected) {
for(Action action : selectable.getActions()) { for(Action action : selectable.getActions()) {
DebugTab.log(action.name); DebugTab.log(action.name);
actions.add(action); actions.add(action);
} }
}
} }
@Override @Override

View File

@ -11,9 +11,10 @@ import xyz.valnet.engine.graphics.Drawing;
import xyz.valnet.engine.math.TileBox; import xyz.valnet.engine.math.TileBox;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.designation.CutTreesDesignation;
import xyz.valnet.hadean.designation.HaulItemDesignation;
import xyz.valnet.hadean.gameobjects.ui.BottomBar; import xyz.valnet.hadean.gameobjects.ui.BottomBar;
import xyz.valnet.hadean.designations.CutTreesDesignation;
import xyz.valnet.hadean.designations.HaulItemDesignation;
import xyz.valnet.hadean.enums.BuildType;
import xyz.valnet.hadean.gameobjects.Camera; import xyz.valnet.hadean.gameobjects.Camera;
import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer; import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer;
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer; import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
@ -23,7 +24,6 @@ import xyz.valnet.hadean.gameobjects.worldobjects.constructions.Bed;
import xyz.valnet.hadean.gameobjects.worldobjects.constructions.MasonWorkshop; import xyz.valnet.hadean.gameobjects.worldobjects.constructions.MasonWorkshop;
import xyz.valnet.hadean.gameobjects.worldobjects.constructions.Quarry; import xyz.valnet.hadean.gameobjects.worldobjects.constructions.Quarry;
import xyz.valnet.hadean.gameobjects.worldobjects.constructions.Wall; import xyz.valnet.hadean.gameobjects.worldobjects.constructions.Wall;
import xyz.valnet.hadean.interfaces.BuildType;
import xyz.valnet.hadean.interfaces.IBuildLayerListener; import xyz.valnet.hadean.interfaces.IBuildLayerListener;
import xyz.valnet.hadean.interfaces.IBuildable; import xyz.valnet.hadean.interfaces.IBuildable;
import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectable;

View File

@ -2,6 +2,7 @@ package xyz.valnet.hadean.gameobjects.worldobjects;
import xyz.valnet.engine.math.Box; import xyz.valnet.engine.math.Box;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.enums.WorkType;
import xyz.valnet.hadean.gameobjects.jobs.Job; import xyz.valnet.hadean.gameobjects.jobs.Job;
import xyz.valnet.hadean.gameobjects.jobs.JobBoard; import xyz.valnet.hadean.gameobjects.jobs.JobBoard;
import xyz.valnet.hadean.gameobjects.terrain.Tile; import xyz.valnet.hadean.gameobjects.terrain.Tile;
@ -125,4 +126,9 @@ public class Tree extends WorldObject implements ISelectable, IWorkable {
public WorkType getWorkType() { public WorkType getWorkType() {
return WorkType.Chop; return WorkType.Chop;
} }
@Override
public String getWorkableName() {
return "Tree";
}
} }

View File

@ -67,16 +67,6 @@ public abstract class WorldObject extends GameObject implements IWorldObject {
linkedTiles.add(tile); linkedTiles.add(tile);
tile.placeThing(this); tile.placeThing(this);
} }
// ?? this shouldnt bew pivotal to anything?
// if(linkedTiles.size() == 0 && inScene()) {
// remove(this);
// }
// if(linkedTiles.size() != 0 && !inScene()) {
// add(this);
// }
} }
protected void setPosition(Vector4i vector) { protected void setPosition(Vector4i vector) {

View File

@ -16,6 +16,7 @@ import xyz.valnet.engine.shaders.SimpleShader;
import xyz.valnet.hadean.HadeanGame; import xyz.valnet.hadean.HadeanGame;
import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab;
import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject; import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject;
import xyz.valnet.hadean.interfaces.IDestinationProvider;
import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectable;
import xyz.valnet.hadean.pathfinding.AStarPathfinder; import xyz.valnet.hadean.pathfinding.AStarPathfinder;
import xyz.valnet.hadean.pathfinding.IPathfinder; import xyz.valnet.hadean.pathfinding.IPathfinder;
@ -58,11 +59,11 @@ public abstract class Agent extends WorldObject implements ISelectable {
// if we're STILL doing jack, but we have a destination // if we're STILL doing jack, but we have a destination
// try to path to that place // try to path to that place
if(dst != null) goTo(dst); if(dsts != null) goTo(dsts);
if(isAnimating()) return; if(isAnimating()) return;
// if all fails, tell the agent we're idle // if all fails, tell the agent we're idle
idle(); idle(dTime);
} }
// public void goTo(int x, int y) { // public void goTo(int x, int y) {
@ -77,14 +78,14 @@ public abstract class Agent extends WorldObject implements ISelectable {
path.pop(); path.pop();
if(path.isComplete()) { if(path.isComplete()) {
DebugTab.log("Finished Pathing"); DebugTab.log("Finished Pathing");
if(path.getDestination().getPosition().equals(dst)) { if(path.getDestination().getPosition().equals(dsts)) {
dst = null; dsts = null;
} }
path = null; path = null;
return; return;
} }
if(!getTile(path.peek().getPosition()).isWalkable()) { if(!getTile(path.peek().getPosition()).isWalkable()) {
goTo(dst); goTo(dsts);
return; return;
} }
updatePath(); updatePath();
@ -99,24 +100,25 @@ public abstract class Agent extends WorldObject implements ISelectable {
} }
private Path path; private Path path;
private Vector2i dst; private IDestinationProvider dsts;
public void stopPathing() { public void stopPathing() {
path = null; path = null;
dst = null; dsts = null;
} }
public void goTo(Vector2i location) { public boolean goTo(IDestinationProvider location) {
if(isAnimating()) { if(isAnimating()) {
stopPathing(); stopPathing();
dst = location; dsts = location;
return; return true;
} }
Path newPath = pathfinder.getPath(getWorldPosition().xy(), location); Path newPath = pathfinder.getBestPath(getWorldPosition().xy(), location);
path = newPath; path = newPath;
if(path == null) return; if(path == null) return false;
dst = location; dsts = location;
updatePath(); updatePath();
return true;
} }
public void wander() { public void wander() {
@ -131,7 +133,7 @@ public abstract class Agent extends WorldObject implements ISelectable {
} while (terrain.isOutOfBounds(random.x, random.y)); } while (terrain.isOutOfBounds(random.x, random.y));
goTo(random); goTo(new IDestinationProvider.SingleDestination(random));
} }
@Override @Override
@ -173,7 +175,8 @@ public abstract class Agent extends WorldObject implements ISelectable {
} }
Assets.flat.swapColor(Color.yellow); Assets.flat.swapColor(Color.yellow);
if(dst != null) { if(dsts != null) {
for(Vector2i dst : dsts.getDestinations())
camera.draw( camera.draw(
Layers.GROUND_MARKERS, Layers.GROUND_MARKERS,
Assets.selectionFrame, Assets.selectionFrame,
@ -207,7 +210,7 @@ public abstract class Agent extends WorldObject implements ISelectable {
return new Box(getCalculatedPosition(), 1, 1); return new Box(getCalculatedPosition(), 1, 1);
} }
protected abstract void idle(); protected abstract void idle(float dTime);
public Vector2f getCalculatedPosition() { public Vector2f getCalculatedPosition() {
if(!isAnimating()) if(!isAnimating())

View File

@ -1,29 +0,0 @@
package xyz.valnet.hadean.gameobjects.worldobjects.agents.pawn;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
import xyz.valnet.hadean.interfaces.IItemPredicate;
public interface Desire {
record BeAtLocation(
Vector2i dest,
Reason reason
) implements Desire {}
record BeAtDynamicLocation(
Vector2i dest,
Reason reason
) implements Desire {}
record HoldItemByPredicate(
IItemPredicate item,
Reason reason
) implements Desire {}
record HoldExplicitItem(
Item item,
Reason reason
) implements Desire {}
public Reason reason();
}

View File

@ -10,6 +10,8 @@ import xyz.valnet.engine.math.Vector2f;
import xyz.valnet.engine.util.Names; import xyz.valnet.engine.util.Names;
import xyz.valnet.hadean.HadeanGame; import xyz.valnet.hadean.HadeanGame;
import xyz.valnet.hadean.gameobjects.jobs.Job; import xyz.valnet.hadean.gameobjects.jobs.Job;
import xyz.valnet.hadean.gameobjects.jobs.JobBoard;
import xyz.valnet.hadean.gameobjects.jobs.JobBoard.ENoJobsAvailable;
import xyz.valnet.hadean.gameobjects.terrain.Terrain; import xyz.valnet.hadean.gameobjects.terrain.Terrain;
import xyz.valnet.hadean.gameobjects.worldobjects.agents.Agent; import xyz.valnet.hadean.gameobjects.worldobjects.agents.Agent;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item; import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
@ -22,30 +24,66 @@ public class Pawn extends Agent {
private String name = Names.getRandomName(); private String name = Names.getRandomName();
private Set<Desire> desires = new HashSet<>(); private Set<Item> inventory = new HashSet<>();
private Job currentJob = null;
private void doWorkJob(Job.Work workJob, float dTime) {
if(!this.getWorldPosition().xy().isOneOf(workJob.workable().getDestinations())) {
if(goTo(workJob.workable())) {
return;
} else {
cancelJob(currentJob);
}
}
workJob.workable().doWork(dTime);
}
private void doHaulJob(Job.Haul haulJob, float dTime) {
}
private void doJob(float dTime) {
if(currentJob instanceof Job.Haul haul) {
doHaulJob(haul, dTime);
} else if (currentJob instanceof Job.Work work) {
doWorkJob(work, dTime);
}
}
@Override @Override
protected void ready() { public void idle(float dTime) {
super.ready(); if(currentJob != null) {
doJob(dTime);
return;
}
// TODO implement some sort of negotiating pattern between pawn and jobboard
// such that a pawn can decide if its capable of a job (imagine a pawn stuck
// in a place where it cant reach the job location. or in future, where it
// may lack a skill)
if((currentJob = get(JobBoard.class).takeJob(this)) != null) {
doJob(dTime);
return;
}
}
public void cancelJob(Job job) {
currentJob = null;
} }
protected void create() { protected void create() {
setPosition( setPosition(
Terrain.WORLD_SIZE / 2, (int) (Math.random() * Terrain.WORLD_SIZE),
Terrain.WORLD_SIZE / 2 (int) (Math.random() * Terrain.WORLD_SIZE)
// (int) (Math.random() * Terrain.WORLD_SIZE),
// (int) (Math.random() * Terrain.WORLD_SIZE)
); );
} }
@Override @Override
public void render() { public void render() {
super.render(); super.render();
// if(currentActivity instanceof SleepActivity) {
// Assets.flat.pushColor(Color.grey(0.5f));
// } else {
Assets.flat.pushColor(Color.white); Assets.flat.pushColor(Color.white);
// }
float shake = 0.0f; float shake = 0.0f;
camera.draw( camera.draw(
@ -74,86 +112,13 @@ public class Pawn extends Agent {
return "Pawn"; return "Pawn";
} }
private Set<Item> inventory = new HashSet<>();
public void cancelJob(Job job) {
}
// private float restlessness = 0;
// private final
@Override
public void idle() {
switch(currentWanderState) {
case On:
wander();
break;
case Off: break;
case Random:
if(Math.random() < 0.005) wander();
break;
}
}
private enum WanderState {
Off,
Random,
On
}
private WanderState currentWanderState = WanderState.Off;
public static final Action CYCLE_WANDER_STATE_ON = new Action("Wander\nON");
public static final Action CYCLE_WANDER_STATE_RANDOM = new Action("Wander\nRANDOM");
public static final Action CYCLE_WANDER_STATE_OFF = new Action("Wander\nOFF");
public static final Action FORCE_WANDER = new Action("Wander");
public static final Action CANCEL_PATH = new Action("Cancel\n Path");
@Override @Override
public Action[] getActions() { public Action[] getActions() {
Action wanderAction = null; return new Action[] {};
switch(currentWanderState) {
case Off: {
wanderAction = CYCLE_WANDER_STATE_OFF;
break;
}
case Random: {
wanderAction = CYCLE_WANDER_STATE_RANDOM;
break;
}
case On: {
wanderAction = CYCLE_WANDER_STATE_ON;
break;
}
}
if(HadeanGame.debugView) {
return new Action[] {
wanderAction,
FORCE_WANDER,
CANCEL_PATH
};
}
return new Action[] {
};
} }
@Override @Override
public void runAction(Action action) { public void runAction(Action action) {
if(action == CYCLE_WANDER_STATE_ON) {
currentWanderState = WanderState.Off;
} else if (action == CYCLE_WANDER_STATE_RANDOM) {
currentWanderState = WanderState.On;
} else if (action == CYCLE_WANDER_STATE_OFF) {
currentWanderState = WanderState.Random;
} else if (action == FORCE_WANDER) {
wander();
} else if (action == CANCEL_PATH) {
stopPathing();
}
} }
} }

View File

@ -1,14 +0,0 @@
package xyz.valnet.hadean.gameobjects.worldobjects.agents.pawn;
public interface Reason {
record Job(
xyz.valnet.hadean.gameobjects.jobs.Job job
) implements Reason {}
record Need(
) implements Reason {}
record Desire(
Desire desire
) implements Reason {}
}

View File

@ -6,11 +6,11 @@ import java.util.List;
import xyz.valnet.engine.graphics.Color; import xyz.valnet.engine.graphics.Color;
import xyz.valnet.engine.graphics.Sprite; import xyz.valnet.engine.graphics.Sprite;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.enums.BuildType;
import xyz.valnet.hadean.gameobjects.jobs.Job; import xyz.valnet.hadean.gameobjects.jobs.Job;
import xyz.valnet.hadean.gameobjects.jobs.JobBoard; import xyz.valnet.hadean.gameobjects.jobs.JobBoard;
import xyz.valnet.hadean.gameobjects.worldobjects.Buildable; import xyz.valnet.hadean.gameobjects.worldobjects.Buildable;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item; import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
import xyz.valnet.hadean.interfaces.BuildType;
import xyz.valnet.hadean.interfaces.IItemPredicate; import xyz.valnet.hadean.interfaces.IItemPredicate;
import xyz.valnet.hadean.interfaces.IItemReceiver; import xyz.valnet.hadean.interfaces.IItemReceiver;
import xyz.valnet.hadean.interfaces.IWorkable; import xyz.valnet.hadean.interfaces.IWorkable;

View File

@ -5,9 +5,9 @@ import java.util.EnumSet;
import xyz.valnet.engine.graphics.Sprite; import xyz.valnet.engine.graphics.Sprite;
import xyz.valnet.engine.graphics.Tile16.Direction; import xyz.valnet.engine.graphics.Tile16.Direction;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.enums.BuildType;
import xyz.valnet.hadean.gameobjects.terrain.Tile; import xyz.valnet.hadean.gameobjects.terrain.Tile;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder; import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder;
import xyz.valnet.hadean.interfaces.BuildType;
import xyz.valnet.hadean.interfaces.IItemPredicate; import xyz.valnet.hadean.interfaces.IItemPredicate;
import xyz.valnet.hadean.interfaces.IPingable; import xyz.valnet.hadean.interfaces.IPingable;
import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Action;

View File

@ -82,6 +82,10 @@ public abstract class Item extends WorldObject implements ISelectable {
jobboard.postJob(haulJob); jobboard.postJob(haulJob);
} }
public void destroy() {
remove(this);
}
public boolean matches(IItemPredicate itemPredicate) { public boolean matches(IItemPredicate itemPredicate) {
return itemPredicate.matches(this); return itemPredicate.matches(this);
} }

View File

@ -1,7 +1,7 @@
package xyz.valnet.hadean.gameobjects.worldobjects.zones; package xyz.valnet.hadean.gameobjects.worldobjects.zones;
import xyz.valnet.hadean.enums.BuildType;
import xyz.valnet.hadean.gameobjects.worldobjects.Buildable; import xyz.valnet.hadean.gameobjects.worldobjects.Buildable;
import xyz.valnet.hadean.interfaces.BuildType;
public abstract class Zone extends Buildable { public abstract class Zone extends Buildable {

View File

@ -2,6 +2,7 @@ package xyz.valnet.hadean.interfaces;
import xyz.valnet.engine.math.TileBox; import xyz.valnet.engine.math.TileBox;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.enums.BuildType;
public interface IBuildable { public interface IBuildable {

View File

@ -0,0 +1,16 @@
package xyz.valnet.hadean.interfaces;
import xyz.valnet.engine.math.Vector2i;
public interface IDestinationProvider {
public Vector2i[] getDestinations();
record SingleDestination(Vector2i dst) implements IDestinationProvider {
@Override
public Vector2i[] getDestinations() {
return new Vector2i[] { dst };
}
}
}

View File

@ -9,4 +9,12 @@ public interface IItemReceiver extends Serializable {
public boolean receive(Item item); public boolean receive(Item item);
public Vector2i[] getItemDropoffLocations(); public Vector2i[] getItemDropoffLocations();
public String getName(); public String getName();
public default boolean give(Item item) {
if(receive(item)) {
item.destroy();
return true;
}
return false;
}
} }

View File

@ -3,23 +3,17 @@ package xyz.valnet.hadean.interfaces;
import java.io.Serializable; import java.io.Serializable;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.enums.WorkType;
public interface IWorkable extends Serializable { public interface IWorkable extends Serializable, IDestinationProvider {
public enum WorkType {
Construct("Construct"),
Farm("Till"),
Chop("Chop");
public final String verb;
private WorkType(String verb) {
this.verb = verb;
}
}
public WorkType getWorkType(); public WorkType getWorkType();
public boolean doWork(float dTime); public boolean doWork(float dTime);
public Vector2i[] getWorkablePositions(); public Vector2i[] getWorkablePositions();
public String getName(); public String getWorkableName();
@Override
public default Vector2i[] getDestinations() {
return getWorkablePositions();
}
} }

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.Stack; import java.util.Stack;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.interfaces.IDestinationProvider;
public class AStarPathfinder implements IPathfinder, Serializable { public class AStarPathfinder implements IPathfinder, Serializable {
@ -162,7 +163,9 @@ public class AStarPathfinder implements IPathfinder, Serializable {
} }
@Override @Override
public Path getBestPath(Vector2i src, Vector2i[] dsts) { public Path getBestPath(Vector2i src, IDestinationProvider provider) {
var dsts = provider.getDestinations();
if(src.isOneOf(dsts)) return null; if(src.isOneOf(dsts)) return null;

View File

@ -1,6 +1,7 @@
package xyz.valnet.hadean.pathfinding; package xyz.valnet.hadean.pathfinding;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.interfaces.IDestinationProvider;
public interface IPathfinder { public interface IPathfinder {
public Path getPath(int x1, int y1, int x2, int y2); public Path getPath(int x1, int y1, int x2, int y2);
@ -13,5 +14,5 @@ public interface IPathfinder {
public default Path getPath(Vector2i u, Vector2i v) { public default Path getPath(Vector2i u, Vector2i v) {
return getPath(u.x, u.y, v.x, v.y); return getPath(u.x, u.y, v.x, v.y);
} }
public Path getBestPath(Vector2i src, Vector2i[] dsts); public Path getBestPath(Vector2i src, IDestinationProvider dsts);
} }