basic work jobs work

shops
Ivory 2023-10-22 20:21:07 -04:00
commit fd64b53d6c
39 changed files with 755 additions and 313 deletions

View File

@ -123,7 +123,7 @@ public class App {
// Get the resolution of the primary monitor // Get the resolution of the primary monitor
long primaryMonitor = glfwGetPrimaryMonitor(); long primaryMonitor = glfwGetPrimaryMonitor();
PointerBuffer monitors = glfwGetMonitors(); PointerBuffer monitors = glfwGetMonitors();
primaryMonitor = monitors.get(1); primaryMonitor = monitors.get(0);
GLFWVidMode vidmode = glfwGetVideoMode(primaryMonitor); GLFWVidMode vidmode = glfwGetVideoMode(primaryMonitor);
IntBuffer monitorX = stack.mallocInt(1); // int* IntBuffer monitorX = stack.mallocInt(1); // int*
IntBuffer monitorY = stack.mallocInt(1); // int* IntBuffer monitorY = stack.mallocInt(1); // int*

View File

@ -74,4 +74,9 @@ public class Vector2i implements Serializable {
return new Vector2i(this.x + b.x, this.y + b.y); return new Vector2i(this.x + b.x, this.y + b.y);
} }
public Vector2i[] asArray() {
return new Vector2i[] {
this
};
}
} }

View File

