workorder stuff
parent
c4bfd44cc9
commit
10d86c45ab
|
|
@ -152,4 +152,8 @@ public class Box implements Serializable {
|
|||
(float) Math.ceil(y2)
|
||||
);
|
||||
}
|
||||
|
||||
public TileBox asTileBox() {
|
||||
return new TileBox(pos.asInt(), dim.asInt());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
package xyz.valnet.engine.math;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TileBox implements Serializable {
|
||||
public final int x, y;
|
||||
|
|
@ -49,6 +53,16 @@ public class TileBox implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public List<Vector2i> getTiles() {
|
||||
List<Vector2i> tiles = new ArrayList<>();
|
||||
for(int i = 0; i < w; i ++) {
|
||||
for(int j = 0; j < h; j ++) {
|
||||
tiles.add(new Vector2i(x + i, y + j));
|
||||
}
|
||||
}
|
||||
return tiles;
|
||||
}
|
||||
|
||||
public static TileBox fromPoints(int x, int y, int x2, int y2) {
|
||||
return new TileBox(
|
||||
x <= x2 ? x : x2,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class Job extends GameObject {
|
|||
|
||||
private Job that = this;
|
||||
private List<Callback> closedListeners = new ArrayList<Callback>();
|
||||
private List<Callback> completedListeners = new ArrayList<Callback>();
|
||||
|
||||
public abstract class JobStep implements Serializable {
|
||||
public abstract Vector2i[] getLocations();
|
||||
|
|
@ -27,6 +28,10 @@ public class Job extends GameObject {
|
|||
public abstract boolean isValid();
|
||||
}
|
||||
|
||||
// pickup and dropoff should be all in one step, as each step should
|
||||
// only need state tracked for the job, not the worker.
|
||||
// workers can change between steps.
|
||||
@Deprecated
|
||||
public class PickupItem extends JobStep {
|
||||
public Item item;
|
||||
|
||||
|
|
@ -66,6 +71,10 @@ public class Job extends GameObject {
|
|||
}
|
||||
}
|
||||
|
||||
// pickup and dropoff should be all in one step, as each step should
|
||||
// only need state tracked for the job, not the worker.
|
||||
// workers can change between steps.
|
||||
@Deprecated
|
||||
public class PickupItemByPredicate extends JobStep {
|
||||
public IItemPredicate predicate;
|
||||
|
||||
|
|
@ -156,6 +165,7 @@ public class Job extends GameObject {
|
|||
private String name;
|
||||
private int step;
|
||||
private boolean hasClosed = false;
|
||||
private boolean hasCompleted = false;
|
||||
|
||||
public void reset() {
|
||||
step = 0;
|
||||
|
|
@ -179,7 +189,7 @@ public class Job extends GameObject {
|
|||
public void nextStep() {
|
||||
step ++;
|
||||
if(isCompleted()) {
|
||||
close();
|
||||
completed();
|
||||
remove(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -202,6 +212,15 @@ public class Job extends GameObject {
|
|||
public void apply();
|
||||
}
|
||||
|
||||
private final void completed() {
|
||||
if(hasCompleted) return;
|
||||
hasCompleted = true;
|
||||
for(Callback callback : completedListeners) {
|
||||
callback.apply();
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if(hasClosed) return;
|
||||
hasClosed = true;
|
||||
|
|
@ -218,6 +237,14 @@ public class Job extends GameObject {
|
|||
closedListeners.remove(callback);
|
||||
}
|
||||
|
||||
public void registerCompletedListener(Callback callback) {
|
||||
completedListeners.add(callback);
|
||||
}
|
||||
|
||||
public void unregisterCompletedListener(Callback callback) {
|
||||
completedListeners.remove(callback);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
for(JobStep step : steps) {
|
||||
if(!step.isValid()) return false;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ public class JobBoard extends GameObject {
|
|||
}
|
||||
|
||||
public void postJob(Job job) {
|
||||
if(!job.inScene()) add(job);
|
||||
job.registerClosedListener(() -> {
|
||||
if(allocations.values().contains(job)) {
|
||||
List<Pawn> toFire = new ArrayList<Pawn>();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
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.GameObject;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
|
||||
import xyz.valnet.hadean.interfaces.IItemReceiver;
|
||||
import xyz.valnet.hadean.interfaces.IWorkshop;
|
||||
|
||||
public class WorkOrder extends GameObject {
|
||||
|
|
@ -9,6 +16,9 @@ public class WorkOrder extends GameObject {
|
|||
private int count = 10;
|
||||
private String name = "Cut Stone Blocks";
|
||||
private IWorkshop shop = null;
|
||||
private float maxWork = 1000;
|
||||
|
||||
private Set<Job> relatedJobs;
|
||||
|
||||
public boolean getRecurring() {
|
||||
return recurring;
|
||||
|
|
@ -22,6 +32,10 @@ public class WorkOrder extends GameObject {
|
|||
return name;
|
||||
}
|
||||
|
||||
public float getMaxWork() {
|
||||
return maxWork;
|
||||
}
|
||||
|
||||
public void increaseCount() {
|
||||
count ++;
|
||||
}
|
||||
|
|
@ -40,6 +54,47 @@ public class WorkOrder extends GameObject {
|
|||
}
|
||||
|
||||
public boolean isSpecificToShop(IWorkshop shop) {
|
||||
return this.shop != null && shop == this.shop;
|
||||
return this.shop != null && this.shop == shop;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() {
|
||||
super.create();
|
||||
relatedJobs = new HashSet<>();
|
||||
}
|
||||
|
||||
public boolean isBeingWorkedOn() {
|
||||
return relatedJobs.size() > 0;
|
||||
}
|
||||
|
||||
public boolean canCreateJob() {
|
||||
return count > relatedJobs.size();
|
||||
}
|
||||
|
||||
public Job createNextJob(IWorkshop shop) {
|
||||
Job job = new Job("Cut brickies");
|
||||
job.addStep(job.new PickupItemByPredicate(Boulder.BOULDER_PREDICATE));
|
||||
job.addStep(job.new DropoffPredicateAtItemReceiver(new IItemReceiver() {
|
||||
@Override
|
||||
public boolean receive(Item item) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2i[] getItemDropoffLocations() {
|
||||
return shop.getWorkablePositions();
|
||||
}
|
||||
}, Boulder.BOULDER_PREDICATE));
|
||||
job.addStep(job.new Work(shop));
|
||||
job.registerCompletedListener(() -> {
|
||||
decreaseCount();
|
||||
|
||||
});
|
||||
job.registerClosedListener(() -> {
|
||||
relatedJobs.remove(job);
|
||||
});
|
||||
get(JobBoard.class).postJob(job);
|
||||
return job;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ import xyz.valnet.hadean.gameobjects.Camera;
|
|||
import xyz.valnet.hadean.gameobjects.terrain.Terrain;
|
||||
import xyz.valnet.hadean.gameobjects.terrain.Tile;
|
||||
import xyz.valnet.hadean.interfaces.ITileThing;
|
||||
import xyz.valnet.hadean.interfaces.IWorldObject;
|
||||
|
||||
public abstract class WorldObject extends GameObject {
|
||||
public abstract class WorldObject extends GameObject implements IWorldObject {
|
||||
|
||||
// TODO make it just a box lawl
|
||||
private int x;
|
||||
|
|
@ -119,6 +120,10 @@ public abstract class WorldObject extends GameObject {
|
|||
return terrain.getTile(x, y);
|
||||
}
|
||||
|
||||
public Tile getTile(int x, int y) {
|
||||
return terrain.getTile(x, y);
|
||||
}
|
||||
|
||||
public Set<Tile> getTiles() {
|
||||
return linkedTiles;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import xyz.valnet.hadean.HadeanGame;
|
|||
import xyz.valnet.hadean.gameobjects.Clock;
|
||||
import xyz.valnet.hadean.gameobjects.jobs.JobBoard;
|
||||
import xyz.valnet.hadean.gameobjects.terrain.Terrain;
|
||||
import xyz.valnet.hadean.gameobjects.ui.tabs.DebugTab;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.agents.Agent;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
|
||||
import xyz.valnet.hadean.interfaces.IItemPredicate;
|
||||
|
|
@ -42,6 +43,9 @@ public class Pawn extends Agent {
|
|||
|
||||
public void pickupItemByPredicate(IItemPredicate itemPredicate) {
|
||||
Item item = getTile().pickupByItemPredicate(itemPredicate);
|
||||
if(item == null) {
|
||||
DebugTab.log("This is an issue");
|
||||
}
|
||||
inventory.add(item);
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +70,8 @@ public class Pawn extends Agent {
|
|||
return;
|
||||
}
|
||||
inventory.remove(item);
|
||||
add(item);
|
||||
// TODO this might need to exist at some point
|
||||
// add(item);
|
||||
receiver.receive(item);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import xyz.valnet.hadean.util.Action;
|
|||
import xyz.valnet.hadean.util.Assets;
|
||||
import xyz.valnet.hadean.util.Layers;
|
||||
|
||||
public abstract class Construction extends Buildable implements IItemReceiver {
|
||||
public abstract class Construction extends Buildable {
|
||||
|
||||
private float work = 0;
|
||||
|
||||
|
|
@ -36,7 +36,23 @@ public abstract class Construction extends Buildable implements IItemReceiver {
|
|||
Job job = get(JobBoard.class).postSimpleItemRequirementJob(
|
||||
"Haul items to building",
|
||||
getBuildingMaterial(),
|
||||
this
|
||||
new IItemReceiver() {
|
||||
|
||||
@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
|
||||
public Vector2i[] getItemDropoffLocations() {
|
||||
return getWorldBox().getBorders();
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
job.registerClosedListener(() -> {
|
||||
postNextJob();
|
||||
|
|
@ -108,20 +124,6 @@ public abstract class Construction extends Buildable implements IItemReceiver {
|
|||
return work / getMaxWork();
|
||||
}
|
||||
|
||||
@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
|
||||
public Vector2i[] getItemDropoffLocations() {
|
||||
return getWorldBox().getBorders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
Sprite sprite = getDefaultSprite();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
package xyz.valnet.hadean.gameobjects.worldobjects.constructions;
|
||||
|
||||
import xyz.valnet.engine.graphics.Sprite;
|
||||
import xyz.valnet.engine.math.TileBox;
|
||||
import xyz.valnet.engine.math.Vector2i;
|
||||
import xyz.valnet.hadean.gameobjects.jobs.Job;
|
||||
import xyz.valnet.hadean.gameobjects.jobs.WorkOrder;
|
||||
import xyz.valnet.hadean.gameobjects.jobs.WorkOrderManager;
|
||||
import xyz.valnet.hadean.gameobjects.ui.WorkshopOrdersUI;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.items.Log;
|
||||
import xyz.valnet.hadean.interfaces.IItemPredicate;
|
||||
import xyz.valnet.hadean.interfaces.IWorkshop;
|
||||
|
|
@ -13,6 +18,10 @@ public class MasonWorkshop extends Construction implements IWorkshop {
|
|||
|
||||
private static Action OPEN_ORDERS = new Action("Orders");
|
||||
private transient WorkshopOrdersUI ordersWindow;
|
||||
private WorkOrderManager manager;
|
||||
|
||||
// TODO the job itself should have the work amount...
|
||||
private float workDone = 0;
|
||||
|
||||
@Override
|
||||
protected IItemPredicate getBuildingMaterial() {
|
||||
|
|
@ -62,6 +71,7 @@ public class MasonWorkshop extends Construction implements IWorkshop {
|
|||
protected void connect() {
|
||||
super.connect();
|
||||
ordersWindow = get(WorkshopOrdersUI.class);
|
||||
manager = get(WorkOrderManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -74,4 +84,51 @@ public class MasonWorkshop extends Construction implements IWorkshop {
|
|||
return "Workshops";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doWork(float dTime) {
|
||||
workDone += dTime;
|
||||
return workDone > order.getMaxWork();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2i[] getWorkablePositions() {
|
||||
return getWorldBox().getBorders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJobName() {
|
||||
return "Do Work as Workshop";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileBox getSpawnableArea() {
|
||||
return getWorldBox().asTileBox();
|
||||
}
|
||||
|
||||
private Job job = null;
|
||||
private WorkOrder order = null;
|
||||
|
||||
@Override
|
||||
public void update(float dTime) {
|
||||
super.update(dTime);
|
||||
if(job == null) {
|
||||
tryGetJob();
|
||||
}
|
||||
}
|
||||
|
||||
private final void tryGetJob() {
|
||||
for(WorkOrder order : manager.getOrders(this)) {
|
||||
if(order.canCreateJob()) {
|
||||
this.order = order;
|
||||
job = order.createNextJob(this);
|
||||
job.registerClosedListener(() -> {
|
||||
workDone = 0;
|
||||
job = null;
|
||||
this.order = null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
package xyz.valnet.hadean.interfaces;
|
||||
|
||||
import xyz.valnet.engine.math.TileBox;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
|
||||
|
||||
public interface IItemSpawner extends IWorldObject {
|
||||
public abstract TileBox getSpawnableArea();
|
||||
|
||||
public default void spawn(Item item) {
|
||||
var tiles = getSpawnableArea().getTiles();
|
||||
while(tiles.size() > 0) {
|
||||
int idx = (int) Math.floor(Math.random() * tiles.size());
|
||||
var pos = tiles.get(idx);
|
||||
getTile(pos.x, pos.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,5 +7,7 @@ import xyz.valnet.engine.math.Vector2i;
|
|||
public interface IWorkable extends Serializable {
|
||||
public boolean doWork(float dTime);
|
||||
public Vector2i[] getWorkablePositions();
|
||||
// we should honestly switch to only have names of jobs not steps...
|
||||
@Deprecated
|
||||
public String getJobName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package xyz.valnet.hadean.interfaces;
|
||||
|
||||
public interface IWorkshop extends ISelectable {
|
||||
|
||||
public interface IWorkshop extends ISelectable,
|
||||
IWorkable,
|
||||
IItemSpawner {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package xyz.valnet.hadean.interfaces;
|
||||
|
||||
import xyz.valnet.hadean.gameobjects.terrain.Tile;
|
||||
|
||||
public interface IWorldObject {
|
||||
public Tile getTile(int x, int y);
|
||||
}
|
||||
Loading…
Reference in New Issue