save/load; one bug - cant load after saving in one session form menu
after changing floor
This commit is contained in:
@@ -215,4 +215,28 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
|
||||
{
|
||||
return Mouse.isButtonDown(button);
|
||||
}
|
||||
|
||||
|
||||
public static int getModifierKeys()
|
||||
{
|
||||
int mods = 0;
|
||||
|
||||
if(Keyboard.isKeyDown(Keys.L_ALT) || Keyboard.isKeyDown(Keys.R_ALT)) {
|
||||
mods |= Keys.MOD_ALT;
|
||||
}
|
||||
|
||||
if(Keyboard.isKeyDown(Keys.L_SHIFT) || Keyboard.isKeyDown(Keys.R_SHIFT)) {
|
||||
mods |= Keys.MOD_SHIFT;
|
||||
}
|
||||
|
||||
if(Keyboard.isKeyDown(Keys.L_CONTROL) || Keyboard.isKeyDown(Keys.R_CONTROL)) {
|
||||
mods |= Keys.MOD_CONTROL;
|
||||
}
|
||||
|
||||
if(Keyboard.isKeyDown(Keys.L_META) || Keyboard.isKeyDown(Keys.R_META)) {
|
||||
mods |= Keys.MOD_META;
|
||||
}
|
||||
|
||||
return mods;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,58 +15,42 @@ import org.lwjgl.input.Keyboard;
|
||||
*/
|
||||
public class KeyStroke {
|
||||
|
||||
private final List<Integer> keys = new ArrayList<>(2);
|
||||
private final int mod;
|
||||
private final int key;
|
||||
private final boolean fallingEdge;
|
||||
|
||||
private final List<Integer> badModifs = new ArrayList<>(8);
|
||||
|
||||
|
||||
// {
|
||||
// badModifs.add(Keys.L_ALT);
|
||||
// badModifs.add(Keys.L_CONTROL);
|
||||
// badModifs.add(Keys.L_SHIFT);
|
||||
// badModifs.add(Keys.L_META);
|
||||
// badModifs.add(Keys.R_ALT);
|
||||
// badModifs.add(Keys.R_CONTROL);
|
||||
// badModifs.add(Keys.R_SHIFT);
|
||||
// badModifs.add(Keys.R_META);
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* KeyStroke
|
||||
*
|
||||
* @param fallingEdge true for falling edge, up for rising edge
|
||||
* @param keys keys that must be pressed
|
||||
* @param mod_mask mods mask
|
||||
* @param key key code
|
||||
*/
|
||||
public KeyStroke(boolean fallingEdge, int... keys)
|
||||
{
|
||||
badModifs.add(Keys.L_ALT);
|
||||
badModifs.add(Keys.L_CONTROL);
|
||||
badModifs.add(Keys.L_SHIFT);
|
||||
badModifs.add(Keys.L_META);
|
||||
badModifs.add(Keys.R_ALT);
|
||||
badModifs.add(Keys.R_CONTROL);
|
||||
badModifs.add(Keys.R_SHIFT);
|
||||
badModifs.add(Keys.R_META);
|
||||
|
||||
public KeyStroke(boolean fallingEdge, int key, int mod_mask) {
|
||||
this.fallingEdge = fallingEdge;
|
||||
for (final int k : keys) {
|
||||
this.keys.add(k);
|
||||
|
||||
badModifs.remove((Integer) k);
|
||||
}
|
||||
this.key = key;
|
||||
this.mod = mod_mask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rising edge keystroke
|
||||
* @param mod_mask mods mask
|
||||
* @param key key code
|
||||
*/
|
||||
public KeyStroke(int key, int mod_mask) {
|
||||
this(false, key, mod_mask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rising edge keystroke
|
||||
*
|
||||
* @param keys
|
||||
* @param key key code
|
||||
*/
|
||||
public KeyStroke(int... keys)
|
||||
{
|
||||
this(false, keys);
|
||||
public KeyStroke(int key) {
|
||||
this(false, key, Keys.MOD_NONE);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,65 +59,36 @@ public class KeyStroke {
|
||||
*/
|
||||
public boolean isActive()
|
||||
{
|
||||
boolean st = true;
|
||||
|
||||
for (final int k : keys) {
|
||||
st &= Keyboard.isKeyDown(k);
|
||||
}
|
||||
|
||||
for (final int i : badModifs) {
|
||||
if (Keyboard.isKeyDown(i)) {
|
||||
st = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
boolean st = Keyboard.isKeyDown(key);
|
||||
st &= (InputSystem.getModifierKeys() == mod);
|
||||
|
||||
return fallingEdge ? st : !st;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((keys == null) ? 0 : keys.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof KeyStroke)) return false;
|
||||
final KeyStroke other = (KeyStroke) obj;
|
||||
|
||||
if (keys == null) {
|
||||
if (other.keys != null) return false;
|
||||
} else if (!keys.equals(other.keys)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fallingEdge != other.fallingEdge) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String s = "(";
|
||||
|
||||
int cnt = 0;
|
||||
final Iterator<Integer> i = keys.iterator();
|
||||
for (; i.hasNext(); cnt++) {
|
||||
if (cnt > 0) s += "+";
|
||||
s += Keyboard.getKeyName(i.next());
|
||||
if ((mod & Keys.MOD_CONTROL) != 0) {
|
||||
s += "CTRL+";
|
||||
}
|
||||
|
||||
if ((mod & Keys.MOD_ALT) != 0) {
|
||||
s += "ALT+";
|
||||
}
|
||||
|
||||
if ((mod & Keys.MOD_SHIFT) != 0) {
|
||||
s += "SHIFT+";
|
||||
}
|
||||
|
||||
if ((mod & Keys.MOD_META) != 0) {
|
||||
s += "META+";
|
||||
}
|
||||
|
||||
s += Keyboard.getKeyName(key);
|
||||
|
||||
s += fallingEdge ? ",DOWN" : ",UP";
|
||||
|
||||
s += ")";
|
||||
@@ -142,8 +97,28 @@ public class KeyStroke {
|
||||
}
|
||||
|
||||
|
||||
public List<Integer> getKeys()
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return keys;
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (fallingEdge ? 1231 : 1237);
|
||||
result = prime * result + key;
|
||||
result = prime * result + mod;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
KeyStroke other = (KeyStroke) obj;
|
||||
if (fallingEdge != other.fallingEdge) return false;
|
||||
if (key != other.key) return false;
|
||||
if (mod != other.mod) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,12 @@ public interface Keys {
|
||||
public static final int PAUSE = 0xC5; /* Pause */
|
||||
public static final int INSERT = 0xD2; /* Insert on arrow keypad */
|
||||
public static final int DELETE = 0xD3; /* Delete on arrow keypad */
|
||||
|
||||
public static final byte MOD_NONE = 0;
|
||||
public static final byte MOD_ALT = 1;
|
||||
public static final byte MOD_CONTROL = 2;
|
||||
public static final byte MOD_SHIFT = 4;
|
||||
public static final byte MOD_META = 8;
|
||||
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@@ -182,6 +182,7 @@ public class Ion {
|
||||
*/
|
||||
public static void toFile(File file, IonObjBinary obj) throws IOException
|
||||
{
|
||||
file.getParentFile().mkdirs();
|
||||
try(OutputStream out = new FileOutputStream(file)) {
|
||||
|
||||
toStream(out, obj);
|
||||
|
||||
@@ -26,6 +26,7 @@ import mightypork.rogue.screens.LoadingOverlay;
|
||||
import mightypork.rogue.screens.game.ScreenGame;
|
||||
import mightypork.rogue.screens.menu.ScreenMainMenu;
|
||||
import mightypork.rogue.screens.select_world.ScreenSelectWorld;
|
||||
import mightypork.rogue.world.Inventory;
|
||||
import mightypork.rogue.world.WorldProvider;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
|
||||
@@ -78,6 +79,7 @@ public final class App extends BaseApp {
|
||||
super.registerIonizables();
|
||||
|
||||
Ion.registerType(Level.ION_MARK, Level.class);
|
||||
Ion.registerType(Inventory.ION_MARK, Inventory.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -132,14 +134,18 @@ public final class App extends BaseApp {
|
||||
bindEventToKey(new ActionRequest(RequestType.FULLSCREEN), Keys.F11);
|
||||
bindEventToKey(new ActionRequest(RequestType.SCREENSHOT), Keys.F2);
|
||||
|
||||
bindEventToKey(new GameStateRequest(GameState.EXIT), Keys.L_CONTROL, Keys.Q);
|
||||
bindEventToKey(new GameStateRequest(GameState.MAIN_MENU), Keys.L_CONTROL, Keys.M);
|
||||
bindEventToKey(new GameStateRequest(GameState.EXIT), Keys.Q, Keys.MOD_CONTROL);
|
||||
bindEventToKey(new GameStateRequest(GameState.MAIN_MENU), Keys.M, Keys.MOD_CONTROL);
|
||||
}
|
||||
|
||||
|
||||
private void bindEventToKey(final BusEvent<?> event, int... keys)
|
||||
private void bindEventToKey(final BusEvent<?> event, int key)
|
||||
{
|
||||
getInput().bindKey(new KeyStroke(keys), new Runnable() {
|
||||
bindEventToKey(event, key, Keys.MOD_NONE);
|
||||
}
|
||||
|
||||
private void bindEventToKey(final BusEvent<?> event, int key, byte mod)
|
||||
{
|
||||
getInput().bindKey(new KeyStroke(key, mod), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
|
||||
@@ -5,28 +5,18 @@ import mightypork.gamecore.eventbus.BusEvent;
|
||||
|
||||
public class LoaderRequest extends BusEvent<LoadingOverlay> {
|
||||
|
||||
private final boolean show;
|
||||
private final String msg;
|
||||
private Runnable task;
|
||||
|
||||
|
||||
public LoaderRequest(boolean show, String msg) {
|
||||
this.show = show;
|
||||
public LoaderRequest(String msg, Runnable task) {
|
||||
this.task = task;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public LoaderRequest(boolean show) {
|
||||
this.show = show;
|
||||
this.msg = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBy(LoadingOverlay handler)
|
||||
{
|
||||
if(show) {
|
||||
handler.show(msg);
|
||||
}else {
|
||||
handler.hide();
|
||||
}
|
||||
handler.show(msg, task);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import mightypork.gamecore.gui.components.painters.QuadPainter;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
import mightypork.gamecore.gui.events.ScreenRequest;
|
||||
import mightypork.gamecore.gui.screens.Overlay;
|
||||
import mightypork.gamecore.util.Utils;
|
||||
import mightypork.gamecore.util.math.Easing;
|
||||
import mightypork.gamecore.util.math.color.Color;
|
||||
import mightypork.gamecore.util.math.color.pal.PAL16;
|
||||
@@ -36,7 +37,29 @@ public class LoadingOverlay extends Overlay {
|
||||
return msg == null ? "" : msg;
|
||||
}
|
||||
};
|
||||
|
||||
private boolean busy;
|
||||
private String msg;
|
||||
private Runnable task;
|
||||
|
||||
private TimedTask tt = new TimedTask() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Utils.runAsThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
task.run();
|
||||
alpha.setEasing(Easing.SINE_OUT);
|
||||
alpha.fadeOut(T_OUT);
|
||||
busy = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public LoadingOverlay(AppAccess app) {
|
||||
@@ -47,6 +70,7 @@ public class LoadingOverlay extends Overlay {
|
||||
root.add(qp);
|
||||
|
||||
updated.add(alpha);
|
||||
updated.add(tt);
|
||||
|
||||
Rect textRect = root.shrink(Num.ZERO, root.height().perc(48));
|
||||
textRect = textRect.moveY(root.height().perc(-10));
|
||||
@@ -54,7 +78,7 @@ public class LoadingOverlay extends Overlay {
|
||||
final TextPainter tp = new TextPainter(Res.getFont("thick"), AlignX.CENTER, RGB.WHITE, msgStrProv);
|
||||
|
||||
tp.setRect(textRect);
|
||||
tp.setShadow(RGB.BLACK_60, tp.height().mul(1/8D).toVectXY());
|
||||
tp.setShadow(RGB.BLACK_60, tp.height().mul(1 / 8D).toVectXY());
|
||||
root.add(tp);
|
||||
}
|
||||
|
||||
@@ -66,21 +90,21 @@ public class LoadingOverlay extends Overlay {
|
||||
}
|
||||
|
||||
|
||||
public void show(String message)
|
||||
public void show(String message, Runnable task)
|
||||
{
|
||||
if(busy) throw new IllegalStateException("Loader is busy with another task.");
|
||||
|
||||
this.msg = message;
|
||||
this.task = task;
|
||||
this.busy = true;
|
||||
|
||||
alpha.setEasing(Easing.SINE_IN);
|
||||
alpha.fadeIn(T_IN);
|
||||
}
|
||||
|
||||
|
||||
public void hide()
|
||||
{
|
||||
|
||||
alpha.setEasing(Easing.SINE_OUT);
|
||||
alpha.fadeOut(T_OUT);
|
||||
tt.start(T_IN);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package mightypork.rogue.screens.game;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.gamecore.app.AppAccess;
|
||||
@@ -9,6 +11,7 @@ import mightypork.gamecore.gui.ActionGroup;
|
||||
import mightypork.gamecore.gui.screens.LayeredScreen;
|
||||
import mightypork.gamecore.input.KeyStroke;
|
||||
import mightypork.gamecore.input.Keys;
|
||||
import mightypork.gamecore.logging.Log;
|
||||
import mightypork.gamecore.util.math.Calc;
|
||||
import mightypork.rogue.Config;
|
||||
import mightypork.rogue.world.PlayerFacade;
|
||||
@@ -84,7 +87,38 @@ public class ScreenGame extends LayeredScreen {
|
||||
worldLayer.map.toggleMag();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public Action actionSave = new Action() {
|
||||
|
||||
@Override
|
||||
public void execute()
|
||||
{
|
||||
try {
|
||||
WorldProvider.get().saveWorld();
|
||||
WorldProvider.get().getWorld().getConsole().msgWorldSaved();
|
||||
} catch (Exception e) {
|
||||
Log.e("Could not save the world.", e);
|
||||
WorldProvider.get().getWorld().getConsole().msgWorldSaveError();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public Action actionRestore = new Action() {
|
||||
|
||||
@Override
|
||||
public void execute()
|
||||
{
|
||||
try {
|
||||
File f = WorldProvider.get().getWorld().getSaveFile();
|
||||
WorldProvider.get().loadWorld(f);
|
||||
WorldProvider.get().getWorld().getConsole().msgReloaded();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("Could not load the world.", e);
|
||||
WorldProvider.get().getWorld().getConsole().msgLoadFailed();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set gui state (overlay)
|
||||
@@ -142,7 +176,7 @@ public class ScreenGame extends LayeredScreen {
|
||||
worldLayer.setVisible(true);
|
||||
|
||||
// TODO temporary here ↓
|
||||
bindKey(new KeyStroke(Keys.L_CONTROL, Keys.N), new Runnable() {
|
||||
bindKey(new KeyStroke(Keys.N, Keys.MOD_CONTROL), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
@@ -160,6 +194,9 @@ public class ScreenGame extends LayeredScreen {
|
||||
bindKey(new KeyStroke(Keys.E), actionEat);
|
||||
bindKey(new KeyStroke(Keys.M), actionToggleMinimap);
|
||||
bindKey(new KeyStroke(Keys.Z), actionToggleZoom);
|
||||
|
||||
bindKey(new KeyStroke(Keys.R, Keys.MOD_CONTROL), actionRestore);
|
||||
bindKey(new KeyStroke(Keys.S, Keys.MOD_CONTROL), actionSave);
|
||||
|
||||
// add as actions - enableables.
|
||||
worldActions.add(worldLayer);
|
||||
@@ -170,6 +207,9 @@ public class ScreenGame extends LayeredScreen {
|
||||
worldActions.add(actionTogglePause);
|
||||
worldActions.add(actionToggleZoom);
|
||||
|
||||
worldActions.add(actionSave);
|
||||
worldActions.add(actionRestore);
|
||||
|
||||
worldActions.enable(true);
|
||||
|
||||
// TMP TODO remove
|
||||
|
||||
@@ -14,6 +14,7 @@ import mightypork.gamecore.gui.components.painters.QuadPainter;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
import mightypork.gamecore.gui.events.CrossfadeRequest;
|
||||
import mightypork.gamecore.gui.events.ScreenRequest;
|
||||
import mightypork.gamecore.logging.Log;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.util.Utils;
|
||||
import mightypork.gamecore.util.ion.Ion;
|
||||
@@ -91,28 +92,44 @@ public class WorldSlot extends ConstraintLayout {
|
||||
msg = "Creating world...";
|
||||
}
|
||||
|
||||
getEventBus().send(new LoaderRequest(true, msg));
|
||||
|
||||
Utils.runAsThread(new Runnable() {
|
||||
getEventBus().send(new LoaderRequest(msg, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try {
|
||||
final World w = new World();
|
||||
w.setSaveFile(file);
|
||||
w.load(worldBundle);
|
||||
WorldProvider.get().setWorld(w);
|
||||
} catch (final Exception e) {
|
||||
WorldProvider.get().createWorld(Double.doubleToLongBits(Math.random()));
|
||||
World w;
|
||||
|
||||
if (worldBundle == null) {
|
||||
|
||||
try {
|
||||
w = WorldProvider.get().createWorld(Double.doubleToLongBits(Math.random()));
|
||||
w.setSaveFile(file);
|
||||
|
||||
WorldProvider.get().saveWorld();
|
||||
|
||||
getEventBus().send(new ScreenRequest("game"));
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("Could not create & save the world.", e);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
try {
|
||||
w = new World();
|
||||
w.setSaveFile(file);
|
||||
w.load(worldBundle);
|
||||
WorldProvider.get().setWorld(w);
|
||||
|
||||
getEventBus().send(new ScreenRequest("game"));
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e("Could not load the world.", e);
|
||||
}
|
||||
}
|
||||
|
||||
getEventBus().send(new LoaderRequest(false));
|
||||
//getEventBus().send(new GameStateRequest(GameState.PLAY_WORLD));
|
||||
|
||||
getEventBus().send(new ScreenRequest("game"));
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ import mightypork.rogue.world.item.Items;
|
||||
|
||||
public class Inventory implements IonObjBinary {
|
||||
|
||||
private static final short ION_MARK = 0;
|
||||
public static final short ION_MARK = 54;
|
||||
private Item[] items;
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import mightypork.gamecore.eventbus.BusAccess;
|
||||
import mightypork.gamecore.eventbus.EventBus;
|
||||
import mightypork.gamecore.eventbus.clients.DelegatingClient;
|
||||
import mightypork.gamecore.eventbus.events.Updateable;
|
||||
import mightypork.gamecore.logging.Log;
|
||||
import mightypork.gamecore.util.ion.IonBundle;
|
||||
import mightypork.gamecore.util.ion.IonObjBundled;
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
@@ -79,9 +80,12 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
||||
|
||||
in.loadBundled("player", playerData);
|
||||
|
||||
playerEntity = levels.get(playerData.getLevelNumber()).getEntity(playerData.getEID());
|
||||
int eid = playerData.getEID();
|
||||
int lvl = playerData.getLevelNumber();
|
||||
|
||||
playerEntity = levels.get(lvl).getEntity(eid);
|
||||
if (playerEntity == null) {
|
||||
throw new RuntimeException("Player entity not found in the world.");
|
||||
throw new RuntimeException("Player entity not found in the world: " + eid + " on floor " + lvl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +216,8 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
||||
|
||||
// update console timing - not as child client
|
||||
console.update(delta);
|
||||
|
||||
if (saveFile == null) Log.w("World has no save file.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,8 +34,7 @@ public class WorldConsole implements Updateable {
|
||||
private double elapsed = 0;
|
||||
|
||||
|
||||
private Entry(String text)
|
||||
{
|
||||
private Entry(String text) {
|
||||
this.text = text;
|
||||
this.fadeout = new NumAnimated(1, Easing.LINEAR);
|
||||
this.fadeout.setDefaultDuration(0.5);
|
||||
@@ -196,4 +195,28 @@ public class WorldConsole implements Updateable {
|
||||
{
|
||||
addMessage("Your " + item.getVisualName() + " has broken!");
|
||||
}
|
||||
|
||||
|
||||
public void msgWorldSaved()
|
||||
{
|
||||
addMessage("Game saved to file.");
|
||||
}
|
||||
|
||||
|
||||
public void msgWorldSaveError()
|
||||
{
|
||||
addMessage("Error while saving; See the log for details.");
|
||||
}
|
||||
|
||||
|
||||
public void msgReloaded()
|
||||
{
|
||||
addMessage("World loaded from file.");
|
||||
}
|
||||
|
||||
|
||||
public void msgLoadFailed()
|
||||
{
|
||||
addMessage("Error while loading; See the log for details.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@ public class WorldProvider extends RootBusNode {
|
||||
}
|
||||
|
||||
|
||||
public WorldProvider(BusAccess busAccess)
|
||||
{
|
||||
public WorldProvider(BusAccess busAccess) {
|
||||
super(busAccess);
|
||||
setListening(false);
|
||||
}
|
||||
@@ -50,9 +49,11 @@ public class WorldProvider extends RootBusNode {
|
||||
};
|
||||
|
||||
|
||||
public void createWorld(long seed)
|
||||
public World createWorld(long seed)
|
||||
{
|
||||
setWorld(WorldCreator.createWorld(seed));
|
||||
World w = WorldCreator.createWorld(seed);
|
||||
setWorld(w);
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +84,7 @@ public class WorldProvider extends RootBusNode {
|
||||
public void loadWorld(File file) throws IOException
|
||||
{
|
||||
setWorld(Ion.fromFile(file, World.class));
|
||||
world.setSaveFile(file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@ public class BossRatAi extends GrayRatAi {
|
||||
@Override
|
||||
protected int getAttackStrength()
|
||||
{
|
||||
return Calc.randInt(5, 11);
|
||||
return Calc.randInt(3, 11);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getPreyAbandonDistance()
|
||||
{
|
||||
return Calc.randInt(15, 18);
|
||||
return Calc.randInt(12, 18);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,13 @@ public class BossRatAi extends GrayRatAi {
|
||||
public void update(double delta)
|
||||
{
|
||||
super.update(delta);
|
||||
|
||||
healTimer.update(delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double getStepTime()
|
||||
{
|
||||
return isIdle() ? 0.6 : 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,20 +19,26 @@ public class BrownRatAi extends GrayRatAi {
|
||||
@Override
|
||||
protected double getScanRadius()
|
||||
{
|
||||
return isSleeping() ? Calc.randInt(3, 5) : Calc.randInt(5, 8);
|
||||
return isIdle() ? Calc.randInt(2, 4) : Calc.randInt(5, 8);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getAttackStrength()
|
||||
{
|
||||
return Calc.randInt(2, 5);
|
||||
return Calc.randInt(1, 4);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getPreyAbandonDistance()
|
||||
{
|
||||
return Calc.randInt(11, 14);
|
||||
return Calc.randInt(7, 12);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double getStepTime()
|
||||
{
|
||||
return isIdle() ? 0.5 : 0.38;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ public class EntityBossRat extends Entity {
|
||||
addModule("ai", ai);
|
||||
pos.addMoveListener(ai);
|
||||
|
||||
pos.setStepTime(0.4);
|
||||
setDespawnDelay(1);
|
||||
|
||||
health.setHealthMax(80);
|
||||
|
||||
@@ -28,7 +28,6 @@ public class EntityBrownRat extends Entity {
|
||||
addModule("ai", ai);
|
||||
pos.addMoveListener(ai);
|
||||
|
||||
pos.setStepTime(0.38); // faster than gray rat
|
||||
setDespawnDelay(1);
|
||||
|
||||
health.setHealthMax(20);
|
||||
|
||||
@@ -28,7 +28,6 @@ public class EntityGrayRat extends Entity {
|
||||
addModule("ai", ai);
|
||||
pos.addMoveListener(ai);
|
||||
|
||||
pos.setStepTime(0.5);
|
||||
setDespawnDelay(1);
|
||||
|
||||
health.setHealthMax(6);
|
||||
|
||||
@@ -19,7 +19,7 @@ public class GrayRatAi extends MonsterAi {
|
||||
@Override
|
||||
protected double getScanRadius()
|
||||
{
|
||||
return isSleeping() ? Calc.randInt(2, 4) : Calc.randInt(4, 6);
|
||||
return isIdle() ? Calc.randInt(2, 3) : Calc.randInt(4, 6);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,27 +33,20 @@ public class GrayRatAi extends MonsterAi {
|
||||
@Override
|
||||
protected int getAttackStrength()
|
||||
{
|
||||
return 1 + (Calc.rand.nextInt(5) == 0 ? 1 : 0);
|
||||
return Calc.randInt(1, 2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getPreyAbandonDistance()
|
||||
{
|
||||
return Calc.randInt(8, 11);
|
||||
return Calc.randInt(7, 11);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean shouldSkipScan()
|
||||
protected double getStepTime()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean shouldRandomlyAbandonPrey()
|
||||
{
|
||||
return false;
|
||||
return isIdle() ? 0.7 : 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import mightypork.rogue.world.tile.Tile;
|
||||
|
||||
public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
|
||||
private boolean sleeping = true;
|
||||
private boolean chasing = false;
|
||||
|
||||
private final AiTimer timerFindPrey = new AiTimer(3) {
|
||||
@@ -30,17 +29,17 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (chasing) return;
|
||||
if (!isIdle()) return;
|
||||
lookForTarget();
|
||||
}
|
||||
};
|
||||
|
||||
private final AiTimer timerAttack = new AiTimer(3) {
|
||||
private final AiTimer timerAttack = new AiTimer(1) {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (!chasing) return;
|
||||
if (!isChasing()) return;
|
||||
|
||||
final Entity prey = getPreyEntity();
|
||||
|
||||
@@ -50,6 +49,21 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
}
|
||||
};
|
||||
|
||||
private final AiTimer timerRandomWalk = new AiTimer(0.2) {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (!isIdle()) return;
|
||||
|
||||
if(entity.pos.isMoving()) return;
|
||||
|
||||
if(Calc.rand.nextInt(10) == 0) {
|
||||
entity.pos.addStep(Sides.randomCardinal());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private PathFinder noDoorPf;
|
||||
|
||||
/** Prey id */
|
||||
@@ -84,18 +98,13 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
{
|
||||
if (entity.isDead()) return;
|
||||
|
||||
if (chasing) {
|
||||
if (isChasing()) {
|
||||
final Entity prey = getPreyEntity();
|
||||
if (!isPreyValid(prey)) {
|
||||
stopChasing();
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldRandomlyAbandonPrey()) {
|
||||
stopChasing();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isPreyInAttackRange(prey)) {
|
||||
stepTowardsPrey(prey);
|
||||
}
|
||||
@@ -122,7 +131,6 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
bundle.putBundled("tattack", timerAttack);
|
||||
|
||||
bundle.put("chasing", chasing);
|
||||
bundle.put("sleeping", sleeping);
|
||||
|
||||
bundle.put("prey", preyId);
|
||||
}
|
||||
@@ -135,7 +143,6 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
bundle.loadBundled("tattack", timerAttack);
|
||||
|
||||
chasing = bundle.get("chasing", chasing);
|
||||
sleeping = bundle.get("sleeping", sleeping);
|
||||
|
||||
preyId = bundle.get("prey", preyId);
|
||||
}
|
||||
@@ -155,46 +162,39 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
|
||||
timerFindPrey.update(delta);
|
||||
timerAttack.update(delta);
|
||||
timerRandomWalk.update(delta);
|
||||
|
||||
if (chasing && !entity.pos.isMoving()) {
|
||||
// go after the prey
|
||||
if (isChasing() && !entity.pos.isMoving()) {
|
||||
final Entity prey = getPreyEntity();
|
||||
if (prey == null) {
|
||||
// prey killed and cleaned from level
|
||||
stopChasing();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isPreyInAttackRange(prey)) {
|
||||
stepTowardsPrey(prey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sleeping && shouldRandomlyWake()) {
|
||||
sleeping = false;
|
||||
}
|
||||
|
||||
if (!chasing && shouldRandomlyFallAsleep()) {
|
||||
sleeping = true;
|
||||
}
|
||||
|
||||
if (!chasing && !sleeping && !entity.pos.isMoving() && Calc.rand.nextInt(10) == 0) {
|
||||
entity.pos.addStep(Sides.randomCardinal());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isSleeping()
|
||||
public boolean isIdle()
|
||||
{
|
||||
return sleeping;
|
||||
return !chasing;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isChasing()
|
||||
{
|
||||
return chasing;
|
||||
}
|
||||
|
||||
private void lookForTarget()
|
||||
{
|
||||
if (entity.isDead()) return;
|
||||
|
||||
if (shouldSkipScan()) return; // not hungry right now
|
||||
|
||||
final Entity prey = entity.getLevel().getClosestEntity(entity.pos.getVisualPos(), EntityType.PLAYER, getScanRadius());
|
||||
if (prey != null) {
|
||||
@@ -233,7 +233,8 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
|
||||
preyId = prey.getEntityId();
|
||||
chasing = true;
|
||||
sleeping = false;
|
||||
|
||||
entity.pos.setStepTime(getStepTime());
|
||||
|
||||
// follow this one prey
|
||||
timerFindPrey.pause();
|
||||
@@ -245,6 +246,9 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
private void stopChasing()
|
||||
{
|
||||
chasing = false;
|
||||
|
||||
entity.pos.setStepTime(getStepTime());
|
||||
|
||||
preyId = -1;
|
||||
timerFindPrey.restart();
|
||||
}
|
||||
@@ -266,7 +270,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
|
||||
// if close enough
|
||||
if (isPreyInAttackRange(prey)) {
|
||||
attackPrey(prey);
|
||||
// attack using the timed loop
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -307,7 +311,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
@DefaultImpl
|
||||
protected double getScanRadius()
|
||||
{
|
||||
return sleeping ? Calc.randInt(1, 3) : Calc.randInt(4, 8); // For override
|
||||
return isIdle() ? Calc.randInt(1, 3) : Calc.randInt(4, 8); // For override
|
||||
}
|
||||
|
||||
|
||||
@@ -331,31 +335,9 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
return 1; // For override
|
||||
}
|
||||
|
||||
|
||||
@DefaultImpl
|
||||
protected boolean shouldSkipScan()
|
||||
protected double getStepTime()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@DefaultImpl
|
||||
protected boolean shouldRandomlyAbandonPrey()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@DefaultImpl
|
||||
protected boolean shouldRandomlyWake()
|
||||
{
|
||||
return Calc.rand.nextInt(10) == 0;
|
||||
}
|
||||
|
||||
|
||||
@DefaultImpl
|
||||
protected boolean shouldRandomlyFallAsleep()
|
||||
{
|
||||
return Calc.rand.nextInt(8) == 0;
|
||||
return isIdle() ? 0.7 : 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import mightypork.rogue.world.gui.MapView;
|
||||
public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndListener, KeyListener, Updateable {
|
||||
|
||||
private static final int[] keys = { Keys.LEFT, Keys.RIGHT, Keys.UP, Keys.DOWN };
|
||||
private static final int[] keys2 = { Keys.A, Keys.D, Keys.W, Keys.S };
|
||||
private static final Step[] sides = { Sides.W, Sides.E, Sides.N, Sides.S };
|
||||
|
||||
|
||||
@@ -44,12 +43,16 @@ public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndLi
|
||||
@Override
|
||||
public void receive(KeyEvent evt)
|
||||
{
|
||||
if (isImmobile()) return;
|
||||
if (isImmobile()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.isDown() || mapView.plc.getPlayer().isMoving()) return; // not interested
|
||||
|
||||
if(InputSystem.getModifierKeys() != Keys.MOD_NONE) return;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (evt.getKey() == keys[i] || evt.getKey() == keys2[i]) {
|
||||
if (evt.getKey() == keys[i]) {
|
||||
mapView.plc.clickTile(sides[i]);
|
||||
}
|
||||
}
|
||||
@@ -62,8 +65,12 @@ public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndLi
|
||||
|
||||
if (mapView.plc.getPlayer().getMoveProgress() < 0.8) return false;
|
||||
|
||||
|
||||
if(InputSystem.getModifierKeys() != Keys.MOD_NONE) return false;
|
||||
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (InputSystem.isKeyDown(keys[i]) || InputSystem.isKeyDown(keys2[i])) {
|
||||
if (InputSystem.isKeyDown(keys[i])) {
|
||||
|
||||
final Step side = sides[i];
|
||||
if (mapView.plc.canGo(side)) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import mightypork.gamecore.util.math.noise.NoiseGen;
|
||||
import mightypork.rogue.world.World;
|
||||
import mightypork.rogue.world.entity.Entities;
|
||||
import mightypork.rogue.world.entity.Entity;
|
||||
import mightypork.rogue.world.entity.EntityPathFinder;
|
||||
import mightypork.rogue.world.entity.EntityType;
|
||||
import mightypork.rogue.world.entity.impl.PlayerEntity;
|
||||
import mightypork.rogue.world.item.Item;
|
||||
@@ -123,13 +124,11 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
|
||||
private double timeSinceLastEntitySort;
|
||||
|
||||
|
||||
public Level()
|
||||
{
|
||||
public Level() {
|
||||
}
|
||||
|
||||
|
||||
public Level(int width, int height)
|
||||
{
|
||||
public Level(int width, int height) {
|
||||
size.setTo(width, height);
|
||||
buildArray();
|
||||
}
|
||||
@@ -165,7 +164,7 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
|
||||
public final Tile getTile(Coord pos)
|
||||
{
|
||||
if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) return Tiles.NULL.createTile(); // out of range
|
||||
|
||||
|
||||
return tiles[pos.y][pos.x];
|
||||
}
|
||||
|
||||
@@ -257,6 +256,9 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
|
||||
ent.setLevel(this);
|
||||
occupyTile(ent.getCoord());
|
||||
entityMap.put(ent.getEntityId(), ent);
|
||||
if (ent instanceof PlayerEntity) {
|
||||
playerCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +368,7 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
|
||||
|
||||
// further
|
||||
for (int i = 0; i < 20; i++) {
|
||||
final Coord c = pos.add(Calc.randInt(-2, 2),Calc.randInt(-2, 2));
|
||||
final Coord c = pos.add(Calc.randInt(-2, 2), Calc.randInt(-2, 2));
|
||||
if (addEntity(entity, c)) return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user