@ -1,13 +1,16 @@
package xyz.valnet.engine.scenegraph; package xyz.valnet.engine.scenegraph;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.scenegraph.SceneGraph.GameObjectCallback; import xyz.valnet.engine.scenegraph.SceneGraph.GameObjectCallback;
import xyz.valnet.hadean.interfaces.ISceneReferent;
import xyz.valnet.hadean.util.Pair; import xyz.valnet.hadean.util.Pair;
public class GameObject implements IRenderable, ITickable, Serializable { public class GameObject implements IRenderable, ITickable, Serializable, ISceneReferent {
private transient SceneGraph scene; private transient SceneGraph scene;
private boolean created = false; private boolean created = false;
@ -41,26 +44,6 @@ public class GameObject implements IRenderable, ITickable, Serializable {
return obj; return obj;
} }
@Override
public void render() {}
@Override
public void renderAlpha() {}
@Override
public void update(float dTime) {}
// call order goes from top to bottom \/\/\/
// ready is called before scene linkage, and serves to initialize
// values that may be needed before incoming requests.
protected void ready() {}
// connect is solely for ensuring links to other objects. get() and getAll()
protected void connect() {}
// create is guaranteed to only run once for an object, even after save/load
protected void create() {}
// start is called any time the object is added to a scene
protected void start() {}
public final void addedToScene() { public final void addedToScene() {
connect(); connect();
if(!created) { if(!created) {
@ -94,19 +77,50 @@ public class GameObject implements IRenderable, ITickable, Serializable {
return scene.getFPS(); return scene.getFPS();
} }
protected void onAddGameObject(GameObjectCallback listener) { protected final void onAddGameObject(GameObjectCallback listener) {
scene.registerAddListener(listener); scene.registerAddListener(listener);
} }
protected void onRemoveGameObject(GameObjectCallback listener) { protected final void onRemoveGameObject(GameObjectCallback listener) {
scene.registerRemoveListener(listener); scene.registerRemoveListener(listener);
} }
protected Vector2i getBufferDimensions() { protected final Vector2i getBufferDimensions() {
return scene.getBufferDimensions(); return scene.getBufferDimensions();
} }
protected void beforeRemoved() {} private final Set<GameObjectCallback> removedListeners = new HashSet<>();
protected void afterRemoved() {} @Override
public final void onRemoved(GameObjectCallback listener) {
removedListeners.add(listener);
}
protected final void finalized() {
for(var listener : removedListeners) {
listener.apply(this);
}
}
protected void cleanup() {}
@Override
public void render() {}
@Override
public void renderAlpha() {}
@Override
public void update(float dTime) {}
// call order goes from top to bottom \/\/\/
// ready is called before scene linkage, and serves to initialize
// values that may be needed before incoming requests.
protected void ready() {}
// connect is solely for ensuring links to other objects. get() and getAll()
protected void connect() {}
// create is guaranteed to only run once for an object, even after save/load
protected void create() {}
// start is called any time the object is added to a scene
protected void start() {}
} }

View File

@ -23,9 +23,9 @@ import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab;
import xyz.valnet.hadean.util.Pair; import xyz.valnet.hadean.util.Pair;
public abstract class SceneGraph implements IScene { public abstract class SceneGraph implements IScene {
protected final List<GameObject> objects = new ArrayList<GameObject>(); private final Set<GameObject> objects = new HashSet<GameObject>();
private final List<GameObject> newObjects = new ArrayList<GameObject>(); private final Set<GameObject> newObjects = new HashSet<GameObject>();
private final List<GameObject> removeObjects = new ArrayList<GameObject>(); private final Set<GameObject> removeObjects = new HashSet<GameObject>();
private IMouseCaptureArea hoveredMouseListener = null; private IMouseCaptureArea hoveredMouseListener = null;
@ -159,7 +159,11 @@ public abstract class SceneGraph implements IScene {
@Override @Override
public void enable(Game game) { public void enable(Game game) {
this.game = game; this.game = game;
this.construct(); Set<GameObject> scene = new HashSet<GameObject>();
this.construct(scene);
this.objects.clear();
this.objects.addAll(scene);
for(GameObject obj : objects) { for(GameObject obj : objects) {
addObjectToCache(obj); addObjectToCache(obj);
@ -190,7 +194,7 @@ public abstract class SceneGraph implements IScene {
} }
} }
protected abstract void construct(); protected abstract void construct(Set<GameObject> scene);
@Override @Override
public void disable() { public void disable() {
@ -217,11 +221,11 @@ public abstract class SceneGraph implements IScene {
public void remove(GameObject obj) { public void remove(GameObject obj) {
removeObjects.add(obj); removeObjects.add(obj);
obj.beforeRemoved(); obj.cleanup();
for(GameObjectCallback listener : onRemoveListeners) { for(GameObjectCallback listener : onRemoveListeners) {
listener.apply(obj); listener.apply(obj);
} }
obj.afterRemoved(); obj.finalized();
} }
public boolean inScene(GameObject gameObject) { public boolean inScene(GameObject gameObject) {

View File

@ -0,0 +1,21 @@
package xyz.valnet.engine.util;
import java.lang.ref.WeakReference;
import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.interfaces.ISceneReferent;
public class SceneReference<T extends ISceneReferent> extends WeakReference<T> {
public SceneReference(T ref) {
super(ref);
ref.onRemoved((GameObject obj) -> {
this.clear();
});
}
public String toString() {
var o = this.get();
if(o == null) return "";
return "[" + o.toString() + "]";
}
}

View File

@ -1,13 +1,25 @@
package xyz.valnet.hadean.enums; package xyz.valnet.hadean.enums;
// TODO skills such as
// upper body strength
// lower body strength
// finess
// plant knowledge
// construction knowledge
// for now, this isnt meant to be any of that. simply categories for turning work on and off for pawns.
public enum WorkType { public enum WorkType {
Construct("Construct"), Basic("basic", "Work on"),
Farm("Till"), Construct("building", "Construct"),
Chop("Chop"); Farm("farming", "Till"),
Chop("felling", "Chop");
public final String verb; public final String verb;
public final String idString;
private WorkType(String verb) { private WorkType(String idString, String verb) {
this.idString = idString;
this.verb = verb; this.verb = verb;
} }
} }

View File

@ -0,0 +1,8 @@
package xyz.valnet.hadean.functions;
import java.io.Serializable;
@FunctionalInterface
public interface FCompleted extends Serializable {
public void apply();
}

View File

@ -0,0 +1,10 @@
package xyz.valnet.hadean.functions;
import java.io.Serializable;
import xyz.valnet.engine.math.Vector2i;
@FunctionalInterface
public interface FGetPositions extends Serializable {
public Vector2i[] get();
}

View File

@ -0,0 +1,8 @@
package xyz.valnet.hadean.functions;
import java.io.Serializable;
@FunctionalInterface
public interface FProgressEvent extends Serializable {
public void progress(float progress);
}

View File

@ -24,7 +24,7 @@ import static xyz.valnet.engine.util.Math.lerp;
public class Camera extends GameObject implements ITransient, IMouseCaptureArea { public class Camera extends GameObject implements ITransient, IMouseCaptureArea {
private int tileWidth = 32; private int tileWidth = 16;
private Vector2f focus = new Vector2f(0, 0); private Vector2f focus = new Vector2f(0, 0);

View File

@ -1,41 +1,79 @@
package xyz.valnet.hadean.gameobjects.jobs; package xyz.valnet.hadean.gameobjects.jobs;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.util.SceneReference;
import xyz.valnet.hadean.gameobjects.worldobjects.agents.pawn.Pawn;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item; import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
import xyz.valnet.hadean.interfaces.IItemReceiver; import xyz.valnet.hadean.interfaces.DItemRequest;
import xyz.valnet.hadean.interfaces.IDestination;
import xyz.valnet.hadean.interfaces.IWorkable; import xyz.valnet.hadean.interfaces.IWorkable;
// TODO create a subtype of job for jobs with
// locations so pawn can generically path to it
public sealed interface Job { public sealed interface Job {
record Work( record Work(
IWorkable workable SceneReference<IWorkable> workable
) implements Job { ) implements Job, IDestination {
@Override @Override
public String getShortDescription() { public String getShortDescription() {
return workable.getWorkType().verb + " " + workable.getWorkableName(); return workable.get().getWorkType().verb + " " + workable.get().getWorkableName();
}
@Override
public boolean isValidForWorker(Pawn worker) {
var workable = this.workable().get();
if(workable == null) return false;
if(workable.getWorkablePositions() == null) return false;
return true;
}
public Vector2i[] getWorkablePositions() {
var workable = this.workable().get();
if(workable == null) return new Vector2i[] {};
return workable.getDestinations();
}
public void doWork(float dTime) {
var workable = this.workable().get();
if(workable == null) return;
workable.doWork(dTime);
}
@Override
public Vector2i[] getDestinations() {
var workable = this.workable().get();
if(workable == null) return null;
return workable.getDestinations();
} }
} }
record Haul( record ItemRequest(
Item item, SceneReference<DItemRequest> recvr
IItemReceiver rcvr
) implements Job { ) implements Job {
@Override @Override
public String getShortDescription() { public String getShortDescription() {
return "Haul " + item.getName() + " to " + rcvr.getName(); return "Fulfilling " + recvr.get().getName() + " item Request";
}
@Override
public boolean isValidForWorker(Pawn worker) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'isValidForWorker'");
}
}
record HaulToStockpile(
SceneReference<Item> item
) implements Job {
@Override
public String getShortDescription() {
return "Haul " + item.get().getName() + " to stockpile";
}
@Override
public boolean isValidForWorker(Pawn worker) {
return item.get() != null;
} }
} }
public String getShortDescription(); public String getShortDescription();
public boolean isValidForWorker(Pawn worker);
// private JobBoard board;
// public void connect(JobBoard board) {
// this.board = boaard;
// }
// public void close() {
// board.close(this);
// }
} }

View File

@ -1,34 +1,71 @@
package xyz.valnet.hadean.gameobjects.jobs; package xyz.valnet.hadean.gameobjects.jobs;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.engine.util.SceneReference;
import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab; 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.gameobjects.worldobjects.items.Item;
import xyz.valnet.hadean.interfaces.DItemRequest;
import xyz.valnet.hadean.interfaces.IWorkable; import xyz.valnet.hadean.interfaces.IWorkable;
public class JobBoard extends GameObject { public class JobBoard extends GameObject {
private Set<Job> availableJobs = new HashSet<Job>(); private Set<Job> availableJobs = new HashSet<Job>();
private List<Job> toRemove = new ArrayList<Job>(); // private Set<Job> toRemove = new HashSet<Job>();
private Map<Pawn, Job> allocations = new HashMap<Pawn, Job>(); // private Map<Pawn, Job> allocations = new HashMap<Pawn, Job>();
public Job postJob(Job job) { public Job post(Job job) {
availableJobs.add(job); availableJobs.add(job);
return job; return job;
} }
public Job post(IWorkable workable) { public Job post(IWorkable workable) {
var job = new Job.Work(workable); SceneReference<IWorkable> ref = new SceneReference<IWorkable>(workable);
return postJob(job); var job = new Job.Work(ref);
return post(job);
} }
public Job post(Item item) {
var job = new Job.HaulToStockpile(item.asRef());
return post(job);
}
public Job post(DItemRequest request) {
var job = new Job.ItemRequest(request.asRef());
return post(job);
}
public void rescind(Job job) {
if(!availableJobs.contains(job)) return;
availableJobs.remove(job);
}
// === migrate it may be idk
public Job takeJob(Pawn worker) {
if(availableJobs.isEmpty()) 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;
}
// ================= lawl old shit // ================= lawl old shit
@ -62,40 +99,40 @@ public class JobBoard extends GameObject {
@Deprecated @Deprecated
public String getTakenJobs() { public String getTakenJobs() {
String str = ""; String str = "Unknown for now, as jobboard does not track taken jobs.";
for(Entry<Pawn, Job> allocation : allocations.entrySet()) { // for(Entry<Pawn, Job> allocation : allocations.entrySet()) {
str += " " + allocation.getKey().getName() + ": " + allocation.getValue().getShortDescription() + "\n"; // str += " " + allocation.getKey().getName() + ": " + allocation.getValue().getShortDescription() + "\n";
} // }
return str; return str;
} }
public void close(Job job) { // public void close(Job job) {
if(allocations.values().contains(job)) { // if(allocations.values().contains(job)) {
Set<Pawn> workers = new HashSet<>(); // Set<Pawn> workers = new HashSet<>();
for(var entry : allocations.entrySet()) { // for(var entry : allocations.entrySet()) {
if(entry.getValue() == job) workers.add(entry.getKey()); // if(entry.getValue() == job) workers.add(entry.getKey());
} // }
for(var worker : workers) { // for(var worker : workers) {
worker.cancelJob(job); // worker.cancelJob(job);
} // }
} // }
} // }
public class ENoJobsAvailable extends Error {} // public class ENoJobsAvailable extends Error {}
public Job takeJob(Pawn worker) { // public Job takeJob(Pawn worker) {
if(availableJobs.size() == 0) return null; // if(availableJobs.size() == 0) return null;
Job[] jobs = new Job[availableJobs.size()]; // Job[] jobs = new Job[availableJobs.size()];
availableJobs.toArray(jobs); // availableJobs.toArray(jobs);
Job job = jobs[(int) (Math.floor(Math.random() * jobs.length))]; // Job job = jobs[(int) (Math.floor(Math.random() * jobs.length))];
DebugTab.log("" + worker.getName() + " took job: " + job.getShortDescription()); // DebugTab.log("" + worker.getName() + " took job: " + job.getShortDescription());
allocations.put(worker, job); // allocations.put(worker, job);
availableJobs.remove(job); // availableJobs.remove(job);
return job; // return job;
} // }
} }

View File

@ -1,57 +0,0 @@
package xyz.valnet.hadean.gameobjects.jobs;
import java.io.Serializable;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.interfaces.IWorkable;
public class SimpleWorkable implements IWorkable {
private final String name;
private float work = 0;
private float MAX_WORK = 0;
private IProgressUpdateCallback callback;
private IGetPositionsFunction positions;
private final WorkType workType;
@FunctionalInterface
public interface IGetPositionsFunction extends Serializable {
public Vector2i[] get();
}
@FunctionalInterface
public interface IProgressUpdateCallback extends Serializable {
public void progress(float progress);
}
public SimpleWorkable(String name, float maxWork, WorkType type, IGetPositionsFunction positionsFunction, IProgressUpdateCallback callback) {
this.name = name;
this.MAX_WORK = maxWork;
this.positions = positionsFunction;
this.callback = callback;
this.workType = type;
}
@Override
public boolean doWork(float dTime) {
work += dTime;
callback.progress(work / MAX_WORK);
return work >= MAX_WORK;
}
@Override
public Vector2i[] getWorkablePositions() {
return positions.get();
}
@Override
public final String getWorkableName() {
return name;
}
@Override
public WorkType getWorkType() {
return workType;
}
}

View File

@ -7,7 +7,7 @@ import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder; import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item; import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
import xyz.valnet.hadean.interfaces.IItemReceiver; import xyz.valnet.hadean.interfaces.DItemRequest;
import xyz.valnet.hadean.interfaces.IWorkshop; import xyz.valnet.hadean.interfaces.IWorkshop;
public class WorkOrder extends GameObject { public class WorkOrder extends GameObject {
@ -72,29 +72,29 @@ public class WorkOrder extends GameObject {
} }
public Job createNextJob(IWorkshop shop) { public Job createNextJob(IWorkshop shop) {
Job job = new Job("Cut brickies"); return null;
job.addStep(job.new PickupItemByPredicate(Boulder.BOULDER_PREDICATE)); // Job job = new Job("Cut brickies");
job.addStep(job.new DropoffPredicateAtItemReceiver(new IItemReceiver() { // job.addStep(job.new PickupItemByPredicate(Boulder.BOULDER_PREDICATE));
@Override // job.addStep(job.new DropoffPredicateAtItemReceiver(new IItemReceiver() {
public boolean receive(Item item) { // @Override
// public boolean receive(Item item) {
return false; // return false;
} // }
@Override // @Override
public Vector2i[] getItemDropoffLocations() { // public Vector2i[] getItemDropoffLocations() {
return shop.getWorkablePositions(); // return shop.getWorkablePositions();
} // }
}, Boulder.BOULDER_PREDICATE)); // }, Boulder.BOULDER_PREDICATE));
job.addStep(job.new Work(shop)); // job.addStep(job.new Work(shop));
job.registerCompletedListener(() -> { // job.registerCompletedListener(() -> {
decreaseCount(); // decreaseCount();
// });
}); // job.registerClosedListener(() -> {
job.registerClosedListener(() -> { // relatedJobs.remove(job);
relatedJobs.remove(job); // });
}); // get(JobBoard.class).post(job);
get(JobBoard.class).postJob(job); // return job;
return job;
} }
} }

View File

@ -0,0 +1,76 @@
package xyz.valnet.hadean.gameobjects.jobs;
import java.util.HashSet;
import java.util.Set;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.scenegraph.SceneGraph.GameObjectCallback;
import xyz.valnet.hadean.enums.WorkType;
import xyz.valnet.hadean.functions.FGetPositions;
import xyz.valnet.hadean.functions.FProgressEvent;
import xyz.valnet.hadean.functions.FCompleted;
import xyz.valnet.hadean.interfaces.ISceneReferent;
import xyz.valnet.hadean.interfaces.IWorkable;
public class Workable implements IWorkable {
private final String name;
private float work = 0;
private float MAX_WORK = 0;
private FProgressEvent progressCallback;
private FGetPositions positions;
private final WorkType workType;
private ISceneReferent linkedSceneObject;
private Set<FCompleted> completedCallback = new HashSet<>();
public Workable(String name, float maxWork, WorkType type, FGetPositions positionsFunction, FProgressEvent progressCallback, ISceneReferent linkedSceneObject) {
this.name = name;
this.MAX_WORK = maxWork;
this.positions = positionsFunction;
this.progressCallback = progressCallback;
this.workType = type;
this.linkedSceneObject = linkedSceneObject;
}
public void onCompleted(FCompleted cb) {
completedCallback.add(cb);
}
private void finished() {
for(var cb : completedCallback)
cb.apply();
}
@Override
public boolean doWork(float dTime) {
if (work >= MAX_WORK) return true;
work += dTime;
progressCallback.progress(work / MAX_WORK);
if (work >= MAX_WORK) {
finished();
return true;
}
return false;
}
@Override
public Vector2i[] getWorkablePositions() {
return positions.get();
}
@Override
public final String getWorkableName() {
return name;
}
@Override
public WorkType getWorkType() {
return workType;
}
@Override
public void onRemoved(GameObjectCallback callback) {
linkedSceneObject.onRemoved(callback);
}
}

View File

@ -0,0 +1,74 @@
package xyz.valnet.hadean.gameobjects.jobs;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.enums.WorkType;
import xyz.valnet.hadean.functions.FGetPositions;
import xyz.valnet.hadean.functions.FProgressEvent;
import xyz.valnet.hadean.functions.FCompleted;
import xyz.valnet.hadean.interfaces.ISceneReferent;
public class WorkableBuilder {
private String name = "work area";
private float maxWork = 1000;
private WorkType type = WorkType.Basic;
private FGetPositions getPositionsFunction;
private FProgressEvent progressUpdateCallback;
private FCompleted completed;
private ISceneReferent linked;
public WorkableBuilder(ISceneReferent linked) {
this.linked = linked;
}
public WorkableBuilder type(WorkType t) {
type = t;
return this;
}
public WorkableBuilder work(float f) {
maxWork = f;
return this;
}
public WorkableBuilder progress(FProgressEvent f) {
this.progressUpdateCallback = f;
return this;
}
public WorkableBuilder name(String n) {
name = n;
return this;
}
public WorkableBuilder positions(Vector2i[] poss) {
getPositionsFunction = () -> {
return poss;
};
return this;
}
public WorkableBuilder position(Vector2i pos) {
var arr = pos.asArray();
getPositionsFunction = () -> {
return arr;
};
return this;
}
public WorkableBuilder positions(FGetPositions f) {
getPositionsFunction = f;
return this;
}
public WorkableBuilder completed(FCompleted f) {
this.completed = f;
return this;
}
public Workable build() {
var o = new Workable(name, maxWork, type, getPositionsFunction, progressUpdateCallback, linked);
o.onCompleted(completed);
return o;
}
}

View File

@ -11,7 +11,7 @@ import xyz.valnet.hadean.pathfinding.IPathable;
public class Terrain extends GameObject implements IPathable, IWorldBoundsAdapter { public class Terrain extends GameObject implements IPathable, IWorldBoundsAdapter {
public static final int WORLD_SIZE = 24; public static final int WORLD_SIZE = 48;
public static final int TILE_SIZE = 8; public static final int TILE_SIZE = 8;
// public static int left, top; // public static int left, top;

View File

@ -8,6 +8,7 @@ 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;
import xyz.valnet.hadean.HadeanGame; import xyz.valnet.hadean.HadeanGame;
import xyz.valnet.hadean.enums.WorkType;
import xyz.valnet.hadean.gameobjects.worldobjects.Tree; import xyz.valnet.hadean.gameobjects.worldobjects.Tree;
import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject; import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder; import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder;

View File

@ -8,6 +8,7 @@ import java.util.Map;
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.engine.scenegraph.ITransient; import xyz.valnet.engine.scenegraph.ITransient;
import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab;
import xyz.valnet.hadean.input.Button; import xyz.valnet.hadean.input.Button;
import xyz.valnet.hadean.input.IButtonListener; import xyz.valnet.hadean.input.IButtonListener;
import xyz.valnet.hadean.input.SimpleButton; import xyz.valnet.hadean.input.SimpleButton;
@ -16,18 +17,11 @@ import xyz.valnet.hadean.util.Layers;
public class BottomBar extends GameObject implements IButtonListener, ITransient { public class BottomBar extends GameObject implements IButtonListener, ITransient {
public static final int bottomBarHeight = 32; public static final int bottomBarHeight = 32;
private int screenWidth = 1024;
private Map<Button, IBottomBarItem> btnItemTable = new HashMap<Button, IBottomBarItem>(); private Map<Button, IBottomBarItem> btnItemTable = new HashMap<Button, IBottomBarItem>();
private List<IBottomBarItem> items = new ArrayList<IBottomBarItem>(); private List<IBottomBarItem> items = new ArrayList<IBottomBarItem>();
@Override
public void start() {
items.clear();
clearButtons();
}
public void registerButton(IBottomBarItem newItem) { public void registerButton(IBottomBarItem newItem) {
Vector2i screen = getBufferDimensions(); Vector2i screen = getBufferDimensions();
clearButtons(); clearButtons();
@ -41,6 +35,7 @@ public class BottomBar extends GameObject implements IButtonListener, ITransient
int w = r - l; int w = r - l;
Button btn = new SimpleButton(item.getTabName(), l, screen.y - bottomBarHeight, w, bottomBarHeight, Layers.BOTTOM_BAR); Button btn = new SimpleButton(item.getTabName(), l, screen.y - bottomBarHeight, w, bottomBarHeight, Layers.BOTTOM_BAR);
// Button btn = new SimpleButton(item.getTabName(), 100 * i, 100, 100, 100, Layers.BOTTOM_BAR);
if(item.isButtonClickSilent()) btn = btn.setClickSound(false); if(item.isButtonClickSilent()) btn = btn.setClickSound(false);
btn.registerClickListener(this); btn.registerClickListener(this);
add(btn); add(btn);

View File

@ -79,7 +79,6 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener
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);
actions.add(action); actions.add(action);
} }
} }

View File

@ -58,7 +58,7 @@ public class Tree extends WorldObject implements ISelectable, IWorkable {
if(chopJob == null) { if(chopJob == null) {
chopJob = get(JobBoard.class).post(this); chopJob = get(JobBoard.class).post(this);
} else { } else {
get(JobBoard.class).close(chopJob); get(JobBoard.class).rescind(chopJob);
chopJob = null; chopJob = null;
} }
} }
@ -111,8 +111,8 @@ public class Tree extends WorldObject implements ISelectable, IWorkable {
} }
@Override @Override
protected void beforeRemoved() { protected void cleanup() {
super.beforeRemoved(); super.cleanup();
Vector2i pos = getWorldPosition().xy(); Vector2i pos = getWorldPosition().xy();
add(new Log(pos.x, pos.y)); add(new Log(pos.x, pos.y));
} }

View File

@ -129,7 +129,7 @@ public abstract class WorldObject extends GameObject implements IWorldObject {
} }
@Override @Override
protected void beforeRemoved() { protected void cleanup() {
for(Tile tile : this.getTiles()) { for(Tile tile : this.getTiles()) {
tile.removeThing(this); tile.removeThing(this);
} }

View File

@ -16,7 +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.IDestination;
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;
@ -100,14 +100,14 @@ public abstract class Agent extends WorldObject implements ISelectable {
} }
private Path path; private Path path;
private IDestinationProvider dsts; private IDestination dsts;
public void stopPathing() { public void stopPathing() {
path = null; path = null;
dsts = null; dsts = null;
} }
public boolean goTo(IDestinationProvider location) { public boolean goTo(IDestination location) {
if(isAnimating()) { if(isAnimating()) {
stopPathing(); stopPathing();
dsts = location; dsts = location;
@ -133,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(new IDestinationProvider.SingleDestination(random)); goTo(new IDestination.Single(random));
} }
@Override @Override
@ -212,6 +212,10 @@ public abstract class Agent extends WorldObject implements ISelectable {
protected abstract void idle(float dTime); protected abstract void idle(float dTime);
protected boolean isPathing() {
return dsts != null;
}
public Vector2f getCalculatedPosition() { public Vector2f getCalculatedPosition() {
if(!isAnimating()) if(!isAnimating())
return getWorldPosition().xy().asFloat(); return getWorldPosition().xy().asFloat();

View File

@ -11,14 +11,16 @@ 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;
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;
import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Action;
import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Assets;
import xyz.valnet.hadean.util.Layers; import xyz.valnet.hadean.util.Layers;
import xyz.valnet.hadean.util.detail.BooleanDetail;
import xyz.valnet.hadean.util.detail.Detail; import xyz.valnet.hadean.util.detail.Detail;
import xyz.valnet.hadean.util.detail.ObjectDetail;
import xyz.valnet.hadean.util.detail.PercentDetail;
public class Pawn extends Agent { public class Pawn extends Agent {
@ -29,23 +31,28 @@ public class Pawn extends Agent {
private Job currentJob = null; private Job currentJob = null;
private void doWorkJob(Job.Work workJob, float dTime) { private void doWorkJob(Job.Work workJob, float dTime) {
if(!this.getWorldPosition().xy().isOneOf(workJob.workable().getDestinations())) { if(!this.getWorldPosition().xy().isOneOf(workJob.getWorkablePositions())) {
if(goTo(workJob.workable())) { if(goTo(workJob)) {
return; return;
} else { } else {
cancelJob(currentJob); cancelJob(currentJob);
} }
} }
workJob.workable().doWork(dTime); workJob.doWork(dTime);
} }
private void doHaulJob(Job.Haul haulJob, float dTime) { private void doHaulToStockpileJob(Job.HaulToStockpile haulJob, float dTime) {
if(inventory.contains(haulJob.item().get()))
} }
private void doJob(float dTime) { private void doJob(float dTime) {
if(currentJob instanceof Job.Haul haul) { if(!currentJob.isValidForWorker(this)) {
doHaulJob(haul, dTime); get(JobBoard.class).post(currentJob);
currentJob = null;
return;
}
if(currentJob instanceof Job.HaulToStockpile haul) {
doHaulToStockpileJob(haul, dTime);
} else if (currentJob instanceof Job.Work work) { } else if (currentJob instanceof Job.Work work) {
doWorkJob(work, dTime); doWorkJob(work, dTime);
} }
@ -99,7 +106,15 @@ public class Pawn extends Agent {
@Override @Override
public Detail[] getDetails() { public Detail[] getDetails() {
return new Detail[] {}; // return needs.getDetails();
Detail[] details = new Detail[] {
// new ObjectDetail<Activity>("Activity", currentActivity),
new BooleanDetail("Pathing", isPathing()),
new ObjectDetail<String>("Job", currentJob == null ? "null" : currentJob.toString()),
new ObjectDetail<Integer>("Inventory", inventory.size())
};
return details;
} }
@Override @Override

View File

@ -6,13 +6,14 @@ 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.engine.scenegraph.SceneGraph.GameObjectCallback;
import xyz.valnet.hadean.enums.BuildType; 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.IItemPredicate; import xyz.valnet.hadean.interfaces.IItemPredicate;
import xyz.valnet.hadean.interfaces.IItemReceiver; import xyz.valnet.hadean.interfaces.DItemRequest;
import xyz.valnet.hadean.interfaces.IWorkable; import xyz.valnet.hadean.interfaces.IWorkable;
import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Action;
import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Assets;
@ -31,32 +32,64 @@ public abstract class Construction extends Buildable {
return containedItems.size() >= getBuildingMaterialCount(); return containedItems.size() >= getBuildingMaterialCount();
} }
private void onItem(Item item) {
containedItems.add(item);
postNextJob();
}
private void postNextJob() { private void postNextJob() {
if(!isBuildingMaterialSatisfied()) { if(!isBuildingMaterialSatisfied()) {
Job job = get(JobBoard.class).postSimpleItemRequirementJob(
"Haul items to building",
getBuildingMaterial(),
new IItemReceiver() {
@Override var itemRequest = new DItemRequest(this, "Haul items to building")
public final boolean receive(Item item) { .accepts(getBuildingMaterial())
if(item == null) return false; .positions(getSelectionWorldBox().getBorders())
if(!item.matches(getBuildingMaterial())) return false; .handleItem((item) -> onItem(item));
remove(item);
containedItems.add(item); var job = get(JobBoard.class).post(itemRequest);
return true; // TODO -> job.onCompleted(postNextJob();)
}
// Job job = get(JobBoard.class).postSimpleItemRequirementJob(
// "Haul items to building",
// getBuildingMaterial(),
// new DItemRequest() {
// @Override
// public final boolean receive(Item item) {
// if(item == null) return false;
// if(!item.matches(getBuildingMaterial())) return false;
// remove(item);
// containedItems.add(item);
// return true;
// }
@Override // @Override
public Vector2i[] getItemDropoffLocations() { // public Vector2i[] getItemDropoffLocations() {
return getSelectionWorldBox().getBorders(); // return getSelectionWorldBox().getBorders();
} // }
// @Override
// public void onRemoved(GameObjectCallback callback) {
// // TODO Auto-generated method stub
// throw new UnsupportedOperationException("Unimplemented method 'onRemoved'");
// }
// @Override
// public String getName() {
// // TODO Auto-generated method stub
// throw new UnsupportedOperationException("Unimplemented method 'getName'");
// }
// @Override
// public IItemPredicate acceptedItems() {
// // TODO Auto-generated method stub
// throw new UnsupportedOperationException("Unimplemented method 'acceptedItems'");
// }
} // }
); // );
job.registerClosedListener(() -> { // job.registerClosedListener(() -> {
postNextJob(); // postNextJob();
}); // });
return; return;
} }
if(!isBuilt()) { if(!isBuilt()) {

View File

@ -4,7 +4,7 @@ import xyz.valnet.engine.graphics.Sprite;
import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector2i;
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.jobs.SimpleWorkable; import xyz.valnet.hadean.gameobjects.jobs.WorkableBuilder;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder; import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder;
import xyz.valnet.hadean.interfaces.IItemPredicate; import xyz.valnet.hadean.interfaces.IItemPredicate;
import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Assets;
@ -25,22 +25,39 @@ public class Quarry extends Construction {
if (digJob != null) return; if (digJob != null) return;
if (terrain.getTile(getWorldPosition().xy().south().east()).has(Boulder.class)) return; if (terrain.getTile(getWorldPosition().xy().south().east()).has(Boulder.class)) return;
digJob = get(JobBoard.class).post(new SimpleWorkable("Mine at Quarry", 5000, () -> { var workable = new WorkableBuilder(this)
return new Vector2i[] { .name("Quarry")
getWorldPosition().xy().south().east() .position(getWorldPosition().xy().south().east())
}; .work(5000)
}, (progress) -> { .progress((p) -> digProgress = p)
digProgress = progress; .completed(() -> {
})); digProgress = 0;
Vector2i dropPos = getWorldPosition().xy().south().east();
Boulder boulder = new Boulder(dropPos.x, dropPos.y);
add(boulder);
boulder.runAction(Boulder.HAUL);
digJob = null;
})
.build();
digJob.registerClosedListener(() -> { digJob = get(JobBoard.class).post(workable);
digProgress = 0;
Vector2i dropPos = getWorldPosition().xy().south().east(); // digJob = get(JobBoard.class).post(new SimpleWorkable("Mine at Quarry", 5000, () -> {
Boulder boulder = new Boulder(dropPos.x, dropPos.y); // return new Vector2i[] {
add(boulder); // getWorldPosition().xy().south().east()
boulder.runAction(Boulder.HAUL); // };
digJob = null; // }, (progress) -> {
}); // digProgress = progress;
// }));
// 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 @Override
@ -79,7 +96,7 @@ public class Quarry extends Construction {
super.render(); super.render();
if(!isBuilt()) return; if(!isBuilt()) return;
if(digJob != null && !digJob.isCompleted() && digProgress > 0) { if(digJob != null && digProgress > 0) {
camera.drawProgressBar(digProgress, getSelectionWorldBox()); camera.drawProgressBar(digProgress, getSelectionWorldBox());
} }
} }

View File

@ -8,7 +8,17 @@ import xyz.valnet.hadean.util.detail.Detail;
public class Boulder extends Item { public class Boulder extends Item {
public static IItemPredicate BOULDER_PREDICATE = (item) -> (item instanceof Boulder); public static IItemPredicate BOULDER_PREDICATE = new IItemPredicate() {
@Override
public String getName() {
return "Boulder";
}
@Override
public boolean matches(Item item) {
return item instanceof Boulder;
}
};
public Boulder(int x, int y) { public Boulder(int x, int y) {
setPosition(x, y); setPosition(x, y);

View File

@ -2,20 +2,26 @@ package xyz.valnet.hadean.gameobjects.worldobjects.items;
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.util.SceneReference;
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.WorldObject; import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject;
import xyz.valnet.hadean.interfaces.IItemPredicate; import xyz.valnet.hadean.interfaces.IItemPredicate;
import xyz.valnet.hadean.interfaces.ISceneReferent;
import xyz.valnet.hadean.interfaces.ISelectable; import xyz.valnet.hadean.interfaces.ISelectable;
import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Action;
import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Assets;
import xyz.valnet.hadean.util.Layers; import xyz.valnet.hadean.util.Layers;
public abstract class Item extends WorldObject implements ISelectable { public abstract class Item extends WorldObject implements ISelectable, ISceneReferent {
protected JobBoard jobboard; protected JobBoard jobboard;
private Job haulJob = null; private Job haulJob = null;
public final SceneReference<Item> asRef() {
return new SceneReference<Item>(this);
}
@Override @Override
protected void connect() { protected void connect() {
super.connect(); super.connect();
@ -67,19 +73,14 @@ public abstract class Item extends WorldObject implements ISelectable {
private void cancelHaul() { private void cancelHaul() {
if(haulJob == null) return; if(haulJob == null) return;
haulJob.close(); jobboard.rescind(haulJob);
haulJob = null; haulJob = null;
} }
private void markForHaul() { private void markForHaul() {
if(haulJob != null) return; if(haulJob != null) return;
haulJob = add(new Job("Haul " + this.getName())); var j = new Job.HaulToStockpile(asRef());
haulJob.addStep(haulJob.new PickupItem(this)); jobboard.post(j);
haulJob.addStep(haulJob.new DropoffAtStockpile(this));
haulJob.registerClosedListener(() -> {
haulJob = null;
});
jobboard.postJob(haulJob);
} }
public void destroy() { public void destroy() {
@ -105,4 +106,8 @@ public abstract class Item extends WorldObject implements ISelectable {
public void setPosition(int x, int y, int w, int h) { public void setPosition(int x, int y, int w, int h) {
super.setPosition(x, y, w, h); super.setPosition(x, y, w, h);
} }
public String toString() {
return getGenericName();
}
} }

View File

@ -13,7 +13,19 @@ import xyz.valnet.hadean.util.detail.Detail;
// when placed in a non stockpile, not just on create. // when placed in a non stockpile, not just on create.
public class Log extends Item { public class Log extends Item {
public static IItemPredicate LOG_PREDICATE = (item) -> (item instanceof Log); public static IItemPredicate LOG_PREDICATE = new IItemPredicate() {
@Override
public boolean matches(Item item) {
return item instanceof Log;
}
@Override
public String getName() {
return "Any Log";
}
};
public Log(int x, int y) { public Log(int x, int y) {
setPosition(x, y); setPosition(x, y);

View File

@ -0,0 +1,92 @@
package xyz.valnet.hadean.interfaces;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.scenegraph.SceneGraph.GameObjectCallback;
import xyz.valnet.engine.util.SceneReference;
import xyz.valnet.hadean.functions.FGetPositions;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
public class DItemRequest implements ISceneReferent, Serializable {
@FunctionalInterface
public interface FItemHandler {
public void give(Item item);
}
private ISceneReferent linked;
private String name = "Default Request Name";
private IItemPredicate acceptedItems = IItemPredicate.NONE;
private FItemHandler itemHandler;
private FGetPositions positionsFn = () -> new Vector2i[] {};
public DItemRequest(ISceneReferent linked, String name) {
this.linked = linked;
}
// === fluent API
public DItemRequest accepts(IItemPredicate accepts) {
acceptedItems = accepts;
return this;
}
public DItemRequest handleItem(FItemHandler handler) {
itemHandler = handler;
return this;
}
public DItemRequest positions(Vector2i[] poss) {
positionsFn = () -> {
return poss;
};
return this;
}
public DItemRequest position(Vector2i pos) {
var arr = pos.asArray();
positionsFn = () -> {
return arr;
};
return this;
}
public DItemRequest positions(FGetPositions f) {
positionsFn = f;
return this;
}
// === public API
public Vector2i[] getLocations() {
return positionsFn.get();
}
public final boolean accepts(Item i) {
return acceptedItems.matches(i);
}
public void give(Item item) {
if(!accepts(item)) throw new Error("Unaccepted Item given to receiver!");
itemHandler.give(item);
item.destroy();
}
@Override
public void onRemoved(GameObjectCallback callback) {
linked.onRemoved(callback);
}
public String getName() {
return name;
}
public SceneReference<DItemRequest> asRef() {
return new SceneReference<DItemRequest>(this);
}
}

View File

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

View File

@ -1,16 +0,0 @@
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

@ -4,7 +4,20 @@ import java.io.Serializable;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item; import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
@FunctionalInterface
public interface IItemPredicate extends Serializable { public interface IItemPredicate extends Serializable {
public boolean matches(Item item); public boolean matches(Item item);
public String getName();
public static IItemPredicate NONE = new IItemPredicate() {
@Override
public boolean matches(Item item) {
return false;
}
@Override
public String getName() {
return "Nothing";
}
};
} }

View File

@ -1,20 +0,0 @@
package xyz.valnet.hadean.interfaces;
import java.io.Serializable;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
public interface IItemReceiver extends Serializable {
public boolean receive(Item item);
public Vector2i[] getItemDropoffLocations();
public String getName();
public default boolean give(Item item) {
if(receive(item)) {
item.destroy();
return true;
}
return false;
}
}

View File

@ -0,0 +1,7 @@
package xyz.valnet.hadean.interfaces;
import xyz.valnet.engine.scenegraph.SceneGraph.GameObjectCallback;
public interface ISceneReferent {
public void onRemoved(GameObjectCallback callback);
}

View File

@ -3,9 +3,10 @@ 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.engine.util.SceneReference;
import xyz.valnet.hadean.enums.WorkType; import xyz.valnet.hadean.enums.WorkType;
public interface IWorkable extends Serializable, IDestinationProvider { public interface IWorkable extends Serializable, IDestination, ISceneReferent {
public WorkType getWorkType(); public WorkType getWorkType();
public boolean doWork(float dTime); public boolean doWork(float dTime);
public Vector2i[] getWorkablePositions(); public Vector2i[] getWorkablePositions();
@ -16,4 +17,7 @@ public interface IWorkable extends Serializable, IDestinationProvider {
return getWorkablePositions(); return getWorkablePositions();
} }
public default SceneReference<IWorkable> asRef() {
return new SceneReference<>(this);
}
} }

View File

@ -7,7 +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; import xyz.valnet.hadean.interfaces.IDestination;
public class AStarPathfinder implements IPathfinder, Serializable { public class AStarPathfinder implements IPathfinder, Serializable {
@ -163,7 +163,7 @@ public class AStarPathfinder implements IPathfinder, Serializable {
} }
@Override @Override
public Path getBestPath(Vector2i src, IDestinationProvider provider) { public Path getBestPath(Vector2i src, IDestination provider) {
var dsts = provider.getDestinations(); var dsts = provider.getDestinations();

View File

@ -1,7 +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; import xyz.valnet.hadean.interfaces.IDestination;
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);
@ -14,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, IDestinationProvider dsts); public Path getBestPath(Vector2i src, IDestination dsts);
} }

View File

@ -1,5 +1,8 @@
package xyz.valnet.hadean.scenes; package xyz.valnet.hadean.scenes;
import java.util.Set;
import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.engine.scenegraph.SceneGraph; import xyz.valnet.engine.scenegraph.SceneGraph;
import xyz.valnet.engine.util.Names; import xyz.valnet.engine.util.Names;
import xyz.valnet.hadean.gameobjects.ui.BottomBar; import xyz.valnet.hadean.gameobjects.ui.BottomBar;
@ -32,37 +35,34 @@ import xyz.valnet.hadean.gameobjects.worldobjects.agents.pawn.Pawn;
public class GameScene extends SceneGraph { public class GameScene extends SceneGraph {
@Override @Override
protected void construct() { protected void construct(Set<GameObject> scene) {
Names.loadNames(); Names.loadNames();
objects.add(new Terrain()); scene.add(new Terrain());
objects.add(new Camera()); scene.add(new Camera());
objects.add(new JobBoard()); scene.add(new JobBoard());
objects.add(new Clock()); scene.add(new Clock());
for(int i = 0; i < 1; i ++) { for(int i = 0; i < 1; i ++) {
objects.add(new Pawn()); scene.add(new Pawn());
} }
objects.add(new WorkOrderManager()); scene.add(new WorkOrderManager());
objects.add(new ExclusivityManager()); scene.add(new ExclusivityManager());
objects.add(new SelectionLayer()); scene.add(new SelectionLayer());
objects.add(new BuildLayer()); scene.add(new BuildLayer());
objects.add(new WorkshopOrdersUI()); scene.add(new WorkshopOrdersUI());
objects.add(new SelectionUI()); scene.add(new SelectionUI());
objects.add(new HoverQuery()); scene.add(new HoverQuery());
objects.add(new BottomBar()); scene.add(new BottomBar());
objects.add(new BuildTab()); scene.add(new BuildTab());
objects.add(new JobBoardTab()); scene.add(new JobBoardTab());
objects.add(new DebugTab()); scene.add(new DebugTab());
objects.add(new MenuTab()); scene.add(new MenuTab());
// objects.add(new Popup());
} }
} }