new job system. QoL things
parent
95cf571450
commit
a1fcec4f26
|
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
"java.configuration.updateBuildConfiguration": "automatic"
|
"java.configuration.updateBuildConfiguration": "automatic",
|
||||||
|
"java.dependency.packagePresentation": "hierarchical"
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package xyz.valnet.engine;
|
package xyz.valnet.engine;
|
||||||
|
|
||||||
import org.lwjgl.*;
|
|
||||||
import org.lwjgl.glfw.*;
|
import org.lwjgl.glfw.*;
|
||||||
import org.lwjgl.opengl.*;
|
import org.lwjgl.opengl.*;
|
||||||
import org.lwjgl.system.*;
|
import org.lwjgl.system.*;
|
||||||
|
|
@ -29,7 +28,6 @@ public class App {
|
||||||
private Game game;
|
private Game game;
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
|
|
||||||
|
|
||||||
init();
|
init();
|
||||||
loop();
|
loop();
|
||||||
|
|
@ -55,7 +53,7 @@ public class App {
|
||||||
// Configure GLFW
|
// Configure GLFW
|
||||||
glfwDefaultWindowHints(); // optional, the current window hints are already the default
|
glfwDefaultWindowHints(); // optional, the current window hints are already the default
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); // the window will be resizable
|
||||||
|
|
||||||
// Create the window
|
// Create the window
|
||||||
window = glfwCreateWindow(width, height, "Hello World!", NULL, NULL);
|
window = glfwCreateWindow(width, height, "Hello World!", NULL, NULL);
|
||||||
|
|
@ -86,7 +84,6 @@ public class App {
|
||||||
game.mouseUp(button);
|
game.mouseUp(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO deprecate these.
|
|
||||||
if(button >= 3) return;
|
if(button >= 3) return;
|
||||||
if(button == GLFW_MOUSE_BUTTON_LEFT) { mouseLeft = action == 1; return; }
|
if(button == GLFW_MOUSE_BUTTON_LEFT) { mouseLeft = action == 1; return; }
|
||||||
if(button == GLFW_MOUSE_BUTTON_RIGHT) { mouseRight = action == 1; return; }
|
if(button == GLFW_MOUSE_BUTTON_RIGHT) { mouseRight = action == 1; return; }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package xyz.valnet.engine.graphics;
|
package xyz.valnet.engine.graphics;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
|
||||||
public class Tile9 {
|
public class Tile9 {
|
||||||
|
|
||||||
private final Sprite topLeft;
|
private final Sprite topLeft;
|
||||||
|
|
@ -34,6 +36,10 @@ public class Tile9 {
|
||||||
this.bottomRight = bottomRight;
|
this.bottomRight = bottomRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void draw(Vector4f box) {
|
||||||
|
draw((int)box.x, (int)box.y, (int)box.z, (int)box.w);
|
||||||
|
}
|
||||||
|
|
||||||
public void draw(int x, int y, int w, int h) {
|
public void draw(int x, int y, int w, int h) {
|
||||||
int a = w < 0 ? x + w : x; // top left x
|
int a = w < 0 ? x + w : x; // top left x
|
||||||
int b = h < 0 ? y + h : y; // top left y
|
int b = h < 0 ? y + h : y; // top left y
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,12 @@ public class Vector2f {
|
||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2i asInt() {
|
||||||
|
return new Vector2i((int)x, (int)y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Vector2f v) {
|
||||||
|
return x == v.x && y == v.y;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,4 +33,8 @@ public class Vector2i {
|
||||||
return (float) Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
|
return (float) Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2f asFloat() {
|
||||||
|
return new Vector2f(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,4 +34,22 @@ public class Vector4f {
|
||||||
return x >= this.x && x < this.x + this.z && y >= this.y && y < this.y + this.w;
|
return x >= this.x && x < this.x + this.z && y >= this.y && y < this.y + this.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector4f toAABB() {
|
||||||
|
return new Vector4f(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
x + z,
|
||||||
|
y + w
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector4f toXYWH() {
|
||||||
|
return new Vector4f(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
z - x,
|
||||||
|
w - y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,13 @@ public class GameObject implements IRenderable, ITickable {
|
||||||
return this.scene.getAll(clazz);
|
return this.scene.getAll(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void add(GameObject obj) {
|
protected final <T extends GameObject> T add(T obj) {
|
||||||
if(obj.inScene()) {
|
if(obj.inScene()) {
|
||||||
System.out.println(obj + " is already in the scene. not adding twice...");
|
System.out.println(obj + " is already in the scene. not adding twice...");
|
||||||
return;
|
return obj;
|
||||||
}
|
}
|
||||||
scene.add(obj);
|
scene.add(obj);
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,11 @@ public class Math {
|
||||||
if(n <= 0) return a;
|
if(n <= 0) return a;
|
||||||
return a + (b - a) * n;
|
return a + (b - a) * n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float lerp(float minT, float maxT, float t, float outMin, float outMax) {
|
||||||
|
if (t <= minT) return outMin;
|
||||||
|
if (t >= maxT) return outMax;
|
||||||
|
float scale = (t - minT) / (maxT - minT);
|
||||||
|
return outMin + (scale * (outMax - outMin));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import xyz.valnet.engine.Game;
|
||||||
import xyz.valnet.engine.graphics.Drawing;
|
import xyz.valnet.engine.graphics.Drawing;
|
||||||
import xyz.valnet.engine.math.Matrix4f;
|
import xyz.valnet.engine.math.Matrix4f;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
import xyz.valnet.hadean.scenes.GameScene;
|
||||||
import xyz.valnet.hadean.scenes.MenuScene;
|
import xyz.valnet.hadean.scenes.MenuScene;
|
||||||
import xyz.valnet.hadean.util.Assets;
|
import xyz.valnet.hadean.util.Assets;
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ public class HadeanGame extends Game {
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
Assets.flat.pushColor(Vector4f.one);
|
Assets.flat.pushColor(Vector4f.one);
|
||||||
changeScene(new MenuScene());
|
changeScene(new GameScene());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package xyz.valnet.hadean.designation;
|
||||||
|
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.Tree;
|
||||||
|
import xyz.valnet.hadean.interfaces.BuildableMetadata;
|
||||||
|
|
||||||
|
@BuildableMetadata(category = "Designations", name = "Chop Trees")
|
||||||
|
public class CutTreesDesignation extends Designation<Tree> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<Tree> getType() {
|
||||||
|
return Tree.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void designate(Tree thing) {
|
||||||
|
thing.runAction(Tree.ACTION_CHOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package xyz.valnet.hadean.designation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
|
import xyz.valnet.hadean.interfaces.IBuildable;
|
||||||
|
import xyz.valnet.hadean.interfaces.ISelectable;
|
||||||
|
|
||||||
|
public abstract class Designation<T extends ISelectable> extends GameObject implements IBuildable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void buildAt(int x, int y, int w, int h) {
|
||||||
|
Class<T> type = getType();
|
||||||
|
List<T> things = getAll(type);
|
||||||
|
for(ISelectable thing : things) {
|
||||||
|
Vector4f box = thing.getWorldBox();
|
||||||
|
if(rectanglesIntersect(x, y, x + w, y + h, box.x, box.y, box.z, box.w))
|
||||||
|
designate((T) thing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean rectanglesIntersect(
|
||||||
|
float minAx, float minAy, float maxAx, float maxAy,
|
||||||
|
float minBx, float minBy, float maxBx, float maxBy ) {
|
||||||
|
boolean aLeftOfB = maxAx <= minBx;
|
||||||
|
boolean aRightOfB = minAx >= maxBx;
|
||||||
|
boolean aAboveB = minAy >= maxBy;
|
||||||
|
boolean aBelowB = maxAy <= minBy;
|
||||||
|
|
||||||
|
return !( aLeftOfB || aRightOfB || aAboveB || aBelowB );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected abstract Class<T> getType();
|
||||||
|
protected abstract void designate(T thing);
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@ package xyz.valnet.hadean.gameobjects;
|
||||||
import xyz.valnet.engine.graphics.Drawing;
|
import xyz.valnet.engine.graphics.Drawing;
|
||||||
import xyz.valnet.engine.graphics.Sprite;
|
import xyz.valnet.engine.graphics.Sprite;
|
||||||
import xyz.valnet.engine.math.Vector2f;
|
import xyz.valnet.engine.math.Vector2f;
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.engine.scenegraph.GameObject;
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
import xyz.valnet.hadean.interfaces.IWorldBoundsAdapter;
|
import xyz.valnet.hadean.interfaces.IWorldBoundsAdapter;
|
||||||
|
|
@ -11,7 +10,7 @@ import xyz.valnet.hadean.interfaces.IWorldBoundsAdapter;
|
||||||
public class Camera extends GameObject {
|
public class Camera extends GameObject {
|
||||||
|
|
||||||
private int tileWidth = 16;
|
private int tileWidth = 16;
|
||||||
// TODO link these in some way to the real resolution.
|
// TODO link these in some way to the real resolution. lot of work here.
|
||||||
private int screenWidth = 1024, screenHeight = 576;
|
private int screenWidth = 1024, screenHeight = 576;
|
||||||
|
|
||||||
private Vector2f focus = new Vector2f(0, 0);
|
private Vector2f focus = new Vector2f(0, 0);
|
||||||
|
|
@ -39,8 +38,13 @@ public class Camera extends GameObject {
|
||||||
return new Vector2f((x - screenWidth / 2 + focus.x * tileWidth) / tileWidth, (y - screenHeight / 2 + focus.y * tileWidth) / tileWidth);
|
return new Vector2f((x - screenWidth / 2 + focus.x * tileWidth) / tileWidth, (y - screenHeight / 2 + focus.y * tileWidth) / tileWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2i screen2worldI(float x, float y) {
|
public Vector4f world2Screen(Vector4f input) {
|
||||||
return new Vector2i((int)Math.floor((x - screenWidth / 2 + focus.x * tileWidth) / tileWidth), (int)Math.floor((y - screenHeight / 2 + focus.y * tileWidth) / tileWidth));
|
return new Vector4f(
|
||||||
|
input.x * tileWidth + screenWidth / 2 - focus.x * tileWidth,
|
||||||
|
input.y * tileWidth + screenHeight / 2 - focus.y * tileWidth,
|
||||||
|
input.z * tileWidth + screenWidth / 2 - focus.x * tileWidth,
|
||||||
|
input.w * tileWidth + screenHeight / 2 - focus.y * tileWidth
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
package xyz.valnet.hadean.gameobjects;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector2f;
|
||||||
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.Stockpile;
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
|
||||||
|
import xyz.valnet.hadean.interfaces.IWorkable;
|
||||||
|
|
||||||
|
public class Job extends GameObject {
|
||||||
|
|
||||||
|
private Terrain terrain;
|
||||||
|
private Job that = this;
|
||||||
|
|
||||||
|
public abstract class JobStep {
|
||||||
|
public abstract Vector2f getLocation();
|
||||||
|
public void next() {
|
||||||
|
that.nextStep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PickupItem extends JobStep {
|
||||||
|
public Item item;
|
||||||
|
public Vector2f[] locations;
|
||||||
|
|
||||||
|
public PickupItem(Item item, Vector2f[] possibleLocations) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector2f getLocation() {
|
||||||
|
return item.getWorldPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DropoffAtStockpile extends JobStep {
|
||||||
|
public Item item;
|
||||||
|
public DropoffAtStockpile(Item item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2f getLocation() {
|
||||||
|
Stockpile pile = that.get(Stockpile.class);
|
||||||
|
Vector4f box = pile.getWorldBox();
|
||||||
|
return new Vector2f(box.x, box.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Work extends JobStep {
|
||||||
|
public IWorkable subject;
|
||||||
|
public Work(IWorkable subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Vector2f getLocation() {
|
||||||
|
return subject.getWorkablePositions()[0].asFloat();
|
||||||
|
}
|
||||||
|
public boolean doWork() {
|
||||||
|
return subject.doWork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<JobStep> steps;
|
||||||
|
private String name;
|
||||||
|
private int step;
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
step = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
this.terrain = get(Terrain.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Job(String name) {
|
||||||
|
this.steps = new ArrayList<JobStep>();
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addStep(JobStep step) {
|
||||||
|
steps.add(step);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2i getLocation() {
|
||||||
|
if(steps.size() == 0) throw new Error("Cannot get location of job with no steps");
|
||||||
|
JobStep step = steps.get(0);
|
||||||
|
return step.getLocation().asInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void nextStep() {
|
||||||
|
step ++;
|
||||||
|
if(isCompleted()) get(JobBoard.class).completeJob(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return step >= steps.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JobStep getCurrentStep() {
|
||||||
|
if(step >= steps.size()) return null;
|
||||||
|
return steps.get(step);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJobName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,24 +10,29 @@ import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector2f;
|
import xyz.valnet.engine.math.Vector2f;
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
|
||||||
import xyz.valnet.engine.scenegraph.GameObject;
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
import xyz.valnet.hadean.interfaces.IJob;
|
import xyz.valnet.hadean.interfaces.IWorkable;
|
||||||
import xyz.valnet.hadean.interfaces.IWorker;
|
import xyz.valnet.hadean.interfaces.IWorker;
|
||||||
import xyz.valnet.hadean.pathfinding.IPathfinder;
|
|
||||||
import xyz.valnet.hadean.pathfinding.Path;
|
|
||||||
import xyz.valnet.hadean.util.Pair;
|
import xyz.valnet.hadean.util.Pair;
|
||||||
|
|
||||||
public class JobBoard extends GameObject {
|
public class JobBoard extends GameObject {
|
||||||
|
|
||||||
private Set<IJob> availableJobs = new HashSet<IJob>();
|
private Set<Job> availableJobs = new HashSet<Job>();
|
||||||
private Map<IWorker, IJob> allocations = new HashMap<IWorker, IJob>();
|
private List<Job> toRemove = new ArrayList<Job>();
|
||||||
|
private Map<IWorker, Job> allocations = new HashMap<IWorker, Job>();
|
||||||
|
|
||||||
public void postJob(IJob job) {
|
public Job postSimpleWorkJob(String name, IWorkable subject) {
|
||||||
|
Job job = add(new Job(name));
|
||||||
|
job.addStep(job.new Work(subject));
|
||||||
|
postJob(job);
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postJob(Job job) {
|
||||||
availableJobs.add(job);
|
availableJobs.add(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rescindJob(IJob job) {
|
public void rescindJob(Job job) {
|
||||||
if(allocations.values().contains(job)) {
|
if(allocations.values().contains(job)) {
|
||||||
List<IWorker> toFire = new ArrayList<IWorker>();
|
List<IWorker> toFire = new ArrayList<IWorker>();
|
||||||
|
|
||||||
|
|
@ -49,27 +54,21 @@ public class JobBoard extends GameObject {
|
||||||
|
|
||||||
public void requestJob(IWorker worker) {
|
public void requestJob(IWorker worker) {
|
||||||
// TODO worker has capabilities?
|
// TODO worker has capabilities?
|
||||||
Vector2f workerLocation = worker.getLocation();
|
Vector2f workerLocation = worker.getWorldPosition();
|
||||||
IPathfinder pathfinder = worker.getPathfinder();
|
|
||||||
|
|
||||||
List<IJob> workables = availableJobs
|
List<Job> workables = availableJobs
|
||||||
.stream()
|
.stream()
|
||||||
// filter available job by the ones that currently have work
|
.map(job -> new Pair<Job, Float>(
|
||||||
// TODO seems like this should be removed at some point
|
job,
|
||||||
// and jobs should post / rescind when they need to
|
job.getLocation().distanceTo(
|
||||||
.filter(workable -> workable.hasWork())
|
|
||||||
// calculate our workers distance to each
|
|
||||||
.map(workable -> new Pair<IJob, Float>(
|
|
||||||
workable,
|
|
||||||
workable.getLocation().distanceTo(
|
|
||||||
(int) workerLocation.x,
|
(int) workerLocation.x,
|
||||||
(int) workerLocation.y
|
(int) workerLocation.y
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
// sort the jobs by their distance from the worker
|
// sort the jobs by their distance from the worker
|
||||||
.sorted(new Comparator<Pair<IJob, Float>>() {
|
.sorted(new Comparator<Pair<Job, Float>>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(Pair<IJob, Float> a, Pair<IJob, Float> b) {
|
public int compare(Pair<Job, Float> a, Pair<Job, Float> b) {
|
||||||
if(a.second() > b.second()) return 1;
|
if(a.second() > b.second()) return 1;
|
||||||
if(b.second() > a.second()) return -1;
|
if(b.second() > a.second()) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -81,38 +80,41 @@ public class JobBoard extends GameObject {
|
||||||
|
|
||||||
|
|
||||||
if(workables.size() > 0) {
|
if(workables.size() > 0) {
|
||||||
for(IJob job : workables) {
|
Job firstJob = workables.get(0);
|
||||||
if(!job.hasWork()) continue;
|
availableJobs.remove(firstJob);
|
||||||
Vector2i[] workablePositions = job.getWorkablePositions();
|
allocations.put(worker, firstJob);
|
||||||
Path bestPathToJob = pathfinder.getBestPath(
|
|
||||||
new Vector2i((int)Math.floor(workerLocation.x), (int)Math.floor(workerLocation.y)),
|
|
||||||
workablePositions
|
|
||||||
);
|
|
||||||
if(bestPathToJob == null) continue;
|
|
||||||
|
|
||||||
// it is decided. job is good, and path is hype
|
|
||||||
worker.setPath(bestPathToJob);
|
|
||||||
availableJobs.remove(job);
|
|
||||||
allocations.put(worker, job);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void completeJob(Job job) {
|
||||||
|
this.rescindJob(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void completeJob(IWorker worker) {
|
||||||
|
if(!workerHasJob(worker)) return;
|
||||||
|
rescindJob(getJob(worker));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dTime) {
|
public void update(float dTime) {
|
||||||
List<IJob> toRemove = new ArrayList<IJob>();
|
for(Job job : toRemove) {
|
||||||
for(IJob job : allocations.values()) {
|
if(allocations.values().contains(job)) {
|
||||||
if(!job.hasWork()) {
|
// I AM NOT SURE THIS WORKS
|
||||||
toRemove.add(job);
|
allocations.values().remove(job);
|
||||||
|
}
|
||||||
|
if(availableJobs.contains(job)) {
|
||||||
|
availableJobs.remove(job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(IJob job : toRemove) {
|
toRemove.clear();
|
||||||
rescindJob(job);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IJob getJob(IWorker worker) {
|
public boolean workerHasJob(IWorker worker) {
|
||||||
|
return allocations.containsKey(worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Job getJob(IWorker worker) {
|
||||||
if(allocations.containsKey(worker)) {
|
if(allocations.containsKey(worker)) {
|
||||||
return allocations.get(worker);
|
return allocations.get(worker);
|
||||||
} else return null;
|
} else return null;
|
||||||
|
|
@ -123,11 +125,11 @@ public class JobBoard extends GameObject {
|
||||||
String takenJobsString = "";
|
String takenJobsString = "";
|
||||||
String availableJobsString = "";
|
String availableJobsString = "";
|
||||||
|
|
||||||
for(Entry<IWorker, IJob> allocation : allocations.entrySet()) {
|
for(Entry<IWorker, Job> allocation : allocations.entrySet()) {
|
||||||
takenJobsString += " " + allocation.getKey().getName() + ": " + allocation.getValue().getJobName() + "\n";
|
takenJobsString += " " + allocation.getKey().getName() + ": " + allocation.getValue().getJobName() + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(IJob job : availableJobs) {
|
for(Job job : availableJobs) {
|
||||||
availableJobsString += " " + job.getJobName() + "\n";
|
availableJobsString += " " + job.getJobName() + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import java.util.List;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
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.hadean.gameobjects.inputlayer.Selection;
|
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
|
||||||
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;
|
||||||
|
|
@ -30,7 +30,7 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener,
|
||||||
|
|
||||||
private Button[] actionButtons = ACTIONS_BUTTONS_NULL;
|
private Button[] actionButtons = ACTIONS_BUTTONS_NULL;
|
||||||
|
|
||||||
private Selection selectionManager;
|
private SelectionLayer selectionManager;
|
||||||
private final int width = 300, height = 200;
|
private final int width = 300, height = 200;
|
||||||
private final int padding = 10;
|
private final int padding = 10;
|
||||||
private final int actionButtonSize = 100;
|
private final int actionButtonSize = 100;
|
||||||
|
|
@ -44,7 +44,7 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener,
|
||||||
private List<ISelectable> newSelection = null;;
|
private List<ISelectable> newSelection = null;;
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
selectionManager = get(Selection.class);
|
selectionManager = get(SelectionLayer.class);
|
||||||
selectionManager.subscribe(this);
|
selectionManager.subscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
package xyz.valnet.hadean.gameobjects;
|
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
|
||||||
import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject;
|
|
||||||
import xyz.valnet.hadean.interfaces.ISelectable;
|
|
||||||
import xyz.valnet.hadean.interfaces.ITileThing;
|
|
||||||
import xyz.valnet.hadean.util.Action;
|
|
||||||
import xyz.valnet.hadean.util.Assets;
|
|
||||||
import xyz.valnet.hadean.util.Layers;
|
|
||||||
|
|
||||||
public class Stockpile extends WorldObject implements ITileThing, ISelectable {
|
|
||||||
|
|
||||||
private WorldObject thing;
|
|
||||||
|
|
||||||
public boolean isFree() {
|
|
||||||
return thing == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
camera.draw(Layers.GROUND, Assets.stockpile, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isWalkable() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldRemove() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRemove() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector4f getWorldBox() {
|
|
||||||
return new Vector4f(x, y, x+1, y+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Action[] getActions() {
|
|
||||||
return new Action[] {};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void runAction(Action action) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String details() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package xyz.valnet.hadean.gameobjects;
|
package xyz.valnet.hadean.gameobjects;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.engine.scenegraph.GameObject;
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
import xyz.valnet.hadean.interfaces.IWorldBoundsAdapter;
|
import xyz.valnet.hadean.interfaces.IWorldBoundsAdapter;
|
||||||
|
|
@ -37,6 +38,10 @@ public class Terrain extends GameObject implements IPathable, IWorldBoundsAdapte
|
||||||
return tiles[x][y];
|
return tiles[x][y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Tile getTile(Vector2i pos) {
|
||||||
|
return getTile(pos.x, pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO implement directionality. even the pathfinder doesnt give this info...
|
// TODO implement directionality. even the pathfinder doesnt give this info...
|
||||||
@Override
|
@Override
|
||||||
public boolean isWalkable(int x, int y, int fromX, int fromY) {
|
public boolean isWalkable(int x, int y, int fromX, int fromY) {
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,6 @@ public class Tile extends WorldObject implements IWorkable {
|
||||||
add(tree);
|
add(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(Math.random() > 0.98) {
|
|
||||||
// Log log = new Log(x, y);
|
|
||||||
// stuff.add(log);
|
|
||||||
// add(log);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void placeThing(ITileThing thing) {
|
public void placeThing(ITileThing thing) {
|
||||||
|
|
@ -58,7 +53,8 @@ public class Tile extends WorldObject implements IWorkable {
|
||||||
}
|
}
|
||||||
if(thing instanceof FarmPlot) {
|
if(thing instanceof FarmPlot) {
|
||||||
desiredTill = true;
|
desiredTill = true;
|
||||||
get(JobBoard.class).postJob(this);
|
|
||||||
|
get(JobBoard.class).postSimpleWorkJob("Till Soil", this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,11 +103,6 @@ public class Tile extends WorldObject implements IWorkable {
|
||||||
desiredTill = till;
|
desiredTill = till;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasWork() {
|
|
||||||
return desiredTill && tillLevel < 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector2i[] getWorkablePositions() {
|
public Vector2i[] getWorkablePositions() {
|
||||||
return new Vector2i[] {
|
return new Vector2i[] {
|
||||||
|
|
@ -127,18 +118,29 @@ public class Tile extends WorldObject implements IWorkable {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector2i getLocation() {
|
|
||||||
return new Vector2i(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getJobName() {
|
public String getJobName() {
|
||||||
return "Till Soil";
|
return "Till Soil";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doWork() {
|
public boolean doWork() {
|
||||||
tillLevel += 0.005f;
|
tillLevel += 0.005f;
|
||||||
|
tillLevel = Math.min(tillLevel, 1);
|
||||||
|
return tillLevel >= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
if (tillLevel == 0) {
|
||||||
|
return "Ground";
|
||||||
|
} else if (tillLevel < 1) {
|
||||||
|
return "Tilled Soil (" + Math.floor(tillLevel * 100) + "%)";
|
||||||
|
} else return "Tilled Soil";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector4f getWorldBox() {
|
||||||
|
return new Vector4f(x, y, x+1, y+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
package xyz.valnet.hadean.gameobjects.inputlayer;
|
package xyz.valnet.hadean.gameobjects.inputlayer;
|
||||||
|
|
||||||
import xyz.valnet.engine.App;
|
import xyz.valnet.engine.App;
|
||||||
import xyz.valnet.engine.math.Vector2f;
|
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
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.hadean.gameobjects.Camera;
|
import xyz.valnet.hadean.gameobjects.Camera;
|
||||||
import xyz.valnet.hadean.interfaces.IBuildLayerListener;
|
import xyz.valnet.hadean.interfaces.IBuildLayerListener;
|
||||||
import xyz.valnet.hadean.util.Assets;
|
|
||||||
import xyz.valnet.hadean.util.Layers;
|
import xyz.valnet.hadean.util.Layers;
|
||||||
|
|
||||||
public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
||||||
|
|
@ -46,7 +44,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void broadcastWorldCoords() {
|
private void broadcastWorldCoords() {
|
||||||
Vector2i worldcoords = camera.screen2worldI(App.mouseX, App.mouseY);
|
Vector2i worldcoords = camera.screen2world(App.mouseX, App.mouseY).asInt();
|
||||||
if(mouseDown) {
|
if(mouseDown) {
|
||||||
Vector2i[] ords = orderCoords(new Vector2i(x, y), worldcoords);
|
Vector2i[] ords = orderCoords(new Vector2i(x, y), worldcoords);
|
||||||
listener.update(ords[0].x, ords[0].y, ords[2].x + 1, ords[2].y + 1);
|
listener.update(ords[0].x, ords[0].y, ords[2].x + 1, ords[2].y + 1);
|
||||||
|
|
@ -80,7 +78,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
||||||
listener.cancel();
|
listener.cancel();
|
||||||
deactiveate();
|
deactiveate();
|
||||||
} else if(button == 0 && active && hovered) {
|
} else if(button == 0 && active && hovered) {
|
||||||
Vector2i worldcoords = camera.screen2worldI(App.mouseX, App.mouseY);
|
Vector2i worldcoords = camera.screen2world(App.mouseX, App.mouseY).asInt();
|
||||||
mouseDown = true;
|
mouseDown = true;
|
||||||
screenX = App.mouseX;
|
screenX = App.mouseX;
|
||||||
screenY = App.mouseY;
|
screenY = App.mouseY;
|
||||||
|
|
@ -92,7 +90,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
||||||
@Override
|
@Override
|
||||||
public void mouseUp(int button) {
|
public void mouseUp(int button) {
|
||||||
if(button == 0 && active && mouseDown) {
|
if(button == 0 && active && mouseDown) {
|
||||||
Vector2i worldcoords = camera.screen2worldI(App.mouseX, App.mouseY);
|
Vector2i worldcoords = camera.screen2world(App.mouseX, App.mouseY).asInt();
|
||||||
mouseDown = false;
|
mouseDown = false;
|
||||||
int x1 = x;
|
int x1 = x;
|
||||||
int y1 = y;
|
int y1 = y;
|
||||||
|
|
@ -102,7 +100,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
||||||
int minY = Math.min(y1, y2);
|
int minY = Math.min(y1, y2);
|
||||||
int maxX = Math.max(x1, x2);
|
int maxX = Math.max(x1, x2);
|
||||||
int maxY = Math.max(y1, y2);
|
int maxY = Math.max(y1, y2);
|
||||||
listener.select(minX, minY, maxX, maxY);
|
listener.build(minX, minY, maxX, maxY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ import xyz.valnet.hadean.util.Layers;
|
||||||
|
|
||||||
import static xyz.valnet.engine.util.Math.lerp;
|
import static xyz.valnet.engine.util.Math.lerp;
|
||||||
|
|
||||||
public class Selection extends GameObject implements IMouseCaptureArea {
|
public class SelectionLayer extends GameObject implements IMouseCaptureArea {
|
||||||
|
|
||||||
public Vector2f initialCoords;
|
public Vector2f initialCoords;
|
||||||
private Camera camera;
|
private Camera camera;
|
||||||
private float animation = 0;
|
private float animation = 0;
|
||||||
private float animationMax = 15;
|
private float animationMax = 30;
|
||||||
private float animationAmplitude = 0.3f;
|
private float animationAmplitude = 0.2f;
|
||||||
private List<ISelectionChangeListener> listeners = new ArrayList<ISelectionChangeListener>();
|
private List<ISelectionChangeListener> listeners = new ArrayList<ISelectionChangeListener>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package xyz.valnet.hadean.gameobjects.ui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.App;
|
||||||
|
import xyz.valnet.engine.math.Vector2f;
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
|
import xyz.valnet.hadean.gameobjects.Camera;
|
||||||
|
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject;
|
||||||
|
import xyz.valnet.hadean.util.Assets;
|
||||||
|
|
||||||
|
public class HoverQuery extends GameObject {
|
||||||
|
|
||||||
|
private Camera camera;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
super.start();
|
||||||
|
camera = get(Camera.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> thingStrings = new ArrayList<String>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dTime) {
|
||||||
|
Vector2f position = camera.screen2world(App.mouseX, App.mouseY);
|
||||||
|
thingStrings.clear();
|
||||||
|
for(WorldObject obj : getAll(WorldObject.class)) {
|
||||||
|
Vector4f box = obj.getWorldBox();
|
||||||
|
if(
|
||||||
|
position.x >= box.x &&
|
||||||
|
position.x < box.z &&
|
||||||
|
position.y >= box.y &&
|
||||||
|
position.y < box.w
|
||||||
|
) {
|
||||||
|
thingStrings.add(obj.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
int i = 16;
|
||||||
|
for(String thingString : thingStrings) {
|
||||||
|
Assets.font.drawString(thingString, 16, i);
|
||||||
|
i += 14;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package xyz.valnet.hadean.gameobjects.tabs;
|
package xyz.valnet.hadean.gameobjects.ui.tabs;
|
||||||
|
|
||||||
import static xyz.valnet.engine.util.Math.lerp;
|
import static xyz.valnet.engine.util.Math.lerp;
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ import xyz.valnet.hadean.gameobjects.BottomBar;
|
||||||
import xyz.valnet.hadean.gameobjects.Camera;
|
import xyz.valnet.hadean.gameobjects.Camera;
|
||||||
import xyz.valnet.hadean.gameobjects.Terrain;
|
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||||
import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer;
|
import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer;
|
||||||
import xyz.valnet.hadean.gameobjects.inputlayer.Selection;
|
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
|
||||||
import xyz.valnet.hadean.gameobjects.worldobjects.FarmPlot;
|
import xyz.valnet.hadean.gameobjects.worldobjects.FarmPlot;
|
||||||
import xyz.valnet.hadean.input.Button;
|
import xyz.valnet.hadean.input.Button;
|
||||||
import xyz.valnet.hadean.input.IButtonListener;
|
import xyz.valnet.hadean.input.IButtonListener;
|
||||||
|
|
@ -39,7 +39,7 @@ import xyz.valnet.hadean.util.SmartBoolean;
|
||||||
|
|
||||||
public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCaptureArea, IButtonListener {
|
public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCaptureArea, IButtonListener {
|
||||||
|
|
||||||
private Selection selection;
|
private SelectionLayer selection;
|
||||||
private BuildLayer buildLayer;
|
private BuildLayer buildLayer;
|
||||||
private Camera camera;
|
private Camera camera;
|
||||||
private Terrain terrain;
|
private Terrain terrain;
|
||||||
|
|
@ -120,7 +120,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
|
||||||
public void start() {
|
public void start() {
|
||||||
super.start();
|
super.start();
|
||||||
buildLayer = get(BuildLayer.class);
|
buildLayer = get(BuildLayer.class);
|
||||||
selection = get(Selection.class);
|
selection = get(SelectionLayer.class);
|
||||||
camera = get(Camera.class);
|
camera = get(Camera.class);
|
||||||
terrain = get(Terrain.class);
|
terrain = get(Terrain.class);
|
||||||
|
|
||||||
|
|
@ -158,15 +158,16 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void select(int x1, int y1, int x2, int y2) {
|
public void build(int x1, int y1, int x2, int y2) {
|
||||||
int ix1 = x1;
|
int ix1 = x1;
|
||||||
int iy1 = y1;
|
int iy1 = y1;
|
||||||
int ix2 = x2;
|
int ix2 = x2;
|
||||||
int iy2 = y2;
|
int iy2 = y2;
|
||||||
try {
|
try {
|
||||||
IBuildable building = selectedBuildable.newInstance();
|
IBuildable building = selectedBuildable.newInstance();
|
||||||
GameObject go = (GameObject) building;
|
if(building instanceof GameObject) {
|
||||||
add(go);
|
add((GameObject) building);
|
||||||
|
}
|
||||||
building.buildAt(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
building.buildAt(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println(e);
|
System.out.println(e);
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package xyz.valnet.hadean.gameobjects.tabs;
|
package xyz.valnet.hadean.gameobjects.ui.tabs;
|
||||||
|
|
||||||
import static xyz.valnet.engine.util.Math.lerp;
|
import static xyz.valnet.engine.util.Math.lerp;
|
||||||
|
|
||||||
|
|
@ -8,7 +8,7 @@ import java.util.List;
|
||||||
import xyz.valnet.engine.graphics.Drawing;
|
import xyz.valnet.engine.graphics.Drawing;
|
||||||
import xyz.valnet.hadean.gameobjects.BottomBar;
|
import xyz.valnet.hadean.gameobjects.BottomBar;
|
||||||
import xyz.valnet.hadean.gameobjects.JobBoard;
|
import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||||
import xyz.valnet.hadean.gameobjects.inputlayer.Selection;
|
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
|
||||||
import xyz.valnet.hadean.interfaces.ISelectable;
|
import xyz.valnet.hadean.interfaces.ISelectable;
|
||||||
import xyz.valnet.hadean.interfaces.ISelectionChangeListener;
|
import xyz.valnet.hadean.interfaces.ISelectionChangeListener;
|
||||||
import xyz.valnet.hadean.util.Assets;
|
import xyz.valnet.hadean.util.Assets;
|
||||||
|
|
@ -17,7 +17,7 @@ import xyz.valnet.hadean.util.SmartBoolean;
|
||||||
|
|
||||||
public class JobBoardTab extends Tab implements ISelectionChangeListener {
|
public class JobBoardTab extends Tab implements ISelectionChangeListener {
|
||||||
|
|
||||||
private Selection selection;
|
private SelectionLayer selection;
|
||||||
private JobBoard jobBoard;
|
private JobBoard jobBoard;
|
||||||
|
|
||||||
private SmartBoolean opened;
|
private SmartBoolean opened;
|
||||||
|
|
@ -37,7 +37,7 @@ public class JobBoardTab extends Tab implements ISelectionChangeListener {
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
super.start();
|
super.start();
|
||||||
selection = get(Selection.class);
|
selection = get(SelectionLayer.class);
|
||||||
jobBoard = get(JobBoard.class);
|
jobBoard = get(JobBoard.class);
|
||||||
|
|
||||||
opened = new SmartBoolean(false, new SmartBoolean.IListener() {
|
opened = new SmartBoolean(false, new SmartBoolean.IListener() {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package xyz.valnet.hadean.gameobjects.tabs;
|
package xyz.valnet.hadean.gameobjects.ui.tabs;
|
||||||
|
|
||||||
public class MenuTab extends Tab {
|
public class MenuTab extends Tab {
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package xyz.valnet.hadean.gameobjects.tabs;
|
package xyz.valnet.hadean.gameobjects.ui.tabs;
|
||||||
|
|
||||||
import xyz.valnet.engine.scenegraph.GameObject;
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
import xyz.valnet.hadean.gameobjects.BottomBar;
|
import xyz.valnet.hadean.gameobjects.BottomBar;
|
||||||
|
|
@ -12,31 +12,8 @@ import xyz.valnet.hadean.util.Layers;
|
||||||
@BuildableMetadata(category = "Zones", name = "Farm Plot")
|
@BuildableMetadata(category = "Zones", name = "Farm Plot")
|
||||||
public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IBuildable {
|
public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IBuildable {
|
||||||
|
|
||||||
// private float progress = 0f;
|
|
||||||
// private int stage = 0;
|
|
||||||
// private boolean planted = false;
|
|
||||||
// private boolean mature = false;
|
|
||||||
|
|
||||||
// private static int STAGE_LENGTH = 1000;
|
|
||||||
// private static int MAX_STAGES = 4;
|
|
||||||
|
|
||||||
// private JobBoard board;
|
|
||||||
|
|
||||||
private int w, h;
|
private int w, h;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
// camera.draw(Layers.TILES, Assets.farmPlot, x, y);
|
|
||||||
|
|
||||||
// if(planted) {
|
|
||||||
// if(stage > 1) {
|
|
||||||
// camera.draw(Layers.AIR, Assets.growingRice[stage], x, y - 1, 1, 2);
|
|
||||||
// } else {
|
|
||||||
// camera.draw(Layers.AIR, Assets.growingRice[stage], x, y);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderAlpha() {
|
public void renderAlpha() {
|
||||||
if(!visible) return;
|
if(!visible) return;
|
||||||
|
|
@ -45,64 +22,6 @@ public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IB
|
||||||
Assets.flat.popColor();
|
Assets.flat.popColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(float dTime) {
|
|
||||||
super.update(dTime);
|
|
||||||
|
|
||||||
// if(stage == MAX_STAGES - 1) {
|
|
||||||
// return;
|
|
||||||
// } if(planted) {
|
|
||||||
// if(Math.random() > 0.95f) {
|
|
||||||
// progress += 10;
|
|
||||||
// if(progress >= STAGE_LENGTH) {
|
|
||||||
// stage ++;
|
|
||||||
// progress = 0;
|
|
||||||
// if(stage == MAX_STAGES - 1) {
|
|
||||||
// mature = true;
|
|
||||||
// board.postJob(this);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else if (progress >= STAGE_LENGTH) {
|
|
||||||
// planted = true;
|
|
||||||
// progress = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
super.start();
|
|
||||||
// board = get(JobBoard.class);
|
|
||||||
// board.postJob(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public boolean hasWork() {
|
|
||||||
// // return !planted || mature;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public Vector2i[] getWorkablePositions() {
|
|
||||||
// return new Vector2i[] {
|
|
||||||
// new Vector2i((int) x, (int) y + 1),
|
|
||||||
// new Vector2i((int) x, (int) y - 1),
|
|
||||||
// new Vector2i((int) x + 1, (int) y),
|
|
||||||
// new Vector2i((int) x - 1, (int) y)
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public Vector2i getLocation() {
|
|
||||||
// return new Vector2i((int) x, (int) y);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public String getJobName() {
|
|
||||||
// return planted ? "Harvest Rice" : "Plant Rice";
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getWorldBox() {
|
public Vector4f getWorldBox() {
|
||||||
return new Vector4f(x, y, x + w, y + h);
|
return new Vector4f(x, y, x + w, y + h);
|
||||||
|
|
@ -126,23 +45,9 @@ public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IB
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String details() {
|
public String details() {
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public void doWork() {
|
|
||||||
// // progress ++;
|
|
||||||
// // if(mature && progress >= STAGE_LENGTH) {
|
|
||||||
// // mature = false;
|
|
||||||
// // planted = false;
|
|
||||||
// // stage = 0;
|
|
||||||
// // if(Math.random() < 0.3) {
|
|
||||||
// // getTile().placeThing(new Rice((int)x, (int)y));
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isWalkable() {
|
public boolean isWalkable() {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -167,7 +72,7 @@ public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IB
|
||||||
this.h = h;
|
this.h = h;
|
||||||
System.out.println("<" + x + ", " + y + ", " + w + ", " + h + ">");
|
System.out.println("<" + x + ", " + y + ", " + w + ", " + h + ">");
|
||||||
System.out.println(inScene());
|
System.out.println(inScene());
|
||||||
terrain.getTile(x, y).placeThing(this);
|
|
||||||
for(int i = x; i < x + w; i ++) {
|
for(int i = x; i < x + w; i ++) {
|
||||||
for(int j = y; j < y + h; j ++) {
|
for(int j = y; j < y + h; j ++) {
|
||||||
terrain.getTile(i, j).placeThing(this);
|
terrain.getTile(i, j).placeThing(this);
|
||||||
|
|
@ -175,4 +80,9 @@ public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Farm Plot";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package xyz.valnet.hadean.gameobjects.worldobjects;
|
|
||||||
|
|
||||||
public class Item {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,42 +1,17 @@
|
||||||
package xyz.valnet.hadean.gameobjects.worldobjects;
|
package xyz.valnet.hadean.gameobjects.worldobjects;
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.hadean.gameobjects.JobBoard;
|
|
||||||
import xyz.valnet.hadean.gameobjects.Stockpile;
|
|
||||||
import xyz.valnet.hadean.gameobjects.Tile;
|
|
||||||
import xyz.valnet.hadean.interfaces.IHaulable;
|
|
||||||
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;
|
||||||
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.SmartBoolean;
|
|
||||||
import xyz.valnet.hadean.util.SmartBoolean.IListener;
|
|
||||||
|
|
||||||
public class Log extends WorldObject implements ITileThing, ISelectable, IHaulable {
|
public class Log extends WorldObject implements ITileThing, ISelectable {
|
||||||
|
|
||||||
private SmartBoolean haul;
|
|
||||||
|
|
||||||
private JobBoard jobboard;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
super.start();
|
super.start();
|
||||||
jobboard = get(JobBoard.class);
|
|
||||||
Log that = this;
|
|
||||||
|
|
||||||
haul = new SmartBoolean(false, new IListener() {
|
|
||||||
@Override
|
|
||||||
public void rise() {
|
|
||||||
jobboard.postJob(that);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fall() {
|
|
||||||
jobboard.rescindJob(that);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log(int x, int y) {
|
public Log(int x, int y) {
|
||||||
|
|
@ -47,9 +22,6 @@ public class Log extends WorldObject implements ITileThing, ISelectable, IHaulab
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
camera.draw(Layers.GROUND, Assets.log, x, y);
|
camera.draw(Layers.GROUND, Assets.log, x, y);
|
||||||
if(haul.value()) {
|
|
||||||
camera.draw(Layers.MARKERS, Assets.haulArrow, x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -81,9 +53,7 @@ public class Log extends WorldObject implements ITileThing, ISelectable, IHaulab
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runAction(Action action) {
|
public void runAction(Action action) {
|
||||||
if(action == ACTION_HAUL) {
|
|
||||||
haul.toggle();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -92,41 +62,8 @@ public class Log extends WorldObject implements ITileThing, ISelectable, IHaulab
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasWork() {
|
public String getName() {
|
||||||
return haul.value();
|
return "Log";
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector2i[] getWorkablePositions() {
|
|
||||||
return new Vector2i[] {
|
|
||||||
new Vector2i((int)x + 1, (int)y),
|
|
||||||
new Vector2i((int)x - 1, (int)y),
|
|
||||||
new Vector2i((int)x, (int)y + 1),
|
|
||||||
new Vector2i((int)x, (int)y - 1)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector2i getLocation() {
|
|
||||||
return new Vector2i((int)x, (int)y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Log take() {
|
|
||||||
haul.set(false);
|
|
||||||
Tile tile = terrain.getTile((int)x, (int)y);
|
|
||||||
tile.remove(this);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tile getDestination() {
|
|
||||||
return get(Stockpile.class).getTile();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getJobName() {
|
|
||||||
return "Haul Log";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,307 +1,121 @@
|
||||||
package xyz.valnet.hadean.gameobjects.worldobjects;
|
package xyz.valnet.hadean.gameobjects.worldobjects;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL11.GL_LINES;
|
|
||||||
import static org.lwjgl.opengl.GL11.glBegin;
|
|
||||||
import static org.lwjgl.opengl.GL11.glEnd;
|
|
||||||
import static org.lwjgl.opengl.GL11.glVertex3f;
|
|
||||||
import static org.lwjgl.opengl.GL20.glVertexAttrib2f;
|
|
||||||
import static xyz.valnet.engine.util.Math.lerp;
|
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector2f;
|
import xyz.valnet.engine.math.Vector2f;
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.engine.shaders.SimpleShader;
|
import xyz.valnet.hadean.gameobjects.Job;
|
||||||
import xyz.valnet.hadean.gameobjects.JobBoard;
|
import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||||
import xyz.valnet.hadean.gameobjects.Terrain;
|
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||||
import xyz.valnet.hadean.gameobjects.Tile;
|
import xyz.valnet.hadean.gameobjects.Job.JobStep;
|
||||||
import xyz.valnet.hadean.interfaces.IHaulable;
|
import xyz.valnet.hadean.gameobjects.worldobjects.agents.Agent;
|
||||||
import xyz.valnet.hadean.interfaces.IJob;
|
|
||||||
import xyz.valnet.hadean.interfaces.ISelectable;
|
|
||||||
import xyz.valnet.hadean.interfaces.ITileThing;
|
|
||||||
import xyz.valnet.hadean.interfaces.IWorkable;
|
|
||||||
import xyz.valnet.hadean.interfaces.IWorker;
|
import xyz.valnet.hadean.interfaces.IWorker;
|
||||||
import xyz.valnet.hadean.pathfinding.AStarPathfinder;
|
|
||||||
import xyz.valnet.hadean.pathfinding.IPathfinder;
|
|
||||||
import xyz.valnet.hadean.pathfinding.Node;
|
|
||||||
import xyz.valnet.hadean.pathfinding.Path;
|
|
||||||
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 class Pawn extends WorldObject implements ISelectable, IWorker {
|
public class Pawn extends Agent implements IWorker {
|
||||||
|
|
||||||
private static int count = 0;
|
private static int pawnCount = 0;
|
||||||
private String name = "Pawn " + (++ count);
|
private String name = "Pawn " + (++ pawnCount);
|
||||||
|
|
||||||
private JobBoard jobboard;
|
|
||||||
private IPathfinder pathfinder;
|
|
||||||
|
|
||||||
private IHaulable carrying = null;
|
|
||||||
|
|
||||||
private float counter = 0;
|
|
||||||
|
|
||||||
private Path path;
|
|
||||||
|
|
||||||
private final float invocationThreshold = 100 + (float)(Math.random() * 50);
|
|
||||||
|
|
||||||
private boolean debug = false;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
super.start();
|
super.start();
|
||||||
jobboard = get(JobBoard.class);
|
jobboard = get(JobBoard.class);
|
||||||
pathfinder = new AStarPathfinder(terrain);
|
x = (int) (Math.random() * Terrain.WORLD_SIZE);
|
||||||
x = 0.5f + (int) (Math.random() * Terrain.WORLD_SIZE);
|
y = (int) (Math.random() * Terrain.WORLD_SIZE);
|
||||||
y = 0.5f + (int) (Math.random() * Terrain.WORLD_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void selectedRender() {
|
|
||||||
if(path != null) {
|
|
||||||
for(Node node : path) {
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
Vector2f u, v;
|
|
||||||
|
|
||||||
if(node.from == null) u = camera.world2screen(x, y);
|
|
||||||
else u = camera.world2screen(node.from.x + 0.5f, node.from.y + 0.5f);
|
|
||||||
|
|
||||||
v = camera.world2screen(node.x + 0.5f, node.y + 0.5f);
|
|
||||||
glVertexAttrib2f(SimpleShader.TEX_COORD, 0, 88 / 256f);
|
|
||||||
glVertex3f(u.x, u.y, 3f);
|
|
||||||
glVertexAttrib2f(SimpleShader.TEX_COORD, 0, 88 / 255f);
|
|
||||||
glVertex3f(v.x, v.y, 3f);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
|
super.render();
|
||||||
if(path != null && !path.isComplete()) {
|
camera.draw(Layers.PAWNS, Assets.pawn, x, y);
|
||||||
Node next = path.peek();
|
|
||||||
float t = counter / invocationThreshold;
|
|
||||||
camera.draw(Layers.PAWNS, Assets.pawn, lerp(x - 0.5f, next.x, t), lerp(y - 0.5f, next.y, t));
|
|
||||||
|
|
||||||
if(path != null && debug) {
|
|
||||||
for(Node node : path) {
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
Vector2f u, v;
|
|
||||||
|
|
||||||
if(node.from == null) u = camera.world2screen(x, y);
|
|
||||||
else u = camera.world2screen(node.from.x + 0.5f, node.from.y + 0.5f);
|
|
||||||
|
|
||||||
v = camera.world2screen(node.x + 0.5f, node.y + 0.5f);
|
|
||||||
glVertexAttrib2f(SimpleShader.TEX_COORD, 0, 88 / 256f);
|
|
||||||
glVertex3f(u.x, u.y, 3f);
|
|
||||||
glVertexAttrib2f(SimpleShader.TEX_COORD, 0, 88 / 255f);
|
|
||||||
glVertex3f(v.x, v.y, 3f);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
camera.draw(Layers.PAWNS, Assets.pawn, x - 0.5f, y - 0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drawing.setLayer(0.1f);
|
|
||||||
// Assets.flat.pushColor(Vector4f.black);
|
|
||||||
// Drawing.drawSprite(Assets.pawn, (int)(Terrain.left + dx * Terrain.TILE_SIZE) - Assets.pawn.width / 2, (int)(Terrain.top + dy * Terrain.TILE_SIZE) - Assets.pawn.height / 2);
|
|
||||||
|
|
||||||
// Assets.flat.swapColor(new Vector4f(1, 0, 0, 1));
|
|
||||||
// Drawing.setLayer(0.05f);
|
|
||||||
|
|
||||||
// Assets.flat.popColor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dTime) {
|
public void runAction(Action action) {}
|
||||||
|
|
||||||
IJob currentJob = jobboard.getJob(this);
|
|
||||||
|
|
||||||
// cleanup current job...
|
|
||||||
if(currentJob != null && !currentJob.hasWork()) {
|
|
||||||
currentJob = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if you dont have a job
|
|
||||||
if(currentJob == null && carrying == null) {
|
|
||||||
// and its a frame to try and get one...
|
|
||||||
if(counter == 0) {
|
|
||||||
tryStartWork();
|
|
||||||
currentJob = jobboard.getJob(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we still dont have a job, try path to wander.
|
|
||||||
if(currentJob == null && (path == null || path.isComplete())) {
|
|
||||||
newPath();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO possibly take care of needs here idk
|
|
||||||
}
|
|
||||||
|
|
||||||
if(path != null && !path.isComplete()) {
|
|
||||||
move();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to do your work!
|
|
||||||
if(currentJob != null && currentJob.hasWork()) {
|
|
||||||
if(getCurrentPos().isOneOf(currentJob.getWorkablePositions())) {
|
|
||||||
if(currentJob instanceof IWorkable) {
|
|
||||||
((IWorkable)currentJob).doWork();
|
|
||||||
} else if (currentJob instanceof IHaulable) {
|
|
||||||
if(carrying == null) {
|
|
||||||
IHaulable thing = (IHaulable) currentJob;
|
|
||||||
Log log = thing.take();
|
|
||||||
carrying = log;
|
|
||||||
Vector2i dst = thing.getDestination().getCoords();
|
|
||||||
path = pathfinder.getPath((int)x, (int)y, dst.x, dst.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (carrying != null) {
|
|
||||||
// if we're at our destination, or if for some reason we just like
|
|
||||||
// didnt make it? but our path is so totally completed...
|
|
||||||
if(carrying.getDestination() == this.getTile() || path == null || path.isComplete()) {
|
|
||||||
this.getTile().placeThing((ITileThing) carrying);
|
|
||||||
carrying = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector2i getCurrentPos() {
|
|
||||||
return new Vector2i((int)Math.floor(x), (int)Math.floor(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryStartWork() {
|
|
||||||
jobboard.requestJob(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void newPath() {
|
|
||||||
// set new destination
|
|
||||||
int randomX = (int)Math.floor(Math.random() * Terrain.WORLD_SIZE);
|
|
||||||
int randomY = (int)Math.floor(Math.random() * Terrain.WORLD_SIZE);
|
|
||||||
path = pathfinder.getPath((int)x, (int)y, randomX, randomY);
|
|
||||||
|
|
||||||
// // and route there.
|
|
||||||
// reroute();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reroute() {
|
|
||||||
// intify all the coordinates
|
|
||||||
int ix = (int)Math.floor(x);
|
|
||||||
int iy = (int)Math.floor(y);
|
|
||||||
|
|
||||||
int idx = path.dst.x;
|
|
||||||
int idy = path.dst.y;
|
|
||||||
|
|
||||||
// try to make a new path.
|
|
||||||
path = pathfinder.getPath(ix, iy, idx, idy);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean paused = false;
|
|
||||||
|
|
||||||
private void move() {
|
|
||||||
if(paused) {
|
|
||||||
counter --;
|
|
||||||
if(counter < 0) counter = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// check if we CAN move.
|
|
||||||
Node nextNode = path.peek();
|
|
||||||
Tile nextTile = terrain.getTile(nextNode.x, nextNode.y);
|
|
||||||
if(!nextTile.isWalkable()) {
|
|
||||||
if(counter > 0) counter --;
|
|
||||||
if(counter < 0) counter = 0;
|
|
||||||
if(counter == 0) {
|
|
||||||
reroute();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
counter ++;
|
|
||||||
if(counter < invocationThreshold) return;
|
|
||||||
|
|
||||||
path.pop();
|
|
||||||
x = nextNode.x + 0.5f;
|
|
||||||
y = nextNode.y + 0.5f;
|
|
||||||
counter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector4f getWorldBox() {
|
|
||||||
if(path != null && !path.isComplete()) {
|
|
||||||
float t = counter / invocationThreshold;
|
|
||||||
Node n = path.peek();
|
|
||||||
float x1 = lerp(x - 0.5f, n.x, t);
|
|
||||||
float y1 = lerp(y - 0.5f, n.y, t);
|
|
||||||
return new Vector4f(x1, y1, x1 + 1, y1 + 1);
|
|
||||||
} else {
|
|
||||||
return new Vector4f(x - 0.5f, y - 0.5f, x + 0.5f, y + 0.5f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Action ACTION_REROUTE = new Action("Re-route");
|
|
||||||
private static final Action ACTION_TOGGLE_DEBUG = new Action("Toggle\nDebug");
|
|
||||||
private static final Action ACTION_PAUSE = new Action("Pause");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Action[] getActions() {
|
|
||||||
return new Action[] {
|
|
||||||
// ACTION_REROUTE,
|
|
||||||
ACTION_TOGGLE_DEBUG,
|
|
||||||
ACTION_PAUSE
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void runAction(Action action) {
|
|
||||||
if(action == ACTION_PAUSE) {
|
|
||||||
paused = !paused;
|
|
||||||
} else if(action == ACTION_REROUTE) {
|
|
||||||
reroute();
|
|
||||||
} else if(action == ACTION_TOGGLE_DEBUG) {
|
|
||||||
debug = !debug;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getCarriedName() {
|
|
||||||
if(carrying == null) return "Nothing";
|
|
||||||
String[] names = carrying.getClass().getName().split("\\.");
|
|
||||||
return names[names.length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String details() {
|
public String details() {
|
||||||
IJob currentJob = jobboard.getJob(this);
|
return "";
|
||||||
String jobString = currentJob == null ? "No Job" : currentJob.getJobName();
|
|
||||||
return "" + name + "\n" +
|
|
||||||
"Held | " + getCarriedName() + "\n" +
|
|
||||||
"Job | " + jobString + "\n" +
|
|
||||||
"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector2f getLocation() {
|
public Vector2f getWorldPosition() {
|
||||||
return new Vector2f(x, y);
|
return new Vector2f(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPathfinder getPathfinder() {
|
|
||||||
return pathfinder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPath(Path path) {
|
|
||||||
this.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector4f getWorldBox() {
|
||||||
|
return new Vector4f(x, y, x + 1, y + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JobBoard jobboard;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void think() {
|
||||||
|
super.think();
|
||||||
|
|
||||||
|
// if we dont have a job
|
||||||
|
if(!jobboard.workerHasJob(this)) {
|
||||||
|
jobboard.requestJob(this); // try to get one
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have a job and need to go to it and we're not pathing to it
|
||||||
|
if(jobboard.workerHasJob(this) && !isAtJobStepLocation() && !isPathingToJobLocation()) {
|
||||||
|
goToJobStepLocation(); // start pathing there.
|
||||||
|
return; // and dont think about anything else.
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we still dont have a job and we're not moving around
|
||||||
|
if(!jobboard.workerHasJob(this) && !isPathing()) {
|
||||||
|
if(Math.random() > 0.001f) wander(); // have a chance of wandering!
|
||||||
|
return; // and dont think about anything else.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPathingToJobLocation() {
|
||||||
|
if(!isPathing()) return false;
|
||||||
|
return getDestination().equals(jobboard.getJob(this).getCurrentStep().getLocation().asInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAtJobStepLocation() {
|
||||||
|
return jobboard.getJob(this).getCurrentStep().getLocation().equals(this.getWorldPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void goToJobStepLocation() {
|
||||||
|
goTo(jobboard
|
||||||
|
.getJob(this)
|
||||||
|
.getCurrentStep()
|
||||||
|
.getLocation()
|
||||||
|
.asInt()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO at some point rewrite this to use an actor component array
|
||||||
|
// where we loop through until something _does_ sometihng.
|
||||||
|
@Override
|
||||||
|
protected boolean act() {
|
||||||
|
if(super.act()) return true;
|
||||||
|
if(doJob()) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doJob() {
|
||||||
|
if(!jobboard.workerHasJob(this)) return false;
|
||||||
|
JobStep step = jobboard.getJob(this).getCurrentStep();
|
||||||
|
if(!getWorldPosition().asInt().equals(step.getLocation().asInt())) return false;
|
||||||
|
|
||||||
|
if(step instanceof Job.Work) {
|
||||||
|
Job.Work workStep = (Job.Work)step;
|
||||||
|
if(workStep.doWork()) step.next();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,42 +81,9 @@ public class Rice extends WorldObject implements ITileThing, ISelectable {
|
||||||
return "Bag of Rice";
|
return "Bag of Rice";
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// public boolean hasWork() {
|
public String getName() {
|
||||||
// return haul.value();
|
return "Rice";
|
||||||
// }
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public Vector2i[] getWorablePositions() {
|
|
||||||
// return new Vector2i[] {
|
|
||||||
// new Vector2i((int)x + 1, (int)y),
|
|
||||||
// new Vector2i((int)x - 1, (int)y),
|
|
||||||
// new Vector2i((int)x, (int)y + 1),
|
|
||||||
// new Vector2i((int)x, (int)y - 1)
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public Vector2i getLocation() {
|
|
||||||
// return new Vector2i((int)x, (int)y);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public Log take() {
|
|
||||||
// haul.set(false);
|
|
||||||
// Tile tile = terrain.getTile((int)x, (int)y);
|
|
||||||
// tile.remove(this);
|
|
||||||
// return this;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public Tile getDestination() {
|
|
||||||
// return get(Stockpile.class).getTile();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public String getJobName() {
|
|
||||||
// return "Haul Log";
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,16 @@
|
||||||
package xyz.valnet.hadean.gameobjects.worldobjects;
|
package xyz.valnet.hadean.gameobjects.worldobjects;
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.hadean.gameobjects.JobBoard;
|
|
||||||
import xyz.valnet.hadean.interfaces.BuildableMetadata;
|
import xyz.valnet.hadean.interfaces.BuildableMetadata;
|
||||||
import xyz.valnet.hadean.interfaces.IBuildable;
|
import xyz.valnet.hadean.interfaces.IBuildable;
|
||||||
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.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;
|
||||||
import xyz.valnet.hadean.util.Layers;
|
import xyz.valnet.hadean.util.Layers;
|
||||||
|
|
||||||
@BuildableMetadata(category = "Zones", name = "Stockpile")
|
@BuildableMetadata(category = "Zones", name = "Stockpile")
|
||||||
public class Stockpile extends WorldObject implements IWorkable, ISelectable, ITileThing, IBuildable {
|
public class Stockpile extends WorldObject implements ISelectable, ITileThing, IBuildable {
|
||||||
|
|
||||||
private JobBoard board;
|
|
||||||
|
|
||||||
private int w, h;
|
private int w, h;
|
||||||
|
|
||||||
|
|
@ -40,33 +35,6 @@ public class Stockpile extends WorldObject implements IWorkable, ISelectable, IT
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
super.start();
|
super.start();
|
||||||
board = get(JobBoard.class);
|
|
||||||
board.postJob(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasWork() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector2i[] getWorkablePositions() {
|
|
||||||
return new Vector2i[] {
|
|
||||||
new Vector2i((int) x, (int) y + 1),
|
|
||||||
new Vector2i((int) x, (int) y - 1),
|
|
||||||
new Vector2i((int) x + 1, (int) y),
|
|
||||||
new Vector2i((int) x - 1, (int) y)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector2i getLocation() {
|
|
||||||
return new Vector2i((int) x, (int) y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getJobName() {
|
|
||||||
return "No jobs here!";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -96,11 +64,6 @@ public class Stockpile extends WorldObject implements IWorkable, ISelectable, IT
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doWork() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isWalkable() {
|
public boolean isWalkable() {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -133,4 +96,10 @@ public class Stockpile extends WorldObject implements IWorkable, ISelectable, IT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return "Stockpile";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package xyz.valnet.hadean.gameobjects.worldobjects;
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
import xyz.valnet.hadean.gameobjects.Job;
|
||||||
import xyz.valnet.hadean.gameobjects.JobBoard;
|
import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||||
import xyz.valnet.hadean.interfaces.ISelectable;
|
import xyz.valnet.hadean.interfaces.ISelectable;
|
||||||
import xyz.valnet.hadean.interfaces.ITileThing;
|
import xyz.valnet.hadean.interfaces.ITileThing;
|
||||||
|
|
@ -15,7 +16,7 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
||||||
private static int counter = 0;
|
private static int counter = 0;
|
||||||
private String name = "Tree " + (++ counter);
|
private String name = "Tree " + (++ counter);
|
||||||
|
|
||||||
private boolean chopFlag = false;
|
private Job chopJob = null;
|
||||||
|
|
||||||
private int x, y;
|
private int x, y;
|
||||||
|
|
||||||
|
|
@ -29,7 +30,7 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
||||||
Assets.flat.pushColor(new Vector4f(1 - getProgress(), 1 - getProgress(), 1 - getProgress(), 1.0f));
|
Assets.flat.pushColor(new Vector4f(1 - getProgress(), 1 - getProgress(), 1 - getProgress(), 1.0f));
|
||||||
camera.draw(Layers.AIR, Assets.tree, x - 1, y - 2, 3, 3);
|
camera.draw(Layers.AIR, Assets.tree, x - 1, y - 2, 3, 3);
|
||||||
Assets.flat.popColor();
|
Assets.flat.popColor();
|
||||||
if(hasWork()) {
|
if(chopJob != null) {
|
||||||
camera.draw(Layers.MARKERS, Assets.lilAxe, x, y);
|
camera.draw(Layers.MARKERS, Assets.lilAxe, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -56,20 +57,15 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
||||||
@Override
|
@Override
|
||||||
public void runAction(Action action) {
|
public void runAction(Action action) {
|
||||||
if(action == ACTION_CHOP) {
|
if(action == ACTION_CHOP) {
|
||||||
chopFlag = !chopFlag;
|
if(chopJob == null) {
|
||||||
if(chopFlag) {
|
chopJob = get(JobBoard.class).postSimpleWorkJob("Chop Tree", this);
|
||||||
get(JobBoard.class).postJob(this);
|
|
||||||
} else {
|
} else {
|
||||||
get(JobBoard.class).rescindJob(this);
|
get(JobBoard.class).rescindJob(chopJob);
|
||||||
|
chopJob = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasWork() {
|
|
||||||
return chopFlag && choppage < strength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector2i[] getWorkablePositions() {
|
public Vector2i[] getWorkablePositions() {
|
||||||
return new Vector2i[] {
|
return new Vector2i[] {
|
||||||
|
|
@ -88,14 +84,15 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doWork() {
|
public boolean doWork() {
|
||||||
choppage ++;
|
choppage ++;
|
||||||
|
return getProgress() >= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String details() {
|
public String details() {
|
||||||
return "" + name + "\n" +
|
return "" + name + "\n" +
|
||||||
"Chop Flag | " + chopFlag + "\n" +
|
"Chop Flag | " + (chopJob != null) + "\n" +
|
||||||
"Progress | " + (String.format("%.2f", getProgress() * 100)) + "%";
|
"Progress | " + (String.format("%.2f", getProgress() * 100)) + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,13 +119,13 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
||||||
add(new Log(x, y));
|
add(new Log(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector2i getLocation() {
|
|
||||||
return new Vector2i(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getJobName() {
|
public String getJobName() {
|
||||||
return "Chop " + name;
|
return "Chop " + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Tree";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
package xyz.valnet.hadean.gameobjects.worldobjects;
|
package xyz.valnet.hadean.gameobjects.worldobjects;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector2f;
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.engine.scenegraph.GameObject;
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
import xyz.valnet.hadean.gameobjects.Camera;
|
import xyz.valnet.hadean.gameobjects.Camera;
|
||||||
import xyz.valnet.hadean.gameobjects.Terrain;
|
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||||
import xyz.valnet.hadean.gameobjects.Tile;
|
import xyz.valnet.hadean.gameobjects.Tile;
|
||||||
|
|
||||||
public class WorldObject extends GameObject {
|
public abstract class WorldObject extends GameObject {
|
||||||
|
|
||||||
protected float x;
|
protected float x;
|
||||||
protected float y;
|
protected float y;
|
||||||
|
|
@ -23,4 +25,11 @@ public class WorldObject extends GameObject {
|
||||||
return terrain.getTile((int)x, (int)y);
|
return terrain.getTile((int)x, (int)y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2f getWorldPosition() {
|
||||||
|
return new Vector2f(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getName();
|
||||||
|
public abstract Vector4f getWorldBox();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
package xyz.valnet.hadean.gameobjects.worldobjects.agents;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_LINES;
|
||||||
|
import static org.lwjgl.opengl.GL11.glBegin;
|
||||||
|
import static org.lwjgl.opengl.GL11.glEnd;
|
||||||
|
import static org.lwjgl.opengl.GL11.glVertex3f;
|
||||||
|
import static org.lwjgl.opengl.GL20.glVertexAttrib2f;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.graphics.Drawing;
|
||||||
|
import xyz.valnet.engine.math.Vector2f;
|
||||||
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
import xyz.valnet.engine.shaders.SimpleShader;
|
||||||
|
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||||
|
import xyz.valnet.hadean.gameobjects.Tile;
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject;
|
||||||
|
import xyz.valnet.hadean.interfaces.ISelectable;
|
||||||
|
import xyz.valnet.hadean.pathfinding.AStarPathfinder;
|
||||||
|
import xyz.valnet.hadean.pathfinding.IPathfinder;
|
||||||
|
import xyz.valnet.hadean.pathfinding.Node;
|
||||||
|
import xyz.valnet.hadean.pathfinding.Path;
|
||||||
|
import xyz.valnet.hadean.util.Action;
|
||||||
|
import xyz.valnet.hadean.util.Assets;
|
||||||
|
import xyz.valnet.hadean.util.Layers;
|
||||||
|
|
||||||
|
public abstract class Agent extends WorldObject implements ISelectable {
|
||||||
|
public abstract String getName();
|
||||||
|
private int frameCounter = 0;
|
||||||
|
private int speed = 100 + (int)(Math.random() * 50);
|
||||||
|
|
||||||
|
private IPathfinder pathfinder;
|
||||||
|
private Path path = null;
|
||||||
|
|
||||||
|
protected boolean isPathing() {
|
||||||
|
return path != null && !path.isComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
super.start();
|
||||||
|
frameCounter = speed;
|
||||||
|
pathfinder = new AStarPathfinder(terrain);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dTime) {
|
||||||
|
think();
|
||||||
|
act();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void move() {
|
||||||
|
frameCounter++;
|
||||||
|
if(frameCounter >= speed) {
|
||||||
|
Vector2i nextPos = path.pop().getPosition();
|
||||||
|
this.x = nextPos.x;
|
||||||
|
this.y = nextPos.y;
|
||||||
|
if(path.isComplete()) path = null;
|
||||||
|
frameCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void correctPath() {
|
||||||
|
if(path != null && path.isComplete()) path = null;
|
||||||
|
if(path == null) return;
|
||||||
|
Tile nextTile = terrain.getTile(path.peek().getPosition());
|
||||||
|
if(!nextTile.isWalkable()) {
|
||||||
|
path = pathfinder.getPath(
|
||||||
|
(int)Math.floor(x),
|
||||||
|
(int)Math.floor(y),
|
||||||
|
path.dst.x,
|
||||||
|
path.dst.y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void think() {
|
||||||
|
correctPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean act() {
|
||||||
|
if(path != null) {
|
||||||
|
move();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void goTo(int x, int y) {
|
||||||
|
if(x == (int) this.x && y == (int) this.y) return;
|
||||||
|
frameCounter = 0;
|
||||||
|
path = pathfinder.getPath((int)this.x, (int)this.y, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void goTo(Vector2i location) {
|
||||||
|
goTo(location.x, location.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void wander() {
|
||||||
|
System.out.println("WANDER!");
|
||||||
|
int randomX = (int)Math.floor(Math.random() * Terrain.WORLD_SIZE);
|
||||||
|
int randomY = (int)Math.floor(Math.random() * Terrain.WORLD_SIZE);
|
||||||
|
path = pathfinder.getPath((int)x, (int)y, randomX, randomY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderAlpha() {
|
||||||
|
Drawing.setLayer(Layers.GENERAL_UI);
|
||||||
|
Assets.flat.pushColor(Vector4f.opacity(0.4f));
|
||||||
|
if(path != null) {
|
||||||
|
for(Node node : path) {
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
Vector2f u, v;
|
||||||
|
|
||||||
|
if(node.from == null) u = camera.world2screen(x, y);
|
||||||
|
else u = camera.world2screen(node.from.x + 0.5f, node.from.y + 0.5f);
|
||||||
|
|
||||||
|
v = camera.world2screen(node.x + 0.5f, node.y + 0.5f);
|
||||||
|
glVertexAttrib2f(SimpleShader.TEX_COORD, 0, 88 / 256f);
|
||||||
|
glVertex3f(u.x, u.y, 3f);
|
||||||
|
glVertexAttrib2f(SimpleShader.TEX_COORD, 0, 88 / 255f);
|
||||||
|
glVertex3f(v.x, v.y, 3f);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
Assets.flat.swapColor(Vector4f.opacity(0.6f));
|
||||||
|
|
||||||
|
Assets.selectionFrame.draw(
|
||||||
|
camera.world2Screen(
|
||||||
|
terrain.getTile(
|
||||||
|
path.getDestination().getPosition()
|
||||||
|
)
|
||||||
|
.getWorldBox()
|
||||||
|
)
|
||||||
|
.toXYWH()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Assets.flat.popColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Action[] getActions() {
|
||||||
|
return new Action[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Vector2i getDestination() {
|
||||||
|
if(path == null) return null;
|
||||||
|
return path.getDestination().getPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package xyz.valnet.hadean.gameobjects.worldobjects.items;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.WorldObject;
|
||||||
|
import xyz.valnet.hadean.util.SmartBoolean;
|
||||||
|
|
||||||
|
public class Item extends WorldObject {
|
||||||
|
protected JobBoard jobboard;
|
||||||
|
|
||||||
|
private SmartBoolean haul;
|
||||||
|
|
||||||
|
// camera.draw(Layers.MARKERS, Assets.haulArrow, x, y);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
super.start();
|
||||||
|
haul = new SmartBoolean(false, new SmartBoolean.IListener() {
|
||||||
|
@Override
|
||||||
|
public void rise() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fall() {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector4f getWorldBox() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,6 @@ package xyz.valnet.hadean.interfaces;
|
||||||
|
|
||||||
public interface IBuildLayerListener {
|
public interface IBuildLayerListener {
|
||||||
public void update(int x, int y, int w, int h);
|
public void update(int x, int y, int w, int h);
|
||||||
public void select(int x, int y, int w, int h);
|
public void build(int x, int y, int w, int h);
|
||||||
public void cancel();
|
public void cancel();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
package xyz.valnet.hadean.interfaces;
|
|
||||||
|
|
||||||
import xyz.valnet.hadean.gameobjects.Tile;
|
|
||||||
import xyz.valnet.hadean.gameobjects.worldobjects.Log;
|
|
||||||
|
|
||||||
public interface IHaulable extends IJob {
|
|
||||||
public Log take();
|
|
||||||
public Tile getDestination();
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package xyz.valnet.hadean.interfaces;
|
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
|
||||||
|
|
||||||
public interface IJob {
|
|
||||||
public boolean hasWork();
|
|
||||||
public Vector2i[] getWorkablePositions();
|
|
||||||
|
|
||||||
@Deprecated // please use the workable positions.
|
|
||||||
public Vector2i getLocation();
|
|
||||||
public String getJobName();
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
package xyz.valnet.hadean.interfaces;
|
package xyz.valnet.hadean.interfaces;
|
||||||
|
|
||||||
public interface IWorkable extends IJob {
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
public void doWork();
|
|
||||||
|
public interface IWorkable {
|
||||||
|
public boolean doWork();
|
||||||
|
public Vector2i[] getWorkablePositions();
|
||||||
|
public String getJobName();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
package xyz.valnet.hadean.interfaces;
|
package xyz.valnet.hadean.interfaces;
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector2f;
|
import xyz.valnet.engine.math.Vector2f;
|
||||||
import xyz.valnet.hadean.pathfinding.IPathfinder;
|
|
||||||
import xyz.valnet.hadean.pathfinding.Path;
|
|
||||||
|
|
||||||
public interface IWorker {
|
public interface IWorker {
|
||||||
public Vector2f getLocation();
|
public Vector2f getWorldPosition();
|
||||||
public IPathfinder getPathfinder();
|
|
||||||
public void setPath(Path path);
|
|
||||||
public String getName();
|
public String getName();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,9 @@ public class AStarPathfinder implements IPathfinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path getPath(int x1, int y1, int x2, int y2) {
|
public Path getPath(int x1, int y1, int x2, int y2) {
|
||||||
|
|
||||||
|
if(x1 == x2 && y1 == y2) return null;
|
||||||
|
|
||||||
List<Node> open = new ArrayList<Node>();
|
List<Node> open = new ArrayList<Node>();
|
||||||
List<Node> closed = new ArrayList<Node>();
|
List<Node> closed = new ArrayList<Node>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package xyz.valnet.hadean.pathfinding;
|
package xyz.valnet.hadean.pathfinding;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
|
|
||||||
public class Node {
|
public class Node {
|
||||||
public int x, y, g, h;
|
public int x, y, g, h;
|
||||||
public Node from;
|
public Node from;
|
||||||
|
|
@ -7,4 +9,8 @@ public class Node {
|
||||||
public int getCost() {
|
public int getCost() {
|
||||||
return g + h;
|
return g + h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2i getPosition() {
|
||||||
|
return new Vector2i(x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ public class Path implements Iterable<Node> {
|
||||||
return nodes.pop();
|
return nodes.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Node getDestination() {
|
||||||
|
return nodes.firstElement();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isComplete() {
|
public boolean isComplete() {
|
||||||
return nodes.isEmpty();
|
return nodes.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,11 @@ import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||||
import xyz.valnet.hadean.gameobjects.SelectionUI;
|
import xyz.valnet.hadean.gameobjects.SelectionUI;
|
||||||
import xyz.valnet.hadean.gameobjects.Terrain;
|
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||||
import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer;
|
import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer;
|
||||||
import xyz.valnet.hadean.gameobjects.inputlayer.Selection;
|
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
|
||||||
import xyz.valnet.hadean.gameobjects.tabs.BuildTab;
|
import xyz.valnet.hadean.gameobjects.ui.HoverQuery;
|
||||||
import xyz.valnet.hadean.gameobjects.tabs.JobBoardTab;
|
import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab;
|
||||||
import xyz.valnet.hadean.gameobjects.tabs.MenuTab;
|
import xyz.valnet.hadean.gameobjects.ui.tabs.JobBoardTab;
|
||||||
|
import xyz.valnet.hadean.gameobjects.ui.tabs.MenuTab;
|
||||||
import xyz.valnet.hadean.gameobjects.worldobjects.Pawn;
|
import xyz.valnet.hadean.gameobjects.worldobjects.Pawn;
|
||||||
|
|
||||||
// TODO BIG IDEAS
|
// TODO BIG IDEAS
|
||||||
|
|
@ -35,7 +36,7 @@ public class GameScene extends SceneGraph {
|
||||||
objects.add(new Pawn());
|
objects.add(new Pawn());
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.add(new Selection());
|
objects.add(new SelectionLayer());
|
||||||
objects.add(new SelectionUI());
|
objects.add(new SelectionUI());
|
||||||
|
|
||||||
objects.add(new BuildLayer());
|
objects.add(new BuildLayer());
|
||||||
|
|
@ -44,6 +45,7 @@ public class GameScene extends SceneGraph {
|
||||||
objects.add(new BuildTab());
|
objects.add(new BuildTab());
|
||||||
objects.add(new JobBoardTab());
|
objects.add(new JobBoardTab());
|
||||||
objects.add(new MenuTab());
|
objects.add(new MenuTab());
|
||||||
|
objects.add(new HoverQuery());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue