better jobs, quarry, immediateui
parent
58e4c02dc1
commit
58618b97bc
|
|
@ -6,50 +6,57 @@ import xyz.valnet.engine.math.Vector4i;
|
||||||
|
|
||||||
public class Font {
|
public class Font {
|
||||||
|
|
||||||
private Map<Character, Sprite> charset;
|
private Map<Character, Sprite> charset;
|
||||||
private final int w, h;
|
private final int w, h;
|
||||||
|
|
||||||
public Font(Map<Character, Sprite> charset, int w, int h) {
|
private final int scale;
|
||||||
this.charset = charset;
|
|
||||||
this.w = w;
|
|
||||||
this.h = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawString(String str, int x, int y) {
|
public Font(Map<Character, Sprite> charset, int w, int h, int scale) {
|
||||||
int cursorX = x;
|
this.charset = charset;
|
||||||
int cursorY = y;
|
this.scale = scale;
|
||||||
|
this.w = w * scale;
|
||||||
|
this.h = h * scale;
|
||||||
|
}
|
||||||
|
|
||||||
Sprite s;
|
public void drawString(String str, int x, int y) {
|
||||||
|
int cursorX = x;
|
||||||
|
int cursorY = y;
|
||||||
|
|
||||||
for(char c : str.toCharArray()) {
|
Sprite s;
|
||||||
if(c == '\n') {
|
|
||||||
cursorY += h;
|
|
||||||
cursorX = x;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(c == '\r') continue;
|
|
||||||
if(c == '\t') {
|
|
||||||
cursorX += w * 4;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(c == ' ' || !charset.containsKey(c)) {
|
|
||||||
cursorX += w;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
s = charset.get(c);
|
|
||||||
Drawing.drawSprite(s, cursorX, cursorY);
|
|
||||||
cursorX += w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector4i measure(String text) {
|
for(char c : str.toCharArray()) {
|
||||||
String[] lines = text.split("\n");
|
if(c == '\n') {
|
||||||
int longest = 0;
|
cursorY += h;
|
||||||
int c = 0;
|
cursorX = x;
|
||||||
for(String line : lines) {
|
continue;
|
||||||
c = line.length();
|
|
||||||
if(c > longest) longest = c;
|
|
||||||
}
|
}
|
||||||
return new Vector4i(longest * w, lines.length * h, 0, 0);
|
if(c == '\r') continue;
|
||||||
|
if(c == '\t') {
|
||||||
|
cursorX += w * 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c == ' ' || !charset.containsKey(c)) {
|
||||||
|
cursorX += w;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s = charset.get(c);
|
||||||
|
Drawing.drawSprite(s, cursorX, cursorY, w, h);
|
||||||
|
cursorX += w;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector4i measure(String text) {
|
||||||
|
String[] lines = text.split("\n");
|
||||||
|
int longest = 0;
|
||||||
|
int c = 0;
|
||||||
|
for(String line : lines) {
|
||||||
|
c = line.length();
|
||||||
|
if(c > longest) longest = c;
|
||||||
|
}
|
||||||
|
return new Vector4i(longest * w, lines.length * h, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLineHeight() {
|
||||||
|
return h;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
package xyz.valnet.engine.graphics;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
import xyz.valnet.engine.math.Vector4i;
|
||||||
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
|
import xyz.valnet.engine.scenegraph.IMouseCaptureArea;
|
||||||
|
import xyz.valnet.hadean.input.Button;
|
||||||
|
import xyz.valnet.hadean.util.Assets;
|
||||||
|
import xyz.valnet.hadean.util.Layers;
|
||||||
|
|
||||||
|
public abstract class ImmediateUI extends GameObject implements IMouseCaptureArea {
|
||||||
|
|
||||||
|
private boolean active;
|
||||||
|
private boolean mouseDown;
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
begin();
|
||||||
|
gui();
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEnter() {
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseLeave() {
|
||||||
|
active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDown(int button) {
|
||||||
|
if(button == 0) mouseDown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseUp(int button) {
|
||||||
|
if(button == 0) mouseDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Vector4f getGuiBox();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayer() {
|
||||||
|
return Layers.GENERAL_UI_INTERACTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void gui();
|
||||||
|
|
||||||
|
private record StackingContext(
|
||||||
|
boolean fixedSize,
|
||||||
|
Vector4f box,
|
||||||
|
Vector4f occlusionBox
|
||||||
|
// layout manager?
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private StackingContext context;
|
||||||
|
private Stack<StackingContext> contextStack;
|
||||||
|
|
||||||
|
private transient Map<String, Button> buttons = new HashMap<String, Button>();
|
||||||
|
private Set<String> usedButtonId = new HashSet<String>();
|
||||||
|
private transient Map<Button, Integer> clicks = new HashMap<Button, Integer>();
|
||||||
|
private int buttonCount;
|
||||||
|
|
||||||
|
private String genButtonId() {
|
||||||
|
buttonCount ++;
|
||||||
|
return "DefaultButton-" + buttonCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasButton(String id) {
|
||||||
|
usedButtonId.add(id);
|
||||||
|
return buttons.containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button getButton(String id) {
|
||||||
|
if(hasButton(id)) return buttons.get(id);
|
||||||
|
System.out.println("Created new Button");
|
||||||
|
Button btn = new Button(Assets.uiFrame, "", 0, 0, 0, 0, 0);
|
||||||
|
btn.registerClickListener((target) -> {
|
||||||
|
if(!clicks.containsKey(target)) clicks.put(target, 0);
|
||||||
|
clicks.put(target, clicks.get(target) + 1);
|
||||||
|
});
|
||||||
|
buttons.put(id, add(btn));
|
||||||
|
return btn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getClick(Button btn) {
|
||||||
|
if(clicks.containsKey(btn)) {
|
||||||
|
int clickCount = clicks.get(btn);
|
||||||
|
if(clickCount > 0) {
|
||||||
|
clicks.put(btn, clickCount - 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void adjustBox(float h) {
|
||||||
|
if(context.fixedSize) {
|
||||||
|
context.box.y += h;
|
||||||
|
context.box.w -= h;
|
||||||
|
} else {
|
||||||
|
context.box.w += h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === ELEMENTS ===
|
||||||
|
|
||||||
|
protected void begin() {
|
||||||
|
buttonCount = 0;
|
||||||
|
usedButtonId.clear();
|
||||||
|
Drawing.setLayer(Layers.GENERAL_UI_INTERACTABLE);
|
||||||
|
context = new StackingContext(true, getGuiBox(), getGuiBox());
|
||||||
|
contextStack = new Stack<StackingContext>();
|
||||||
|
Assets.uiFrame.draw(context.occlusionBox);
|
||||||
|
pad();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean button(String text) {
|
||||||
|
return button(genButtonId(), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean button(String id, String text) {
|
||||||
|
float h = 32;
|
||||||
|
Vector4f buttonBox = new Vector4f(context.box.x, context.box.y, context.box.z, h);
|
||||||
|
Button btn = getButton(id);
|
||||||
|
|
||||||
|
btn.setText(text);
|
||||||
|
btn.setPosition((int) buttonBox.x, (int) buttonBox.y);
|
||||||
|
btn.setSize((int) buttonBox.z, (int) buttonBox.w);
|
||||||
|
btn.setLayer(Layers.GENERAL_UI_INTERACTABLE + contextStack.size());
|
||||||
|
|
||||||
|
// System.out.println("" + buttonBox);
|
||||||
|
|
||||||
|
adjustBox(h);
|
||||||
|
|
||||||
|
return getClick(btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void horizontal(int columns) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void horizontalEnd() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void group() {
|
||||||
|
contextStack.push(context);
|
||||||
|
context = new StackingContext(false,
|
||||||
|
new Vector4f(
|
||||||
|
context.box.x, context.box.y, context.box.z, 0
|
||||||
|
),
|
||||||
|
context.occlusionBox.copy()
|
||||||
|
);
|
||||||
|
pad();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void groupEnd() {
|
||||||
|
padEnd();
|
||||||
|
Drawing.setLayer(getLayer() + contextStack.size() - 1);
|
||||||
|
float h = context.box.w;
|
||||||
|
Assets.uiFrame.draw(context.box);
|
||||||
|
context = contextStack.pop();
|
||||||
|
adjustBox(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void pad() {
|
||||||
|
contextStack.push(context);
|
||||||
|
if(context.fixedSize) {
|
||||||
|
context = new StackingContext(true,
|
||||||
|
new Vector4f(
|
||||||
|
context.box.x + 8, context.box.y + 8, context.box.z - 16, context.box.w - 16
|
||||||
|
),
|
||||||
|
context.occlusionBox.copy()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
context = new StackingContext(false,
|
||||||
|
new Vector4f(
|
||||||
|
context.box.x + 8, context.box.y + 8, context.box.z - 16, 0
|
||||||
|
),
|
||||||
|
context.occlusionBox.copy()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void padEnd() {
|
||||||
|
float h = context.box.w + 16;
|
||||||
|
context = contextStack.pop();
|
||||||
|
adjustBox(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void end() {
|
||||||
|
padEnd();
|
||||||
|
|
||||||
|
List<String> buttonIdsToRemove = new ArrayList<String>();
|
||||||
|
|
||||||
|
for(String id : this.buttons.keySet()) {
|
||||||
|
if(usedButtonId.contains(id)) continue;
|
||||||
|
buttonIdsToRemove.add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String id : buttonIdsToRemove) {
|
||||||
|
Button btn = buttons.get(id);
|
||||||
|
remove(btn);
|
||||||
|
buttons.remove(id);
|
||||||
|
if(clicks.containsKey(btn)) {
|
||||||
|
clicks.remove(btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void text(String text) {
|
||||||
|
text(text, Assets.font);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void header(String text) {
|
||||||
|
text(text, Assets.bigFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void text(String text, Font font) {
|
||||||
|
Vector4i measured = font.measure(text);
|
||||||
|
Drawing.setLayer(getLayer() + contextStack.size());
|
||||||
|
|
||||||
|
// layout manager things...
|
||||||
|
if(context.fixedSize) {
|
||||||
|
font.drawString(text,
|
||||||
|
(int) context.box.x,
|
||||||
|
(int) context.box.y
|
||||||
|
);
|
||||||
|
context.box.y += measured.y;
|
||||||
|
context.box.w -= measured.y;
|
||||||
|
} else {
|
||||||
|
font.drawString(text,
|
||||||
|
(int) context.box.x,
|
||||||
|
(int) context.box.y + (int) context.box.w
|
||||||
|
);
|
||||||
|
context.box.w += measured.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -58,4 +58,15 @@ public class Vector4f implements Serializable {
|
||||||
return new Vector4i((int)x, (int)y, (int)z, (int)w);
|
return new Vector4i((int)x, (int)y, (int)z, (int)w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector4f pad(float all) {
|
||||||
|
return new Vector4f(x + all, y + all, z - all * 2, w - all * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector4f pad(float top, float bottom, float left, float right) {
|
||||||
|
return new Vector4f(x + left, y + top, z - left - right, w - top - bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector4f copy() {
|
||||||
|
return new Vector4f(x, y, z, w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,36 @@ public class Vector4i implements Serializable {
|
||||||
return new Vector2i(x, y);
|
return new Vector2i(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WORKS WITH WIDTH HEIGHT NOT AABB
|
||||||
|
public Vector2i[] getInternals() {
|
||||||
|
int size = z * w;
|
||||||
|
Vector2i[] vecs = new Vector2i[size];
|
||||||
|
for(int i = 0; i < z; i ++) {
|
||||||
|
for(int j = 0; j < w; j ++) {
|
||||||
|
vecs[i * z + j] = new Vector2i(x + i, y + j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WORKS WITH WIDTH HEIGHT NOT AABB
|
||||||
|
public Vector2i[] getBorders() {
|
||||||
|
|
||||||
|
int size = 2 * z + 2 * w;
|
||||||
|
Vector2i[] vecs = new Vector2i[size];
|
||||||
|
|
||||||
|
// top / bottom row
|
||||||
|
for(int i = 0; i < z; i ++) {
|
||||||
|
vecs[i] = new Vector2i(x + i, y - 1);
|
||||||
|
vecs[size - i - 1] = new Vector2i(x + i, y + w);
|
||||||
|
}
|
||||||
|
|
||||||
|
// middle pillars
|
||||||
|
for(int i = 0; i < w; i ++) {
|
||||||
|
vecs[z + i * 2] = new Vector2i(x - 1, y + i);
|
||||||
|
vecs[z + i * 2 + 1] = new Vector2i(x + z, y + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vecs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,6 @@ public interface IMouseCaptureArea {
|
||||||
public void mouseDown(int button);
|
public void mouseDown(int button);
|
||||||
public void mouseUp(int button);
|
public void mouseUp(int button);
|
||||||
|
|
||||||
public Vector4f getBox();
|
public Vector4f getGuiBox();
|
||||||
public float getLayer();
|
public float getLayer();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ public abstract class SceneGraph implements IScene {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for(IMouseCaptureArea listener : mouseListeners) {
|
for(IMouseCaptureArea listener : mouseListeners) {
|
||||||
boolean currentlyEntered = listener.getBox().contains(App.mouseX, App.mouseY);
|
boolean currentlyEntered = listener.getGuiBox().contains(App.mouseX, App.mouseY);
|
||||||
if(currentlyEntered) {
|
if(currentlyEntered) {
|
||||||
if(listener != hoveredMouseListener) {
|
if(listener != hoveredMouseListener) {
|
||||||
if(hoveredMouseListener != null) {
|
if(hoveredMouseListener != null) {
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ public class Job extends GameObject {
|
||||||
private List<JobStep> steps;
|
private List<JobStep> steps;
|
||||||
private String name;
|
private String name;
|
||||||
private int step;
|
private int step;
|
||||||
|
private boolean hasClosed = false;
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
step = 0;
|
step = 0;
|
||||||
|
|
@ -171,17 +172,14 @@ public class Job extends GameObject {
|
||||||
|
|
||||||
public Vector2i[] getLocations() {
|
public Vector2i[] getLocations() {
|
||||||
if(steps.size() == 0) throw new Error("Cannot get location of job with no steps");
|
if(steps.size() == 0) throw new Error("Cannot get location of job with no steps");
|
||||||
JobStep step = steps.get(0);
|
JobStep step = getCurrentStep();
|
||||||
return step.getLocations();
|
return step.getLocations();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void nextStep() {
|
public void nextStep() {
|
||||||
step ++;
|
step ++;
|
||||||
if(isCompleted()) {
|
if(isCompleted()) {
|
||||||
get(JobBoard.class).completeJob(this);
|
close();
|
||||||
for(Callback callback : closedListeners) {
|
|
||||||
callback.apply();
|
|
||||||
}
|
|
||||||
remove(this);
|
remove(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -205,6 +203,8 @@ public class Job extends GameObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
|
if(hasClosed) return;
|
||||||
|
hasClosed = true;
|
||||||
for(Callback callback : closedListeners) {
|
for(Callback callback : closedListeners) {
|
||||||
callback.apply();
|
callback.apply();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,15 @@ import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.engine.scenegraph.GameObject;
|
import xyz.valnet.engine.scenegraph.GameObject;
|
||||||
|
import xyz.valnet.hadean.HadeanGame;
|
||||||
import xyz.valnet.hadean.gameobjects.worldobjects.pawn.Pawn;
|
import xyz.valnet.hadean.gameobjects.worldobjects.pawn.Pawn;
|
||||||
|
import xyz.valnet.hadean.interfaces.IItemPredicate;
|
||||||
|
import xyz.valnet.hadean.interfaces.IItemReceiver;
|
||||||
import xyz.valnet.hadean.interfaces.IWorkable;
|
import xyz.valnet.hadean.interfaces.IWorkable;
|
||||||
|
import xyz.valnet.hadean.util.Assets;
|
||||||
|
import xyz.valnet.hadean.util.Layers;
|
||||||
import xyz.valnet.hadean.util.Pair;
|
import xyz.valnet.hadean.util.Pair;
|
||||||
|
|
||||||
public class JobBoard extends GameObject {
|
public class JobBoard extends GameObject {
|
||||||
|
|
@ -28,30 +34,68 @@ public class JobBoard extends GameObject {
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postJob(Job job) {
|
private Camera camera;
|
||||||
availableJobs.add(job);
|
|
||||||
|
@Override
|
||||||
|
public void connect() {
|
||||||
|
camera = get(Camera.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rescindJob(Job job) {
|
@Override
|
||||||
if(allocations.values().contains(job)) {
|
public void renderAlpha() {
|
||||||
List<Pawn> toFire = new ArrayList<Pawn>();
|
super.render();
|
||||||
|
if(HadeanGame.debugView) {
|
||||||
for(Pawn worker : allocations.keySet()) {
|
float opacity = 0.6f;
|
||||||
if(allocations.get(worker) == job) {
|
Assets.flat.pushColor(new Vector4f(1, 0.8f, 0, opacity));
|
||||||
toFire.add(worker);
|
for(Job job : availableJobs) {
|
||||||
|
for(Vector2i position : job.getLocations()) {
|
||||||
|
if(job.isValid()) {
|
||||||
|
Assets.flat.swapColor(new Vector4f(1, 0.8f, 0, opacity));
|
||||||
|
} else {
|
||||||
|
Assets.flat.swapColor(new Vector4f(1.0f, 0.2f, 0, opacity));
|
||||||
|
}
|
||||||
|
camera.draw(Layers.GROUND_MARKERS, Assets.fillTile, position.asFloat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Assets.flat.swapColor(new Vector4f(0.2f, 1.0f, 0, opacity));
|
||||||
for(Pawn worker : toFire) {
|
for(Job job : allocations.values()) {
|
||||||
allocations.remove(worker);
|
for(Vector2i position : job.getLocations()) {
|
||||||
|
camera.draw(Layers.GROUND_MARKERS, Assets.fillTile, position.asFloat());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Assets.flat.popColor();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(availableJobs.contains(job)) {
|
public Job postSimpleItemRequirementJob(String name, IItemPredicate predicate, IItemReceiver recv) {
|
||||||
availableJobs.remove(job);
|
Job job = add(new Job(name));
|
||||||
}
|
job.addStep(job.new PickupItemByPredicate(predicate));
|
||||||
|
job.addStep(job.new DropoffPredicateAtItemReceiver(recv, predicate));
|
||||||
|
postJob(job);
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
job.close();
|
public void postJob(Job job) {
|
||||||
|
job.registerClosedListener(() -> {
|
||||||
|
if(allocations.values().contains(job)) {
|
||||||
|
List<Pawn> toFire = new ArrayList<Pawn>();
|
||||||
|
|
||||||
|
for(Pawn worker : allocations.keySet()) {
|
||||||
|
if(allocations.get(worker) == job) {
|
||||||
|
toFire.add(worker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Pawn worker : toFire) {
|
||||||
|
allocations.remove(worker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(availableJobs.contains(job)) {
|
||||||
|
availableJobs.remove(job);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
availableJobs.add(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean jobsAvailableForWorker(Pawn worker) {
|
public boolean jobsAvailableForWorker(Pawn worker) {
|
||||||
|
|
@ -97,10 +141,6 @@ public class JobBoard extends GameObject {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void completeJob(Job job) {
|
|
||||||
this.rescindJob(job);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void quitJob(Pawn worker, Job job) {
|
public void quitJob(Pawn worker, Job job) {
|
||||||
if(!allocations.containsKey(worker)) return;
|
if(!allocations.containsKey(worker)) return;
|
||||||
Job foundJob = allocations.get(worker);
|
Job foundJob = allocations.get(worker);
|
||||||
|
|
@ -137,17 +177,28 @@ public class JobBoard extends GameObject {
|
||||||
|
|
||||||
String takenJobsString = "";
|
String takenJobsString = "";
|
||||||
String availableJobsString = "";
|
String availableJobsString = "";
|
||||||
|
String impossibleJobsString = "";
|
||||||
|
|
||||||
|
int possibleJobs = 0;
|
||||||
|
int impossibleJobs = 0;
|
||||||
|
|
||||||
for(Entry<Pawn, Job> allocation : allocations.entrySet()) {
|
for(Entry<Pawn, Job> allocation : allocations.entrySet()) {
|
||||||
takenJobsString += " " + allocation.getKey().getName() + ": " + allocation.getValue().getJobName() + "\n";
|
takenJobsString += " " + allocation.getKey().getName() + ": " + allocation.getValue().getJobName() + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Job job : availableJobs) {
|
for(Job job : availableJobs) {
|
||||||
availableJobsString += " " + job.getJobName() + "\n";
|
if(job.isValid()) {
|
||||||
|
availableJobsString += " " + job.getJobName() + "\n";
|
||||||
|
possibleJobs ++;
|
||||||
|
} else {
|
||||||
|
impossibleJobsString += " " + job.getJobName() + "\n";
|
||||||
|
impossibleJobs ++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Available Jobs: " + availableJobs.size() + "\n" + availableJobsString +
|
return "Available Jobs: " + possibleJobs + "\n" + availableJobsString +
|
||||||
"Taken Jobs: " + allocations.size() + "\n" + takenJobsString;
|
"Taken Jobs: " + allocations.size() + "\n" + takenJobsString +
|
||||||
|
"Impossible Jobs: " + impossibleJobs + "\n" + impossibleJobsString;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,40 +2,29 @@ package xyz.valnet.hadean.gameobjects;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
import xyz.valnet.engine.graphics.ImmediateUI;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.engine.scenegraph.GameObject;
|
|
||||||
import xyz.valnet.engine.scenegraph.IMouseCaptureArea;
|
|
||||||
import xyz.valnet.engine.scenegraph.ITransient;
|
import xyz.valnet.engine.scenegraph.ITransient;
|
||||||
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
|
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;
|
|
||||||
import xyz.valnet.hadean.interfaces.ISelectable;
|
import xyz.valnet.hadean.interfaces.ISelectable;
|
||||||
import xyz.valnet.hadean.interfaces.ISelectionChangeListener;
|
import xyz.valnet.hadean.interfaces.ISelectionChangeListener;
|
||||||
import xyz.valnet.hadean.util.Action;
|
|
||||||
import xyz.valnet.hadean.util.Assets;
|
|
||||||
import xyz.valnet.hadean.util.Layers;
|
import xyz.valnet.hadean.util.Layers;
|
||||||
import xyz.valnet.hadean.util.detail.Detail;
|
import xyz.valnet.hadean.util.detail.Detail;
|
||||||
|
|
||||||
public class SelectionUI extends GameObject implements ISelectionChangeListener, IButtonListener, IMouseCaptureArea, ITransient {
|
public class SelectionUI extends ImmediateUI implements ISelectionChangeListener, ITransient {
|
||||||
|
|
||||||
private String name = "";
|
private class SelectedByType extends HashMap<Class<? extends ISelectable>, List<ISelectable>> {}
|
||||||
private String genericName = "";
|
|
||||||
private int count = 0;
|
private int selectedCount = 0;
|
||||||
|
private String properName;
|
||||||
|
private String genericName;
|
||||||
private List<ISelectable> selected = new ArrayList<ISelectable>();
|
private List<ISelectable> selected = new ArrayList<ISelectable>();
|
||||||
private HashMap<String, Integer> selectedTypes = new HashMap<String, Integer>();
|
private transient SelectedByType selectedByType = new SelectedByType();
|
||||||
private HashMap<String, Button> narrowButtons = new HashMap<String, Button>();
|
|
||||||
private HashMap<Button, List<ISelectable>> narrowBuckets = new HashMap<Button, List<ISelectable>>();
|
|
||||||
|
|
||||||
private static final Button[] ACTIONS_BUTTONS_NULL = new Button[] {};
|
|
||||||
|
|
||||||
private Button[] actionButtons = ACTIONS_BUTTONS_NULL;
|
|
||||||
|
|
||||||
private SelectionLayer selectionManager;
|
private SelectionLayer selectionManager;
|
||||||
|
|
||||||
private final int width = 300, height = 200;
|
private final int width = 300, height = 200;
|
||||||
private final int padding = 10;
|
private final int padding = 10;
|
||||||
private final int actionButtonSize = 100;
|
private final int actionButtonSize = 100;
|
||||||
|
|
@ -46,168 +35,44 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener,
|
||||||
// exception, where the buttons are attempting to
|
// exception, where the buttons are attempting to
|
||||||
// change while updating.
|
// change while updating.
|
||||||
// TODO this could be fixed by delaying button clicks to the next frame.
|
// TODO this could be fixed by delaying button clicks to the next frame.
|
||||||
private List<ISelectable> newSelection = null;;
|
private List<ISelectable> newSelection = null;
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
selectionManager = get(SelectionLayer.class);
|
selectionManager = get(SelectionLayer.class);
|
||||||
selectionManager.subscribe(this);
|
selectionManager.subscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
|
||||||
if(selected.isEmpty()) return;
|
|
||||||
|
|
||||||
Assets.uiFrame.draw(10, 576 - BottomBar.bottomBarHeight - height - padding, width, height);
|
|
||||||
|
|
||||||
if(selectedTypes.size() == 1) {
|
|
||||||
if(count == 1) {
|
|
||||||
Assets.font.drawString(name, 26, 576 - BottomBar.bottomBarHeight - height);
|
|
||||||
String details = Detail.renderDetails(selected.get(0).getDetails());
|
|
||||||
Assets.font.drawString(details, 26, 576 - BottomBar.bottomBarHeight - height + 32);
|
|
||||||
} else {
|
|
||||||
Assets.font.drawString("" + count + "x " + genericName, 26, 576 - BottomBar.bottomBarHeight - height);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dTime) {
|
public void update(float dTime) {
|
||||||
if(newSelection != null) {
|
if(newSelection != null) {
|
||||||
selectionManager.updateSelection(newSelection);
|
selectionManager.updateSelection(newSelection);
|
||||||
newSelection = null;
|
newSelection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(selectedTypes.size() == 1) {
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private HashMap<Button, Action> buttonActionMap = new HashMap<Button, Action>();
|
|
||||||
|
|
||||||
private void addNarrowButton(String str, Button btn) {
|
|
||||||
narrowButtons.put(str, btn);
|
|
||||||
add(btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearNarrowButtons() {
|
|
||||||
for(GameObject obj : narrowButtons.values()) {
|
|
||||||
remove(obj);
|
|
||||||
}
|
|
||||||
narrowButtons.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectionChanged(List<ISelectable> selected) {
|
public void selectionChanged(List<ISelectable> newSelection) {
|
||||||
this.selected = selected;
|
|
||||||
|
|
||||||
selectedTypes.clear();
|
selected = newSelection;
|
||||||
clearNarrowButtons();
|
selectedByType.clear();
|
||||||
narrowBuckets.clear();
|
selectedCount = newSelection.size();
|
||||||
buttonActionMap.clear();
|
|
||||||
setActionButtons(ACTIONS_BUTTONS_NULL);
|
for(ISelectable selectable : newSelection) {
|
||||||
for(ISelectable selectable : selected) {
|
Class<? extends ISelectable> clazz = selectable.getClass();
|
||||||
String name = selectable.getClass().getName();
|
|
||||||
String[] splitName = name.split("\\.");
|
|
||||||
String properName = selectable.getName();
|
|
||||||
String shortName = splitName[splitName.length - 1];
|
|
||||||
|
|
||||||
if(selectedTypes.containsKey(name)) {
|
properName = selectable.getName();
|
||||||
selectedTypes.replace(name, selectedTypes.get(name) + 1);
|
genericName = selectable.getGenericName();
|
||||||
Button btn = narrowButtons.get(name);
|
|
||||||
List<ISelectable> items = narrowBuckets.get(btn);
|
if(!selectedByType.containsKey(clazz)) {
|
||||||
items.add(selectable);
|
selectedByType.put(clazz, new ArrayList<ISelectable>());
|
||||||
btn.setText("" + items.size() + "x " + shortName);
|
|
||||||
count ++;
|
|
||||||
} else {
|
|
||||||
Button btn = new SimpleButton(properName, 20, 576 - BottomBar.bottomBarHeight - height + 30 * selectedTypes.size(), width - padding * 2, 24, Layers.GENERAL_UI_INTERACTABLE);
|
|
||||||
btn.registerClickListener(this);
|
|
||||||
selectedTypes.put(name, 1);
|
|
||||||
addNarrowButton(name, btn);
|
|
||||||
List<ISelectable> list = new ArrayList<ISelectable>();
|
|
||||||
list.add(selectable);
|
|
||||||
narrowBuckets.put(btn, list);
|
|
||||||
count = 1;
|
|
||||||
this.name = properName;
|
|
||||||
this.genericName = shortName;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(selectedTypes.size() == 1) {
|
|
||||||
createActionButtons();
|
|
||||||
}
|
|
||||||
if(selectedTypes.size() <= 1) {
|
|
||||||
clearNarrowButtons();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createActionButtons() {
|
selectedByType.get(clazz).add(selectable);
|
||||||
|
|
||||||
buttonActionMap.clear();
|
|
||||||
setActionButtons(ACTIONS_BUTTONS_NULL);
|
|
||||||
|
|
||||||
Set<Action> actionSet = new HashSet<Action>();
|
|
||||||
for(ISelectable selectable : selected) {
|
|
||||||
for(Action action : selectable.getActions()) {
|
|
||||||
actionSet.add(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Action[] actions = new Action[actionSet.size()];
|
|
||||||
actionSet.toArray(actions);
|
|
||||||
|
|
||||||
Button[] actionButtons = new Button[actions.length];
|
|
||||||
for(int i = 0; i < actions.length; i ++) {
|
|
||||||
actionButtons[i] = new SimpleButton(actions[i].name, width + padding * 2 + i * (actionButtonSize + padding), 576 - padding - actionButtonSize - BottomBar.bottomBarHeight, actionButtonSize, actionButtonSize, Layers.GENERAL_UI_INTERACTABLE);
|
|
||||||
actionButtons[i].registerClickListener(this);
|
|
||||||
buttonActionMap.put(actionButtons[i], actions[i]);
|
|
||||||
}
|
|
||||||
setActionButtons(actionButtons);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setActionButtons(Button[] buttons) {
|
|
||||||
for(Button btn : this.actionButtons) {
|
|
||||||
remove(btn);
|
|
||||||
}
|
|
||||||
this.actionButtons = buttons;
|
|
||||||
for(Button btn : this.actionButtons) {
|
|
||||||
add(btn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void click(Button target) {
|
public Vector4f getGuiBox() {
|
||||||
if(narrowBuckets.containsKey(target)) {
|
|
||||||
newSelection = narrowBuckets.get(target);
|
|
||||||
} else if(buttonActionMap.containsKey(target)) {
|
|
||||||
Action action = buttonActionMap.get(target);
|
|
||||||
for(ISelectable selectable : selected) {
|
|
||||||
selectable.runAction(action);
|
|
||||||
}
|
|
||||||
createActionButtons();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseEnter() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseLeave() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDown(int button) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseUp(int button) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector4f getBox() {
|
|
||||||
if(selected.isEmpty()) return Vector4f.zero;
|
if(selected.isEmpty()) return Vector4f.zero;
|
||||||
return new Vector4f(10, 576 - BottomBar.bottomBarHeight - height - padding, width, height);
|
return new Vector4f(10, 576 - BottomBar.bottomBarHeight - height - padding, width, height);
|
||||||
}
|
}
|
||||||
|
|
@ -216,4 +81,39 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener,
|
||||||
public float getLayer() {
|
public float getLayer() {
|
||||||
return Layers.GENERAL_UI;
|
return Layers.GENERAL_UI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void gui() {
|
||||||
|
if(selected.isEmpty()) return;
|
||||||
|
|
||||||
|
if(selectedByType.size() == 1) {
|
||||||
|
if(selectedCount == 1) {
|
||||||
|
text(properName + "\n ");
|
||||||
|
group();
|
||||||
|
Detail[] details = selected.get(0).getDetails();
|
||||||
|
if(details.length == 0) {
|
||||||
|
text("No details available.");
|
||||||
|
} else for(Detail detail : details) {
|
||||||
|
text(detail.toString(15));
|
||||||
|
}
|
||||||
|
groupEnd();
|
||||||
|
} else {
|
||||||
|
text("" + selectedCount + "x " + genericName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
text(this.selected.size() + " items selected");
|
||||||
|
text("");
|
||||||
|
|
||||||
|
for(var entry : selectedByType.entrySet()) {
|
||||||
|
List<ISelectable> list = entry.getValue();
|
||||||
|
int count = list.size();
|
||||||
|
if(count <= 0) continue;
|
||||||
|
String name = list.get(0).getGenericName();
|
||||||
|
|
||||||
|
if(button(name, count + "x " + name)) {
|
||||||
|
newSelection = list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getBox() {
|
public Vector4f getGuiBox() {
|
||||||
return active ? new Vector4f(0, 0, 1024, 576) : Vector4f.zero;
|
return active ? new Vector4f(0, 0, 1024, 576) : Vector4f.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getBox() {
|
public Vector4f getGuiBox() {
|
||||||
return new Vector4f(0, 0, 1000, 1000);
|
return new Vector4f(0, 0, 1000, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package xyz.valnet.hadean.gameobjects.ui;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.graphics.ImmediateUI;
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
|
||||||
|
public class Popup extends ImmediateUI {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector4f getGuiBox() {
|
||||||
|
return new Vector4f(256, 100, 512, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void gui() {
|
||||||
|
header(" Popup Test");
|
||||||
|
|
||||||
|
text("1\n1.5");
|
||||||
|
text("2");
|
||||||
|
|
||||||
|
group();
|
||||||
|
text("This should be in a frame!");
|
||||||
|
text("And this!");
|
||||||
|
groupEnd();
|
||||||
|
|
||||||
|
text("But not this...");
|
||||||
|
|
||||||
|
if(button("Click Me!")) {
|
||||||
|
System.out.println("The Event!");
|
||||||
|
}
|
||||||
|
|
||||||
|
text("This after button...");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -289,7 +289,7 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
|
||||||
public void mouseUp(int button) {}
|
public void mouseUp(int button) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getBox() {
|
public Vector4f getGuiBox() {
|
||||||
return new Vector4f(padding, 576 - BottomBar.bottomBarHeight - padding - height, width, height);
|
return new Vector4f(padding, 576 - BottomBar.bottomBarHeight - padding - height, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public class Tree extends WorldObject implements ITileThing, ISelectable, IWorka
|
||||||
if(chopJob == null) {
|
if(chopJob == null) {
|
||||||
chopJob = get(JobBoard.class).postSimpleWorkJob("Chop Tree", this);
|
chopJob = get(JobBoard.class).postSimpleWorkJob("Chop Tree", this);
|
||||||
} else {
|
} else {
|
||||||
get(JobBoard.class).rescindJob(chopJob);
|
chopJob.close();
|
||||||
chopJob = null;
|
chopJob = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -159,8 +159,8 @@ public abstract class Agent extends WorldObject implements ISelectable {
|
||||||
@Override
|
@Override
|
||||||
public void renderAlpha() {
|
public void renderAlpha() {
|
||||||
if(!HadeanGame.debugView) return;
|
if(!HadeanGame.debugView) return;
|
||||||
Drawing.setLayer(Layers.GENERAL_UI);
|
Drawing.setLayer(Layers.GROUND_MARKERS);
|
||||||
Assets.flat.pushColor(Vector4f.opacity(0.4f));
|
Assets.flat.pushColor(Vector4f.opacity(0.6f));
|
||||||
if(path != null) {
|
if(path != null) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for(Node node : path) {
|
for(Node node : path) {
|
||||||
|
|
@ -183,7 +183,6 @@ public abstract class Agent extends WorldObject implements ISelectable {
|
||||||
glEnd();
|
glEnd();
|
||||||
count ++;
|
count ++;
|
||||||
}
|
}
|
||||||
Assets.flat.swapColor(Vector4f.opacity(0.6f));
|
|
||||||
|
|
||||||
Assets.selectionFrame.draw(
|
Assets.selectionFrame.draw(
|
||||||
camera.world2Screen(
|
camera.world2Screen(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
package xyz.valnet.hadean.gameobjects.worldobjects.constructions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
|
import xyz.valnet.hadean.gameobjects.Job;
|
||||||
|
import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.Buildable;
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder;
|
||||||
|
import xyz.valnet.hadean.gameobjects.worldobjects.items.Item;
|
||||||
|
import xyz.valnet.hadean.interfaces.IItemPredicate;
|
||||||
|
import xyz.valnet.hadean.interfaces.IItemReceiver;
|
||||||
|
import xyz.valnet.hadean.interfaces.IWorkable;
|
||||||
|
|
||||||
|
public abstract class Construction extends Buildable implements IItemReceiver {
|
||||||
|
|
||||||
|
private float work = 0;
|
||||||
|
|
||||||
|
private List<Item> containedItems = new ArrayList<Item>();
|
||||||
|
|
||||||
|
protected abstract IItemPredicate getBuildingMaterial();
|
||||||
|
protected abstract int getBuildingMaterialCount();
|
||||||
|
protected Vector2i getDimensions() {
|
||||||
|
return new Vector2i(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean isBuildingMaterialSatisfied() {
|
||||||
|
return containedItems.size() >= getBuildingMaterialCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postNextJob() {
|
||||||
|
if(!isBuildingMaterialSatisfied()) {
|
||||||
|
Job job = get(JobBoard.class).postSimpleItemRequirementJob(
|
||||||
|
"Haul items to building",
|
||||||
|
getBuildingMaterial(),
|
||||||
|
this
|
||||||
|
);
|
||||||
|
job.registerClosedListener(() -> {
|
||||||
|
postNextJob();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!isBuilt()) {
|
||||||
|
Job job = get(JobBoard.class).postSimpleWorkJob(
|
||||||
|
"Build " + getName(),
|
||||||
|
new IWorkable() {
|
||||||
|
@Override
|
||||||
|
public boolean doWork(float dTime) {
|
||||||
|
work += dTime;
|
||||||
|
return isBuilt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector2i[] getWorkablePositions() {
|
||||||
|
return getWorldBox().toXYWH().asInt().getBorders();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJobName() {
|
||||||
|
return "Build " + getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
job.registerClosedListener(() -> {
|
||||||
|
postNextJob();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float getMaxWork() {
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBuilt() {
|
||||||
|
return work >= getMaxWork();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create() {
|
||||||
|
super.create();
|
||||||
|
postNextJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract boolean isWalkable();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldRemove() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
protected final boolean isBuilding() {
|
||||||
|
return isBuildingMaterialSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final float getBuildProgress() {
|
||||||
|
return work / getMaxWork();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean receive(Item item) {
|
||||||
|
if(item == null) return false;
|
||||||
|
if(!item.matches(Boulder.BOULDER_PREDICATE)) return false;
|
||||||
|
remove(item);
|
||||||
|
// boulders ++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector2i[] getItemDropoffLocations() {
|
||||||
|
return getWorldBox().toXYWH().asInt().getBorders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,45 +4,19 @@ import xyz.valnet.engine.math.Vector2i;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
import xyz.valnet.hadean.gameobjects.Job;
|
import xyz.valnet.hadean.gameobjects.Job;
|
||||||
import xyz.valnet.hadean.gameobjects.JobBoard;
|
import xyz.valnet.hadean.gameobjects.JobBoard;
|
||||||
import xyz.valnet.hadean.gameobjects.worldobjects.Buildable;
|
|
||||||
import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder;
|
import xyz.valnet.hadean.gameobjects.worldobjects.items.Boulder;
|
||||||
import xyz.valnet.hadean.interfaces.BuildableMetadata;
|
import xyz.valnet.hadean.interfaces.BuildableMetadata;
|
||||||
|
import xyz.valnet.hadean.interfaces.IItemPredicate;
|
||||||
import xyz.valnet.hadean.interfaces.IWorkable;
|
import xyz.valnet.hadean.interfaces.IWorkable;
|
||||||
import xyz.valnet.hadean.util.Assets;
|
import xyz.valnet.hadean.util.Assets;
|
||||||
import xyz.valnet.hadean.util.Layers;
|
import xyz.valnet.hadean.util.Layers;
|
||||||
|
|
||||||
@BuildableMetadata(category = "Buildings", name = "Quarry", type = BuildableMetadata.Type.SINGLE)
|
@BuildableMetadata(category = "Buildings", name = "Quarry", type = BuildableMetadata.Type.SINGLE)
|
||||||
public class Quarry extends Buildable {
|
public class Quarry extends Construction {
|
||||||
|
|
||||||
private float work = 0;
|
private float work = 0;
|
||||||
private static float MAX_WORK = 10000;
|
|
||||||
|
|
||||||
private Job digJob = null;
|
private Job digJob = null;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void create() {
|
|
||||||
super.create();
|
|
||||||
get(JobBoard.class).postSimpleWorkJob("Build Quarry", new IWorkable() {
|
|
||||||
@Override
|
|
||||||
public boolean doWork(float dTime) {
|
|
||||||
work += dTime;
|
|
||||||
return isBuilt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector2i[] getWorkablePositions() {
|
|
||||||
return new Vector2i[] {
|
|
||||||
getWorldPosition().xy().south().east()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getJobName() {
|
|
||||||
return "Build Quarry";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
if(isBuilt()) {
|
if(isBuilt()) {
|
||||||
|
|
@ -53,14 +27,13 @@ public class Quarry extends Buildable {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
float p = work / MAX_WORK;
|
|
||||||
float b = 4;
|
float b = 4;
|
||||||
|
|
||||||
Assets.flat.pushColor(new Vector4f(b, b, b, 0.5f));
|
Assets.flat.pushColor(new Vector4f(b, b, b, 0.5f));
|
||||||
camera.draw(Layers.GROUND, Assets.quarry, getWorldPosition());
|
camera.draw(Layers.GROUND, Assets.quarry, getWorldPosition());
|
||||||
Assets.flat.popColor();
|
Assets.flat.popColor();
|
||||||
|
|
||||||
camera.drawProgressBar(p, getWorldBox());
|
camera.drawProgressBar(getBuildProgress(), getWorldBox());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,6 +49,9 @@ public class Quarry extends Buildable {
|
||||||
if (digJob != null) return;
|
if (digJob != null) return;
|
||||||
if (terrain.getTile(getWorldPosition().xy().south().east()).has(Boulder.class)) return;
|
if (terrain.getTile(getWorldPosition().xy().south().east()).has(Boulder.class)) return;
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("Dig job?");
|
||||||
|
|
||||||
digJob = get(JobBoard.class)
|
digJob = get(JobBoard.class)
|
||||||
.postSimpleWorkJob("Mine at Quarry", new IWorkable() {
|
.postSimpleWorkJob("Mine at Quarry", new IWorkable() {
|
||||||
|
|
||||||
|
|
@ -118,10 +94,6 @@ public class Quarry extends Buildable {
|
||||||
tryCreateDigJob();
|
tryCreateDigJob();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBuilt() {
|
|
||||||
return work >= MAX_WORK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isWalkable() {
|
public boolean isWalkable() {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -140,4 +112,14 @@ public class Quarry extends Buildable {
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "Quarry";
|
return "Quarry";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IItemPredicate getBuildingMaterial() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getBuildingMaterialCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ public abstract class Item extends WorldObject implements ISelectable, ITileThin
|
||||||
|
|
||||||
private void cancelHaul() {
|
private void cancelHaul() {
|
||||||
if(haulJob == null) return;
|
if(haulJob == null) return;
|
||||||
jobboard.rescindJob(haulJob);
|
haulJob.close();
|
||||||
haulJob = null;
|
haulJob = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,11 @@ public class Pawn extends Agent {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGenericName() {
|
||||||
|
return "Pawn";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getWorldBox() {
|
public Vector4f getWorldBox() {
|
||||||
Vector2f pos = getCalculatedPosition();
|
Vector2f pos = getCalculatedPosition();
|
||||||
|
|
|
||||||
|
|
@ -53,22 +53,29 @@ public class Button extends GameObject implements IMouseCaptureArea, ITransient
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(String text) {
|
public Button setText(String text) {
|
||||||
|
if(text == this.text) return this;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
Vector4i measuredText = Assets.font.measure(text);
|
Vector4i measuredText = Assets.font.measure(text);
|
||||||
textWidth = measuredText.x;
|
textWidth = measuredText.x;
|
||||||
textHeight = measuredText.y;
|
textHeight = measuredText.y;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setLayer(float layer) {
|
||||||
|
this.layer = layer;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
Drawing.setLayer(layer);
|
Drawing.setLayer(layer);
|
||||||
if(state == HOVER) {
|
if(state == HOVER) {
|
||||||
frameHover.draw(box.x, box.y, box.z, box.w);
|
Assets.uiFrameLight.draw(box.x, box.y, box.z, box.w);
|
||||||
} else if(state == ACTIVE) {
|
} else if(state == ACTIVE) {
|
||||||
frameActive.draw(box.x, box.y, box.z, box.w);
|
Assets.uiFrameDark.draw(box.x, box.y, box.z, box.w);
|
||||||
} else {
|
} else {
|
||||||
frame.draw(box.x, box.y, box.z, box.w);
|
Assets.uiFrame.draw(box.x, box.y, box.z, box.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assets.flat.pushColor(Vector4f.black);
|
Assets.flat.pushColor(Vector4f.black);
|
||||||
|
|
@ -80,6 +87,20 @@ public class Button extends GameObject implements IMouseCaptureArea, ITransient
|
||||||
Assets.flat.popColor();
|
Assets.flat.popColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Button setPosition(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
box = new Vector4i(x, y, width, height);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setSize(int w, int h) {
|
||||||
|
this.width = w;
|
||||||
|
this.height = h;
|
||||||
|
box = new Vector4i(x, y, w, h);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// public void draw(int x, int y, int w, int h) {
|
// public void draw(int x, int y, int w, int h) {
|
||||||
// this.x = x;
|
// this.x = x;
|
||||||
// this.y = y;
|
// this.y = y;
|
||||||
|
|
@ -201,7 +222,7 @@ public class Button extends GameObject implements IMouseCaptureArea, ITransient
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getBox() {
|
public Vector4f getGuiBox() {
|
||||||
return new Vector4f(x, y, width, height);
|
return new Vector4f(x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package xyz.valnet.hadean.input;
|
package xyz.valnet.hadean.input;
|
||||||
|
|
||||||
public interface IButtonListener {
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IButtonListener extends Serializable {
|
||||||
public void click(Button target);
|
public void click(Button target);
|
||||||
}
|
}
|
||||||
|
|
@ -31,4 +31,7 @@ public interface ISelectable {
|
||||||
return Priority.NORMAL;
|
return Priority.NORMAL;
|
||||||
}
|
}
|
||||||
public String getName();
|
public String getName();
|
||||||
|
public default String getGenericName() {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ import xyz.valnet.hadean.gameobjects.Terrain;
|
||||||
import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer;
|
import xyz.valnet.hadean.gameobjects.inputlayer.BuildLayer;
|
||||||
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
|
import xyz.valnet.hadean.gameobjects.inputlayer.SelectionLayer;
|
||||||
import xyz.valnet.hadean.gameobjects.ui.HoverQuery;
|
import xyz.valnet.hadean.gameobjects.ui.HoverQuery;
|
||||||
|
import xyz.valnet.hadean.gameobjects.ui.Popup;
|
||||||
import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab;
|
import xyz.valnet.hadean.gameobjects.ui.tabs.BuildTab;
|
||||||
import xyz.valnet.hadean.gameobjects.ui.tabs.JobBoardTab;
|
import xyz.valnet.hadean.gameobjects.ui.tabs.JobBoardTab;
|
||||||
import xyz.valnet.hadean.gameobjects.ui.tabs.LoadTab;
|
import xyz.valnet.hadean.gameobjects.ui.tabs.LoadTab;
|
||||||
|
|
@ -42,7 +43,7 @@ public class GameScene extends SceneGraph {
|
||||||
for(int i = 0; i < 5; i ++) {
|
for(int i = 0; i < 5; i ++) {
|
||||||
objects.add(new Pawn());
|
objects.add(new Pawn());
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.add(new SelectionLayer());
|
objects.add(new SelectionLayer());
|
||||||
objects.add(new SelectionUI());
|
objects.add(new SelectionUI());
|
||||||
|
|
||||||
|
|
@ -57,6 +58,8 @@ public class GameScene extends SceneGraph {
|
||||||
objects.add(new MenuTab());
|
objects.add(new MenuTab());
|
||||||
objects.add(new SaveTab());
|
objects.add(new SaveTab());
|
||||||
objects.add(new LoadTab());
|
objects.add(new LoadTab());
|
||||||
|
|
||||||
|
// objects.add(new Popup());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ public class Assets {
|
||||||
|
|
||||||
public static final Texture atlas;
|
public static final Texture atlas;
|
||||||
public static final Font font;
|
public static final Font font;
|
||||||
|
public static final Font bigFont;
|
||||||
public static final Font miniFont;
|
public static final Font miniFont;
|
||||||
public static final Tile9 redFrame;
|
public static final Tile9 redFrame;
|
||||||
public static final Tile9 frame;
|
public static final Tile9 frame;
|
||||||
|
|
@ -52,6 +53,7 @@ public class Assets {
|
||||||
public static final Sprite lilPickaxe;
|
public static final Sprite lilPickaxe;
|
||||||
public static final Sprite testTile;
|
public static final Sprite testTile;
|
||||||
public static final Sprite quarry;
|
public static final Sprite quarry;
|
||||||
|
public static final Sprite fillTile;
|
||||||
|
|
||||||
|
|
||||||
public static final SimpleShader flat;
|
public static final SimpleShader flat;
|
||||||
|
|
@ -198,7 +200,8 @@ public class Assets {
|
||||||
charset.put('\\', new Sprite(atlas, 208, 32, 8, 16));
|
charset.put('\\', new Sprite(atlas, 208, 32, 8, 16));
|
||||||
charset.put('♥', new Sprite(atlas, 216, 32, 8, 16));
|
charset.put('♥', new Sprite(atlas, 216, 32, 8, 16));
|
||||||
charset.put('|', new Sprite(atlas, 224, 32, 8, 16));
|
charset.put('|', new Sprite(atlas, 224, 32, 8, 16));
|
||||||
font = new Font(charset, 8, 16);
|
font = new Font(charset, 8, 16, 1);
|
||||||
|
bigFont = new Font(charset, 8, 16, 2);
|
||||||
|
|
||||||
Map<Character, Sprite> miniCharset = new HashMap<Character, Sprite>();
|
Map<Character, Sprite> miniCharset = new HashMap<Character, Sprite>();
|
||||||
miniCharset.put('1', new Sprite(atlas, 0, 112, 4, 5));
|
miniCharset.put('1', new Sprite(atlas, 0, 112, 4, 5));
|
||||||
|
|
@ -211,7 +214,7 @@ public class Assets {
|
||||||
miniCharset.put('8', new Sprite(atlas, 28, 112, 4, 5));
|
miniCharset.put('8', new Sprite(atlas, 28, 112, 4, 5));
|
||||||
miniCharset.put('9', new Sprite(atlas, 32, 112, 4, 5));
|
miniCharset.put('9', new Sprite(atlas, 32, 112, 4, 5));
|
||||||
miniCharset.put('0', new Sprite(atlas, 36, 112, 4, 5));
|
miniCharset.put('0', new Sprite(atlas, 36, 112, 4, 5));
|
||||||
miniFont = new Font(miniCharset, 4, 5);
|
miniFont = new Font(miniCharset, 4, 5, 1);
|
||||||
|
|
||||||
frame = new Tile9(
|
frame = new Tile9(
|
||||||
new Sprite(atlas, 24, 88, 8, 8),
|
new Sprite(atlas, 24, 88, 8, 8),
|
||||||
|
|
@ -272,6 +275,8 @@ public class Assets {
|
||||||
new Sprite(atlas, 44, 64, 1, 1),
|
new Sprite(atlas, 44, 64, 1, 1),
|
||||||
new Sprite(atlas, 44, 64, 1, 1)
|
new Sprite(atlas, 44, 64, 1, 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fillTile = new Sprite(atlas, 0, 88, 8, 8);
|
||||||
|
|
||||||
uiFrame = new Tile9(
|
uiFrame = new Tile9(
|
||||||
new Sprite(atlas, 32, 80, 1, 1),
|
new Sprite(atlas, 32, 80, 1, 1),
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ public class Layers {
|
||||||
|
|
||||||
public static final float BACKGROUND = current ++;
|
public static final float BACKGROUND = current ++;
|
||||||
public static final float TILES = current ++;
|
public static final float TILES = current ++;
|
||||||
|
public static final float GROUND_MARKERS = current ++;
|
||||||
public static final float GROUND = current ++;
|
public static final float GROUND = current ++;
|
||||||
public static final float AIR = current ++;
|
public static final float AIR = current ++;
|
||||||
public static final float PAWNS = Layers.AIR + 0.001f;
|
public static final float PAWNS = Layers.AIR + 0.001f;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue