diff --git a/src/mightypork/gamecore/eventbus/clients/RootBusNode.java b/src/mightypork/gamecore/eventbus/clients/RootBusNode.java
index c598037..4e543b3 100644
--- a/src/mightypork/gamecore/eventbus/clients/RootBusNode.java
+++ b/src/mightypork/gamecore/eventbus/clients/RootBusNode.java
@@ -3,6 +3,7 @@ package mightypork.gamecore.eventbus.clients;
import mightypork.gamecore.eventbus.BusAccess;
import mightypork.gamecore.eventbus.events.Destroyable;
+import mightypork.gamecore.util.annot.DefaultImpl;
/**
@@ -36,6 +37,9 @@ public abstract class RootBusNode extends BusNode implements Destroyable {
* Deinitialize the subsystem
* (called during destruction)
*/
- protected abstract void deinit();
+ @DefaultImpl
+ protected void deinit()
+ {
+ }
}
diff --git a/src/mightypork/gamecore/gui/components/BaseComponent.java b/src/mightypork/gamecore/gui/components/BaseComponent.java
index f55a18d..c68db4a 100644
--- a/src/mightypork/gamecore/gui/components/BaseComponent.java
+++ b/src/mightypork/gamecore/gui/components/BaseComponent.java
@@ -5,6 +5,7 @@ import mightypork.gamecore.gui.Enableable;
import mightypork.gamecore.gui.events.LayoutChangeEvent;
import mightypork.gamecore.gui.events.LayoutChangeListener;
import mightypork.gamecore.input.InputSystem;
+import mightypork.gamecore.logging.Log;
import mightypork.gamecore.render.Renderable;
import mightypork.gamecore.util.annot.DefaultImpl;
import mightypork.gamecore.util.math.constraints.rect.Rect;
@@ -34,7 +35,7 @@ public abstract class BaseComponent extends AbstractRectCache implements Compone
@Override
- public final void setRect(RectBound rect)
+ public void setRect(RectBound rect)
{
this.source = new RectBoundAdapter(rect);
}
@@ -73,10 +74,11 @@ public abstract class BaseComponent extends AbstractRectCache implements Compone
@Override
public final void onLayoutChanged()
{
- if (getRect() == null) {
- throw new NullPointerException("Component is missing a bounding rect.");
+ try {
+ poll();
+ } catch (final NullPointerException e) {
+ Log.e("Component is missing a bounding rect, at: " + Log.str(getClass()));
}
- poll();
}
diff --git a/src/mightypork/gamecore/gui/components/LayoutComponent.java b/src/mightypork/gamecore/gui/components/LayoutComponent.java
index f675cba..42733f9 100644
--- a/src/mightypork/gamecore/gui/components/LayoutComponent.java
+++ b/src/mightypork/gamecore/gui/components/LayoutComponent.java
@@ -116,28 +116,12 @@ public abstract class LayoutComponent extends BaseComponent implements ClientHub
}
-// @Override
-// public void enable(boolean yes)
-// {
-// subModule.setDelegating(yes);
-// subModule.setListening(yes);
-// enabled = yes;
-// }
-//
-//
-// @Override
-// public boolean isEnabled()
-// {
-// return enabled;
-// }
-
-
/**
* Connect to bus and add to element list
*
* @param component added component, whose context has already been set.
*/
- public final void attach(Component component)
+ protected final void attach(Component component)
{
if (component == null) return;
if (component == this) throw new IllegalArgumentException("Uruboros. (infinite recursion evaded)");
diff --git a/src/mightypork/gamecore/input/KeyStroke.java b/src/mightypork/gamecore/input/KeyStroke.java
index 75b6644..2bc9012 100644
--- a/src/mightypork/gamecore/input/KeyStroke.java
+++ b/src/mightypork/gamecore/input/KeyStroke.java
@@ -1,9 +1,9 @@
package mightypork.gamecore.input;
+import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Set;
+import java.util.List;
import org.lwjgl.input.Keyboard;
@@ -15,9 +15,23 @@ import org.lwjgl.input.Keyboard;
*/
public class KeyStroke {
- private final Set keys = new LinkedHashSet<>();
+ private final List keys = new ArrayList<>(2);
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
@@ -27,9 +41,20 @@ public class KeyStroke {
*/
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);
+
this.fallingEdge = fallingEdge;
for (final int k : keys) {
this.keys.add(k);
+
+ badModifs.remove((Integer) k);
}
}
@@ -41,10 +66,7 @@ public class KeyStroke {
*/
public KeyStroke(int... keys)
{
- fallingEdge = false;
- for (final int k : keys) {
- this.keys.add(k);
- }
+ this(false, keys);
}
@@ -54,10 +76,18 @@ 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;
+ }
+ }
+
return fallingEdge ? st : !st;
}
@@ -112,10 +142,7 @@ public class KeyStroke {
}
- /**
- * @return the key set
- */
- public Set getKeys()
+ public List getKeys()
{
return keys;
}
diff --git a/src/mightypork/rogue/App.java b/src/mightypork/rogue/App.java
index 9c6eaee..81d61c9 100644
--- a/src/mightypork/rogue/App.java
+++ b/src/mightypork/rogue/App.java
@@ -8,7 +8,6 @@ import mightypork.gamecore.app.BaseApp;
import mightypork.gamecore.app.MainLoop;
import mightypork.gamecore.eventbus.BusEvent;
import mightypork.gamecore.eventbus.EventBus;
-import mightypork.gamecore.gui.events.CrossfadeRequest;
import mightypork.gamecore.gui.screens.ScreenRegistry;
import mightypork.gamecore.input.InputSystem;
import mightypork.gamecore.input.KeyStroke;
@@ -18,12 +17,14 @@ import mightypork.gamecore.logging.writers.LogWriter;
import mightypork.gamecore.render.DisplaySystem;
import mightypork.gamecore.resources.loading.AsyncResourceLoader;
import mightypork.gamecore.util.ion.Ion;
+import mightypork.rogue.GameStateManager.GameState;
import mightypork.rogue.events.ActionRequest;
import mightypork.rogue.events.ActionRequest.RequestType;
+import mightypork.rogue.events.GameStateRequest;
import mightypork.rogue.screens.FpsOverlay;
import mightypork.rogue.screens.game.ScreenGame;
import mightypork.rogue.screens.menu.ScreenMainMenu;
-import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy;
+import mightypork.rogue.screens.select_world.ScreenSelectWorld;
import mightypork.rogue.world.WorldProvider;
import mightypork.rogue.world.level.Level;
@@ -112,9 +113,10 @@ public final class App extends BaseApp {
/* game screen references world provider instance */
WorldProvider.init(this);
- screens.addScreen("test.bouncy", new ScreenTestBouncy(this));
+ getEventBus().subscribe(new GameStateManager(this));
- screens.addScreen("menu", new ScreenMainMenu(this));
+ screens.addScreen("main_menu", new ScreenMainMenu(this));
+ screens.addScreen("select_world", new ScreenSelectWorld(this));
screens.addScreen("game", new ScreenGame(this));
screens.addOverlay(new FpsOverlay(this));
@@ -128,9 +130,8 @@ public final class App extends BaseApp {
bindEventToKey(new ActionRequest(RequestType.FULLSCREEN), Keys.F11);
bindEventToKey(new ActionRequest(RequestType.SCREENSHOT), Keys.F2);
- bindEventToKey(new CrossfadeRequest(null), Keys.L_CONTROL, Keys.Q);
-
- bindEventToKey(new CrossfadeRequest("menu"), Keys.L_CONTROL, Keys.M);
+ bindEventToKey(new GameStateRequest(GameState.EXIT), Keys.L_CONTROL, Keys.Q);
+ bindEventToKey(new GameStateRequest(GameState.MAIN_MENU), Keys.L_CONTROL, Keys.M);
}
@@ -158,8 +159,10 @@ public final class App extends BaseApp {
protected void postInit()
{
// TODO tmp
- WorldProvider.get().createWorld(Double.doubleToLongBits(Math.random()));
+ //WorldProvider.get().createWorld(Double.doubleToLongBits(Math.random()));
+
+ //getEventBus().send(new CrossfadeRequest("game", true));
- getEventBus().send(new CrossfadeRequest("game", true));
+ getEventBus().send(new GameStateRequest(GameState.MAIN_MENU));
}
}
diff --git a/src/mightypork/rogue/GameStateManager.java b/src/mightypork/rogue/GameStateManager.java
new file mode 100644
index 0000000..cc1e22a
--- /dev/null
+++ b/src/mightypork/rogue/GameStateManager.java
@@ -0,0 +1,55 @@
+package mightypork.rogue;
+
+
+import mightypork.gamecore.app.AppAccess;
+import mightypork.gamecore.app.AppModule;
+import mightypork.gamecore.gui.events.CrossfadeRequest;
+import mightypork.gamecore.logging.Log;
+import mightypork.rogue.world.WorldProvider;
+
+
+public class GameStateManager extends AppModule {
+
+ public GameStateManager(AppAccess app)
+ {
+ super(app);
+ }
+
+ public static enum GameState
+ {
+ MAIN_MENU, SELECT_WORLD, PLAY_WORLD, EXIT
+ }
+
+
+ public void triggerAction(GameState state)
+ {
+ switch (state) {
+ case MAIN_MENU:
+ getEventBus().send(new CrossfadeRequest("main_menu"));
+ break;
+
+ case SELECT_WORLD:
+ getEventBus().send(new CrossfadeRequest("select_world"));
+ break;
+
+ case PLAY_WORLD:
+
+ if (WorldProvider.get().getWorld() == null) {
+ Log.w("WorldProvider has no world.");
+ }
+
+ getEventBus().send(new CrossfadeRequest("game"));
+ break;
+
+ case EXIT:
+ getEventBus().send(new CrossfadeRequest(null));
+ break;
+
+ default:
+ Log.w("Unknown action: " + state);
+ break;
+ }
+ }
+
+
+}
diff --git a/src/mightypork/rogue/Paths.java b/src/mightypork/rogue/Paths.java
index c63c3b5..6eddd35 100644
--- a/src/mightypork/rogue/Paths.java
+++ b/src/mightypork/rogue/Paths.java
@@ -20,4 +20,8 @@ public final class Paths {
public static final String DIR_MUSIC = "res/sounds/music/";
public static final String DIR_LOOPS = "res/sounds/loops/";
+ public static final File SAVE_SLOT_1 = new File(WORKDIR, "saves/slot_1.ion");
+ public static final File SAVE_SLOT_2 = new File(WORKDIR, "saves/slot_2.ion");
+ public static final File SAVE_SLOT_3 = new File(WORKDIR, "saves/slot_3.ion");
+
}
diff --git a/src/mightypork/rogue/events/GameStateRequest.java b/src/mightypork/rogue/events/GameStateRequest.java
new file mode 100644
index 0000000..eb98eb2
--- /dev/null
+++ b/src/mightypork/rogue/events/GameStateRequest.java
@@ -0,0 +1,25 @@
+package mightypork.rogue.events;
+
+
+import mightypork.gamecore.eventbus.BusEvent;
+import mightypork.rogue.GameStateManager;
+import mightypork.rogue.GameStateManager.GameState;
+
+
+public class GameStateRequest extends BusEvent {
+
+ final private GameState requested;
+
+
+ public GameStateRequest(GameState requested)
+ {
+ this.requested = requested;
+ }
+
+
+ @Override
+ protected void handleBy(GameStateManager handler)
+ {
+ handler.triggerAction(requested);
+ }
+}
diff --git a/src/mightypork/rogue/screens/game/HudLayer.java b/src/mightypork/rogue/screens/game/HudLayer.java
index 4e9ef80..39b1492 100644
--- a/src/mightypork/rogue/screens/game/HudLayer.java
+++ b/src/mightypork/rogue/screens/game/HudLayer.java
@@ -128,8 +128,8 @@ public class HudLayer extends ScreenLayer {
// TODO actions
- nav.addLeft(new NavButton(Res.txq("nav.button.fg.options")));
- nav.addLeft(new NavButton(Res.txq("nav.button.fg.help")));
+ //nav.addLeft(new NavButton(Res.txq("nav.button.fg.options")));
+ //nav.addLeft(new NavButton(Res.txq("nav.button.fg.help")));
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.map")));
btn.setAction(gameScreen.actionToggleMinimap);
diff --git a/src/mightypork/rogue/screens/menu/MenuButton.java b/src/mightypork/rogue/screens/menu/MenuButton.java
index fd0842e..82caa83 100644
--- a/src/mightypork/rogue/screens/menu/MenuButton.java
+++ b/src/mightypork/rogue/screens/menu/MenuButton.java
@@ -20,7 +20,8 @@ class MenuButton extends ClickableComponent {
private final VectVar offset = Vect.makeVar();
private final Vect offsetPassive = height().div(16).toVectXY();
- private final Vect offsetPassive2 = height().div(24).toVectXY();
+ private final Vect offsetPassive2 = height().div(20).toVectXY();
+ private final Vect offsetUnder = height().div(32).toVectXY();
private final Color color;
@@ -32,6 +33,7 @@ class MenuButton extends ClickableComponent {
this.painter = new TextPainter(font, AlignX.CENTER, this.color, text);
this.painter.setRect(this);
this.painter.setShadow(RGB.BLACK_30, offset);
+ painter.setPaddingHPerc(0, 5);
}
@@ -40,7 +42,7 @@ class MenuButton extends ClickableComponent {
{
if (isMouseOver()) {
if (InputSystem.isMouseButtonDown(0)) {
- offset.setTo(Vect.ZERO);
+ offset.setTo(offsetUnder);
} else {
offset.setTo(offsetPassive2);
}
diff --git a/src/mightypork/rogue/screens/menu/MenuLayer.java b/src/mightypork/rogue/screens/menu/MenuLayer.java
deleted file mode 100644
index c6131c6..0000000
--- a/src/mightypork/rogue/screens/menu/MenuLayer.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package mightypork.rogue.screens.menu;
-
-
-import mightypork.gamecore.gui.Action;
-import mightypork.gamecore.gui.components.layout.GridLayout;
-import mightypork.gamecore.gui.components.painters.ImagePainter;
-import mightypork.gamecore.gui.components.painters.QuadPainter;
-import mightypork.gamecore.gui.events.CrossfadeRequest;
-import mightypork.gamecore.gui.screens.Screen;
-import mightypork.gamecore.gui.screens.ScreenLayer;
-import mightypork.gamecore.util.math.color.Color;
-import mightypork.gamecore.util.math.color.pal.PAL16;
-import mightypork.gamecore.util.math.constraints.num.Num;
-import mightypork.gamecore.util.math.constraints.rect.Rect;
-import mightypork.rogue.Res;
-
-
-class MenuLayer extends ScreenLayer {
-
- public MenuLayer(Screen screen)
- {
- super(screen);
-
- init();
- }
-
-
- private void init()
- {
- final Rect menuBox = root.shrink(Num.ZERO, root.height().mul(0.15)).moveY(root.height().mul(-0.04));
-
- final GridLayout layout = new GridLayout(root, menuBox, 11, 1);
- layout.enableCaching(true);
-
- final QuadPainter bg = QuadPainter.gradV(Color.fromHex(0x007eb3), PAL16.SEABLUE);
- bg.setRect(root);
- root.add(bg);
-
- root.add(layout);
-
- int r = 0;
- final ImagePainter ip = new ImagePainter(Res.txq("logo"));
- ip.keepAspectRatio();
- layout.put(ip, r, 0, 5, 1);
- r += 6;
-
- MenuButton btn;
-
-
- // world button
- btn = new MenuButton("Game", PAL16.SLIMEGREEN);
- btn.setAction(new Action() {
-
- @Override
- protected void execute()
- {
- getEventBus().send(new CrossfadeRequest("game"));
- }
- });
- layout.put(btn, r, 0, 2, 1);
- r += 3;
-
- /*
- // bouncy text button
- btn = new MenuButton("Bouncy", PAL16.CLOUDBLUE);
- btn.setAction(new Action() {
-
- @Override
- protected void execute()
- {
- getEventBus().send(new CrossfadeRequest("test.bouncy"));
- }
- });
- layout.put(btn, r, 0, 2, 1);
- r += 3;
- */
-
- // quit button
- btn = new MenuButton("Bye!", PAL16.BLOODRED);
- btn.setAction(new Action() {
-
- @Override
- protected void execute()
- {
- getEventBus().send(new CrossfadeRequest(null)); // null -> fade and halt
- }
- });
- layout.put(btn, r, 0, 2, 1);
-
-
- root.add(layout);
- }
-
-
- @Override
- public int getZIndex()
- {
- return 2;
- }
-
-}
diff --git a/src/mightypork/rogue/screens/menu/ScreenMainMenu.java b/src/mightypork/rogue/screens/menu/ScreenMainMenu.java
index 374bba4..4449714 100644
--- a/src/mightypork/rogue/screens/menu/ScreenMainMenu.java
+++ b/src/mightypork/rogue/screens/menu/ScreenMainMenu.java
@@ -2,15 +2,121 @@ package mightypork.rogue.screens.menu;
import mightypork.gamecore.app.AppAccess;
+import mightypork.gamecore.gui.Action;
+import mightypork.gamecore.gui.components.layout.GridLayout;
+import mightypork.gamecore.gui.components.painters.ImagePainter;
+import mightypork.gamecore.gui.components.painters.QuadPainter;
import mightypork.gamecore.gui.screens.LayeredScreen;
+import mightypork.gamecore.gui.screens.Screen;
+import mightypork.gamecore.gui.screens.ScreenLayer;
+import mightypork.gamecore.util.math.color.Color;
+import mightypork.gamecore.util.math.color.pal.PAL16;
+import mightypork.gamecore.util.math.constraints.num.Num;
+import mightypork.gamecore.util.math.constraints.rect.Rect;
+import mightypork.rogue.GameStateManager.GameState;
+import mightypork.rogue.Res;
+import mightypork.rogue.events.GameStateRequest;
+/**
+ * Main menu screen
+ *
+ * @author MightyPork
+ */
public class ScreenMainMenu extends LayeredScreen {
+
public ScreenMainMenu(AppAccess app)
{
super(app);
addLayer(new MenuLayer(this));
}
+
+ /**
+ * The layer
+ *
+ * @author MightyPork
+ */
+ class MenuLayer extends ScreenLayer {
+
+ public MenuLayer(Screen screen)
+ {
+ super(screen);
+
+ init();
+ }
+
+
+ private void init()
+ {
+ final Rect menuBox = root.shrink(Num.ZERO, root.height().perc(15)).moveY(root.height().perc(-4));
+
+
+ final QuadPainter bg = QuadPainter.gradV(Color.fromHex(0x007eb3), PAL16.SEABLUE);
+ bg.setRect(root);
+ root.add(bg);
+
+ final GridLayout layout = new GridLayout(root, menuBox, 10, 1);
+ layout.enableCaching(true);
+ root.add(layout);
+
+ int r = 0;
+ final ImagePainter ip = new ImagePainter(Res.txq("logo"));
+ ip.keepAspectRatio();
+ layout.put(ip, r, 0, 4, 1);
+ r += 5;
+
+ MenuButton btn;
+
+
+ // world button
+ btn = new MenuButton("Play", PAL16.SLIMEGREEN);
+ btn.setAction(new Action() {
+
+ @Override
+ protected void execute()
+ {
+ getEventBus().send(new GameStateRequest(GameState.SELECT_WORLD));
+ }
+ });
+ layout.put(btn, r, 0, 2, 1);
+ r += 3;
+
+ /*
+ // bouncy text button
+ btn = new MenuButton("Bouncy", PAL16.CLOUDBLUE);
+ btn.setAction(new Action() {
+
+ @Override
+ protected void execute()
+ {
+ getEventBus().send(new CrossfadeRequest("test.bouncy"));
+ }
+ });
+ layout.put(btn, r, 0, 2, 1);
+ r += 3;
+ */
+
+ // quit button
+ btn = new MenuButton("Exit", PAL16.BLOODRED);
+ btn.setAction(new Action() {
+
+ @Override
+ protected void execute()
+ {
+ getEventBus().send(new GameStateRequest(GameState.EXIT));
+ }
+ });
+ layout.put(btn, r, 0, 2, 1);
+ }
+
+
+ @Override
+ public int getZIndex()
+ {
+ return 2;
+ }
+
+ }
}
diff --git a/src/mightypork/rogue/screens/select_world/ClickableWrapper.java b/src/mightypork/rogue/screens/select_world/ClickableWrapper.java
new file mode 100644
index 0000000..fe1c90b
--- /dev/null
+++ b/src/mightypork/rogue/screens/select_world/ClickableWrapper.java
@@ -0,0 +1,65 @@
+package mightypork.rogue.screens.select_world;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import mightypork.gamecore.eventbus.clients.DelegatingClient;
+import mightypork.gamecore.gui.components.ClickableComponent;
+import mightypork.gamecore.gui.components.Component;
+
+
+public class ClickableWrapper extends ClickableComponent implements DelegatingClient {
+
+
+ private final Component wrapped;
+ private final List list;
+
+
+ public ClickableWrapper(Component wrapped)
+ {
+ this.wrapped = wrapped;
+ wrapped.setRect(this);
+
+ list = new ArrayList<>(1);
+ list.add(wrapped);
+ }
+
+
+ @Override
+ public Collection> getChildClients()
+ {
+ return list;
+ }
+
+
+ @Override
+ public boolean doesDelegate()
+ {
+ return true;
+ }
+
+
+ @Override
+ public boolean isEnabled()
+ {
+ return super.isEnabled() && wrapped.isEnabled();
+ }
+
+
+ @Override
+ public void enable(boolean yes)
+ {
+ super.enable(yes);
+ wrapped.enable(yes);
+ }
+
+
+ @Override
+ protected void renderComponent()
+ {
+ wrapped.render();
+ }
+
+}
diff --git a/src/mightypork/rogue/screens/select_world/ScreenSelectWorld.java b/src/mightypork/rogue/screens/select_world/ScreenSelectWorld.java
new file mode 100644
index 0000000..638889c
--- /dev/null
+++ b/src/mightypork/rogue/screens/select_world/ScreenSelectWorld.java
@@ -0,0 +1,86 @@
+package mightypork.rogue.screens.select_world;
+
+
+import mightypork.gamecore.app.AppAccess;
+import mightypork.gamecore.gui.AlignX;
+import mightypork.gamecore.gui.components.layout.GridLayout;
+import mightypork.gamecore.gui.components.painters.QuadPainter;
+import mightypork.gamecore.gui.components.painters.TextPainter;
+import mightypork.gamecore.gui.screens.LayeredScreen;
+import mightypork.gamecore.gui.screens.Screen;
+import mightypork.gamecore.gui.screens.ScreenLayer;
+import mightypork.gamecore.util.math.color.Color;
+import mightypork.gamecore.util.math.color.pal.PAL16;
+import mightypork.gamecore.util.math.color.pal.RGB;
+import mightypork.gamecore.util.math.constraints.rect.Rect;
+import mightypork.rogue.Paths;
+import mightypork.rogue.Res;
+
+
+/**
+ * Main menu screen
+ *
+ * @author MightyPork
+ */
+public class ScreenSelectWorld extends LayeredScreen {
+
+
+ public ScreenSelectWorld(AppAccess app)
+ {
+ super(app);
+
+ addLayer(new WorldsLayer(this));
+ }
+
+
+ class WorldsLayer extends ScreenLayer {
+
+ public WorldsLayer(Screen screen)
+ {
+ super(screen);
+
+ init();
+ }
+
+
+ private void init()
+ {
+ final Rect menuBox = root.shrink(root.width().perc(25), root.height().perc(20));
+
+
+ final QuadPainter bg = QuadPainter.gradV(Color.fromHex(0x007eb3), PAL16.SEABLUE);
+ bg.setRect(root);
+ root.add(bg);
+
+ final GridLayout layout = new GridLayout(root, menuBox, 7, 1);
+ layout.enableCaching(true);
+ root.add(layout);
+
+ TextPainter tp;
+
+ layout.put(tp = new TextPainter(Res.getFont("thick"), AlignX.CENTER, RGB.YELLOW, "Save slot:"), 0, 0, 1, 1);
+ tp.setPaddingHPerc(0, 20);
+ tp.setShadow(RGB.BLACK_50, tp.height().mul(0.6 / 8D).toVectXY());
+
+
+ WorldSlot wsl;
+
+ wsl = new WorldSlot(root, Paths.SAVE_SLOT_1);
+ layout.put(wsl, 1, 0, 1, 1);
+
+ wsl = new WorldSlot(root, Paths.SAVE_SLOT_2);
+ layout.put(wsl, 2, 0, 1, 1);
+
+ wsl = new WorldSlot(root, Paths.SAVE_SLOT_3);
+ layout.put(wsl, 3, 0, 1, 1);
+ }
+
+
+ @Override
+ public int getZIndex()
+ {
+ return 2;
+ }
+
+ }
+}
diff --git a/src/mightypork/rogue/screens/select_world/WorldSlot.java b/src/mightypork/rogue/screens/select_world/WorldSlot.java
new file mode 100644
index 0000000..f7a6eeb
--- /dev/null
+++ b/src/mightypork/rogue/screens/select_world/WorldSlot.java
@@ -0,0 +1,132 @@
+package mightypork.rogue.screens.select_world;
+
+
+import java.io.File;
+import java.io.IOException;
+
+import mightypork.gamecore.app.AppAccess;
+import mightypork.gamecore.gui.Action;
+import mightypork.gamecore.gui.AlignX;
+import mightypork.gamecore.gui.components.layout.ConstraintLayout;
+import mightypork.gamecore.gui.components.layout.GridLayout;
+import mightypork.gamecore.gui.components.painters.QuadPainter;
+import mightypork.gamecore.gui.components.painters.TextPainter;
+import mightypork.gamecore.resources.fonts.GLFont;
+import mightypork.gamecore.util.ion.Ion;
+import mightypork.gamecore.util.ion.IonBundle;
+import mightypork.gamecore.util.math.color.pal.RGB;
+import mightypork.gamecore.util.math.constraints.num.Num;
+import mightypork.gamecore.util.math.constraints.rect.Rect;
+import mightypork.gamecore.util.strings.StringProvider;
+import mightypork.rogue.GameStateManager.GameState;
+import mightypork.rogue.Res;
+import mightypork.rogue.events.GameStateRequest;
+import mightypork.rogue.world.World;
+import mightypork.rogue.world.WorldProvider;
+
+
+public class WorldSlot extends ConstraintLayout {
+
+ private final StringProvider lblStrp = new StringProvider() {
+
+ @Override
+ public String getString()
+ {
+ return label;
+ }
+ };
+
+ private File file;
+ private String label;
+
+ private IonBundle worldBundle;
+
+
+ public WorldSlot(AppAccess app, File worldFile)
+ {
+ super(app);
+
+ this.file = worldFile;
+
+ final Rect innerRect = shrink(height().perc(5));
+
+ final QuadPainter qp = new QuadPainter(RGB.BLACK.withAlpha(new Num() {
+
+ @Override
+ public double value()
+ {
+ return isMouseOver() ? 0.2 : 0.1;
+ }
+ }));
+
+
+ qp.setRect(innerRect);
+ add(qp);
+
+
+ final GridLayout gridl = new GridLayout(app, 1, 8);
+ gridl.setRect(innerRect.shrink(width().perc(10), Num.ZERO));
+ add(gridl);
+
+ TextPainter tp;
+ ClickableWrapper btn;
+ final GLFont font = Res.getFont("thick");
+
+ tp = new TextPainter(font, AlignX.LEFT, RGB.WHITE, lblStrp);
+ tp.setPaddingHPerc(0, 20);
+
+ gridl.put(btn = new ClickableWrapper(tp), 0, 0, 1, 7);
+ btn.setAction(new Action() {
+
+ @Override
+ protected void execute()
+ {
+ 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()));
+ }
+
+ getEventBus().send(new GameStateRequest(GameState.PLAY_WORLD));
+ }
+ });
+
+ tp = new TextPainter(font, AlignX.LEFT, RGB.RED, "X");
+ tp.setPaddingHPerc(0, 20);
+ gridl.put(btn = new ClickableWrapper(tp), 0, 7, 1, 1);
+ btn.setAction(new Action() {
+
+ @Override
+ protected void execute()
+ {
+ file.delete();
+ refresh();
+ }
+ });
+
+ refresh();
+ }
+
+
+ public void refresh()
+ {
+ if (!file.exists()) {
+ label = "";
+ } else {
+ try {
+ worldBundle = Ion.fromFile(file);
+ final int lvl = worldBundle.get("meta.last_level", -1);
+
+ if (lvl == -1) throw new RuntimeException(); // let the catch block handle it
+
+ label = "Floor " + (lvl + 1);
+ } catch (final IOException e) {
+ label = "";
+ }
+ }
+ }
+
+}
diff --git a/src/mightypork/rogue/screens/test_bouncyboxes/BouncyBox.java b/src/mightypork/rogue/screens/test_bouncyboxes/BouncyBox.java
deleted file mode 100644
index b309629..0000000
--- a/src/mightypork/rogue/screens/test_bouncyboxes/BouncyBox.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package mightypork.rogue.screens.test_bouncyboxes;
-
-
-import java.util.Random;
-
-import mightypork.gamecore.eventbus.events.Updateable;
-import mightypork.gamecore.gui.components.BaseComponent;
-import mightypork.gamecore.render.Render;
-import mightypork.gamecore.util.math.Easing;
-import mightypork.gamecore.util.math.color.pal.RGB;
-import mightypork.gamecore.util.math.constraints.num.Num;
-import mightypork.gamecore.util.math.constraints.num.mutable.NumAnimated;
-import mightypork.gamecore.util.math.constraints.rect.Rect;
-import mightypork.gamecore.util.math.constraints.rect.caching.RectCache;
-
-
-public class BouncyBox extends BaseComponent implements Updateable {
-
- private final Random rand = new Random();
-
- private final RectCache box;
-
- private final NumAnimated pos = new NumAnimated(0, Easing.BOUNCE_OUT);
-
-
- public BouncyBox()
- {
- super();
- enableCaching(true);
-
- Rect abox;
-
- abox = leftEdge().growRight(height());
- abox = abox.move(width().sub(height()).mul(pos), Num.ZERO);
- abox = abox.shrink(height().perc(10));
-
- box = abox.cached();
- }
-
-
- @Override
- public void renderComponent()
- {
- Render.quad(box, RGB.GREEN);
- }
-
-
- public void goLeft()
- {
- pos.animate(1, 0, 1 + rand.nextDouble() * 1);
- }
-
-
- public void goRight()
- {
- pos.animate(0, 1, 1 + rand.nextDouble() * 1);
- }
-
-
- @Override
- public void update(double delta)
- {
- if (pos.isInProgress()) {
- pos.update(delta);
- box.poll();
- }
- }
-
-
- @Override
- public void updateLayout()
- {
- box.poll();
- }
-
-}
diff --git a/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java b/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java
deleted file mode 100644
index 2d63bd6..0000000
--- a/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package mightypork.rogue.screens.test_bouncyboxes;
-
-
-import java.util.ArrayList;
-import java.util.List;
-
-import mightypork.gamecore.gui.AlignX;
-import mightypork.gamecore.gui.components.layout.RowHolder;
-import mightypork.gamecore.gui.components.painters.TextPainter;
-import mightypork.gamecore.gui.screens.Screen;
-import mightypork.gamecore.gui.screens.ScreenLayer;
-import mightypork.gamecore.input.KeyStroke;
-import mightypork.gamecore.input.Keys;
-import mightypork.gamecore.util.math.color.pal.RGB;
-import mightypork.gamecore.util.math.constraints.num.Num;
-import mightypork.gamecore.util.math.constraints.vect.Vect;
-import mightypork.rogue.Res;
-
-
-public class LayerBouncyBoxes extends ScreenLayer {
-
- List boxes = new ArrayList<>();
- private RowHolder layout;
-
-
- public LayerBouncyBoxes(Screen screen)
- {
- super(screen);
-
- bindKey(new KeyStroke(true, Keys.RIGHT), new Runnable() {
-
- @Override
- public void run()
- {
- goRight();
- }
- });
-
- bindKey(new KeyStroke(true, Keys.LEFT), new Runnable() {
-
- @Override
- public void run()
- {
- goLeft();
- }
- });
-
- // shrink screen rect by 8% on all sides
-
- root.add(layout = new RowHolder(this, root.shrink(root.height().perc(5)), 10));
-
- for (int i = 0; i < 9; i++) {
- final BouncyBox bbr = new BouncyBox();
- layout.add(bbr);
- boxes.add(bbr);
- }
-
- final TextPainter tp = new TextPainter(Res.getFont("thick"), AlignX.LEFT, RGB.WHITE);
- tp.setText("Press left & right to move.");
- final Num shadowOffset = tp.height().div(16);
- tp.setShadow(RGB.RED, Vect.make(shadowOffset, shadowOffset));
-
- layout.add(tp);
- }
-
-
- public void goLeft()
- {
- for (final BouncyBox bbr : boxes) {
- bbr.goLeft();
- }
- }
-
-
- public void goRight()
- {
- for (final BouncyBox bbr : boxes) {
- bbr.goRight();
- }
- }
-
-
- @Override
- public int getZIndex()
- {
- return 0;
- }
-}
diff --git a/src/mightypork/rogue/screens/test_bouncyboxes/ScreenTestBouncy.java b/src/mightypork/rogue/screens/test_bouncyboxes/ScreenTestBouncy.java
deleted file mode 100644
index e028773..0000000
--- a/src/mightypork/rogue/screens/test_bouncyboxes/ScreenTestBouncy.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package mightypork.rogue.screens.test_bouncyboxes;
-
-
-import mightypork.gamecore.app.AppAccess;
-import mightypork.gamecore.gui.screens.LayeredScreen;
-
-
-public class ScreenTestBouncy extends LayeredScreen {
-
- public ScreenTestBouncy(AppAccess app)
- {
- super(app);
-
- addLayer(new LayerBouncyBoxes(this));
- }
-
-}
diff --git a/src/mightypork/rogue/world/World.java b/src/mightypork/rogue/world/World.java
index 6355e90..f3281cb 100644
--- a/src/mightypork/rogue/world/World.java
+++ b/src/mightypork/rogue/world/World.java
@@ -1,6 +1,7 @@
package mightypork.rogue.world;
+import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -46,6 +47,8 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
/** Next entity ID */
private int eid;
+ private File saveFile;
+
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
@@ -90,6 +93,9 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
out.put("next_eid", eid);
out.putSequence("levels", levels);
out.putBundled("player", playerData);
+
+ // used for peking in before actually loading the world.
+ out.put("meta.last_level", playerData.getLevelNumber());
}
@@ -213,4 +219,16 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
{
return console;
}
+
+
+ public void setSaveFile(File file)
+ {
+ this.saveFile = file;
+ }
+
+
+ public File getSaveFile()
+ {
+ return saveFile;
+ }
}
diff --git a/src/mightypork/rogue/world/WorldConsole.java b/src/mightypork/rogue/world/WorldConsole.java
index 6091d90..59dbe79 100644
--- a/src/mightypork/rogue/world/WorldConsole.java
+++ b/src/mightypork/rogue/world/WorldConsole.java
@@ -130,6 +130,9 @@ public class WorldConsole implements Updateable {
public void msgDie(Entity attacker)
{
addMessage("You've been defeated by a " + attacker.getVisualName() + "!");
+
+ addMessage("CTRL+M ... main menu");
+ addMessage("CTRL+N ... new game");
}
diff --git a/src/mightypork/rogue/world/WorldProvider.java b/src/mightypork/rogue/world/WorldProvider.java
index 6c6a06f..4672a6b 100644
--- a/src/mightypork/rogue/world/WorldProvider.java
+++ b/src/mightypork/rogue/world/WorldProvider.java
@@ -68,7 +68,7 @@ public class WorldProvider extends RootBusNode {
}
- private void setWorld(World newWorld)
+ public void setWorld(World newWorld)
{
if (world != null) removeChildClient(world);
world = newWorld;
@@ -88,11 +88,29 @@ public class WorldProvider extends RootBusNode {
public void saveWorld(File file) throws IOException
{
- if (world == null) throw new IllegalStateException("Trying to save a NULL world.");
+ if (world == null) {
+ throw new IllegalStateException("Trying to save a NULL world.");
+ }
Ion.toFile(file, world);
}
+ public void saveWorld() throws IOException
+ {
+ if (world == null) {
+ throw new IllegalStateException("Trying to save a NULL world.");
+ }
+
+ final File f = world.getSaveFile();
+
+ if (f == null) {
+ throw new IllegalStateException("Trying to save world to a NULL file.");
+ }
+
+ Ion.toFile(f, world);
+ }
+
+
public Level getCurrentLevel()
{
return getWorld().getPlayer().getLevel();
@@ -113,10 +131,4 @@ public class WorldProvider extends RootBusNode {
return playerControl;
}
-
- @Override
- protected void deinit()
- {
- }
-
}
diff --git a/src/mightypork/rogue/world/entity/impl/EntityBossRat.java b/src/mightypork/rogue/world/entity/impl/EntityBossRat.java
index 33b3e33..2c24999 100644
--- a/src/mightypork/rogue/world/entity/impl/EntityBossRat.java
+++ b/src/mightypork/rogue/world/entity/impl/EntityBossRat.java
@@ -8,7 +8,6 @@ import mightypork.rogue.world.entity.EntityPathFinder;
import mightypork.rogue.world.entity.EntityRenderer;
import mightypork.rogue.world.entity.EntityType;
import mightypork.rogue.world.entity.render.EntityRendererMobLR;
-import mightypork.rogue.world.item.Items;
public class EntityBossRat extends Entity {
@@ -65,22 +64,9 @@ public class EntityBossRat extends Entity {
@Override
public void onKilled()
{
- // TODO drop rare stuff & fire event.
-
- if (rand.nextInt(8) == 0) {
- getLevel().dropNear(getCoord(), Items.BONE.createItem());
- return;
- }
-
- if (rand.nextInt(3) == 0) {
- getLevel().dropNear(getCoord(), Items.MEAT.createItem());
- return;
- }
-
- if (rand.nextInt(6) == 0) {
- getLevel().dropNear(getCoord(), Items.CHEESE.createItem());
- return;
- }
+ getWorld().getConsole().addMessage("YOU DEFEATED THE BOSS RAT");
+ getWorld().getConsole().addMessage("CTRL+M ... main menu");
+ getWorld().getConsole().addMessage("CTRL+N ... new game");
}
diff --git a/src/mightypork/rogue/world/gen/rooms/BossRoom.java b/src/mightypork/rogue/world/gen/rooms/BossRoom.java
index 2bc738f..f948d78 100644
--- a/src/mightypork/rogue/world/gen/rooms/BossRoom.java
+++ b/src/mightypork/rogue/world/gen/rooms/BossRoom.java
@@ -3,6 +3,7 @@ package mightypork.rogue.world.gen.rooms;
import java.util.Random;
+import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.algo.Coord;
import mightypork.rogue.world.entity.Entities;
import mightypork.rogue.world.entity.Entity;
@@ -16,7 +17,7 @@ public class BossRoom extends SecretRoom {
@Override
protected int getDoorCount(Random rand)
{
- return 2;
+ return Calc.randInt(rand, 1, 3);
}
diff --git a/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java b/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java
index d263631..b40a232 100644
--- a/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java
+++ b/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java
@@ -3,6 +3,7 @@ package mightypork.rogue.world.gen.rooms;
import java.util.Random;
+import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.algo.Coord;
import mightypork.rogue.world.gen.MapTheme;
import mightypork.rogue.world.gen.ScratchMap;
@@ -54,7 +55,7 @@ public class EntranceRoom extends AbstractRectRoom {
@Override
protected int getDoorCount(Random rand)
{
- return 1 + rand.nextInt(4);
+ return Calc.randInt(rand, 1, 4);
}
}
diff --git a/src/mightypork/rogue/world/gen/rooms/HeartPieceRoom.java b/src/mightypork/rogue/world/gen/rooms/HeartPieceRoom.java
index 35bd9e2..543ad58 100644
--- a/src/mightypork/rogue/world/gen/rooms/HeartPieceRoom.java
+++ b/src/mightypork/rogue/world/gen/rooms/HeartPieceRoom.java
@@ -3,6 +3,7 @@ package mightypork.rogue.world.gen.rooms;
import java.util.Random;
+import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.algo.Coord;
import mightypork.rogue.world.gen.MapTheme;
import mightypork.rogue.world.gen.ScratchMap;
@@ -16,7 +17,7 @@ public class HeartPieceRoom extends SecretRoom {
@Override
protected int getDoorCount(Random rand)
{
- return 1;
+ return Calc.randInt(rand, 1, 3);
}
diff --git a/src/mightypork/rogue/world/gen/rooms/SecretRoom.java b/src/mightypork/rogue/world/gen/rooms/SecretRoom.java
index dbb32c8..e951bc3 100644
--- a/src/mightypork/rogue/world/gen/rooms/SecretRoom.java
+++ b/src/mightypork/rogue/world/gen/rooms/SecretRoom.java
@@ -3,6 +3,7 @@ package mightypork.rogue.world.gen.rooms;
import java.util.Random;
+import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.algo.Coord;
import mightypork.rogue.world.gen.MapTheme;
import mightypork.rogue.world.gen.TileProtectLevel;
@@ -21,7 +22,7 @@ public abstract class SecretRoom extends AbstractRectRoom {
@Override
protected int getDoorCount(Random rand)
{
- return 1 + rand.nextInt(2);
+ return Calc.randInt(rand, 1, 3);
}