Merge branch 'world-object-unification-project' into stable

bottom-bar
Ivory 2023-01-10 03:58:39 -05:00
commit 76fa3b0f8a
24 changed files with 357 additions and 222 deletions

19
idea.md
View File

@ -51,3 +51,22 @@ consequence is that without proper care a single
event could immediately open & close the panel in
the same frame. so, the event should be able to
be captured and cease propogation.
# ready()
call order goes from top to bottom \/\/\/
ready is called before scene linkage, and
serves to initialize values that may be
needed before incoming requests.
# connect()
connect is solely for ensuring links to
other objects. get() and getAll()
# create()
create is guaranteed to only run once for
an object, even after save/load
# start()
start is called any time the object is added
to a scene

View File

@ -20,4 +20,8 @@ public class Vector4i implements Serializable {
this.w = w;
}
public Vector2i xy() {
return new Vector2i(x, y);
}
}

View File

@ -36,7 +36,7 @@ public class Job extends GameObject {
@Override
public Vector2i[] getLocations() {
return new Vector2i[] { item.getWorldPosition().asInt() };
return new Vector2i[] { item.getWorldPosition().xy() };
}
@Override
@ -78,7 +78,7 @@ public class Job extends GameObject {
Set<Vector2i> positionSet = new HashSet<Vector2i>();
for(Item item : that.getAll(Item.class)) {
if(!item.matches(predicate)) continue;
positionSet.add(item.getWorldPosition().asInt());
positionSet.add(item.getWorldPosition().xy());
}
Vector2i[] positions = new Vector2i[positionSet.size()];
positionSet.toArray(positions);

View File

@ -9,7 +9,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Stream;
import xyz.valnet.engine.math.Vector2f;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.gameobjects.worldobjects.pawn.Pawn;
import xyz.valnet.hadean.interfaces.IWorkable;
@ -59,7 +59,7 @@ public class JobBoard extends GameObject {
}
private List<Job> getJobsForWorker(Pawn worker) {
Vector2f workerLocation = worker.getWorldPosition();
Vector2i workerLocation = worker.getWorldPosition().xy();
List<Job> workables = availableJobs
.stream()

View File

@ -1,11 +1,13 @@
package xyz.valnet.hadean.gameobjects;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import xyz.valnet.engine.math.Vector2f;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.math.Vector4f;
import xyz.valnet.engine.math.Vector4i;
import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.gameobjects.worldobjects.FarmPlot;
import xyz.valnet.hadean.gameobjects.worldobjects.Tree;
@ -28,47 +30,44 @@ public class Tile extends WorldObject implements IWorkable {
private final int tileSelector = (int)Math.floor(Math.random() * 4);
private boolean rocks = false;
private List<ITileThing> stuff = new ArrayList<ITileThing>();
private Set<ITileThing> stuff = new HashSet<ITileThing>();
// TODO remove remove queue, cause like, we dont iterate over
// things? so why remove queue them? that just leads to unneccesary
// timing issues. you dumb fuck.
private List<ITileThing> toRemove = new ArrayList<ITileThing>();
public Tile(int x, int y) {
this.x = x;
this.y = y;
setPosition(x, y);
}
public Vector2i getCoords() {
return new Vector2f(x, y).asInt();
return getWorldPosition().xy();
}
public void start() {
super.start();
Vector4i pos = getWorldPosition();
float scale = 1;
float red = (float) terrain.getNoise(redSeed, x * scale, y * scale);
float green = (float) terrain.getNoise(greenSeed, x * scale, y * scale);
float blue = (float) terrain.getNoise(blueSeed, x * scale, y * scale);
float red = (float) terrain.getNoise(redSeed, pos.x * scale, pos.y * scale);
float green = (float) terrain.getNoise(greenSeed, pos.x * scale, pos.y * scale);
float blue = (float) terrain.getNoise(blueSeed, pos.x * scale, pos.y * scale);
if(color == null) color = new Vector4f(red * 0.1f, 0.4f + green * 0.15f, blue * 0.05f, 1f);
}
@Override
protected void create() {
Vector4i pos = getWorldPosition();
if(Math.random() > 0.95) {
rocks = true;
}
if(Math.random() > 0.97) {
Tree tree = new Tree((int)x, (int)y);
stuff.add(tree);
add(tree);
add(new Tree(pos.x, pos.y));
} else if(Math.random() > 0.98) {
rocks = false;
Boulder tree = new Boulder((int)x, (int)y);
stuff.add(tree);
add(tree);
add(new Boulder(pos.x, pos.y));
}
}
@ -130,15 +129,16 @@ public class Tile extends WorldObject implements IWorkable {
@Override
public void render() {
Vector4i pos = getWorldPosition();
if(tillLevel < 1f) {
Assets.flat.pushColor(color);
camera.draw(Layers.TILES, Assets.defaultTerrain[tileSelector], x, y);
camera.draw(Layers.TILES, Assets.defaultTerrain[tileSelector], pos.x, pos.y);
Assets.flat.popColor();
if(rocks) camera.draw(Layers.TILES, Assets.rocks, x, y);
if(rocks) camera.draw(Layers.TILES, Assets.rocks, pos.x, pos.y);
}
if(tillLevel > 0f) {
Assets.flat.pushColor(Vector4f.opacity(tillLevel));
camera.draw(Layers.TILES, Assets.farmPlot[tileSelector], x, y);
camera.draw(Layers.TILES, Assets.farmPlot[tileSelector], pos.x, pos.y);
Assets.flat.popColor();
}
}
@ -154,16 +154,17 @@ public class Tile extends WorldObject implements IWorkable {
@Override
public Vector2i[] getWorkablePositions() {
Vector4i pos = getWorldPosition();
return new Vector2i[] {
new Vector2i((int)x - 1, (int)y - 1),
new Vector2i((int)x, (int)y - 1),
new Vector2i((int)x + 1, (int)y - 1),
new Vector2i((int)x - 1, (int)y + 0),
new Vector2i((int)x, (int)y + 0),
new Vector2i((int)x + 1, (int)y + 0),
new Vector2i((int)x - 1, (int)y + 1),
new Vector2i((int)x, (int)y + 1),
new Vector2i((int)x + 1, (int)y + 1),
new Vector2i(pos.x - 1, pos.y - 1),
new Vector2i(pos.x, pos.y - 1),
new Vector2i(pos.x + 1, pos.y - 1),
new Vector2i(pos.x - 1, pos.y + 0),
new Vector2i(pos.x, pos.y + 0),
new Vector2i(pos.x + 1, pos.y + 0),
new Vector2i(pos.x - 1, pos.y + 1),
new Vector2i(pos.x, pos.y + 1),
new Vector2i(pos.x + 1, pos.y + 1),
};
}
@ -188,11 +189,6 @@ public class Tile extends WorldObject implements IWorkable {
} else return "Tilled Soil";
}
@Override
public Vector4f getWorldBox() {
return new Vector4f(x, y, x+1, y+1);
}
public String toThingsString() {
if(stuff.size() == 0) return " - Nothing";
String str = "";

View File

@ -7,6 +7,7 @@ import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.engine.scenegraph.IMouseCaptureArea;
import xyz.valnet.engine.scenegraph.ITransient;
import xyz.valnet.hadean.gameobjects.Camera;
import xyz.valnet.hadean.interfaces.BuildableMetadata;
import xyz.valnet.hadean.interfaces.IBuildLayerListener;
import xyz.valnet.hadean.util.Layers;
@ -20,6 +21,12 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi
private IBuildLayerListener listener = null;
private BuildableMetadata.Type type = BuildableMetadata.Type.AREA;
public void setBuildType(BuildableMetadata.Type type) {
this.type = type;
}
@Override
protected void connect() {
camera = get(Camera.class);
@ -28,6 +35,8 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi
@Override
public void update(float dTime) {
if(listener == null) return;
if(type == BuildableMetadata.Type.SINGLE && mouseDown) return;
broadcastWorldCoords();
}
@ -77,18 +86,23 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi
if(button == 1 && active && hovered) {
listener.cancel();
} else if(button == 0 && active && hovered) {
// TODO this conversion in negative numbers definitely works wrong.
Vector2i worldcoords = camera.screen2world(App.mouseX, App.mouseY).asInt();
mouseDown = true;
x = worldcoords.x;
y = worldcoords.y;
if(type == BuildableMetadata.Type.SINGLE) {
listener.build(x, y);
}
}
}
@Override
public void mouseUp(int button) {
if(button == 0 && active && mouseDown) {
Vector2i worldcoords = camera.screen2world(App.mouseX, App.mouseY).asInt();
mouseDown = false;
if(type == BuildableMetadata.Type.AREA) {
Vector2i worldcoords = camera.screen2world(App.mouseX, App.mouseY).asInt();
int x1 = x;
int y1 = y;
int x2 = worldcoords.x;
@ -100,6 +114,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi
listener.build(minX, minY, maxX, maxY);
}
}
}

View File

@ -67,7 +67,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
public record BuildableRecord(
String name,
Constructor<? extends IBuildable> constructor,
int type
BuildableMetadata.Type type
) {}
public static void registerBuildable(Class<? extends IBuildable> clazz) {
@ -88,7 +88,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
String category = annotation.category();
String name = annotation.name();
int type = annotation.type();
BuildableMetadata.Type type = annotation.type();
System.out.println("Added " + category + " / " + name);
@ -160,6 +160,11 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
if(buildableRecord == null) deselectBuilding();
if (selectedBuildable == null) activateBuildLayer();
selectedBuildable = buildableRecord;
swapBuildLayerType(selectedBuildable.type);
}
private void swapBuildLayerType(BuildableMetadata.Type type) {
buildLayer.setBuildType(type);
}
private void activateBuildLayer() {
@ -188,6 +193,22 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
// opened.set(false);
}
@Override
public void build(int x1, int y1) {
if(selectedBuildable == null) return;
try {
IBuildable building = selectedBuildable.constructor.newInstance();
if(building instanceof GameObject) {
add((GameObject) building);
}
building.buildAt(x1, y1);
} catch (Exception e) {
System.out.println(e);
}
// opened.set(false);
}
@Override
public void cancel() {
if(selectedBuildable == null) {

View File

@ -4,10 +4,10 @@ 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.gameobjects.Tile;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Log;
import xyz.valnet.hadean.interfaces.BuildableMetadata;
import xyz.valnet.hadean.interfaces.IBuildable;
import xyz.valnet.hadean.interfaces.IItemReceiver;
import xyz.valnet.hadean.interfaces.ISelectable;
import xyz.valnet.hadean.interfaces.IWorkable;
@ -19,8 +19,8 @@ import xyz.valnet.hadean.util.detail.Detail;
import xyz.valnet.hadean.util.detail.ObjectDetail;
import xyz.valnet.hadean.util.detail.PercentDetail;
@BuildableMetadata(category = "Furniture", name = "Bed", type = BuildableMetadata.SINGLE)
public class Bed extends WorldObject implements IBuildable, IItemReceiver, IWorkable, ISelectable {
@BuildableMetadata(category = "Furniture", name = "Bed", type = BuildableMetadata.Type.SINGLE)
public class Bed extends Buildable implements IItemReceiver, IWorkable, ISelectable {
private int logs = 0;
private float work = 0;
@ -28,11 +28,15 @@ public class Bed extends WorldObject implements IBuildable, IItemReceiver, IWork
private Job job = null;
@Override
protected Vector2i getDefaultDimensions() {
return new Vector2i(1, 2);
}
@Override
protected void create() {
super.create();
job = add(new Job("Build Bed"));
Log log = get(Log.class);
job.addStep(job.new PickupItemByPredicate(Log.LOG_PREDICATE));
job.addStep(job.new DropoffPredicateAtItemReceiver(this, Log.LOG_PREDICATE));
job.addStep(job.new Work(this));
@ -42,15 +46,16 @@ public class Bed extends WorldObject implements IBuildable, IItemReceiver, IWork
@Override
public void render() {
super.render();
Vector2i pos = getWorldPosition().xy();
if(isBuilt()) {
camera.draw(Layers.GROUND, Assets.bed, (int)x, (int)y, 1, 2);
camera.draw(Layers.GROUND, Assets.bed, pos.x, pos.y, 1, 2);
} else {
float p = work / maxWork;
float b = 4;
Assets.flat.pushColor(new Vector4f(b, b, b, 0.5f));
camera.draw(Layers.GROUND, Assets.bed, (int)x, (int)y, 1, 2);
camera.draw(Layers.GROUND, Assets.bed, pos.x, pos.y, 1, 2);
Assets.flat.popColor();
if(logs > 0) {
@ -61,24 +66,11 @@ public class Bed extends WorldObject implements IBuildable, IItemReceiver, IWork
}
}
@Override
public void buildAt(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = 1;
this.h = 2;
}
@Override
public String getName() {
return "Bed";
}
@Override
public Vector4f getWorldBox() {
return new Vector4f(x, y, x+w, y+h);
}
@Override
public boolean receive(Item item) {
if(item == null) return false;
@ -99,16 +91,17 @@ public class Bed extends WorldObject implements IBuildable, IItemReceiver, IWork
}
private Vector2i[] getBorders() {
Vector2i pos = getWorldPosition().xy();
return new Vector2i[] {
new Vector2i((int) x, (int) y - 1),
new Vector2i(pos.x, pos.y - 1),
new Vector2i((int) x - 1, (int) y),
new Vector2i((int) x + 1, (int) y),
new Vector2i(pos.x - 1, pos.y),
new Vector2i(pos.x + 1, pos.y),
new Vector2i((int) x - 1, (int) y + 1),
new Vector2i((int) x + 1, (int) y + 1),
new Vector2i(pos.x - 1, pos.y + 1),
new Vector2i(pos.x + 1, pos.y + 1),
new Vector2i((int) x, (int) y + 2),
new Vector2i(pos.x, pos.y + 2),
};
}
@ -146,4 +139,18 @@ public class Bed extends WorldObject implements IBuildable, IItemReceiver, IWork
};
}
@Override
public boolean isWalkable() {
return false;
}
@Override
public boolean shouldRemove() {
return false;
}
@Override
public void onRemove() {
}
}

View File

@ -0,0 +1,27 @@
package xyz.valnet.hadean.gameobjects.worldobjects;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.gameobjects.Tile;
import xyz.valnet.hadean.interfaces.IBuildable;
import xyz.valnet.hadean.interfaces.ITileThing;
public abstract class Buildable extends WorldObject implements IBuildable, ITileThing {
protected Vector2i getDefaultDimensions() {
return new Vector2i(1, 1);
}
@Override
public void buildAt(int x, int y, int w, int h) {
setPosition(x, y, w, h);
}
@Override
public void buildAt(int x, int y) {
Vector2i dim = getDefaultDimensions();
setPosition(x, y, dim.x, dim.y);
}
@Override
public void onPlaced(Tile tile) {}
}

View File

@ -1,34 +1,27 @@
package xyz.valnet.hadean.gameobjects.worldobjects;
import xyz.valnet.engine.math.Vector4f;
import xyz.valnet.engine.math.Vector4i;
import xyz.valnet.hadean.gameobjects.Tile;
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.util.Action;
import xyz.valnet.hadean.util.Assets;
import xyz.valnet.hadean.util.Layers;
import xyz.valnet.hadean.util.detail.Detail;
@BuildableMetadata(category = "Zones", name = "Farm Plot")
public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IBuildable {
private int w, h;
public class FarmPlot extends Buildable implements ISelectable {
@Override
public void renderAlpha() {
if(!visible) return;
Vector4i pos = getWorldPosition();
Assets.flat.pushColor(new Vector4f(0.4f, 1f, 0.3f, 0.2f));
camera.draw(Layers.GROUND, Assets.whiteBox, x, y, w, h);
camera.draw(Layers.GROUND, Assets.whiteBox, pos.x, pos.y, pos.z, pos.w);
Assets.flat.popColor();
}
@Override
public Vector4f getWorldBox() {
return new Vector4f(x, y, x + w, y + h);
}
private static Action TOGGLE_VISIBILITY = new Action("Hide\n----\nShow");
@Override
@ -65,20 +58,6 @@ public class FarmPlot extends WorldObject implements ISelectable, ITileThing, IB
}
@Override
public void buildAt(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
for(int i = x; i < x + w; i ++) {
for(int j = y; j < y + h; j ++) {
terrain.getTile(i, j).placeThing(this);
}
}
}
@Override
public String getName() {
return "Farm Plot";

View File

@ -1,6 +1,7 @@
package xyz.valnet.hadean.gameobjects.worldobjects;
import xyz.valnet.engine.math.Vector2f;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.math.Vector4f;
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
import xyz.valnet.hadean.util.Action;
@ -12,16 +13,16 @@ public class Rice extends Item {
public Rice(int x, int y) {
this.x = x;
this.y = y;
setPosition(x, y);
}
@Override
public void render() {
camera.draw(Layers.AIR, Assets.riceBag, x, y);
Vector2i pos = getWorldPosition().xy();
camera.draw(Layers.AIR, Assets.riceBag, pos.x, pos.y);
Assets.flat.pushColor(Vector4f.black);
Vector2f screeCoords = camera.world2screen(x, y);
Vector2f screeCoords = camera.world2screen(pos.x, pos.y);
Assets.miniFont.drawString("123", (int)screeCoords.x, (int)screeCoords.y);
Assets.flat.popColor();
}
@ -39,11 +40,6 @@ public class Rice extends Item {
@Override
public void onRemove() {}
@Override
public Vector4f getWorldBox() {
return new Vector4f(x, y, x + 1, y + 1);
}
@Override
public Action[] getActions() {
return new Action[] {};

View File

@ -1,21 +1,20 @@
package xyz.valnet.hadean.gameobjects.worldobjects;
import java.util.Set;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.math.Vector4f;
import xyz.valnet.engine.math.Vector4i;
import xyz.valnet.hadean.gameobjects.Tile;
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.util.Action;
import xyz.valnet.hadean.util.Assets;
import xyz.valnet.hadean.util.Layers;
import xyz.valnet.hadean.util.detail.Detail;
@BuildableMetadata(category = "Zones", name = "Stockpile")
public class Stockpile extends WorldObject implements ISelectable, ITileThing, IBuildable {
private int w, h;
public class Stockpile extends Buildable implements ISelectable {
@Override
public void render() {
@ -24,43 +23,20 @@ public class Stockpile extends WorldObject implements ISelectable, ITileThing, I
@Override
public void renderAlpha() {
if(!visible) return;
Vector4i pos = getWorldPosition();
Assets.flat.pushColor(new Vector4f(1f, 0.2f, 0.1f, 0.3f));
camera.draw(Layers.TILES, Assets.whiteBox, x, y, w, h);
camera.draw(Layers.TILES, Assets.whiteBox, pos.x, pos.y, pos.z, pos.w);
Assets.flat.popColor();
}
@Override
public void update(float dTime) {
super.update(dTime);
}
private Tile[] getTiles() {
Vector4f box = getWorldBox();
int count = 0;
Tile[] tiles = new Tile[(int)box.z * (int)box.w];
for(float x = box.x; x < box.z; x ++) {
for(float y = box.y; y < box.w; y ++) {
tiles[count] = terrain.getTile((int)x, (int)y);
count ++;
}
}
return tiles;
}
public Vector2i getFreeTile() {
Tile[] tiles = getTiles();
Set<Tile> tiles = getTiles();
for(Tile tile : tiles) {
if(tile.isTileFree()) return tile.getCoords();
}
return null;
}
@Override
public Vector4f getWorldBox() {
return new Vector4f(x, y, x + w, y + h);
}
private static Action TOGGLE_VISIBILITY = new Action("Hide / Show");
@Override
@ -97,20 +73,6 @@ public class Stockpile extends WorldObject implements ISelectable, ITileThing, I
}
@Override
public void buildAt(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
for(int i = x; i < x + w; i ++) {
for(int j = y; j < y + h; j ++) {
terrain.getTile(i, j).placeThing(this);
}
}
}
@Override
public String getName() {
return "Stockpile";

View File

@ -24,20 +24,20 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
private Job chopJob = null;
public Tree(int x, int y) {
this.x = x;
this.y = y;
setPosition(x, y);
}
@Override
public void render() {
Vector2i pos = getWorldPosition().xy();
// 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, pos.x - 1, pos.y - 2, 3, 3);
// Assets.flat.popColor();
if(chopJob != null) {
if(getProgress() > 0) {
camera.drawProgressBar(getProgress(), new Vector4f(x - 1, y - 2, x + 2, y + 1));
camera.drawProgressBar(getProgress(), new Vector4f(pos.x - 1, pos.y - 2, pos.x + 2, pos.y + 1));
}
camera.draw(Layers.MARKERS, Assets.lilAxe, x, y);
camera.draw(Layers.MARKERS, Assets.lilAxe, pos.x, pos.y);
}
}
@ -46,11 +46,6 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
return false;
}
@Override
public Vector4f getWorldBox() {
return new Vector4f(x, y, x + 1, y + 1);
}
public static final Action ACTION_CHOP = new Action("Chop");
@Override
@ -74,11 +69,12 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
@Override
public Vector2i[] getWorkablePositions() {
Vector2i pos = getWorldPosition().xy();
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)
new Vector2i(pos.x, pos.y - 1),
new Vector2i(pos.x, pos.y + 1),
new Vector2i(pos.x - 1, pos.y),
new Vector2i(pos.x + 1, pos.y)
};
}
@ -123,8 +119,8 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
@Override
public void onRemove() {
Log log = new Log((int)x, (int)y);
getTile().placeThing(log);
Vector2i pos = getWorldPosition().xy();
add(new Log(pos.x, pos.y));
}
@Override

View File

@ -1,37 +1,132 @@
package xyz.valnet.hadean.gameobjects.worldobjects;
import xyz.valnet.engine.math.Vector2f;
import java.util.HashSet;
import java.util.Set;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.math.Vector4f;
import xyz.valnet.engine.math.Vector4i;
import xyz.valnet.engine.scenegraph.GameObject;
import xyz.valnet.hadean.gameobjects.Camera;
import xyz.valnet.hadean.gameobjects.Terrain;
import xyz.valnet.hadean.gameobjects.Tile;
import xyz.valnet.hadean.interfaces.ITileThing;
public abstract class WorldObject extends GameObject {
protected float x;
protected float y;
protected float w;
protected float h;
private int x;
private int y;
private int w;
private int h;
protected Camera camera;
protected Terrain terrain;
private Set<Tile> linkedTiles;
@Override
protected void ready() {
if(linkedTiles == null) linkedTiles = new HashSet<Tile>();
}
@Override
protected void connect() {
camera = get(Camera.class);
terrain = get(Terrain.class);
}
public Tile getTile() {
return terrain.getTile((int)x, (int)y);
@Override
protected void start() {
setPosition(x, y, w, h);
}
public Vector2f getWorldPosition() {
return new Vector2f(x, y);
private void updateTileLinks(Set<Tile> tiles) {
if(tiles == null || tiles.size() == 0) return;
if(!(this instanceof ITileThing)) return;
boolean inScene = inScene();
Set<Tile> removeTiles = new HashSet<Tile>();
Set<Tile> addTiles = new HashSet<Tile>();
for(Tile tile : tiles) {
if(linkedTiles.contains(tile)) continue;
addTiles.add(tile);
}
for(Tile tile : linkedTiles) {
if(tiles.contains(tile)) continue;
removeTiles.add(tile);
}
for(Tile tile : removeTiles) {
linkedTiles.remove(tile);
if(this instanceof ITileThing) {
tile.removeThing((ITileThing) this);
}
}
for(Tile tile : addTiles) {
linkedTiles.add(tile);
if(this instanceof ITileThing) {
tile.placeThing((ITileThing) this);
}
}
if(linkedTiles.size() == 0 && inScene()) {
remove(this);
}
if(linkedTiles.size() != 0 && !inScene()) {
add(this);
}
}
protected void setPosition(Vector4i vector) {
setPosition(vector.x, vector.y, vector.z, vector.w);
}
protected void setPosition(Vector2i vector) {
setPosition(vector.x, vector.y);
}
protected void setPosition(int x, int y) {
setPosition(x, y, 1, 1);
}
protected void setPosition(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
if(terrain == null) return;
Set<Tile> tiles = new HashSet<Tile>();
for(int i = 0; i < w; i ++) {
for(int j = 0; j < h; j ++) {
tiles.add(terrain.getTile(x + i, y + j));
}
}
updateTileLinks(tiles);
}
public Tile getTile() {
return terrain.getTile(x, y);
}
public Set<Tile> getTiles() {
return linkedTiles;
}
public Vector4i getWorldPosition() {
return new Vector4i(x, y, w, h);
}
public abstract String getName();
public abstract Vector4f getWorldBox();
public Vector4f getWorldBox() {
return new Vector4f(x, y, x + w, y + h);
}
}

View File

@ -40,11 +40,12 @@ public abstract class Agent extends WorldObject implements ISelectable {
}
public Vector2f getCalculatedPosition() {
if(path == null || path.isComplete()) return getWorldPosition();
if(path == null || path.isComplete()) return getWorldPosition().xy().asFloat();
Vector2i pos = getWorldPosition().xy();
Vector2f nextPos = path.peek().getPosition().asFloat();
return new Vector2f(
lerp(x, nextPos.x, frameCounter / (float)speed),
lerp(y, nextPos.y, frameCounter / (float)speed)
lerp(pos.x, nextPos.x, frameCounter / (float)speed),
lerp(pos.y, nextPos.y, frameCounter / (float)speed)
);
}
@ -68,8 +69,7 @@ public abstract class Agent extends WorldObject implements ISelectable {
frameCounter += dTime;
if(frameCounter >= speed) {
Vector2i nextPos = path.pop().getPosition();
this.x = nextPos.x;
this.y = nextPos.y;
setPosition(nextPos.x, nextPos.y);
if(nextPath != null) {
path = nextPath;
nextPath = null;
@ -92,16 +92,17 @@ public abstract class Agent extends WorldObject implements ISelectable {
private void correctPath() {
if(path != null && path.isComplete()) path = null;
if(path == null) return;
if(path.peek().getPosition().equals(this.getWorldPosition().asInt())) {
if(path.peek().getPosition().equals(this.getWorldPosition().xy())) {
path.pop();
}
if(path != null && path.isComplete()) path = null;
if(path == null) return;
Tile nextTile = terrain.getTile(path.peek().getPosition());
if(!nextTile.isWalkable()) {
Vector2i pos = getWorldPosition().xy();
path = pathfinder.getPath(
(int)Math.floor(x),
(int)Math.floor(y),
pos.x,
pos.y,
path.dst.x,
path.dst.y
);
@ -124,7 +125,8 @@ public abstract class Agent extends WorldObject implements ISelectable {
private Path nextPath = null;
public void goTo(int x, int y) {
Path newPath = pathfinder.getPath((int)this.x, (int)this.y, x, y);
Vector2i pos = getWorldPosition().xy();
Path newPath = pathfinder.getPath(pos.x, pos.y, x, y);
if(path == null) {
path = newPath;
frameCounter -= 0;
@ -134,7 +136,7 @@ public abstract class Agent extends WorldObject implements ISelectable {
}
public void goToClosest(Vector2i[] destinations) {
Path newPath = pathfinder.getBestPath(this.getWorldPosition().asInt(), destinations);
Path newPath = pathfinder.getBestPath(getWorldPosition().xy(), destinations);
if(path == null) {
path = newPath;
frameCounter = 0;
@ -148,9 +150,10 @@ public abstract class Agent extends WorldObject implements ISelectable {
}
public void wander() {
Vector2i pos = getWorldPosition().xy();
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);
path = pathfinder.getPath(pos.x, pos.y, randomX, randomY);
}
@Override
@ -164,7 +167,8 @@ public abstract class Agent extends WorldObject implements ISelectable {
glBegin(GL_LINES);
Vector2f u, v;
if(node.from == null) u = camera.world2screen(x, y);
Vector2i pos = getWorldPosition().xy();
if(node.from == null) u = camera.world2screen(pos.x, pos.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);

View File

@ -1,5 +1,6 @@
package xyz.valnet.hadean.gameobjects.worldobjects.items;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.util.Assets;
import xyz.valnet.hadean.util.Layers;
import xyz.valnet.hadean.util.detail.Detail;
@ -7,8 +8,7 @@ import xyz.valnet.hadean.util.detail.Detail;
public class Boulder extends Item {
public Boulder(int x, int y) {
this.x = x;
this.y = y;
setPosition(x, y);
}
@Override
@ -18,7 +18,8 @@ public class Boulder extends Item {
@Override
public void render() {
camera.draw(Layers.GROUND, Assets.bigRock, x, y);
Vector2i pos = getWorldPosition().xy();
camera.draw(Layers.GROUND, Assets.bigRock, pos.x, pos.y);
}
@Override

View File

@ -1,6 +1,7 @@
package xyz.valnet.hadean.gameobjects.worldobjects.items;
import xyz.valnet.engine.math.Vector4f;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.engine.math.Vector4i;
import xyz.valnet.hadean.gameobjects.Job;
import xyz.valnet.hadean.gameobjects.JobBoard;
import xyz.valnet.hadean.gameobjects.Tile;
@ -37,11 +38,6 @@ public abstract class Item extends WorldObject implements ISelectable, ITileThin
return null;
}
@Override
public Vector4f getWorldBox() {
return new Vector4f(x, y, x + 1, y + 1);
}
public static final Action HAUL = new Action("Haul");
public static final Action CANCEL_HAUL = new Action("Cancel\n Haul");
@ -57,7 +53,7 @@ public abstract class Item extends WorldObject implements ISelectable, ITileThin
public void renderAlpha() {
if(haulJob != null) {
// Assets.flat.pushColor(Vector4f.opacity(1f));
camera.draw(Layers.MARKERS, Assets.haulArrow, getWorldPosition());
camera.draw(Layers.MARKERS, Assets.haulArrow, getWorldPosition().xy().asFloat());
// Assets.flat.popColor();
}
}
@ -90,11 +86,28 @@ public abstract class Item extends WorldObject implements ISelectable, ITileThin
@Override
public void onPlaced(Tile tile) {
this.x = tile.getCoords().x;
this.y = tile.getCoords().y;
setPosition(tile.getWorldPosition());
}
public boolean matches(IItemPredicate itemPredicate) {
return itemPredicate.matches(this);
}
public void setPosition(Vector4i vector) {
super.setPosition(vector);
}
public void setPosition(Vector2i vector) {
super.setPosition(vector);
}
public void setPosition(int x, int y) {
super.setPosition(x, y);
}
public void setPosition(int x, int y, int w, int h) {
super.setPosition(x, y, w, h);
}
}

View File

@ -1,5 +1,6 @@
package xyz.valnet.hadean.gameobjects.worldobjects.items;
import xyz.valnet.engine.math.Vector2i;
import xyz.valnet.hadean.interfaces.IItemPredicate;
import xyz.valnet.hadean.util.Assets;
import xyz.valnet.hadean.util.Layers;
@ -15,13 +16,13 @@ public class Log extends Item {
public static IItemPredicate LOG_PREDICATE = (item) -> (item instanceof Log);
public Log(int x, int y) {
this.x = x;
this.y = y;
setPosition(x, y);
}
@Override
public void render() {
camera.draw(Layers.GROUND, Assets.log, x, y);
Vector2i pos = getWorldPosition().xy();
camera.draw(Layers.GROUND, Assets.log, pos.x, pos.y);
}
@Override

View File

@ -43,7 +43,7 @@ public class JobActivity extends Activity {
}
private boolean isAtJobStepLocation() {
return worker.getWorldPosition().asInt().isOneOf(job.getCurrentStep().getLocations());
return worker.getWorldPosition().xy().isOneOf(job.getCurrentStep().getLocations());
}
private void goToJobStepLocation() {

View File

@ -42,8 +42,6 @@ public class Pawn extends Agent {
public void pickupItemByPredicate(IItemPredicate itemPredicate) {
Item item = getTile().pickupByItemPredicate(itemPredicate);
if(item == null) return;
remove(item);
inventory.add(item);
}
@ -58,8 +56,8 @@ public class Pawn extends Agent {
if(!inventory.contains(item)) {
return;
}
inventory.remove(item);
add(item);
inventory.remove(add(item));
item.setPosition(getWorldPosition().xy());
getTile().placeThing(item);
}
@ -103,8 +101,10 @@ public class Pawn extends Agent {
}
protected void create() {
x = (int) (Math.random() * Terrain.WORLD_SIZE);
y = (int) (Math.random() * Terrain.WORLD_SIZE);
setPosition(
(int) (Math.random() * Terrain.WORLD_SIZE),
(int) (Math.random() * Terrain.WORLD_SIZE)
);
}
@Override
@ -133,11 +133,6 @@ public class Pawn extends Agent {
});
}
@Override
public Vector2f getWorldPosition() {
return new Vector2f(x, y);
}
@Override
public String getName() {
return name;

View File

@ -6,10 +6,12 @@ import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface BuildableMetadata {
public static int AREA = 0;
public static int SINGLE = 1;
public enum Type {
AREA,
SINGLE
}
public String name();
public String category();
public int type() default AREA;
public Type type() default Type.AREA;
}

View File

@ -3,5 +3,6 @@ package xyz.valnet.hadean.interfaces;
public interface IBuildLayerListener {
public void update(int x, int y, int w, int h);
public void build(int x, int y, int w, int h);
public void build(int x, int y);
public void cancel();
}

View File

@ -3,5 +3,6 @@ package xyz.valnet.hadean.interfaces;
public interface IBuildable {
public void buildAt(int x, int y, int w, int h);
public void buildAt(int x, int y);
}