beds are slightly better.

world-object-unification-project
Ivory 2023-01-04 03:33:20 -05:00
parent 2e1533d9d0
commit 1af8f12a99
9 changed files with 128 additions and 8 deletions

View File

@ -0,0 +1,3 @@
0 1 2 3 4
| 0xACED | short version |

View File

@ -2,12 +2,15 @@ package xyz.valnet.hadean.gameobjects;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
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.GameObject; import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.gameobjects.worldobjects.Stockpile; import xyz.valnet.hadean.gameobjects.worldobjects.Stockpile;
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.IItemReceiver; import xyz.valnet.hadean.interfaces.IItemReceiver;
import xyz.valnet.hadean.interfaces.IWorkable; import xyz.valnet.hadean.interfaces.IWorkable;
@ -42,6 +45,52 @@ public class Job extends GameObject {
} }
} }
public class DropoffPredicateAtItemReceiver extends JobStep {
public IItemReceiver receiver;
public IItemPredicate predicate;
public DropoffPredicateAtItemReceiver(IItemReceiver receiver, IItemPredicate predicate) {
this.receiver = receiver;
this.predicate = predicate;
}
@Override
public Vector2i[] getLocations() {
return receiver.getItemDropoffLocations();
}
@Override
public boolean isValid() {
return true;
}
}
public class PickupItemByPredicate extends JobStep {
public IItemPredicate predicate;
public PickupItemByPredicate(IItemPredicate predicate) {
this.predicate = predicate;
}
@Override
public Vector2i[] getLocations() {
Set<Vector2i> positionSet = new HashSet<Vector2i>();
for(Item item : that.getAll(Item.class)) {
if(!item.matches(predicate)) continue;
positionSet.add(item.getWorldPosition().asInt());
}
Vector2i[] positions = new Vector2i[positionSet.size()];
positionSet.toArray(positions);
return positions;
}
@Override
public boolean isValid() {
return getLocations().length > 0;
}
}
public class DropoffAtItemReceiver extends JobStep { public class DropoffAtItemReceiver extends JobStep {
public IItemReceiver receiver; public IItemReceiver receiver;

View File

@ -12,6 +12,7 @@ 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;
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.ITileThing; import xyz.valnet.hadean.interfaces.ITileThing;
import xyz.valnet.hadean.interfaces.IWorkable; import xyz.valnet.hadean.interfaces.IWorkable;
import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Assets;
@ -23,7 +24,6 @@ public class Tile extends WorldObject implements IWorkable {
private static int greenSeed = (int)(Math.random() * 10000); private static int greenSeed = (int)(Math.random() * 10000);
private static int blueSeed = (int)(Math.random() * 10000); private static int blueSeed = (int)(Math.random() * 10000);
// private final int x, y;
private Vector4f color; private Vector4f color;
private final int tileSelector = (int)Math.floor(Math.random() * 4); private final int tileSelector = (int)Math.floor(Math.random() * 4);
private boolean rocks = false; private boolean rocks = false;
@ -80,6 +80,18 @@ public class Tile extends WorldObject implements IWorkable {
return true; return true;
} }
public Item pickupByItemPredicate(IItemPredicate itemPredicate) {
for(ITileThing thing : stuff) {
if(thing instanceof Item) {
Item item = (Item) thing;
if(item.matches(itemPredicate)) {
return removeThing(item);
}
}
}
return null;
}
public void placeThing(ITileThing thing) { public void placeThing(ITileThing thing) {
stuff.add(thing); stuff.add(thing);
if(thing instanceof GameObject) { if(thing instanceof GameObject) {

View File

@ -33,13 +33,10 @@ public class Bed extends WorldObject implements IBuildable, IItemReceiver, IWork
@Override @Override
protected void create() { protected void create() {
super.create(); super.create();
// TODO eventually we're going to need a serializable ItemPredicate to select valid items.
// it will be useful for stockpile filters, pickup items, etc. basically a placeholder
// for "any item that matches X" as a data type.
job = add(new Job("Build Bed")); job = add(new Job("Build Bed"));
Log log = get(Log.class); Log log = get(Log.class);
job.addStep(job.new PickupItem(log)); job.addStep(job.new PickupItemByPredicate(Log.LOG_PREDICATE));
job.addStep(job.new DropoffAtItemReceiver(this, log)); job.addStep(job.new DropoffPredicateAtItemReceiver(this, Log.LOG_PREDICATE));
job.addStep(job.new Work(this)); job.addStep(job.new Work(this));
get(JobBoard.class).postJob(job); get(JobBoard.class).postJob(job);
} }
@ -76,6 +73,8 @@ public class Bed extends WorldObject implements IBuildable, IItemReceiver, IWork
@Override @Override
public boolean receive(Item item) { public boolean receive(Item item) {
if(item == null) return false;
if(!item.matches(Log.LOG_PREDICATE)) return false;
remove(item); remove(item);
logs ++; logs ++;
return true; return true;

View File

@ -5,6 +5,7 @@ import xyz.valnet.hadean.gameobjects.Job;
import xyz.valnet.hadean.gameobjects.JobBoard; import xyz.valnet.hadean.gameobjects.JobBoard;
import xyz.valnet.hadean.gameobjects.Tile; import xyz.valnet.hadean.gameobjects.Tile;
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.ISelectable; import xyz.valnet.hadean.interfaces.ISelectable;
import xyz.valnet.hadean.interfaces.ITileThing; import xyz.valnet.hadean.interfaces.ITileThing;
import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Action;
@ -92,4 +93,8 @@ public abstract class Item extends WorldObject implements ISelectable, ITileThin
this.x = tile.getCoords().x; this.x = tile.getCoords().x;
this.y = tile.getCoords().y; this.y = tile.getCoords().y;
} }
public boolean matches(IItemPredicate itemPredicate) {
return itemPredicate.matches(this);
}
} }

View File

@ -1,5 +1,6 @@
package xyz.valnet.hadean.gameobjects.worldobjects.items; package xyz.valnet.hadean.gameobjects.worldobjects.items;
import xyz.valnet.hadean.interfaces.IItemPredicate;
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.Detail; import xyz.valnet.hadean.util.detail.Detail;
@ -11,6 +12,8 @@ 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 Log(int x, int y) { public Log(int x, int y) {
this.x = x; this.x = x;
this.y = y; this.y = y;

View File

@ -82,7 +82,8 @@ public class JobActivity extends Activity {
jobboard.quitJob(worker, job); jobboard.quitJob(worker, job);
job = null; job = null;
} }
// TODO pawns should keep tabs of what job step an item is picked up from
// so dropoff steps can reference the pickup step.
private boolean doJob(float dTime) { private boolean doJob(float dTime) {
if(!jobboard.workerHasJob(worker)) return false; if(!jobboard.workerHasJob(worker)) return false;
JobStep step = job.getCurrentStep(); JobStep step = job.getCurrentStep();
@ -108,6 +109,17 @@ public class JobActivity extends Activity {
Job.DropoffAtItemReceiver dropoffStep = (Job.DropoffAtItemReceiver) step; Job.DropoffAtItemReceiver dropoffStep = (Job.DropoffAtItemReceiver) step;
worker.dropoffItem(dropoffStep.item, dropoffStep.receiver); worker.dropoffItem(dropoffStep.item, dropoffStep.receiver);
step.next(); step.next();
return true;
} else if(step instanceof Job.DropoffPredicateAtItemReceiver) {
Job.DropoffPredicateAtItemReceiver dropoffStep = (Job.DropoffPredicateAtItemReceiver) step;
worker.dropoffPredicate(dropoffStep.predicate, dropoffStep.receiver);
step.next();
return true;
} else if(step instanceof Job.PickupItemByPredicate) {
Job.PickupItemByPredicate pickupStep = (Job.PickupItemByPredicate) step;
worker.pickupItemByPredicate(pickupStep.predicate);
step.next();
return true;
} }
return false; return false;

View File

@ -13,6 +13,7 @@ import xyz.valnet.hadean.gameobjects.JobBoard;
import xyz.valnet.hadean.gameobjects.Terrain; import xyz.valnet.hadean.gameobjects.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.interfaces.IItemPredicate;
import xyz.valnet.hadean.interfaces.IItemReceiver; import xyz.valnet.hadean.interfaces.IItemReceiver;
import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Action;
import xyz.valnet.hadean.util.Assets; import xyz.valnet.hadean.util.Assets;
@ -37,6 +38,15 @@ public class Pawn extends Agent {
private transient List<Activity> activities = new ArrayList<Activity>(); private transient List<Activity> activities = new ArrayList<Activity>();
private Activity currentActivity = null; private Activity currentActivity = null;
private Item heldItem = null;
public void pickupItemByPredicate(IItemPredicate itemPredicate) {
Item item = getTile().pickupByItemPredicate(itemPredicate);
if(item == null) return;
remove(item);
inventory.add(item);
}
public void pickupItem(Item i) { public void pickupItem(Item i) {
Item item = getTile().removeThing(i); Item item = getTile().removeThing(i);
if(item == null) return; if(item == null) return;
@ -62,6 +72,22 @@ public class Pawn extends Agent {
receiver.receive(item); receiver.receive(item);
} }
private Item getInventoryItemByPredicate(IItemPredicate predicate) {
for(Item item : inventory) {
if(!item.matches(predicate)) continue;
return item;
}
return null;
}
public void dropoffPredicate(IItemPredicate predicate, IItemReceiver receiver) {
Item item = getInventoryItemByPredicate(predicate);
if(!inventory.contains(item)) {
return;
}
dropoffItem(item, receiver);
}
@Override @Override
protected void ready() { protected void ready() {
super.ready(); super.ready();
@ -102,7 +128,8 @@ public class Pawn extends Agent {
return mergeDetails(needs.getDetails(), new Detail[] { return mergeDetails(needs.getDetails(), new Detail[] {
new ObjectDetail<Activity>("Activity", currentActivity), new ObjectDetail<Activity>("Activity", currentActivity),
new PercentDetail("Sleep Value", activities.get(1).getBenefit(), 2), new PercentDetail("Sleep Value", activities.get(1).getBenefit(), 2),
new BooleanDetail("Pathing", isPathing()) new BooleanDetail("Pathing", isPathing()),
new ObjectDetail<Integer>("Inventory", inventory.size())
}); });
} }

View File

@ -0,0 +1,10 @@
package xyz.valnet.hadean.interfaces;
import java.io.Serializable;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
@FunctionalInterface
public interface IItemPredicate extends Serializable {
public boolean matches(Item item);
}