diff --git a/res/font/Born2bSportyV2.ttf b/res/font/Born2bSportyV2.ttf new file mode 100644 index 0000000..0200178 Binary files /dev/null and b/res/font/Born2bSportyV2.ttf differ diff --git a/res/font/C64Font.ttf b/res/font/C64Font.ttf new file mode 100644 index 0000000..133de49 Binary files /dev/null and b/res/font/C64Font.ttf differ diff --git a/res/font/DigitalMonsters.ttf b/res/font/DigitalMonsters.ttf new file mode 100644 index 0000000..d97c1cc Binary files /dev/null and b/res/font/DigitalMonsters.ttf differ diff --git a/res/font/Handheld.ttf b/res/font/Handheld.ttf new file mode 100644 index 0000000..c68c1aa Binary files /dev/null and b/res/font/Handheld.ttf differ diff --git a/res/font/Simpleton.ttf b/res/font/Simpleton.ttf new file mode 100644 index 0000000..74b8175 Binary files /dev/null and b/res/font/Simpleton.ttf differ diff --git a/res/img/gui.png b/res/img/gui.png index 18a87c1..890576a 100644 Binary files a/res/img/gui.png and b/res/img/gui.png differ diff --git a/res/img/gui.xcf b/res/img/gui.xcf index 8708725..4185224 100644 Binary files a/res/img/gui.xcf and b/res/img/gui.xcf differ diff --git a/src/mightypork/gamecore/gui/ActionGroup.java b/src/mightypork/gamecore/gui/ActionGroup.java new file mode 100644 index 0000000..fbc591a --- /dev/null +++ b/src/mightypork/gamecore/gui/ActionGroup.java @@ -0,0 +1,36 @@ +package mightypork.gamecore.gui; + + +import java.util.HashSet; +import java.util.Set; + + +public class ActionGroup implements Enableable { + + private boolean enabled = true; + + private final Set groupMembers = new HashSet<>(); + + + @Override + public void enable(boolean yes) + { + enabled = yes; + for (final Enableable e : groupMembers) + e.enable(yes); + } + + + @Override + public boolean isEnabled() + { + return enabled; + } + + + public void add(Enableable action) + { + groupMembers.add(action); + } + +} diff --git a/src/mightypork/gamecore/gui/components/VisualComponent.java b/src/mightypork/gamecore/gui/components/VisualComponent.java index 6f6552a..ae806e6 100644 --- a/src/mightypork/gamecore/gui/components/VisualComponent.java +++ b/src/mightypork/gamecore/gui/components/VisualComponent.java @@ -70,7 +70,9 @@ public abstract class VisualComponent extends AbstractRectCache implements Compo @Override public final void onLayoutChanged() { - if (source == null) throw new NullPointerException("Component is missing a bounding rect."); + if (getRect() == null) { + throw new NullPointerException("Component is missing a bounding rect."); + } poll(); } diff --git a/src/mightypork/gamecore/gui/components/layout/GridLayout.java b/src/mightypork/gamecore/gui/components/layout/GridLayout.java index db21534..945655b 100644 --- a/src/mightypork/gamecore/gui/components/layout/GridLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/GridLayout.java @@ -65,11 +65,11 @@ public class GridLayout extends LayoutComponent { /** * Put with span * + * @param elem * @param row * @param column * @param rowspan * @param colspan - * @param elem */ public void put(Component elem, int row, int column, int rowspan, int colspan) { diff --git a/src/mightypork/gamecore/gui/components/layout/HorizontalFixedFlowLayout.java b/src/mightypork/gamecore/gui/components/layout/HorizontalFixedFlowLayout.java index 28c40a0..cde7ea2 100644 --- a/src/mightypork/gamecore/gui/components/layout/HorizontalFixedFlowLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/HorizontalFixedFlowLayout.java @@ -18,7 +18,7 @@ import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound; public class HorizontalFixedFlowLayout extends LayoutComponent { private int col = 0; - private final Num colWidth; + private Num elementWidth; private final AlignX align; @@ -31,7 +31,7 @@ public class HorizontalFixedFlowLayout extends LayoutComponent { public HorizontalFixedFlowLayout(AppAccess app, RectBound context, Num elementWidth, AlignX align) { super(app, context); - this.colWidth = elementWidth; + this.elementWidth = elementWidth; this.align = align; if (align != AlignX.LEFT && align != AlignX.RIGHT) { @@ -67,10 +67,10 @@ public class HorizontalFixedFlowLayout extends LayoutComponent { switch (align) { case LEFT: - r = leftEdge().growRight(colWidth).moveX(colWidth.mul(col++)); + r = leftEdge().growRight(elementWidth).moveX(elementWidth.mul(col++)); break; case RIGHT: - r = rightEdge().growLeft(colWidth).moveX(colWidth.mul(-(col++))); + r = rightEdge().growLeft(elementWidth).moveX(elementWidth.mul(-(col++))); break; default: throw new IllegalArgumentException("Bad align."); @@ -81,4 +81,10 @@ public class HorizontalFixedFlowLayout extends LayoutComponent { attach(elem); } + + public void setElementWidth(Num elementWidth) + { + this.elementWidth = elementWidth; + } + } diff --git a/src/mightypork/gamecore/gui/components/layout/VerticalFixedFlowLayout.java b/src/mightypork/gamecore/gui/components/layout/VerticalFixedFlowLayout.java index a7955e9..daf955f 100644 --- a/src/mightypork/gamecore/gui/components/layout/VerticalFixedFlowLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/VerticalFixedFlowLayout.java @@ -18,7 +18,7 @@ import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound; public class VerticalFixedFlowLayout extends LayoutComponent { private int row = 0; - private final Num rowHeight; + private Num elementHeight; private final AlignY align; @@ -31,7 +31,7 @@ public class VerticalFixedFlowLayout extends LayoutComponent { public VerticalFixedFlowLayout(AppAccess app, RectBound context, Num elementHeight, AlignY align) { super(app, context); - this.rowHeight = elementHeight; + this.elementHeight = elementHeight; this.align = align; if (align != AlignY.TOP && align != AlignY.BOTTOM) { @@ -67,10 +67,10 @@ public class VerticalFixedFlowLayout extends LayoutComponent { switch (align) { case TOP: - r = topEdge().growDown(rowHeight).moveY(rowHeight.mul(row++)); + r = topEdge().growDown(elementHeight).moveY(elementHeight.mul(row++)); break; case BOTTOM: - r = bottomEdge().growUp(rowHeight).moveY(rowHeight.mul(-(row++))); + r = bottomEdge().growUp(elementHeight).moveY(elementHeight.mul(-(row++))); break; default: throw new IllegalArgumentException("Bad align."); @@ -81,4 +81,9 @@ public class VerticalFixedFlowLayout extends LayoutComponent { attach(elem); } + + public void setElementHeight(Num elementHeight) + { + this.elementHeight = elementHeight; + } } diff --git a/src/mightypork/gamecore/gui/components/painters/TextPainter.java b/src/mightypork/gamecore/gui/components/painters/TextPainter.java index 7eb4cad..20df900 100644 --- a/src/mightypork/gamecore/gui/components/painters/TextPainter.java +++ b/src/mightypork/gamecore/gui/components/painters/TextPainter.java @@ -6,6 +6,7 @@ import mightypork.gamecore.gui.components.VisualComponent; import mightypork.gamecore.resources.fonts.FontRenderer; import mightypork.gamecore.resources.fonts.GLFont; import mightypork.gamecore.util.math.color.Color; +import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.strings.StringProvider; @@ -27,7 +28,7 @@ public class TextPainter extends VisualComponent { private StringProvider text; private boolean shadow; - private Color shadowColor = Color.BLACK; + private Color shadowColor = RGB.BLACK; private Vect shadowOffset = Vect.make(2, 2); @@ -36,7 +37,7 @@ public class TextPainter extends VisualComponent { */ public TextPainter(GLFont font) { - this(font, AlignX.LEFT, Color.WHITE); + this(font, AlignX.LEFT, RGB.WHITE); } diff --git a/src/mightypork/gamecore/render/Render.java b/src/mightypork/gamecore/render/Render.java index e3afe42..66bd8fb 100644 --- a/src/mightypork/gamecore/render/Render.java +++ b/src/mightypork/gamecore/render/Render.java @@ -11,6 +11,7 @@ import mightypork.gamecore.resources.textures.GLTexture; import mightypork.gamecore.resources.textures.TxQuad; import mightypork.gamecore.util.files.FileUtils; import mightypork.gamecore.util.math.color.Color; +import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.caching.RectDigest; import mightypork.gamecore.util.math.constraints.vect.Vect; @@ -432,7 +433,7 @@ public class Render { */ public static void quadTextured(Rect quad, TxQuad txquad) { - quadTextured(quad, txquad, Color.WHITE); + quadTextured(quad, txquad, RGB.WHITE); } diff --git a/src/mightypork/gamecore/resources/fonts/FontRenderer.java b/src/mightypork/gamecore/resources/fonts/FontRenderer.java index 446b08b..11e5a46 100644 --- a/src/mightypork/gamecore/resources/fonts/FontRenderer.java +++ b/src/mightypork/gamecore/resources/fonts/FontRenderer.java @@ -4,6 +4,7 @@ package mightypork.gamecore.resources.fonts; import mightypork.gamecore.gui.AlignX; import mightypork.gamecore.render.Render; import mightypork.gamecore.util.math.color.Color; +import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.vect.Vect; @@ -25,7 +26,7 @@ public class FontRenderer { */ public FontRenderer(GLFont font) { - this(font, Color.WHITE); + this(font, RGB.WHITE); } @@ -68,7 +69,10 @@ public class FontRenderer { private double getScale(double height) { - return height / font.getLineHeight(); + final double fontHeight = font.getLineHeight(); + final double usefulHeight = fontHeight - fontHeight * font.getTopDiscardRatio() - fontHeight * font.getBottomDiscardRatio(); + + return height / usefulHeight; } @@ -106,8 +110,10 @@ public class FontRenderer { { Render.pushMatrix(); - Render.translateXY(pos); - Render.scaleXY(getScale(height)); + final double sc = getScale(height); + + Render.translate(pos.x(), pos.y() - font.getTopDiscardRatio() * sc); + Render.scaleXY(sc); font.draw(text, color); diff --git a/src/mightypork/gamecore/resources/fonts/GLFont.java b/src/mightypork/gamecore/resources/fonts/GLFont.java index fba6ebb..f17557d 100644 --- a/src/mightypork/gamecore/resources/fonts/GLFont.java +++ b/src/mightypork/gamecore/resources/fonts/GLFont.java @@ -47,4 +47,13 @@ public interface GLFont { * @return specified font size */ int getFontSize(); + + + void setDiscardRatio(double top, double bottom); + + + double getTopDiscardRatio(); + + + double getBottomDiscardRatio(); } diff --git a/src/mightypork/gamecore/resources/fonts/impl/CachedFont.java b/src/mightypork/gamecore/resources/fonts/impl/CachedFont.java index de023a8..c084560 100644 --- a/src/mightypork/gamecore/resources/fonts/impl/CachedFont.java +++ b/src/mightypork/gamecore/resources/fonts/impl/CachedFont.java @@ -77,6 +77,10 @@ public class CachedFont implements GLFont { private final FilterMode filter; + private double discardTop; + + private double discardBottom; + /** * Make a font @@ -448,4 +452,25 @@ public class CachedFont implements GLFont { return Vect.make(getWidth(text), getLineHeight()); } + + @Override + public void setDiscardRatio(double top, double bottom) + { + discardTop = top; + discardBottom = bottom; + } + + + @Override + public double getTopDiscardRatio() + { + return discardTop; + } + + + @Override + public double getBottomDiscardRatio() + { + return discardBottom; + } } diff --git a/src/mightypork/gamecore/resources/fonts/impl/DeferredFont.java b/src/mightypork/gamecore/resources/fonts/impl/DeferredFont.java index 1a1e2ce..ae9b23b 100644 --- a/src/mightypork/gamecore/resources/fonts/impl/DeferredFont.java +++ b/src/mightypork/gamecore/resources/fonts/impl/DeferredFont.java @@ -44,6 +44,8 @@ public class DeferredFont extends DeferredResource implements GLFont { private String chars; private FilterMode filter; private boolean antialias; + private double discardTop; + private double discardBottom; /** @@ -208,4 +210,26 @@ public class DeferredFont extends DeferredResource implements GLFont { // this will have to suffice font = null; } + + + @Override + public void setDiscardRatio(double top, double bottom) + { + discardTop = top; + discardBottom = bottom; + } + + + @Override + public double getTopDiscardRatio() + { + return discardTop; + } + + + @Override + public double getBottomDiscardRatio() + { + return discardBottom; + } } diff --git a/src/mightypork/gamecore/util/math/color/Color.java b/src/mightypork/gamecore/util/math/color/Color.java index 75132fa..edb19cc 100644 --- a/src/mightypork/gamecore/util/math/color/Color.java +++ b/src/mightypork/gamecore/util/math/color/Color.java @@ -17,26 +17,6 @@ import mightypork.gamecore.util.math.constraints.num.Num; */ public abstract class Color { - public static final Color NONE = rgba(0, 0, 0, 0); - public static final Color SHADOW = rgba(0, 0, 0, 0.5); - - public static final Color WHITE = fromHex(0xFFFFFF); - public static final Color BLACK = fromHex(0x000000); - public static final Color DARK_GRAY = fromHex(0x808080); - public static final Color GRAY = rgb(0.5, 0.5, 0.5); - public static final Color LIGHT_GRAY = rgb(0.75, 0.75, 0.75); - - public static final Color RED = rgb(1, 0, 0); - public static final Color GREEN = rgb(0, 1, 0); - public static final Color BLUE = rgb(0, 0, 1); - - public static final Color YELLOW = rgb(1, 1, 0); - public static final Color MAGENTA = rgb(1, 0, 1); - public static final Color CYAN = rgb(0, 1, 1); - - public static final Color ORANGE = rgb(1, 0.78, 0); - public static final Color PINK = rgb(1, 0.68, 0.68); - private static final Stack alphaStack = new Stack<>(); private static volatile boolean alphaStackEnabled = true; diff --git a/src/mightypork/gamecore/util/math/color/pal/RGB.java b/src/mightypork/gamecore/util/math/color/pal/RGB.java index 36a84c8..ac81669 100644 --- a/src/mightypork/gamecore/util/math/color/pal/RGB.java +++ b/src/mightypork/gamecore/util/math/color/pal/RGB.java @@ -9,24 +9,35 @@ import mightypork.gamecore.util.math.color.Color; * * @author MightyPork */ -public interface RGB { +public class RGB { - Color WHITE = Color.fromHex(0xFFFFFF); - Color BLACK = Color.fromHex(0x000000); - Color GRAY_DARK = Color.fromHex(0x808080); - Color GRAY = Color.fromHex(0xA0A0A0); - Color GRAY_LIGHT = Color.fromHex(0xC0C0C0); + public static final Color BLACK_10 = Color.rgba(0, 0, 0, 0.1); + public static final Color BLACK_20 = Color.rgba(0, 0, 0, 0.2); + public static final Color BLACK_30 = Color.rgba(0, 0, 0, 0.3); + public static final Color BLACK_40 = Color.rgba(0, 0, 0, 0.4); + public static final Color BLACK_50 = Color.rgba(0, 0, 0, 0.5); + public static final Color BLACK_60 = Color.rgba(0, 0, 0, 0.6); + public static final Color BLACK_70 = Color.rgba(0, 0, 0, 0.7); + public static final Color BLACK_80 = Color.rgba(0, 0, 0, 0.8); + public static final Color BLACK_90 = Color.rgba(0, 0, 0, 0.9); - Color RED = Color.fromHex(0xFF0000); - Color GREEN = Color.fromHex(0x00FF00); - Color BLUE = Color.fromHex(0x0000FF); - Color YELLOW = Color.fromHex(0xFFFF00); - Color CYAN = Color.fromHex(0x00FFFF); - Color MAGENTA = Color.fromHex(0xFF00FF); + public static final Color WHITE = Color.fromHex(0xFFFFFF); + public static final Color BLACK = Color.fromHex(0x000000); + public static final Color GRAY_DARK = Color.fromHex(0x808080); + public static final Color GRAY = Color.fromHex(0xA0A0A0); + public static final Color GRAY_LIGHT = Color.fromHex(0xC0C0C0); - Color PINK = Color.fromHex(0xFF3FFC); - Color ORANGE = Color.fromHex(0xFC4800); + public static final Color RED = Color.fromHex(0xFF0000); + public static final Color GREEN = Color.fromHex(0x00FF00); + public static final Color BLUE = Color.fromHex(0x0000FF); - Color NONE = Color.NONE; + public static final Color YELLOW = Color.fromHex(0xFFFF00); + public static final Color CYAN = Color.fromHex(0x00FFFF); + public static final Color MAGENTA = Color.fromHex(0xFF00FF); + + public static final Color PINK = Color.fromHex(0xFF3FFC); + public static final Color ORANGE = Color.fromHex(0xFC4800); + + public static final Color NONE = Color.rgba(0, 0, 0, 0); } diff --git a/src/mightypork/rogue/App.java b/src/mightypork/rogue/App.java index 7502336..9c6eaee 100644 --- a/src/mightypork/rogue/App.java +++ b/src/mightypork/rogue/App.java @@ -130,7 +130,7 @@ public final class App extends BaseApp { bindEventToKey(new CrossfadeRequest(null), Keys.L_CONTROL, Keys.Q); - bindEventToKey(new CrossfadeRequest("menu"), Keys.ESCAPE); + bindEventToKey(new CrossfadeRequest("menu"), Keys.L_CONTROL, Keys.M); } diff --git a/src/mightypork/rogue/Res.java b/src/mightypork/rogue/Res.java index 2684de5..8f57b4a 100644 --- a/src/mightypork/rogue/Res.java +++ b/src/mightypork/rogue/Res.java @@ -49,14 +49,17 @@ public final class Res { private static void loadFonts() { - fonts.loadFont("polygon_pixel", new DeferredFont("/res/font/PolygonPixel5x7Standard.ttf", Glyphs.basic, 16)); - fonts.loadFont("press_start", new DeferredFont("/res/font/PressStart2P.ttf", Glyphs.basic, 16)); + DeferredFont font; + + //fonts.loadFont("polygon_pixel", new DeferredFont("/res/font/PolygonPixel5x7Standard.ttf", Glyphs.basic, 16)); + fonts.loadFont("press_start", font = new DeferredFont("/res/font/PressStart2P.ttf", Glyphs.basic, 16)); + fonts.loadFont("polygon_pixel", font = new DeferredFont("/res/font/Simpleton.ttf", Glyphs.basic, 16)); + font.setDiscardRatio(5 / 16D, 2 / 16D); // aliases based on concrete usage - fonts.addAlias("default", "polygon_pixel"); - fonts.addAlias("main_menu_button", "press_start"); - fonts.addAlias("main_menu_title", "press_start"); - fonts.addAlias("hud", "press_start"); + fonts.addAlias("thick", "press_start"); + + fonts.addAlias("thin", "polygon_pixel"); } @@ -88,6 +91,12 @@ public final class Res { textures.add("nav.button.fg.attack", grid.makeQuad(2, 6)); textures.add("nav.button.fg.options", grid.makeQuad(3, 6)); textures.add("nav.button.fg.help", grid.makeQuad(4, 6)); + textures.add("nav.button.fg.map", grid.makeQuad(5, 6)); + textures.add("nav.button.fg.pause", grid.makeQuad(6, 6)); + textures.add("nav.button.fg.magnify", grid.makeQuad(7, 6)); + + textures.add("inv.slot.base", grid.makeQuad(0, 5)); + textures.add("inv.slot.selected", grid.makeQuad(1, 5)); // sprites diff --git a/src/mightypork/rogue/screens/FpsOverlay.java b/src/mightypork/rogue/screens/FpsOverlay.java index ef3dc94..40769b1 100644 --- a/src/mightypork/rogue/screens/FpsOverlay.java +++ b/src/mightypork/rogue/screens/FpsOverlay.java @@ -9,7 +9,7 @@ import mightypork.gamecore.gui.screens.Overlay; import mightypork.gamecore.input.KeyStroke; import mightypork.gamecore.input.Keys; import mightypork.gamecore.resources.fonts.GLFont; -import mightypork.gamecore.util.math.color.Color; +import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.constraints.num.Num; import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound; import mightypork.gamecore.util.math.constraints.vect.Vect; @@ -38,12 +38,12 @@ public class FpsOverlay extends Overlay { } }); - final GLFont font = Res.getFont("default"); + final GLFont font = Res.getFont("thin"); final Num h = root.height(); - final RectBound constraint = root.shrink(h.perc(3)).topRight().startRect().growDown(h.perc(8).max(32)); + final RectBound constraint = root.shrink(h.perc(3)).topRight().startRect().growDown(h.perc(5).max(16)); - tp = new TextPainter(font, AlignX.RIGHT, Color.WHITE, new StringProvider() { + tp = new TextPainter(font, AlignX.RIGHT, RGB.WHITE, new StringProvider() { @Override public String getString() @@ -53,7 +53,7 @@ public class FpsOverlay extends Overlay { }); tp.setRect(constraint); - tp.setShadow(Color.BLACK, Vect.make(tp.height().div(16).round())); + tp.setShadow(RGB.BLACK, Vect.make(tp.height().div(8).round())); root.add(tp); diff --git a/src/mightypork/rogue/screens/game/HudLayer.java b/src/mightypork/rogue/screens/game/HudLayer.java index d4c8233..eb1bc99 100644 --- a/src/mightypork/rogue/screens/game/HudLayer.java +++ b/src/mightypork/rogue/screens/game/HudLayer.java @@ -3,15 +3,13 @@ package mightypork.rogue.screens.game; import mightypork.gamecore.gui.AlignX; 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.rect.Rect; import mightypork.gamecore.util.strings.StringProvider; import mightypork.rogue.Res; +import mightypork.rogue.world.World; import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.gui.Minimap; @@ -36,27 +34,21 @@ public class HudLayer extends ScreenLayer { } }; - private Minimap mm; + protected Minimap mm; + private final ScreenGame gameScreen; - public HudLayer(Screen screen) + + public HudLayer(ScreenGame screen) { super(screen); + this.gameScreen = screen; buildNav(); buildDisplays(); buildMinimap(); - - bindKey(new KeyStroke(Keys.M), new Runnable() { - - @Override - public void run() - { - mm.setVisible(!mm.isVisible()); - } - }); } @@ -90,12 +82,13 @@ public class HudLayer extends ScreenLayer { root.add(hearts); - final TextPainter lvl = new TextPainter(Res.getFont("hud"), AlignX.RIGHT, RGB.WHITE, new StringProvider() { + final TextPainter lvl = new TextPainter(Res.getFont("thick"), AlignX.RIGHT, RGB.WHITE, new StringProvider() { @Override public String getString() { - return "Floor " + (1 + WorldProvider.get().getWorld().getPlayer().getLevelNumber()); + final World w = WorldProvider.get().getWorld(); + return (w.isPaused() ? "[P] " : "") + "Floor " + (1 + w.getPlayer().getLevelNumber()); } }); @@ -117,14 +110,27 @@ public class HudLayer extends ScreenLayer { nav.setRect(root.bottomEdge().growUp(root.height().perc(12))); root.add(nav); + NavButton btn; + // ltr - nav.addLeft(new NavButton(Res.txq("nav.button.fg.inventory"))); - nav.addLeft(new NavButton(Res.txq("nav.button.fg.eat"))); - nav.addLeft(new NavButton(Res.txq("nav.button.fg.attack"))); + nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.inventory"))); + btn.setAction(gameScreen.actionInv); + + nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.eat"))); + btn.setAction(gameScreen.actionEat); - // rtl + nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.pause"))); + btn.setAction(gameScreen.actionTogglePause); + + // TODO actions nav.addRight(new NavButton(Res.txq("nav.button.fg.options"))); nav.addRight(new NavButton(Res.txq("nav.button.fg.help"))); + + nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.map"))); + btn.setAction(gameScreen.actionToggleMinimap); + + nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.magnify"))); + btn.setAction(gameScreen.actionToggleZoom); } diff --git a/src/mightypork/rogue/screens/game/InvLayer.java b/src/mightypork/rogue/screens/game/InvLayer.java new file mode 100644 index 0000000..243f2df --- /dev/null +++ b/src/mightypork/rogue/screens/game/InvLayer.java @@ -0,0 +1,197 @@ +package mightypork.rogue.screens.game; + + +import mightypork.gamecore.gui.AlignX; +import mightypork.gamecore.gui.components.layout.ConstraintLayout; +import mightypork.gamecore.gui.components.layout.GridLayout; +import mightypork.gamecore.gui.components.layout.HorizontalFixedFlowLayout; +import mightypork.gamecore.gui.components.painters.QuadPainter; +import mightypork.gamecore.gui.components.painters.TextPainter; +import mightypork.gamecore.gui.screens.ScreenLayer; +import mightypork.gamecore.input.KeyStroke; +import mightypork.gamecore.input.Keys; +import mightypork.gamecore.util.math.color.Color; +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.Res; +import mightypork.rogue.screens.game.ScreenGame.GScrState; +import mightypork.rogue.world.World.PlayerFacade; +import mightypork.rogue.world.WorldProvider; +import mightypork.rogue.world.item.Item; +import mightypork.rogue.world.item.ItemType; + + +public class InvLayer extends ScreenLayer { + + private final StringProvider contextStrProv = new StringProvider() { + + @Override + public String getString() + { + String s = "Esc - close"; + + final int selected = getSelectedSlot(); + if (selected != -1) { + + final PlayerFacade pl = WorldProvider.get().getPlayer(); + + final Item itm = pl.getInventory().getItem(selected); + if (itm != null && !itm.isEmpty()) { + s = "D - drop, " + s; + + if (itm.getType() == ItemType.FOOD) { + s = "E - eat, " + s; + } + + if (itm.getType() == ItemType.WEAPON) { + s = "E - equip, " + s; + } + } + } + + return s; + } + }; + + private final InvSlot[] slots = new InvSlot[8]; + + + private int getSelectedSlot() + { + for (final InvSlot sl : slots) { + if (sl.selected) { + // stuff + return sl.index; + } + } + return -1; + } + + + public InvLayer(final ScreenGame screen) + { + super(screen); + + final Rect fg = root.shrink(root.height().perc(15)); + + final QuadPainter qp = new QuadPainter(Color.rgba(0, 0, 0, 0.5)); + qp.setRect(root); + root.add(qp); + + int pos = 0; + + final GridLayout gl = new GridLayout(root, fg, 21, 1); + root.add(gl); + + final TextPainter txp = new TextPainter(Res.getFont("thick"), AlignX.CENTER, RGB.YELLOW, "Inventory"); + gl.put(txp, pos, 0, 2, 1); + pos += 3; + + final HorizontalFixedFlowLayout row1 = new HorizontalFixedFlowLayout(root, null, AlignX.LEFT); + row1.setElementWidth(row1.height()); + final ConstraintLayout cl1 = new ConstraintLayout(root); + row1.setRect(cl1.axisV().grow(cl1.height().mul(2), Num.ZERO)); + cl1.add(row1); + + gl.put(cl1, pos, 0, 8, 1); + pos += 8; + + row1.add(slots[0] = new InvSlot(0, slots)); + row1.add(slots[1] = new InvSlot(1, slots)); + row1.add(slots[2] = new InvSlot(2, slots)); + row1.add(slots[3] = new InvSlot(3, slots)); + + + final HorizontalFixedFlowLayout row2 = new HorizontalFixedFlowLayout(root, null, AlignX.LEFT); + row2.setElementWidth(row2.height()); + final ConstraintLayout cl2 = new ConstraintLayout(root); + row2.setRect(cl2.axisV().grow(cl2.height().mul(2), Num.ZERO)); + cl2.add(row2); + gl.put(cl2, pos, 0, 8, 1); + pos += 8; + + row2.add(slots[4] = new InvSlot(4, slots)); + row2.add(slots[5] = new InvSlot(5, slots)); + row2.add(slots[6] = new InvSlot(6, slots)); + row2.add(slots[7] = new InvSlot(7, slots)); + + final TextPainter txp2 = new TextPainter(Res.getFont("thin"), AlignX.CENTER, RGB.WHITE, contextStrProv); + gl.put(txp2, pos + 1, 0, 1, 1); + + setVisible(false); + + bindKey(new KeyStroke(Keys.ESCAPE), new Runnable() { + + @Override + public void run() + { + if (!isVisible()) return; + + screen.setState(GScrState.WORLD); + } + }); + + bindKey(new KeyStroke(Keys.E), new Runnable() { + + @Override + public void run() + { + if (!isVisible()) return; + + final int selected = getSelectedSlot(); + if (selected != -1) { + final PlayerFacade pl = WorldProvider.get().getPlayer(); + final Item itm = pl.getInventory().getItem(selected); + if (itm != null && !itm.isEmpty()) { + + if (itm.getType() == ItemType.FOOD) { + if (pl.eatFood(itm)) { + if (itm.consume()) { + pl.getInventory().setItem(selected, null); + } + } + } + + if (itm.getType() == ItemType.WEAPON) { + pl.selectWeapon(selected); + } + } + } + } + }); + + bindKey(new KeyStroke(Keys.D), new Runnable() { + + @Override + public void run() + { + if (!isVisible()) return; + + final int selected = getSelectedSlot(); + if (selected != -1) { + final PlayerFacade pl = WorldProvider.get().getPlayer(); + final Item itm = pl.getInventory().getItem(selected); + if (itm != null && !itm.isEmpty()) { + + final Item piece = itm.split(1); + if (itm.isEmpty()) pl.getInventory().setItem(selected, null); + + if (!pl.getLevel().getTile(pl.getCoord()).dropItem(piece)) { + pl.getInventory().addItem(piece); // add back + } + } + } + } + }); + } + + + @Override + public int getZIndex() + { + return 200; + } + +} diff --git a/src/mightypork/rogue/screens/game/InvSlot.java b/src/mightypork/rogue/screens/game/InvSlot.java new file mode 100644 index 0000000..9247872 --- /dev/null +++ b/src/mightypork/rogue/screens/game/InvSlot.java @@ -0,0 +1,118 @@ +package mightypork.rogue.screens.game; + + +import mightypork.gamecore.gui.Action; +import mightypork.gamecore.gui.AlignX; +import mightypork.gamecore.gui.components.ClickableComponent; +import mightypork.gamecore.gui.components.painters.TextPainter; +import mightypork.gamecore.render.Render; +import mightypork.gamecore.resources.textures.TxQuad; +import mightypork.gamecore.util.math.color.pal.RGB; +import mightypork.gamecore.util.math.constraints.rect.caching.RectCache; +import mightypork.rogue.Res; +import mightypork.rogue.world.World.PlayerFacade; +import mightypork.rogue.world.WorldProvider; +import mightypork.rogue.world.item.Item; + + +/** + * Button in the ingame nav + * + * @author MightyPork + */ +public class InvSlot extends ClickableComponent { + + private final TxQuad txBase, txSelected; + + protected boolean selected = false; + protected int index; + + private final RectCache itemRect; + + private final InvSlot[] slots; + + private final TextPainter txt; + + private final RectCache txtRect; + + + public InvSlot(int index, InvSlot[] allSlots) + { + super(); + this.txBase = Res.txq("inv.slot.base"); + this.txSelected = Res.txq("inv.slot.selected"); + + this.index = index; + this.slots = allSlots; + + this.itemRect = getRect().shrink(height().perc(16)).cached(); + + //@formatter:off + this.txtRect = itemRect.bottomEdge() + .move(itemRect.height().perc(5).neg(), itemRect.height().perc(10).neg()) + .growUp(itemRect.height().perc(35)).cached(); + //@formatter:on + + txt = new TextPainter(Res.getFont("thin"), AlignX.RIGHT, RGB.WHITE); + txt.setRect(txtRect); + txt.setShadow(RGB.BLACK_60, txt.getRect().height().div(8).toVectXY()); + + setAction(new Action() { + + @Override + protected void execute() + { + for (final InvSlot sl : slots) { + sl.selected = false; + } + + selected = true; + } + + }); + } + + + @Override + public void updateLayout() + { + itemRect.poll(); + txtRect.poll(); + } + + + @Override + protected void renderComponent() + { + TxQuad bg; + + if (selected) { + bg = txSelected; + } else { + bg = txBase; + } + + Render.quadTextured(this, bg); + + final PlayerFacade pl = WorldProvider.get().getPlayer(); + + final Item itm = pl.getInventory().getItem(index); + if (itm != null && !itm.isEmpty()) { + itm.render(itemRect); + if (itm.getAmount() > 1) { + txt.setText("" + itm.getAmount()); + txt.setColor(RGB.WHITE); + txt.render(); + } + + if (pl.getSelectedWeapon() == index) { + txt.setText("*"); + txt.setColor(RGB.YELLOW); + txt.render(); + } + + + } + } + +} diff --git a/src/mightypork/rogue/screens/game/ScreenGame.java b/src/mightypork/rogue/screens/game/ScreenGame.java index bb43efa..da2fae2 100644 --- a/src/mightypork/rogue/screens/game/ScreenGame.java +++ b/src/mightypork/rogue/screens/game/ScreenGame.java @@ -4,26 +4,131 @@ package mightypork.rogue.screens.game; import java.util.Random; import mightypork.gamecore.app.AppAccess; +import mightypork.gamecore.gui.Action; +import mightypork.gamecore.gui.ActionGroup; import mightypork.gamecore.gui.screens.LayeredScreen; import mightypork.gamecore.input.KeyStroke; import mightypork.gamecore.input.Keys; import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.events.WorldPauseRequest; +import mightypork.rogue.world.events.WorldPauseRequest.PauseAction; public class ScreenGame extends LayeredScreen { + /** + * Game gui state. + * + * @author MightyPork + */ + public enum GScrState + { + WORLD, INV; + } + private final Random rand = new Random(); + private InvLayer invLayer; + private HudLayer hudLayer; + + private GScrState state = GScrState.WORLD; + + private final ActionGroup worldActions = new ActionGroup(); + + public Action actionEat = new Action() { + + @Override + public void execute() + { + WorldProvider.get().getPlayer().tryToEatSomeFood(); + } + }; + + public Action actionInv = new Action() { + + @Override + public void execute() + { + setState(GScrState.INV); + } + }; + + public Action actionToggleMinimap = new Action() { + + @Override + public void execute() + { + hudLayer.mm.setVisible(!hudLayer.mm.isVisible()); + } + }; + + public Action actionTogglePause = new Action() { + + @Override + public void execute() + { + getEventBus().send(new WorldPauseRequest(PauseAction.TOGGLE)); + } + }; + + public Action actionToggleZoom = new Action() { + + @Override + public void execute() + { + worldLayer.map.toggleMag(); + } + }; + + private WorldLayer worldLayer; + + + /** + * Set gui state (overlay) + * + * @param nstate new state + */ + public void setState(GScrState nstate) + { + if (this.state == nstate) return; + + if (nstate != GScrState.WORLD) { // leaving world. + getEventBus().send(new WorldPauseRequest(PauseAction.PAUSE)); + + worldActions.enable(false); // disable world actions + } + + if (nstate == GScrState.WORLD) { + getEventBus().send(new WorldPauseRequest(PauseAction.RESUME)); + + invLayer.setVisible(false); // hide all extra layers + + worldActions.enable(true); + } + + if (nstate == GScrState.INV) { + invLayer.setVisible(true); + } + + this.state = nstate; + } + + + public GScrState getState() + { + return state; + } public ScreenGame(AppAccess app) { super(app); - addLayer(new HudLayer(this)); - addLayer(new WorldLayer(this)); + addLayer(invLayer = new InvLayer(this)); + addLayer(hudLayer = new HudLayer(this)); + addLayer(worldLayer = new WorldLayer(this)); + // TODO temporary here ↓ bindKey(new KeyStroke(Keys.L_CONTROL, Keys.N), new Runnable() { @Override @@ -33,18 +138,22 @@ public class ScreenGame extends LayeredScreen { } }); - final Runnable pauseIt = new Runnable() { - - @Override - public void run() - { - getEventBus().send(new WorldPauseRequest()); - } - }; - //pause key - bindKey(new KeyStroke(Keys.P), pauseIt); - bindKey(new KeyStroke(Keys.PAUSE), pauseIt); + bindKey(new KeyStroke(Keys.P), actionTogglePause); + bindKey(new KeyStroke(Keys.PAUSE), actionTogglePause); + + bindKey(new KeyStroke(Keys.I), actionInv); + bindKey(new KeyStroke(Keys.E), actionEat); + bindKey(new KeyStroke(Keys.M), actionToggleMinimap); + bindKey(new KeyStroke(Keys.Z), actionToggleZoom); + + worldActions.add(actionEat); + worldActions.add(actionInv); + worldActions.add(actionToggleMinimap); + worldActions.add(actionTogglePause); + worldActions.add(actionToggleZoom); + + worldActions.enable(true); } diff --git a/src/mightypork/rogue/screens/game/WorldLayer.java b/src/mightypork/rogue/screens/game/WorldLayer.java index 5ad645c..a84bef0 100644 --- a/src/mightypork/rogue/screens/game/WorldLayer.java +++ b/src/mightypork/rogue/screens/game/WorldLayer.java @@ -11,7 +11,7 @@ import mightypork.rogue.world.gui.interaction.MIPMouse; public class WorldLayer extends ScreenLayer { - private final MapView worldView; + protected final MapView map; public WorldLayer(Screen screen) @@ -20,17 +20,17 @@ public class WorldLayer extends ScreenLayer { // render component - worldView = new MapView(); + map = new MapView(); // map input plugins - worldView.addPlugin(new MIPKeyboard(worldView)); - worldView.addPlugin(new MIPMouse(worldView)); + map.addPlugin(new MIPKeyboard(map)); + map.addPlugin(new MIPMouse(map)); // size of lower navbar final Num lownav = root.height().perc(12); - worldView.setRect(root.shrinkBottom(lownav)); + map.setRect(root.shrinkBottom(lownav)); - root.add(worldView); + root.add(map); } diff --git a/src/mightypork/rogue/screens/menu/MenuButton.java b/src/mightypork/rogue/screens/menu/MenuButton.java index e4b5c68..fd0842e 100644 --- a/src/mightypork/rogue/screens/menu/MenuButton.java +++ b/src/mightypork/rogue/screens/menu/MenuButton.java @@ -7,6 +7,7 @@ import mightypork.gamecore.gui.components.painters.TextPainter; import mightypork.gamecore.input.InputSystem; import mightypork.gamecore.resources.fonts.GLFont; import mightypork.gamecore.util.math.color.Color; +import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.math.constraints.vect.mutable.VectVar; import mightypork.rogue.Res; @@ -14,7 +15,7 @@ import mightypork.rogue.Res; class MenuButton extends ClickableComponent { - private static GLFont font = Res.getFont("main_menu_button"); + private static GLFont font = Res.getFont("thick"); private final TextPainter painter; private final VectVar offset = Vect.makeVar(); @@ -30,7 +31,7 @@ class MenuButton extends ClickableComponent { this.painter = new TextPainter(font, AlignX.CENTER, this.color, text); this.painter.setRect(this); - this.painter.setShadow(Color.BLACK.withAlpha(0.3), offset); + this.painter.setShadow(RGB.BLACK_30, offset); } diff --git a/src/mightypork/rogue/screens/menu/MenuLayer.java b/src/mightypork/rogue/screens/menu/MenuLayer.java index 3a54c54..c6131c6 100644 --- a/src/mightypork/rogue/screens/menu/MenuLayer.java +++ b/src/mightypork/rogue/screens/menu/MenuLayer.java @@ -29,7 +29,7 @@ class MenuLayer extends ScreenLayer { { 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, 14, 1); + final GridLayout layout = new GridLayout(root, menuBox, 11, 1); layout.enableCaching(true); final QuadPainter bg = QuadPainter.gradV(Color.fromHex(0x007eb3), PAL16.SEABLUE); @@ -60,7 +60,7 @@ class MenuLayer extends ScreenLayer { layout.put(btn, r, 0, 2, 1); r += 3; - + /* // bouncy text button btn = new MenuButton("Bouncy", PAL16.CLOUDBLUE); btn.setAction(new Action() { @@ -73,7 +73,7 @@ class MenuLayer extends ScreenLayer { }); layout.put(btn, r, 0, 2, 1); r += 3; - + */ // quit button btn = new MenuButton("Bye!", PAL16.BLOODRED); diff --git a/src/mightypork/rogue/screens/test_bouncyboxes/BouncyBox.java b/src/mightypork/rogue/screens/test_bouncyboxes/BouncyBox.java index feef5f8..48c9817 100644 --- a/src/mightypork/rogue/screens/test_bouncyboxes/BouncyBox.java +++ b/src/mightypork/rogue/screens/test_bouncyboxes/BouncyBox.java @@ -7,7 +7,7 @@ import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.gui.components.VisualComponent; import mightypork.gamecore.render.Render; import mightypork.gamecore.util.math.Easing; -import mightypork.gamecore.util.math.color.Color; +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; @@ -41,7 +41,7 @@ public class BouncyBox extends VisualComponent implements Updateable { @Override public void renderComponent() { - Render.quad(box, Color.GREEN); + Render.quad(box, RGB.GREEN); } diff --git a/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java b/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java index 4366279..2d63bd6 100644 --- a/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java +++ b/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java @@ -11,7 +11,7 @@ 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.Color; +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; @@ -55,10 +55,10 @@ public class LayerBouncyBoxes extends ScreenLayer { boxes.add(bbr); } - final TextPainter tp = new TextPainter(Res.getFont("default"), AlignX.LEFT, Color.WHITE); + 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(Color.RED, Vect.make(shadowOffset, shadowOffset)); + tp.setShadow(RGB.RED, Vect.make(shadowOffset, shadowOffset)); layout.add(tp); } diff --git a/src/mightypork/rogue/world/PlayerControl.java b/src/mightypork/rogue/world/PlayerControl.java index 4ef9aee..54d9db0 100644 --- a/src/mightypork/rogue/world/PlayerControl.java +++ b/src/mightypork/rogue/world/PlayerControl.java @@ -117,7 +117,6 @@ public abstract class PlayerControl { } //2nd try to click tile - System.out.println("do click: " + Coord.fromVect(pos)); return getLevel().getTile(Coord.fromVect(pos)).onClick(); } diff --git a/src/mightypork/rogue/world/PlayerInfo.java b/src/mightypork/rogue/world/PlayerInfo.java index c87aa4c..9cdb72c 100644 --- a/src/mightypork/rogue/world/PlayerInfo.java +++ b/src/mightypork/rogue/world/PlayerInfo.java @@ -91,10 +91,22 @@ public class PlayerInfo implements IonObjBundled { } - public Item getEquippedWeapon() + public int getSelectedWeaponIndex() + { + return selectedWeapon; + } + + + public Item getSelectedWeapon() { if (selectedWeapon == NO_WEAPON) return null; return inventory.getItem(selectedWeapon); } + + public void selectWeapon(int selectedWeapon) + { + this.selectedWeapon = selectedWeapon; + } + } diff --git a/src/mightypork/rogue/world/World.java b/src/mightypork/rogue/world/World.java index 153e016..ddee98a 100644 --- a/src/mightypork/rogue/world/World.java +++ b/src/mightypork/rogue/world/World.java @@ -18,6 +18,7 @@ import mightypork.gamecore.util.math.timing.Pauseable; import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.item.Item; +import mightypork.rogue.world.item.ItemType; import mightypork.rogue.world.level.Level; @@ -171,20 +172,62 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea public int getAttackStrength() { - final Item weapon = playerInfo.getEquippedWeapon(); + final Item weapon = playerInfo.getSelectedWeapon(); if (weapon == null) return PlayerInfo.BARE_ATTACK; return Math.min(weapon.getAttackPoints(), playerInfo.BARE_ATTACK); } + + public boolean eatFood(Item itm) + { + if (itm == null || itm.isEmpty() || itm.getType() != ItemType.FOOD) return false; + + if (getHealth() < getHealthMax()) { + + playerEntity.health.addHealth(itm.getFoodPoints()); + + return true; + } + + + return false; + } + + + public void selectWeapon(int selected) + { + playerInfo.selectWeapon(selected); + } + + + public int getSelectedWeapon() + { + return playerInfo.getSelectedWeaponIndex(); + } + + + public void tryToEatSomeFood() + { + for (int i = 0; i < getInventory().getSize(); i++) { + final Item itm = getInventory().getItem(i); + if (itm == null || itm.isEmpty()) continue; + + final Item slice = itm.split(1); + if (!eatFood(slice)) itm.addItem(slice); + if (itm.isEmpty()) getInventory().setItem(i, null); + return; + } + } + } // not saved stuffs private final PlayerFacade player = new PlayerFacade(); private Entity playerEntity; private BusAccess bus; - private boolean paused; + private int pauseDepth = 0; private final ArrayList levels = new ArrayList<>(); @@ -209,7 +252,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea @Override public boolean doesDelegate() { - return !paused; + return !isPaused(); } @@ -324,21 +367,21 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea @Override public void pause() { - paused = true; + pauseDepth++; } @Override public void resume() { - paused = false; + if (pauseDepth > 0) pauseDepth--; } @Override public boolean isPaused() { - return paused; + return pauseDepth > 0; } diff --git a/src/mightypork/rogue/world/entity/entities/RatEntity.java b/src/mightypork/rogue/world/entity/entities/RatEntity.java index 898a45a..93ace9f 100644 --- a/src/mightypork/rogue/world/entity/entities/RatEntity.java +++ b/src/mightypork/rogue/world/entity/entities/RatEntity.java @@ -71,11 +71,16 @@ public class RatEntity extends Entity { public void onKilled() { super.onKilled(); - + } + + + @Override + public void onCorpseRemoved() + { // drop rat meat final Item meat = Items.MEAT.createItem(); - getLevel().getTile(getCoord()).dropItem(meat); + getLevel().dropNear(getCoord(), meat); } } diff --git a/src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java b/src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java index 2d26d79..007cf90 100644 --- a/src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java +++ b/src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java @@ -102,6 +102,12 @@ public class EntityModuleHealth extends EntityModule { } + public void addHealth(int healthPoints) + { + setHealth(health + healthPoints); + } + + public void fill() { setHealth(maxHealth); diff --git a/src/mightypork/rogue/world/events/WorldPauseRequest.java b/src/mightypork/rogue/world/events/WorldPauseRequest.java index 30980a5..d2ffa94 100644 --- a/src/mightypork/rogue/world/events/WorldPauseRequest.java +++ b/src/mightypork/rogue/world/events/WorldPauseRequest.java @@ -12,10 +12,36 @@ import mightypork.rogue.world.World; */ public class WorldPauseRequest extends BusEvent { + public static enum PauseAction + { + PAUSE, RESUME, TOGGLE; + } + + private final PauseAction op; + + + public WorldPauseRequest(PauseAction op) + { + super(); + this.op = op; + } + @Override protected void handleBy(World handler) { + if (op == PauseAction.PAUSE) { + handler.pause(); + return; + } + + if (op == PauseAction.RESUME) { + handler.resume(); + return; + } + + // else + // toggle paused state if (!handler.isPaused()) { handler.pause(); diff --git a/src/mightypork/rogue/world/gen/LevelGenerator.java b/src/mightypork/rogue/world/gen/LevelGenerator.java index 2c55f8d..dff8ee7 100644 --- a/src/mightypork/rogue/world/gen/LevelGenerator.java +++ b/src/mightypork/rogue/world/gen/LevelGenerator.java @@ -10,10 +10,7 @@ import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.gen.rooms.Rooms; import mightypork.rogue.world.gen.themes.ThemeBrick; -import mightypork.rogue.world.item.Item; -import mightypork.rogue.world.item.Items; import mightypork.rogue.world.level.Level; -import mightypork.rogue.world.tile.Tile; public class LevelGenerator { @@ -65,18 +62,18 @@ public class LevelGenerator { } } - for (int i = 0; i < 4 + complexity + rand.nextInt(1 + complexity); i++) { - - final Item meat = Items.MEAT.createItem(); - - for (int j = 0; j < 20; j++) { - pos.x = rand.nextInt(lvl.getWidth()); - pos.y = rand.nextInt(lvl.getHeight()); - - final Tile t = lvl.getTile(pos); - if (t.dropItem(meat)) break; - } - } +// for (int i = 0; i < 4 + complexity + rand.nextInt(1 + complexity); i++) { +// +// final Item meat = Items.MEAT.createItem(); +// +// for (int j = 0; j < 20; j++) { +// pos.x = rand.nextInt(lvl.getWidth()); +// pos.y = rand.nextInt(lvl.getHeight()); +// +// final Tile t = lvl.getTile(pos); +// if (t.dropItem(meat)) break; +// } +// } return lvl; diff --git a/src/mightypork/rogue/world/gen/ScratchMap.java b/src/mightypork/rogue/world/gen/ScratchMap.java index 1f9c622..cbbd0a4 100644 --- a/src/mightypork/rogue/world/gen/ScratchMap.java +++ b/src/mightypork/rogue/world/gen/ScratchMap.java @@ -149,16 +149,16 @@ public class ScratchMap { switch (rand.nextInt(4)) { case 0: - center.x += 1 + rand.nextInt(critical ? 6 : 4); + center.x += 1 + (failed_total / 50); break; case 1: - center.x -= 1 + rand.nextInt(critical ? 6 : 4); + center.x -= 1 + (failed_total / 50); break; case 2: - center.y += 1 + rand.nextInt(critical ? 6 : 4); + center.y += 1 + (failed_total / 50); break; case 3: - center.y -= 1 + rand.nextInt(critical ? 6 : 4); + center.y -= 1 + (failed_total / 50); } final RoomDesc rd = rb.buildToFit(this, theme, rand, center); @@ -173,14 +173,14 @@ public class ScratchMap { clampBounds(); nodes.add(center); - Log.f3("placed room: " + rd.min + " -> " + rd.max); +// Log.f3("placed room: " + rd.min + " -> " + rd.max); return; } else { failed++; failed_total++; - if (failed > 200) { + if (failed > 400) { Log.w("Faild to build room."); if (critical) { @@ -309,7 +309,7 @@ public class ScratchMap { public void buildCorridors() { - Log.f3("Building corridors."); +// Log.f3("Building corridors."); Coord start = nodes.get(0); final Set starts = new HashSet<>(); @@ -328,7 +328,7 @@ public class ScratchMap { private void buildCorridor(Coord node1, Coord node2) { - Log.f3("Building corridor " + node1 + " -> " + node2); +// Log.f3("Building corridor " + node1 + " -> " + node2); final List steps = pathf.findPath(node1, node2); if (steps == null) { @@ -539,7 +539,7 @@ public class ScratchMap { final Coord entrance = new Coord(enterPoint.x - genMin.x, enterPoint.y - genMin.y); level.setEnterPoint(entrance); - System.out.println("Entrance = " + entrance + ", original: " + enterPoint + ", minG=" + genMin + ", maxG=" + genMax); +// System.out.println("Entrance = " + entrance + ", original: " + enterPoint + ", minG=" + genMin + ", maxG=" + genMax); final Coord exit = new Coord(exitPoint.x - genMin.x, exitPoint.y - genMin.y); level.setExitPoint(exit); diff --git a/src/mightypork/rogue/world/gui/MapView.java b/src/mightypork/rogue/world/gui/MapView.java index 03d0398..937a4bc 100644 --- a/src/mightypork/rogue/world/gui/MapView.java +++ b/src/mightypork/rogue/world/gui/MapView.java @@ -8,9 +8,6 @@ import java.util.Set; import mightypork.gamecore.eventbus.clients.DelegatingClient; import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.gui.components.InputComponent; -import mightypork.gamecore.input.Keys; -import mightypork.gamecore.input.events.KeyEvent; -import mightypork.gamecore.input.events.KeyListener; import mightypork.gamecore.input.events.MouseButtonEvent; import mightypork.gamecore.input.events.MouseButtonListener; import mightypork.gamecore.render.Render; @@ -35,7 +32,7 @@ import mightypork.rogue.world.gui.interaction.MapInteractionPlugin; * * @author MightyPork */ -public class MapView extends InputComponent implements DelegatingClient, KeyListener, MouseButtonListener, Updateable, WorldAscendRequestListener, +public class MapView extends InputComponent implements DelegatingClient, MouseButtonListener, Updateable, WorldAscendRequestListener, WorldDescendRequestListener { private static final double transition_time = 0.8; @@ -152,20 +149,15 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList } - @Override - public void receive(KeyEvent event) + public void toggleMag() { - if (event.getKey() == Keys.Z && event.isDown()) { - if (zoom_in) { - zoom.fadeIn(); - zoom_in = false; - } else { - zoom.fadeOut(); - zoom_in = true; - } + if (zoom_in) { + zoom.fadeIn(); + zoom_in = false; + } else { + zoom.fadeOut(); + zoom_in = true; } - - // don't consume key events, can be useful for others. } diff --git a/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java b/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java index 6ba6b7a..d8b0d6b 100644 --- a/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java +++ b/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java @@ -17,6 +17,7 @@ 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 }; @@ -48,7 +49,7 @@ public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndLi if (evt.isDown() || mapView.plc.getPlayer().isMoving()) return; // not interested for (int i = 0; i < 4; i++) { - if (evt.getKey() == keys[i]) { + if (evt.getKey() == keys[i] || evt.getKey() == keys2[i]) { mapView.plc.clickTile(sides[i]); } } @@ -62,7 +63,7 @@ public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndLi if (mapView.plc.getPlayer().getMoveProgress() < 0.8) return false; for (int i = 0; i < 4; i++) { - if (InputSystem.isKeyDown(keys[i])) { + if (InputSystem.isKeyDown(keys[i]) || InputSystem.isKeyDown(keys2[i])) { final Step side = sides[i]; if (mapView.plc.canGo(side)) { diff --git a/src/mightypork/rogue/world/item/items/ItemMeat.java b/src/mightypork/rogue/world/item/items/ItemMeat.java index 24758c0..c4e74bf 100644 --- a/src/mightypork/rogue/world/item/items/ItemMeat.java +++ b/src/mightypork/rogue/world/item/items/ItemMeat.java @@ -25,7 +25,7 @@ public class ItemMeat extends ItemBaseFood { @Override public int getFoodPoints() { - return 4; + return 2; } } diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index 2c46622..5ef4c88 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -26,6 +26,7 @@ import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.EntityType; import mightypork.rogue.world.entity.entities.PlayerEntity; +import mightypork.rogue.world.item.Item; import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.Tiles; @@ -59,6 +60,8 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl } + private static final Random rand = new Random(); + public static final int ION_MARK = 53; private static final Comparator ENTITY_RENDER_CMP = new EntityRenderComparator(); @@ -277,6 +280,7 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl for (final Entity e : toRemove) { removeEntity(e); + e.onCorpseRemoved(); } } @@ -546,18 +550,12 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl Entity closest = null; double minDist = Double.MAX_VALUE; - if (type == EntityType.MONSTER) System.out.println("Finding entity in range " + radius + " of " + pos); - for (final Entity e : entityList) { if (e.isDead()) continue; if (e.getType() == type) { final double dist = e.pos.getVisualPos().dist(pos).value(); - if (type == EntityType.MONSTER && dist < radius * 2) { - System.out.println("Entity " + e + ", dist: " + dist + ", standing at: " + e.pos.getCoord() + ", visual: " + e.pos.getVisualPos()); - } - if (dist <= radius && dist < minDist) { minDist = dist; closest = e; @@ -656,4 +654,17 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl { return isListening(); } + + + public boolean dropNear(Coord coord, Item itm) + { + if (getTile(coord).dropItem(itm)) return true; + + for (int i = 0; i < 6; i++) { + final Coord c = coord.add(-1 + rand.nextInt(3), -1 + rand.nextInt(3)); + if (getTile(c).dropItem(itm)) return true; + } + + return false; + } } diff --git a/src/mightypork/rogue/world/tile/tiles/TileWithItems.java b/src/mightypork/rogue/world/tile/tiles/TileWithItems.java index c3ba64d..8e2bf3c 100644 --- a/src/mightypork/rogue/world/tile/tiles/TileWithItems.java +++ b/src/mightypork/rogue/world/tile/tiles/TileWithItems.java @@ -96,4 +96,20 @@ public abstract class TileWithItems extends Tile { { return !items.isEmpty(); } + + + @Override + public boolean onClick() + { + if (hasItem()) { + final Item item = pickItem(); + if (getWorld().getPlayer().getInventory().addItem(item)) { + // player picked item + } else { + dropItem(item); // put back. + } + return true; + } + return false; + } }