From 84ef9fb9fed5d9e6d485aece6121ec6ca5bd8f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sat, 26 Apr 2014 01:57:29 +0200 Subject: [PATCH] minimap! --- .../gui/components/InputComponent.java | 2 +- .../rogue/screens/gamescreen/HudLayer.java | 27 ++++- .../rogue/screens/gamescreen/ScreenGame.java | 9 +- .../rogue/screens/gamescreen/WorldLayer.java | 7 ++ .../gamescreen/world/MIPClickPathfWalk.java | 2 +- .../screens/gamescreen/world/Minimap.java | 106 ++++++++++++++++++ src/mightypork/rogue/world/Coord.java | 7 ++ src/mightypork/rogue/world/World.java | 1 + src/mightypork/rogue/world/WorldCreator.java | 2 +- .../world/entity/models/PlayerModel.java | 14 +++ .../rogue/world/gen/ScratchMap.java | 8 +- src/mightypork/rogue/world/level/Level.java | 19 ++++ src/mightypork/rogue/world/tile/Tile.java | 17 +-- src/mightypork/rogue/world/tile/TileData.java | 54 +++++++++ .../rogue/world/tile/TileModel.java | 10 +- .../world/tile/models/AbstractNullTile.java | 7 -- .../rogue/world/tile/models/AbstractTile.java | 7 -- .../rogue/world/tile/models/Floor.java | 12 ++ .../rogue/world/tile/models/NullTile.java | 11 ++ .../rogue/world/tile/models/SimpleDoor.java | 9 ++ .../rogue/world/tile/models/Wall.java | 11 ++ .../util/error/YouFuckedUpException.java | 29 +++++ src/mightypork/util/math/Calc.java | 6 + 23 files changed, 339 insertions(+), 38 deletions(-) create mode 100644 src/mightypork/rogue/screens/gamescreen/world/Minimap.java create mode 100644 src/mightypork/rogue/world/tile/TileData.java create mode 100644 src/mightypork/util/error/YouFuckedUpException.java diff --git a/src/mightypork/gamecore/gui/components/InputComponent.java b/src/mightypork/gamecore/gui/components/InputComponent.java index c69aa32..78c6142 100644 --- a/src/mightypork/gamecore/gui/components/InputComponent.java +++ b/src/mightypork/gamecore/gui/components/InputComponent.java @@ -20,7 +20,7 @@ public abstract class InputComponent extends VisualComponent implements Enableab @Override public boolean isEnabled() { - return enabled; + return enabled && isVisible(); } diff --git a/src/mightypork/rogue/screens/gamescreen/HudLayer.java b/src/mightypork/rogue/screens/gamescreen/HudLayer.java index 230c241..96cccf0 100644 --- a/src/mightypork/rogue/screens/gamescreen/HudLayer.java +++ b/src/mightypork/rogue/screens/gamescreen/HudLayer.java @@ -6,16 +6,20 @@ import mightypork.gamecore.gui.components.layout.HorizontalFixedFlowLayout; import mightypork.gamecore.gui.components.painters.ImagePainter; import mightypork.gamecore.gui.screens.Screen; import mightypork.gamecore.gui.screens.ScreenLayer; +import mightypork.gamecore.input.KeyStroke; +import mightypork.gamecore.input.Keys; import mightypork.rogue.Res; import mightypork.rogue.screens.gamescreen.gui.HeartBar; import mightypork.rogue.screens.gamescreen.gui.NavItemSlot; +import mightypork.rogue.screens.gamescreen.world.Minimap; +import mightypork.rogue.world.World; import mightypork.util.math.constraints.num.Num; import mightypork.util.math.constraints.rect.Rect; public class HudLayer extends ScreenLayer { - public HudLayer(Screen screen) + public HudLayer(Screen screen, World world) { super(screen); @@ -46,6 +50,20 @@ public class HudLayer extends ScreenLayer { final Rect xp_box = shrunk.topRight().startRect().growDown(displays_height); experience.setRect(xp_box); root.add(experience); + + + final Minimap mm = new Minimap(world); + mm.setRect(root.shrink(root.width().perc(5), root.height().perc(15))); + root.add(mm); + + bindKey(new KeyStroke(Keys.M), new Runnable() { + + @Override + public void run() + { + mm.setVisible(!mm.isVisible()); + } + }); } @@ -63,4 +81,11 @@ public class HudLayer extends ScreenLayer { super.render(); } + + @Override + public int getEventPriority() + { + return 100; + } + } diff --git a/src/mightypork/rogue/screens/gamescreen/ScreenGame.java b/src/mightypork/rogue/screens/gamescreen/ScreenGame.java index a0751a5..6b18bd3 100644 --- a/src/mightypork/rogue/screens/gamescreen/ScreenGame.java +++ b/src/mightypork/rogue/screens/gamescreen/ScreenGame.java @@ -15,12 +15,17 @@ import mightypork.util.files.ion.Ion; public class ScreenGame extends LayeredScreen { + private final World world; + + public ScreenGame(AppAccess app) { super(app); - addLayer(new WorldLayer(this, obtainWorld())); //TODO with provided world - addLayer(new HudLayer(this)); + this.world = obtainWorld(); + + addLayer(new WorldLayer(this, world)); + addLayer(new HudLayer(this, world)); } diff --git a/src/mightypork/rogue/screens/gamescreen/WorldLayer.java b/src/mightypork/rogue/screens/gamescreen/WorldLayer.java index 0c8e123..dd0bdb8 100644 --- a/src/mightypork/rogue/screens/gamescreen/WorldLayer.java +++ b/src/mightypork/rogue/screens/gamescreen/WorldLayer.java @@ -42,4 +42,11 @@ public class WorldLayer extends ScreenLayer { return -1; // stay down } + + @Override + public int getEventPriority() + { + return 0; + } + } diff --git a/src/mightypork/rogue/screens/gamescreen/world/MIPClickPathfWalk.java b/src/mightypork/rogue/screens/gamescreen/world/MIPClickPathfWalk.java index c8c9ac8..e728af0 100644 --- a/src/mightypork/rogue/screens/gamescreen/world/MIPClickPathfWalk.java +++ b/src/mightypork/rogue/screens/gamescreen/world/MIPClickPathfWalk.java @@ -9,7 +9,7 @@ import mightypork.util.math.constraints.vect.Vect; public class MIPClickPathfWalk implements MapInteractionPlugin { - private static final int BTN = 1; // right + private static final int BTN = 0; // left @Override diff --git a/src/mightypork/rogue/screens/gamescreen/world/Minimap.java b/src/mightypork/rogue/screens/gamescreen/world/Minimap.java new file mode 100644 index 0000000..3819662 --- /dev/null +++ b/src/mightypork/rogue/screens/gamescreen/world/Minimap.java @@ -0,0 +1,106 @@ +package mightypork.rogue.screens.gamescreen.world; + + +import mightypork.gamecore.control.events.input.MouseButtonEvent; +import mightypork.gamecore.control.events.input.MouseButtonListener; +import mightypork.gamecore.gui.components.InputComponent; +import mightypork.gamecore.render.Render; +import mightypork.rogue.world.Coord; +import mightypork.rogue.world.EntityPos; +import mightypork.rogue.world.World; +import mightypork.rogue.world.entity.Entity; +import mightypork.rogue.world.level.Level; +import mightypork.rogue.world.tile.Tile; +import mightypork.util.math.color.Color; +import mightypork.util.math.constraints.rect.Rect; +import mightypork.util.math.constraints.rect.mutable.RectMutable; +import mightypork.util.math.constraints.vect.Vect; + +import org.lwjgl.opengl.GL11; + + +public class Minimap extends InputComponent implements MouseButtonListener { + + private final World world; + private final RectMutable bounds = Rect.makeVar(); + private int unit = 0; + private final Color back = Color.rgba(0, 0.2, 0.2, 0.4); + private final Color back2 = Color.rgba(0, 0.5, 0.5, 0.5); + + + public Minimap(World w) + { + this.world = w; + } + + + @Override + protected void renderComponent() + { + + final Level lvl = world.getCurrentLevel(); + unit = (int) Math.min(Math.max(2, Math.ceil(height().value() / (lvl.getHeight() + 2))), 8); + + final World w = lvl.getWorld(); + final Entity e = w.getPlayerEntity(); + final EntityPos plCoord = e.getPosition(); + + final int lw = lvl.getWidth(); + final int lh = lvl.getHeight(); + + final Vect tl = topRight().sub(unit * lw, 0); + + bounds.setTo(tl, unit * lw, unit * lh); + + Render.quad(bounds.grow(unit * 0.5), back); + Render.quad(bounds, back2); + + final Coord point = new Coord(tl.xi(), tl.yi()); + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glBegin(GL11.GL_QUADS); + for (final Coord pos = Coord.zero(); pos.y < lh; pos.y++, point.y += unit) { + for (pos.x = 0, point.x = tl.xi(); pos.x < lw; pos.x++, point.x += unit) { + + final Tile t = lvl.getTile(pos); + if (t.isNull() || !t.data.explored) continue; + + final Color clr = t.getMapColor(); + + GL11.glColor4d(clr.r(), clr.g(), clr.b(), clr.a() * 0.9); + + GL11.glVertex2i(point.x, point.y); + GL11.glVertex2i(point.x + unit, point.y); + GL11.glVertex2i(point.x + unit, point.y + unit); + GL11.glVertex2i(point.x, point.y + unit); + } + } + + // player + GL11.glColor3d(1, 0, 0); + + final double plx = tl.xi() + plCoord.visualX() * unit; + final double ply = tl.yi() + plCoord.visualY() * unit; + + GL11.glVertex2d(plx, ply); + GL11.glVertex2d(plx + unit, ply); + GL11.glVertex2d(plx + unit, ply + unit); + GL11.glVertex2d(plx, ply + unit); + + GL11.glEnd(); + } + + + @Override + public void receive(MouseButtonEvent event) + { + if (event.isOver(bounds) && event.isUp()) { + final Vect relative = event.getPos().sub(bounds.origin()); + final Coord actual = Coord.make(relative.xi() / unit, relative.yi() / unit); + + if (!world.getCurrentLevel().getTile(actual).data.explored) return; // unexplored + + world.getPlayerEntity().navigateTo(actual); + event.consume(); + } + } +} diff --git a/src/mightypork/rogue/world/Coord.java b/src/mightypork/rogue/world/Coord.java index 31fdcfc..ecef169 100644 --- a/src/mightypork/rogue/world/Coord.java +++ b/src/mightypork/rogue/world/Coord.java @@ -6,6 +6,7 @@ import java.io.IOException; import mightypork.util.annotations.FactoryMethod; import mightypork.util.files.ion.IonBundle; import mightypork.util.files.ion.IonBundled; +import mightypork.util.math.Calc; /** @@ -140,4 +141,10 @@ public class Coord implements IonBundled { if (y != other.y) return false; return true; } + + + public double dist(Coord coord) + { + return Calc.dist(x, y, coord.x, coord.y); + } } diff --git a/src/mightypork/rogue/world/World.java b/src/mightypork/rogue/world/World.java index c9de696..4263ea1 100644 --- a/src/mightypork/rogue/world/World.java +++ b/src/mightypork/rogue/world/World.java @@ -64,6 +64,7 @@ public class World implements IonBundled, Updateable { public void addLevel(Level level) { levels.add(level); + level.setWorld(this); } diff --git a/src/mightypork/rogue/world/WorldCreator.java b/src/mightypork/rogue/world/WorldCreator.java index 09079a5..7731ad6 100644 --- a/src/mightypork/rogue/world/WorldCreator.java +++ b/src/mightypork/rogue/world/WorldCreator.java @@ -23,7 +23,7 @@ public class WorldCreator { Level l; // first level - l = LevelGenerator.build(rand.nextLong(), 2, LevelGenerator.DUNGEON_THEME); // + l = LevelGenerator.build(rand.nextLong(), 16, LevelGenerator.DUNGEON_THEME); // w.addLevel(l); w.createPlayer(0); diff --git a/src/mightypork/rogue/world/entity/models/PlayerModel.java b/src/mightypork/rogue/world/entity/models/PlayerModel.java index 40fa596..ab5dc73 100644 --- a/src/mightypork/rogue/world/entity/models/PlayerModel.java +++ b/src/mightypork/rogue/world/entity/models/PlayerModel.java @@ -1,9 +1,12 @@ package mightypork.rogue.world.entity.models; +import mightypork.rogue.world.Coord; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.EntityData; import mightypork.rogue.world.entity.renderers.PlayerRenderer; +import mightypork.rogue.world.level.Level; +import mightypork.rogue.world.tile.Tile; /** @@ -39,6 +42,9 @@ public class PlayerModel extends EntityModel { @Override public void onStepFinished(Entity entity) { + final Level l = entity.getLevel(); + + l.markExplored(entity.getCoord(), 4.5); } @@ -58,4 +64,12 @@ public class PlayerModel extends EntityModel { public void initMetadata(EntityData metadata) { } + + + @Override + public boolean canWalkInto(Entity entity, Coord pos) + { + final Tile t = entity.getLevel().getTile(pos); + return (t.data.explored || pos.dist(entity.getCoord()) < 6) && t.isWalkable(); + } } diff --git a/src/mightypork/rogue/world/gen/ScratchMap.java b/src/mightypork/rogue/world/gen/ScratchMap.java index 4769de9..50b9c32 100644 --- a/src/mightypork/rogue/world/gen/ScratchMap.java +++ b/src/mightypork/rogue/world/gen/ScratchMap.java @@ -123,16 +123,16 @@ public class ScratchMap { switch (rand.nextInt(4)) { case 0: - center.x += 1 + rand.nextInt(5); + center.x += 2 + rand.nextInt(6); break; case 1: - center.x -= 1 + rand.nextInt(5); + center.x -= 2 + rand.nextInt(6); break; case 2: - center.y += 1 + rand.nextInt(5); + center.y += 2 + rand.nextInt(6); break; case 3: - center.y -= 1 + rand.nextInt(5); + center.y -= 2 + rand.nextInt(6); } final RoomDesc rd = rb.buildToFit(this, theme, rand, center); diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index 58497be..7c770da 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -19,6 +19,7 @@ import mightypork.util.files.ion.IonBundle; import mightypork.util.files.ion.IonInput; import mightypork.util.files.ion.IonOutput; import mightypork.util.logging.Log; +import mightypork.util.math.Calc; import mightypork.util.math.noise.NoiseGen; @@ -320,4 +321,22 @@ public class Level implements MapAccess, IonBinary { { this.world = world; } + + + public void markExplored(Coord coord, double radius) + { + final int cr = (int) Math.ceil(radius); + + final Coord c = Coord.zero(); + for (c.y = coord.y - cr; c.y <= coord.y + cr; c.y++) { + for (c.x = coord.x - cr; c.x <= coord.x + cr; c.x++) { + if (Calc.dist(coord.x, coord.y, c.x, c.y) > radius) continue; + final Tile t = getTile(c); + if (!t.isNull()) { + t.data.explored = true; + } + } + } + + } } diff --git a/src/mightypork/rogue/world/tile/Tile.java b/src/mightypork/rogue/world/tile/Tile.java index 252ff8b..99a455b 100644 --- a/src/mightypork/rogue/world/tile/Tile.java +++ b/src/mightypork/rogue/world/tile/Tile.java @@ -8,9 +8,9 @@ import mightypork.rogue.world.item.Item; import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.util.files.ion.IonBinary; -import mightypork.util.files.ion.IonBundle; import mightypork.util.files.ion.IonInput; import mightypork.util.files.ion.IonOutput; +import mightypork.util.math.color.Color; /** @@ -30,7 +30,7 @@ public final class Tile implements IonBinary { private final Stack items = new Stack<>(); /** persistent field for model, reflected by renderer */ - public final IonBundle metadata = new IonBundle(); + public final TileData data = new TileData(); public final TileRenderData renderData = new TileRenderData(); public final TileGenData genData = new TileGenData(); @@ -99,9 +99,7 @@ public final class Tile implements IonBinary { out.writeSequence(items); } - if (model.hasMetadata()) { - out.writeBundle(metadata); - } + data.save(out); } @@ -119,9 +117,7 @@ public final class Tile implements IonBinary { in.readSequence(items); } - if (model.hasMetadata()) { - in.readBundle(metadata); - } + data.load(in); } @@ -209,4 +205,9 @@ public final class Tile implements IonBinary { return model.isPotentiallyWalkable(); } + + public Color getMapColor() + { + return model.getMapColor(this); + } } diff --git a/src/mightypork/rogue/world/tile/TileData.java b/src/mightypork/rogue/world/tile/TileData.java new file mode 100644 index 0000000..6bd1902 --- /dev/null +++ b/src/mightypork/rogue/world/tile/TileData.java @@ -0,0 +1,54 @@ +package mightypork.rogue.world.tile; + + +import java.io.IOException; + +import mightypork.util.error.YouFuckedUpException; +import mightypork.util.files.ion.IonBinary; +import mightypork.util.files.ion.IonBundle; +import mightypork.util.files.ion.IonInput; +import mightypork.util.files.ion.IonOutput; + + +public class TileData implements IonBinary { + + private static final byte BIT_EXPLORED = 1 << 0; + private static final byte BIT_LOCKED = 1 << 1; + + public boolean explored = false; + public boolean locked = false; + + public final IonBundle extra = new IonBundle(); + + + @Override + public void load(IonInput in) throws IOException + { + final byte flags = in.readByte(); + in.readBundle(extra); + + explored = (flags & BIT_EXPLORED) != 0; + locked = (flags & BIT_LOCKED) != 0; + } + + + @Override + public void save(IonOutput out) throws IOException + { + byte flags = 0; + if (explored) flags |= BIT_EXPLORED; + if (locked) flags |= BIT_LOCKED; + out.writeByte(flags); + + + out.writeBundle(extra); + } + + + @Override + public short getIonMark() + { + throw new YouFuckedUpException("TileData is not to be read from ION using mark."); + } + +} diff --git a/src/mightypork/rogue/world/tile/TileModel.java b/src/mightypork/rogue/world/tile/TileModel.java index c35ea66..56931ee 100644 --- a/src/mightypork/rogue/world/tile/TileModel.java +++ b/src/mightypork/rogue/world/tile/TileModel.java @@ -2,6 +2,7 @@ package mightypork.rogue.world.tile; import mightypork.rogue.world.level.Level; +import mightypork.util.math.color.Color; /** @@ -66,12 +67,6 @@ public abstract class TileModel { public abstract void update(Tile tile, Level level, double delta); - /** - * @return true if this item type has metadata worth saving - */ - public abstract boolean hasMetadata(); - - /** * @return true if this item can have dropped items */ @@ -84,4 +79,7 @@ public abstract class TileModel { */ public abstract boolean isPotentiallyWalkable(); + + public abstract Color getMapColor(Tile tile); + } diff --git a/src/mightypork/rogue/world/tile/models/AbstractNullTile.java b/src/mightypork/rogue/world/tile/models/AbstractNullTile.java index 6719760..99da189 100644 --- a/src/mightypork/rogue/world/tile/models/AbstractNullTile.java +++ b/src/mightypork/rogue/world/tile/models/AbstractNullTile.java @@ -38,13 +38,6 @@ public abstract class AbstractNullTile extends AbstractTile { } - @Override - public boolean hasMetadata() - { - return false; - } - - @Override public boolean hasDroppedItems() { diff --git a/src/mightypork/rogue/world/tile/models/AbstractTile.java b/src/mightypork/rogue/world/tile/models/AbstractTile.java index 9d6906c..cdbf74b 100644 --- a/src/mightypork/rogue/world/tile/models/AbstractTile.java +++ b/src/mightypork/rogue/world/tile/models/AbstractTile.java @@ -48,13 +48,6 @@ public abstract class AbstractTile extends TileModel { } - @Override - public boolean hasMetadata() - { - return false; - } - - @Override @DefaultImpl public void update(Tile tile, Level level, double delta) diff --git a/src/mightypork/rogue/world/tile/models/Floor.java b/src/mightypork/rogue/world/tile/models/Floor.java index 304c061..7c1fbf1 100644 --- a/src/mightypork/rogue/world/tile/models/Floor.java +++ b/src/mightypork/rogue/world/tile/models/Floor.java @@ -1,6 +1,11 @@ package mightypork.rogue.world.tile.models; +import mightypork.rogue.world.tile.Tile; +import mightypork.util.math.color.COMMODORE; +import mightypork.util.math.color.Color; + + public class Floor extends AbstractTile { public Floor(int id) @@ -35,4 +40,11 @@ public class Floor extends AbstractTile { { return true; } + + + @Override + public Color getMapColor(Tile tile) + { + return COMMODORE.GRAY_DARK; + } } diff --git a/src/mightypork/rogue/world/tile/models/NullTile.java b/src/mightypork/rogue/world/tile/models/NullTile.java index 74a5aa6..4f2c67c 100644 --- a/src/mightypork/rogue/world/tile/models/NullTile.java +++ b/src/mightypork/rogue/world/tile/models/NullTile.java @@ -1,6 +1,11 @@ package mightypork.rogue.world.tile.models; +import mightypork.rogue.world.tile.Tile; +import mightypork.util.math.color.Color; +import mightypork.util.math.color.RGB; + + public class NullTile extends AbstractNullTile { public NullTile(int id) @@ -15,4 +20,10 @@ public class NullTile extends AbstractNullTile { return false; } + + @Override + public Color getMapColor(Tile tile) + { + return RGB.NONE; + } } diff --git a/src/mightypork/rogue/world/tile/models/SimpleDoor.java b/src/mightypork/rogue/world/tile/models/SimpleDoor.java index 63a89c5..470859e 100644 --- a/src/mightypork/rogue/world/tile/models/SimpleDoor.java +++ b/src/mightypork/rogue/world/tile/models/SimpleDoor.java @@ -3,6 +3,8 @@ package mightypork.rogue.world.tile.models; import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.renderers.DoorRenderer; +import mightypork.util.math.color.COMMODORE; +import mightypork.util.math.color.Color; public class SimpleDoor extends AbstractTile { @@ -53,4 +55,11 @@ public class SimpleDoor extends AbstractTile { { return false; } + + + @Override + public Color getMapColor(Tile tile) + { + return COMMODORE.BROWN; + } } diff --git a/src/mightypork/rogue/world/tile/models/Wall.java b/src/mightypork/rogue/world/tile/models/Wall.java index 20abb98..8433661 100644 --- a/src/mightypork/rogue/world/tile/models/Wall.java +++ b/src/mightypork/rogue/world/tile/models/Wall.java @@ -1,6 +1,11 @@ package mightypork.rogue.world.tile.models; +import mightypork.rogue.world.tile.Tile; +import mightypork.util.math.color.COMMODORE; +import mightypork.util.math.color.Color; + + /** * Template for wall tiles with no metadata * @@ -41,4 +46,10 @@ public class Wall extends AbstractTile { return false; } + + @Override + public Color getMapColor(Tile tile) + { + return COMMODORE.GRAY_LIGHT; + } } diff --git a/src/mightypork/util/error/YouFuckedUpException.java b/src/mightypork/util/error/YouFuckedUpException.java new file mode 100644 index 0000000..e5a8b83 --- /dev/null +++ b/src/mightypork/util/error/YouFuckedUpException.java @@ -0,0 +1,29 @@ +package mightypork.util.error; + + +public class YouFuckedUpException extends RuntimeException { + + public YouFuckedUpException() + { + super(); + } + + + public YouFuckedUpException(String message, Throwable cause) + { + super(message, cause); + } + + + public YouFuckedUpException(String message) + { + super(message); + } + + + public YouFuckedUpException(Throwable cause) + { + super(cause); + } + +} diff --git a/src/mightypork/util/math/Calc.java b/src/mightypork/util/math/Calc.java index 0acb32d..b4b66bd 100644 --- a/src/mightypork/util/math/Calc.java +++ b/src/mightypork/util/math/Calc.java @@ -656,4 +656,10 @@ public class Calc { { if (!inRange(index, 0, length - 1)) { throw new IndexOutOfBoundsException(); } } + + + public static double dist(double x1, double y1, double x2, double y2) + { + return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); + } }