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;
|
||||
|
||||
import org.lwjgl.*;
|
||||
import org.lwjgl.glfw.*;
|
||||
import org.lwjgl.opengl.*;
|
||||
import org.lwjgl.system.*;
|
||||
|
|
@ -29,7 +28,6 @@ public class App {
|
|||
private Game game;
|
||||
|
||||
public void run() {
|
||||
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
|
||||
|
||||
init();
|
||||
loop();
|
||||
|
|
@ -55,7 +53,7 @@ public class App {
|
|||
// Configure GLFW
|
||||
glfwDefaultWindowHints(); // optional, the current window hints are already the default
|
||||
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
|
||||
window = glfwCreateWindow(width, height, "Hello World!", NULL, NULL);
|
||||
|
|
@ -86,7 +84,6 @@ public class App {
|
|||
game.mouseUp(button);
|
||||
}
|
||||
|
||||
// TODO deprecate these.
|
||||
if(button >= 3) return;
|
||||
if(button == GLFW_MOUSE_BUTTON_LEFT) { mouseLeft = action == 1; return; }
|
||||
if(button == GLFW_MOUSE_BUTTON_RIGHT) { mouseRight = action == 1; return; }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package xyz.valnet.engine.graphics;
|
||||
|
||||
import xyz.valnet.engine.math.Vector4f;
|
||||
|
||||
public class Tile9 {
|
||||
|
||||
private final Sprite topLeft;
|
||||
|
|
@ -34,6 +36,10 @@ public class Tile9 {
|
|||
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) {
|
||||
int a = w < 0 ? x + w : x; // top left x
|
||||
int b = h < 0 ? y + h : y; // top left y
|
||||
|
|
|
|||
|
|
@ -14,4 +14,12 @@ public class Vector2f {
|
|||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
protected final void add(GameObject obj) {
|
||||
protected final <T extends GameObject> T add(T obj) {
|
||||
if(obj.inScene()) {
|
||||
System.out.println(obj + " is already in the scene. not adding twice...");
|
||||
return;
|
||||
return obj;
|
||||
}
|
||||
scene.add(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -6,4 +6,11 @@ public class Math {
|
|||
if(n <= 0) return a;
|
||||
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.math.Matrix4f;
|
||||
import xyz.valnet.engine.math.Vector4f;
|
||||
|
||||
import xyz.valnet.hadean.scenes.GameScene;
|
||||
import xyz.valnet.hadean.scenes.MenuScene;
|
||||
import xyz.valnet.hadean.util.Assets;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ public class HadeanGame extends Game {
|
|||
@Override
|
||||
public void start() {
|
||||
Assets.flat.pushColor(Vector4f.one);
|
||||
changeScene(new MenuScene());
|
||||
changeScene(new GameScene());
|
||||
}
|
||||
|
||||
@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.Sprite;
|
||||
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.interfaces.IWorldBoundsAdapter;
|
||||
|
|
@ -11,7 +10,7 @@ import xyz.valnet.hadean.interfaces.IWorldBoundsAdapter;
|
|||
public class Camera extends GameObject {
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
public Vector2i screen2worldI(float x, float y) {
|
||||
return new Vector2i((int)Math.floor((x - screenWidth / 2 + focus.x * tileWidth) / tileWidth), (int)Math.floor((y - screenHeight / 2 + focus.y * tileWidth) / tileWidth));
|
||||
public Vector4f world2Screen(Vector4f input) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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 xyz.valnet.engine.math.Vector2f;
|
||||
import xyz.valnet.engine.math.Vector2i;
|
||||
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.pathfinding.IPathfinder;
|
||||
import xyz.valnet.hadean.pathfinding.Path;
|
||||
import xyz.valnet.hadean.util.Pair;
|
||||
|
||||
public class JobBoard extends GameObject {
|
||||
|
||||
private Set<IJob> availableJobs = new HashSet<IJob>();
|
||||
private Map<IWorker, IJob> allocations = new HashMap<IWorker, IJob>();
|
||||
private Set<Job> availableJobs = new HashSet<Job>();
|
||||
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);
|
||||
}
|
||||
|
||||
public void rescindJob(IJob job) {
|
||||
public void rescindJob(Job job) {
|
||||
if(allocations.values().contains(job)) {
|
||||
List<IWorker> toFire = new ArrayList<IWorker>();
|
||||
|
||||
|
|
@ -49,27 +54,21 @@ public class JobBoard extends GameObject {
|
|||
|
||||
public void requestJob(IWorker worker) {
|
||||
// TODO worker has capabilities?
|
||||
Vector2f workerLocation = worker.getLocation();
|
||||
IPathfinder pathfinder = worker.getPathfinder();
|
||||
Vector2f workerLocation = worker.getWorldPosition();
|
||||
|
||||
List<IJob> workables = availableJobs
|
||||
List<Job> workables = availableJobs
|
||||
.stream()
|
||||
// filter available job by the ones that currently have work
|
||||
// TODO seems like this should be removed at some point
|
||||
// and jobs should post / rescind when they need to
|
||||
.filter(workable -> workable.hasWork())
|
||||
// calculate our workers distance to each
|
||||
.map(workable -> new Pair<IJob, Float>(
|
||||
workable,
|
||||
workable.getLocation().distanceTo(
|
||||
.map(job -> new Pair<Job, Float>(
|
||||
job,
|
||||
job.getLocation().distanceTo(
|
||||
(int) workerLocation.x,
|
||||
(int) workerLocation.y
|
||||
)
|
||||
))
|
||||
// sort the jobs by their distance from the worker
|
||||
.sorted(new Comparator<Pair<IJob, Float>>() {
|
||||
.sorted(new Comparator<Pair<Job, Float>>() {
|
||||
@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(b.second() > a.second()) return -1;
|
||||
return 0;
|
||||
|
|
@ -81,38 +80,41 @@ public class JobBoard extends GameObject {
|
|||
|
||||
|
||||
if(workables.size() > 0) {
|
||||
for(IJob job : workables) {
|
||||
if(!job.hasWork()) continue;
|
||||
Vector2i[] workablePositions = job.getWorkablePositions();
|
||||
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;
|
||||
}
|
||||
Job firstJob = workables.get(0);
|
||||
availableJobs.remove(firstJob);
|
||||
allocations.put(worker, firstJob);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void completeJob(Job job) {
|
||||
this.rescindJob(job);
|
||||
}
|
||||
|
||||
public void completeJob(IWorker worker) {
|
||||
if(!workerHasJob(worker)) return;
|
||||
rescindJob(getJob(worker));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dTime) {
|
||||
List<IJob> toRemove = new ArrayList<IJob>();
|
||||
for(IJob job : allocations.values()) {
|
||||
if(!job.hasWork()) {
|
||||
toRemove.add(job);
|
||||
for(Job job : toRemove) {
|
||||
if(allocations.values().contains(job)) {
|
||||
// I AM NOT SURE THIS WORKS
|
||||
allocations.values().remove(job);
|
||||
}
|
||||
if(availableJobs.contains(job)) {
|
||||
availableJobs.remove(job);
|
||||
}
|
||||
}
|
||||
for(IJob job : toRemove) {
|
||||
rescindJob(job);
|
||||
}
|
||||
toRemove.clear();
|
||||
}
|
||||
|
||||
public IJob getJob(IWorker worker) {
|
||||
public boolean workerHasJob(IWorker worker) {
|
||||
return allocations.containsKey(worker);
|
||||
}
|
||||
|
||||
public Job getJob(IWorker worker) {
|
||||
if(allocations.containsKey(worker)) {
|
||||
return allocations.get(worker);
|
||||
} else return null;
|
||||
|
|
@ -123,11 +125,11 @@ public class JobBoard extends GameObject {
|
|||
String takenJobsString = "";
|
||||
String availableJobsString = "";
|
||||
|
||||
for(Entry<IWorker, IJob> allocation : allocations.entrySet()) {
|
||||
for(Entry<IWorker, Job> allocation : allocations.entrySet()) {
|
||||
takenJobsString += " " + allocation.getKey().getName() + ": " + allocation.getValue().getJobName() + "\n";
|
||||
}
|
||||
|
||||
for(IJob job : availableJobs) {
|
||||
for(Job job : availableJobs) {
|
||||
availableJobsString += " " + job.getJobName() + "\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import java.util.List;
|
|||
import xyz.valnet.engine.math.Vector4f;
|
||||
import xyz.valnet.engine.scenegraph.GameObject;
|
||||
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.IButtonListener;
|
||||
import xyz.valnet.hadean.input.SimpleButton;
|
||||
|
|
@ -30,7 +30,7 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener,
|
|||
|
||||
private Button[] actionButtons = ACTIONS_BUTTONS_NULL;
|
||||
|
||||
private Selection selectionManager;
|
||||
private SelectionLayer selectionManager;
|
||||
private final int width = 300, height = 200;
|
||||
private final int padding = 10;
|
||||
private final int actionButtonSize = 100;
|
||||
|
|
@ -44,7 +44,7 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener,
|
|||
private List<ISelectable> newSelection = null;;
|
||||
|
||||
public void start() {
|
||||
selectionManager = get(Selection.class);
|
||||
selectionManager = get(SelectionLayer.class);
|
||||
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;
|
||||
|
||||
import xyz.valnet.engine.math.Vector2i;
|
||||
import xyz.valnet.engine.math.Vector4f;
|
||||
import xyz.valnet.engine.scenegraph.GameObject;
|
||||
import xyz.valnet.hadean.interfaces.IWorldBoundsAdapter;
|
||||
|
|
@ -37,6 +38,10 @@ public class Terrain extends GameObject implements IPathable, IWorldBoundsAdapte
|
|||
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...
|
||||
@Override
|
||||
public boolean isWalkable(int x, int y, int fromX, int fromY) {
|
||||
|
|
|
|||
|
|
@ -43,12 +43,7 @@ public class Tile extends WorldObject implements IWorkable {
|
|||
stuff.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) {
|
||||
|
|
@ -58,7 +53,8 @@ public class Tile extends WorldObject implements IWorkable {
|
|||
}
|
||||
if(thing instanceof FarmPlot) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWork() {
|
||||
return desiredTill && tillLevel < 1f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2i[] getWorkablePositions() {
|
||||
return new Vector2i[] {
|
||||
|
|
@ -127,18 +118,29 @@ public class Tile extends WorldObject implements IWorkable {
|
|||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2i getLocation() {
|
||||
return new Vector2i(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJobName() {
|
||||
return "Till Soil";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doWork() {
|
||||
public boolean doWork() {
|
||||
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;
|
||||
|
||||
import xyz.valnet.engine.App;
|
||||
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.engine.scenegraph.IMouseCaptureArea;
|
||||
import xyz.valnet.hadean.gameobjects.Camera;
|
||||
import xyz.valnet.hadean.interfaces.IBuildLayerListener;
|
||||
import xyz.valnet.hadean.util.Assets;
|
||||
import xyz.valnet.hadean.util.Layers;
|
||||
|
||||
public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
||||
|
|
@ -46,7 +44,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
|||
}
|
||||
|
||||
private void broadcastWorldCoords() {
|
||||
Vector2i worldcoords = camera.screen2worldI(App.mouseX, App.mouseY);
|
||||
Vector2i worldcoords = camera.screen2world(App.mouseX, App.mouseY).asInt();
|
||||
if(mouseDown) {
|
||||
Vector2i[] ords = orderCoords(new Vector2i(x, y), worldcoords);
|
||||
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();
|
||||
deactiveate();
|
||||
} 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;
|
||||
screenX = App.mouseX;
|
||||
screenY = App.mouseY;
|
||||
|
|
@ -92,7 +90,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
|||
@Override
|
||||
public void mouseUp(int button) {
|
||||
if(button == 0 && active && mouseDown) {
|
||||
Vector2i worldcoords = camera.screen2worldI(App.mouseX, App.mouseY);
|
||||
Vector2i worldcoords = camera.screen2world(App.mouseX, App.mouseY).asInt();
|
||||
mouseDown = false;
|
||||
int x1 = x;
|
||||
int y1 = y;
|
||||
|
|
@ -102,7 +100,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea {
|
|||
int minY = Math.min(y1, y2);
|
||||
int maxX = Math.max(x1, x2);
|
||||
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;
|
||||
|
||||
public class Selection extends GameObject implements IMouseCaptureArea {
|
||||
public class SelectionLayer extends GameObject implements IMouseCaptureArea {
|
||||
|
||||
public Vector2f initialCoords;
|
||||
private Camera camera;
|
||||
private float animation = 0;
|
||||
private float animationMax = 15;
|
||||
private float animationAmplitude = 0.3f;
|
||||
private float animationMax = 30;
|
||||
private float animationAmplitude = 0.2f;
|
||||
private List<ISelectionChangeListener> listeners = new ArrayList<ISelectionChangeListener>();
|
||||
|
||||
@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;
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ import xyz.valnet.hadean.gameobjects.BottomBar;
|
|||
import xyz.valnet.hadean.gameobjects.Camera;
|
||||
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||
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.input.Button;
|
||||
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 {
|
||||
|
||||
private Selection selection;
|
||||
private SelectionLayer selection;
|
||||
private BuildLayer buildLayer;
|
||||
private Camera camera;
|
||||
private Terrain terrain;
|
||||
|
|
@ -120,7 +120,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
|
|||
public void start() {
|
||||
super.start();
|
||||
buildLayer = get(BuildLayer.class);
|
||||
selection = get(Selection.class);
|
||||
selection = get(SelectionLayer.class);
|
||||
camera = get(Camera.class);
|
||||
terrain = get(Terrain.class);
|
||||
|
||||
|
|
@ -158,15 +158,16 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
|
|||
}
|
||||
|
||||
@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 iy1 = y1;
|
||||
int ix2 = x2;
|
||||
int iy2 = y2;
|
||||
try {
|
||||
IBuildable building = selectedBuildable.newInstance();
|
||||
GameObject go = (GameObject) building;
|
||||
add(go);
|
||||
if(building instanceof GameObject) {
|
||||
add((GameObject) building);
|
||||
}
|
||||
building.buildAt(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||
} catch (Exception 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;
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ import java.util.List;
|
|||
import xyz.valnet.engine.graphics.Drawing;
|
||||
import xyz.valnet.hadean.gameobjects.BottomBar;
|
||||
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.ISelectionChangeListener;
|
||||
import xyz.valnet.hadean.util.Assets;
|
||||
|
|
@ -17,7 +17,7 @@ import xyz.valnet.hadean.util.SmartBoolean;
|
|||
|
||||
public class JobBoardTab extends Tab implements ISelectionChangeListener {
|
||||
|
||||
private Selection selection;
|
||||
private SelectionLayer selection;
|
||||
private JobBoard jobBoard;
|
||||
|
||||
private SmartBoolean opened;
|
||||
|
|
@ -37,7 +37,7 @@ public class JobBoardTab extends Tab implements ISelectionChangeListener {
|
|||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
selection = get(Selection.class);
|
||||
selection = get(SelectionLayer.class);
|
||||
jobBoard = get(JobBoard.class);
|
||||
|
||||
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 {
|
||||
|
||||
|
|
@ -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.hadean.gameobjects.BottomBar;
|
||||
|
|
@ -12,31 +12,8 @@ import xyz.valnet.hadean.util.Layers;
|
|||
@BuildableMetadata(category = "Zones", name = "Farm Plot")
|
||||
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;
|
||||
|
||||
@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
|
||||
public void renderAlpha() {
|
||||
if(!visible) return;
|
||||
|
|
@ -45,64 +22,6 @@ public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IB
|
|||
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
|
||||
public Vector4f getWorldBox() {
|
||||
return new Vector4f(x, y, x + w, y + h);
|
||||
|
|
@ -126,23 +45,9 @@ public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IB
|
|||
|
||||
@Override
|
||||
public String details() {
|
||||
|
||||
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
|
||||
public boolean isWalkable() {
|
||||
return true;
|
||||
|
|
@ -167,7 +72,7 @@ public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IB
|
|||
this.h = h;
|
||||
System.out.println("<" + x + ", " + y + ", " + w + ", " + h + ">");
|
||||
System.out.println(inScene());
|
||||
terrain.getTile(x, y).placeThing(this);
|
||||
|
||||
for(int i = x; i < x + w; i ++) {
|
||||
for(int j = y; j < y + h; j ++) {
|
||||
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;
|
||||
|
||||
import xyz.valnet.engine.math.Vector2i;
|
||||
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.ITileThing;
|
||||
import xyz.valnet.hadean.util.Action;
|
||||
import xyz.valnet.hadean.util.Assets;
|
||||
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 {
|
||||
|
||||
private SmartBoolean haul;
|
||||
|
||||
private JobBoard jobboard;
|
||||
public class Log extends WorldObject implements ITileThing, ISelectable {
|
||||
|
||||
@Override
|
||||
public void 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) {
|
||||
|
|
@ -47,9 +22,6 @@ public class Log extends WorldObject implements ITileThing, ISelectable, IHaulab
|
|||
@Override
|
||||
public void render() {
|
||||
camera.draw(Layers.GROUND, Assets.log, x, y);
|
||||
if(haul.value()) {
|
||||
camera.draw(Layers.MARKERS, Assets.haulArrow, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -81,9 +53,7 @@ public class Log extends WorldObject implements ITileThing, ISelectable, IHaulab
|
|||
|
||||
@Override
|
||||
public void runAction(Action action) {
|
||||
if(action == ACTION_HAUL) {
|
||||
haul.toggle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -92,41 +62,8 @@ public class Log extends WorldObject implements ITileThing, ISelectable, IHaulab
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWork() {
|
||||
return haul.value();
|
||||
}
|
||||
|
||||
@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";
|
||||
public String getName() {
|
||||
return "Log";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,307 +1,121 @@
|
|||
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.Vector2i;
|
||||
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.Terrain;
|
||||
import xyz.valnet.hadean.gameobjects.Tile;
|
||||
import xyz.valnet.hadean.interfaces.IHaulable;
|
||||
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.gameobjects.Job.JobStep;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.agents.Agent;
|
||||
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.Assets;
|
||||
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 String name = "Pawn " + (++ count);
|
||||
|
||||
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;
|
||||
private static int pawnCount = 0;
|
||||
private String name = "Pawn " + (++ pawnCount);
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
jobboard = get(JobBoard.class);
|
||||
pathfinder = new AStarPathfinder(terrain);
|
||||
x = 0.5f + (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();
|
||||
}
|
||||
}
|
||||
x = (int) (Math.random() * Terrain.WORLD_SIZE);
|
||||
y = (int) (Math.random() * Terrain.WORLD_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
|
||||
if(path != null && !path.isComplete()) {
|
||||
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();
|
||||
super.render();
|
||||
camera.draw(Layers.PAWNS, Assets.pawn, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dTime) {
|
||||
|
||||
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];
|
||||
}
|
||||
public void runAction(Action action) {}
|
||||
|
||||
@Override
|
||||
public String details() {
|
||||
IJob currentJob = jobboard.getJob(this);
|
||||
String jobString = currentJob == null ? "No Job" : currentJob.getJobName();
|
||||
return "" + name + "\n" +
|
||||
"Held | " + getCarriedName() + "\n" +
|
||||
"Job | " + jobString + "\n" +
|
||||
"";
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2f getLocation() {
|
||||
public Vector2f getWorldPosition() {
|
||||
return new Vector2f(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPathfinder getPathfinder() {
|
||||
return pathfinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPath(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
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";
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean hasWork() {
|
||||
// return haul.value();
|
||||
// }
|
||||
|
||||
// @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";
|
||||
// }
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Rice";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,16 @@
|
|||
package xyz.valnet.hadean.gameobjects.worldobjects;
|
||||
|
||||
import xyz.valnet.engine.math.Vector2i;
|
||||
import xyz.valnet.engine.math.Vector4f;
|
||||
import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||
import xyz.valnet.hadean.interfaces.BuildableMetadata;
|
||||
import xyz.valnet.hadean.interfaces.IBuildable;
|
||||
import xyz.valnet.hadean.interfaces.ISelectable;
|
||||
import xyz.valnet.hadean.interfaces.ITileThing;
|
||||
import xyz.valnet.hadean.interfaces.IWorkable;
|
||||
import xyz.valnet.hadean.util.Action;
|
||||
import xyz.valnet.hadean.util.Assets;
|
||||
import xyz.valnet.hadean.util.Layers;
|
||||
|
||||
@BuildableMetadata(category = "Zones", name = "Stockpile")
|
||||
public class Stockpile extends WorldObject implements IWorkable, ISelectable, ITileThing, IBuildable {
|
||||
|
||||
private JobBoard board;
|
||||
public class Stockpile extends WorldObject implements ISelectable, ITileThing, IBuildable {
|
||||
|
||||
private int w, h;
|
||||
|
||||
|
|
@ -40,33 +35,6 @@ public class Stockpile extends WorldObject implements IWorkable, ISelectable, IT
|
|||
@Override
|
||||
public void 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
|
||||
|
|
@ -96,11 +64,6 @@ public class Stockpile extends WorldObject implements IWorkable, ISelectable, IT
|
|||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doWork() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalkable() {
|
||||
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.Vector4f;
|
||||
import xyz.valnet.hadean.gameobjects.Job;
|
||||
import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||
import xyz.valnet.hadean.interfaces.ISelectable;
|
||||
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 String name = "Tree " + (++ counter);
|
||||
|
||||
private boolean chopFlag = false;
|
||||
private Job chopJob = null;
|
||||
|
||||
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));
|
||||
camera.draw(Layers.AIR, Assets.tree, x - 1, y - 2, 3, 3);
|
||||
Assets.flat.popColor();
|
||||
if(hasWork()) {
|
||||
if(chopJob != null) {
|
||||
camera.draw(Layers.MARKERS, Assets.lilAxe, x, y);
|
||||
}
|
||||
}
|
||||
|
|
@ -56,20 +57,15 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
|||
@Override
|
||||
public void runAction(Action action) {
|
||||
if(action == ACTION_CHOP) {
|
||||
chopFlag = !chopFlag;
|
||||
if(chopFlag) {
|
||||
get(JobBoard.class).postJob(this);
|
||||
if(chopJob == null) {
|
||||
chopJob = get(JobBoard.class).postSimpleWorkJob("Chop Tree", this);
|
||||
} else {
|
||||
get(JobBoard.class).rescindJob(this);
|
||||
get(JobBoard.class).rescindJob(chopJob);
|
||||
chopJob = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWork() {
|
||||
return chopFlag && choppage < strength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2i[] getWorkablePositions() {
|
||||
return new Vector2i[] {
|
||||
|
|
@ -88,14 +84,15 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
|||
}
|
||||
|
||||
@Override
|
||||
public void doWork() {
|
||||
public boolean doWork() {
|
||||
choppage ++;
|
||||
return getProgress() >= 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String details() {
|
||||
return "" + name + "\n" +
|
||||
"Chop Flag | " + chopFlag + "\n" +
|
||||
"Chop Flag | " + (chopJob != null) + "\n" +
|
||||
"Progress | " + (String.format("%.2f", getProgress() * 100)) + "%";
|
||||
}
|
||||
|
||||
|
|
@ -122,13 +119,13 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
|||
add(new Log(x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2i getLocation() {
|
||||
return new Vector2i(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJobName() {
|
||||
return "Chop " + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Tree";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
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.hadean.gameobjects.Camera;
|
||||
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||
import xyz.valnet.hadean.gameobjects.Tile;
|
||||
|
||||
public class WorldObject extends GameObject {
|
||||
public abstract class WorldObject extends GameObject {
|
||||
|
||||
protected float x;
|
||||
protected float y;
|
||||
|
|
@ -23,4 +25,11 @@ public class WorldObject extends GameObject {
|
|||
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 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
public interface IWorkable extends IJob {
|
||||
public void doWork();
|
||||
import xyz.valnet.engine.math.Vector2i;
|
||||
|
||||
public interface IWorkable {
|
||||
public boolean doWork();
|
||||
public Vector2i[] getWorkablePositions();
|
||||
public String getJobName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
package xyz.valnet.hadean.interfaces;
|
||||
|
||||
import xyz.valnet.engine.math.Vector2f;
|
||||
import xyz.valnet.hadean.pathfinding.IPathfinder;
|
||||
import xyz.valnet.hadean.pathfinding.Path;
|
||||
|
||||
public interface IWorker {
|
||||
public Vector2f getLocation();
|
||||
public IPathfinder getPathfinder();
|
||||
public void setPath(Path path);
|
||||
public Vector2f getWorldPosition();
|
||||
public String getName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ public class AStarPathfinder implements IPathfinder {
|
|||
}
|
||||
|
||||
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> closed = new ArrayList<Node>();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package xyz.valnet.hadean.pathfinding;
|
||||
|
||||
import xyz.valnet.engine.math.Vector2i;
|
||||
|
||||
public class Node {
|
||||
public int x, y, g, h;
|
||||
public Node from;
|
||||
|
|
@ -7,4 +9,8 @@ public class Node {
|
|||
public int getCost() {
|
||||
return g + h;
|
||||
}
|
||||
|
||||
public Vector2i getPosition() {
|
||||
return new Vector2i(x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ public class Path implements Iterable<Node> {
|
|||
return nodes.pop();
|
||||
}
|
||||
|
||||
public Node getDestination() {
|
||||
return nodes.firstElement();
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return nodes.isEmpty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ import xyz.valnet.hadean.gameobjects.JobBoard;
|
|||
import xyz.valnet.hadean.gameobjects.SelectionUI;
|
||||
import xyz.valnet.hadean.gameobjects.Terrain;
|
||||
import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer;
|
||||
import xyz.valnet.hadean.gameobjects.inputlayer.Selection;
|
||||
import xyz.valnet.hadean.gameobjects.tabs.BuildTab;
|
||||
import xyz.valnet.hadean.gameobjects.tabs.JobBoardTab;
|
||||
import xyz.valnet.hadean.gameobjects.tabs.MenuTab;
|
||||
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
|
||||
import xyz.valnet.hadean.gameobjects.ui.HoverQuery;
|
||||
import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab;
|
||||
import xyz.valnet.hadean.gameobjects.ui.tabs.JobBoardTab;
|
||||
import xyz.valnet.hadean.gameobjects.ui.tabs.MenuTab;
|
||||
import xyz.valnet.hadean.gameobjects.worldobjects.Pawn;
|
||||
|
||||
// TODO BIG IDEAS
|
||||
|
|
@ -35,7 +36,7 @@ public class GameScene extends SceneGraph {
|
|||
objects.add(new Pawn());
|
||||
}
|
||||
|
||||
objects.add(new Selection());
|
||||
objects.add(new SelectionLayer());
|
||||
objects.add(new SelectionUI());
|
||||
|
||||
objects.add(new BuildLayer());
|
||||
|
|
@ -44,6 +45,7 @@ public class GameScene extends SceneGraph {
|
|||
objects.add(new BuildTab());
|
||||
objects.add(new JobBoardTab());
|
||||
objects.add(new MenuTab());
|
||||
objects.add(new HoverQuery());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue