diff --git a/src/mightypork/gamecore/input/InputSystem.java b/src/mightypork/gamecore/input/InputSystem.java index d394731..fd060e0 100644 --- a/src/mightypork/gamecore/input/InputSystem.java +++ b/src/mightypork/gamecore/input/InputSystem.java @@ -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; + } } diff --git a/src/mightypork/gamecore/input/KeyStroke.java b/src/mightypork/gamecore/input/KeyStroke.java index 2bc9012..a5df576 100644 --- a/src/mightypork/gamecore/input/KeyStroke.java +++ b/src/mightypork/gamecore/input/KeyStroke.java @@ -15,58 +15,42 @@ import org.lwjgl.input.Keyboard; */ public class KeyStroke { - private final List keys = new ArrayList<>(2); + private final int mod; + private final int key; private final boolean fallingEdge; - private final List 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,20 +59,41 @@ public class KeyStroke { */ public boolean isActive() { - boolean st = true; + boolean st = Keyboard.isKeyDown(key); + st &= (InputSystem.getModifierKeys() == mod); + + return fallingEdge ? st : !st; + } + + + @Override + public String toString() + { + String s = "("; - for (final int k : keys) { - st &= Keyboard.isKeyDown(k); + if ((mod & Keys.MOD_CONTROL) != 0) { + s += "CTRL+"; } - for (final int i : badModifs) { - if (Keyboard.isKeyDown(i)) { - st = false; - break; - } + if ((mod & Keys.MOD_ALT) != 0) { + s += "ALT+"; } - return fallingEdge ? st : !st; + 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 += ")"; + + return s; } @@ -97,7 +102,9 @@ public class KeyStroke { { final int prime = 31; int result = 1; - result = prime * result + ((keys == null) ? 0 : keys.hashCode()); + result = prime * result + (fallingEdge ? 1231 : 1237); + result = prime * result + key; + result = prime * result + mod; return result; } @@ -107,43 +114,11 @@ public class KeyStroke { { 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 (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; } - - - @Override - public String toString() - { - String s = "("; - - int cnt = 0; - final Iterator i = keys.iterator(); - for (; i.hasNext(); cnt++) { - if (cnt > 0) s += "+"; - s += Keyboard.getKeyName(i.next()); - } - - s += fallingEdge ? ",DOWN" : ",UP"; - - s += ")"; - - return s; - } - - - public List getKeys() - { - return keys; - } } diff --git a/src/mightypork/gamecore/input/Keys.java b/src/mightypork/gamecore/input/Keys.java index 435f2d6..1f6fcc9 100644 --- a/src/mightypork/gamecore/input/Keys.java +++ b/src/mightypork/gamecore/input/Keys.java @@ -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 } diff --git a/src/mightypork/gamecore/util/ion/Ion.java b/src/mightypork/gamecore/util/ion/Ion.java index 1dc56a8..e155f34 100644 --- a/src/mightypork/gamecore/util/ion/Ion.java +++ b/src/mightypork/gamecore/util/ion/Ion.java @@ -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); diff --git a/src/mightypork/rogue/App.java b/src/mightypork/rogue/App.java index fcf8a61..6bdd24c 100644 --- a/src/mightypork/rogue/App.java +++ b/src/mightypork/rogue/App.java @@ -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 key) + { + bindEventToKey(event, key, Keys.MOD_NONE); + } - private void bindEventToKey(final BusEvent event, int... keys) + private void bindEventToKey(final BusEvent event, int key, byte mod) { - getInput().bindKey(new KeyStroke(keys), new Runnable() { + getInput().bindKey(new KeyStroke(key, mod), new Runnable() { @Override public void run() diff --git a/src/mightypork/rogue/screens/LoaderRequest.java b/src/mightypork/rogue/screens/LoaderRequest.java index c4678a7..645b360 100644 --- a/src/mightypork/rogue/screens/LoaderRequest.java +++ b/src/mightypork/rogue/screens/LoaderRequest.java @@ -5,28 +5,18 @@ import mightypork.gamecore.eventbus.BusEvent; public class LoaderRequest extends BusEvent { - 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); } } diff --git a/src/mightypork/rogue/screens/LoadingOverlay.java b/src/mightypork/rogue/screens/LoadingOverlay.java index c77ce14..18796c0 100644 --- a/src/mightypork/rogue/screens/LoadingOverlay.java +++ b/src/mightypork/rogue/screens/LoadingOverlay.java @@ -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() { diff --git a/src/mightypork/rogue/screens/game/ScreenGame.java b/src/mightypork/rogue/screens/game/ScreenGame.java index 327ac47..ded51cb 100644 --- a/src/mightypork/rogue/screens/game/ScreenGame.java +++ b/src/mightypork/rogue/screens/game/ScreenGame.java @@ -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 diff --git a/src/mightypork/rogue/screens/select_world/WorldSlot.java b/src/mightypork/rogue/screens/select_world/WorldSlot.java index 777f319..fd55400 100644 --- a/src/mightypork/rogue/screens/select_world/WorldSlot.java +++ b/src/mightypork/rogue/screens/select_world/WorldSlot.java @@ -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")); } - }); + })); } }); diff --git a/src/mightypork/rogue/world/Inventory.java b/src/mightypork/rogue/world/Inventory.java index 9d12a41..a5e8586 100644 --- a/src/mightypork/rogue/world/Inventory.java +++ b/src/mightypork/rogue/world/Inventory.java @@ -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; diff --git a/src/mightypork/rogue/world/World.java b/src/mightypork/rogue/world/World.java index f3281cb..dfc9232 100644 --- a/src/mightypork/rogue/world/World.java +++ b/src/mightypork/rogue/world/World.java @@ -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."); } diff --git a/src/mightypork/rogue/world/WorldConsole.java b/src/mightypork/rogue/world/WorldConsole.java index 59dbe79..b120e38 100644 --- a/src/mightypork/rogue/world/WorldConsole.java +++ b/src/mightypork/rogue/world/WorldConsole.java @@ -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."); + } } diff --git a/src/mightypork/rogue/world/WorldProvider.java b/src/mightypork/rogue/world/WorldProvider.java index 4672a6b..e4fd04e 100644 --- a/src/mightypork/rogue/world/WorldProvider.java +++ b/src/mightypork/rogue/world/WorldProvider.java @@ -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); } diff --git a/src/mightypork/rogue/world/entity/impl/BossRatAi.java b/src/mightypork/rogue/world/entity/impl/BossRatAi.java index e1addde..8151826 100644 --- a/src/mightypork/rogue/world/entity/impl/BossRatAi.java +++ b/src/mightypork/rogue/world/entity/impl/BossRatAi.java @@ -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; + } } diff --git a/src/mightypork/rogue/world/entity/impl/BrownRatAi.java b/src/mightypork/rogue/world/entity/impl/BrownRatAi.java index f86553c..68eb9da 100644 --- a/src/mightypork/rogue/world/entity/impl/BrownRatAi.java +++ b/src/mightypork/rogue/world/entity/impl/BrownRatAi.java @@ -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; } } diff --git a/src/mightypork/rogue/world/entity/impl/EntityBossRat.java b/src/mightypork/rogue/world/entity/impl/EntityBossRat.java index 9459315..fd3f7a1 100644 --- a/src/mightypork/rogue/world/entity/impl/EntityBossRat.java +++ b/src/mightypork/rogue/world/entity/impl/EntityBossRat.java @@ -27,7 +27,6 @@ public class EntityBossRat extends Entity { addModule("ai", ai); pos.addMoveListener(ai); - pos.setStepTime(0.4); setDespawnDelay(1); health.setHealthMax(80); diff --git a/src/mightypork/rogue/world/entity/impl/EntityBrownRat.java b/src/mightypork/rogue/world/entity/impl/EntityBrownRat.java index 091e17e..f5b0159 100644 --- a/src/mightypork/rogue/world/entity/impl/EntityBrownRat.java +++ b/src/mightypork/rogue/world/entity/impl/EntityBrownRat.java @@ -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); diff --git a/src/mightypork/rogue/world/entity/impl/EntityGrayRat.java b/src/mightypork/rogue/world/entity/impl/EntityGrayRat.java index aaf79bc..2671829 100644 --- a/src/mightypork/rogue/world/entity/impl/EntityGrayRat.java +++ b/src/mightypork/rogue/world/entity/impl/EntityGrayRat.java @@ -28,7 +28,6 @@ public class EntityGrayRat extends Entity { addModule("ai", ai); pos.addMoveListener(ai); - pos.setStepTime(0.5); setDespawnDelay(1); health.setHealthMax(6); diff --git a/src/mightypork/rogue/world/entity/impl/GrayRatAi.java b/src/mightypork/rogue/world/entity/impl/GrayRatAi.java index 02d3194..17453e2 100644 --- a/src/mightypork/rogue/world/entity/impl/GrayRatAi.java +++ b/src/mightypork/rogue/world/entity/impl/GrayRatAi.java @@ -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() - { - return false; - } - + @Override - protected boolean shouldRandomlyAbandonPrey() + protected double getStepTime() { - return false; + return isIdle() ? 0.7 : 0.5; } } diff --git a/src/mightypork/rogue/world/entity/impl/MonsterAi.java b/src/mightypork/rogue/world/entity/impl/MonsterAi.java index b87cafc..9a5e627 100644 --- a/src/mightypork/rogue/world/entity/impl/MonsterAi.java +++ b/src/mightypork/rogue/world/entity/impl/MonsterAi.java @@ -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() - { - return false; - } - - - @DefaultImpl - protected boolean shouldRandomlyAbandonPrey() - { - return false; - } - - - @DefaultImpl - protected boolean shouldRandomlyWake() - { - return Calc.rand.nextInt(10) == 0; - } - - @DefaultImpl - protected boolean shouldRandomlyFallAsleep() + protected double getStepTime() { - return Calc.rand.nextInt(8) == 0; + return isIdle() ? 0.7 : 0.4; } } diff --git a/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java b/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java index 7404aee..13e2e22 100644 --- a/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java +++ b/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java @@ -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)) { diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index bcdaffc..1606443 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -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; }