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); }