From c74869d3b752500b1c08eaefbcc0bc03150a37d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sat, 10 May 2014 02:25:40 +0200 Subject: [PATCH] Up/Down stairs, transition fade, improved controls. --- res/img/tiles16.png | Bin 9012 -> 9088 bytes res/img/tiles16.xcf | Bin 22740 -> 23709 bytes .../gamecore/eventbus/EventBus.java | 2 +- .../math/algo/pathfinding/PathFinder.java | 28 ++- src/mightypork/rogue/Res.java | 26 ++- .../rogue/screens/game/HudLayer.java | 12 +- .../rogue/screens/game/NavItemSlot.java | 2 +- .../rogue/screens/menu/MenuLayer.java | 2 +- src/mightypork/rogue/world/PlayerControl.java | 4 +- src/mightypork/rogue/world/World.java | 48 ++++- src/mightypork/rogue/world/WorldCreator.java | 6 +- src/mightypork/rogue/world/WorldProvider.java | 4 +- src/mightypork/rogue/world/WorldRenderer.java | 6 +- src/mightypork/rogue/world/entity/Entity.java | 8 +- .../world/entity/entities/MonsterAi.java | 6 +- .../entity/render/EntityRendererMobLR.java | 2 +- .../world/events/WorldAscendRequest.java | 20 ++ .../events/WorldAscendRequestListener.java | 10 + .../world/events/WorldDescendRequest.java | 15 ++ .../events/WorldDescendRequestListener.java | 10 + .../rogue/world/gen/LevelGenerator.java | 12 +- src/mightypork/rogue/world/gen/MapTheme.java | 6 + .../rogue/world/gen/ScratchMap.java | 80 +++++-- .../world/gen/rooms/AbstractRectRoom.java | 18 +- .../rogue/world/gen/rooms/EntranceRoom.java | 60 ++++++ .../rogue/world/gen/rooms/ExitRoom.java | 52 +++++ .../rogue/world/gen/rooms/Rooms.java | 2 + .../rogue/world/gen/themes/ThemeBrick.java | 14 ++ src/mightypork/rogue/world/gui/MapView.java | 90 +++++++- src/mightypork/rogue/world/gui/Minimap.java | 6 +- .../world/gui/interaction/MIPKeyboard.java | 18 +- .../rogue/world/gui/interaction/MIPMouse.java | 30 +-- .../gui/interaction/MapInteractionPlugin.java | 12 +- .../rogue/world/item/items/ItemMeat.java | 2 +- src/mightypork/rogue/world/level/Level.java | 198 +++++++++++++++--- .../rogue/world/level/LevelAccess.java | 109 ---------- .../rogue/world/level/LevelReadAccess.java | 127 ----------- .../level/render/EntityRenderContext.java | 4 +- .../world/level/render/MapRenderContext.java | 6 +- .../world/level/render/TileRenderContext.java | 4 +- src/mightypork/rogue/world/tile/Tile.java | 25 ++- .../rogue/world/tile/TileRenderer.java | 32 +-- src/mightypork/rogue/world/tile/TileType.java | 4 +- src/mightypork/rogue/world/tile/Tiles.java | 8 +- .../tile/render/OneFrameTileRenderer.java | 33 +++ .../tile/render/TwoHighTileRenderer.java | 35 ++++ .../world/tile/tiles/TileBaseEntrance.java | 34 +++ .../rogue/world/tile/tiles/TileBaseExit.java | 34 +++ .../world/tile/tiles/TileBaseStairs.java | 22 ++ .../world/tile/tiles/brick/TileBrickDoor.java | 6 +- .../tile/tiles/brick/TileBrickEntrance.java | 25 +++ .../world/tile/tiles/brick/TileBrickExit.java | 25 +++ .../tile/tiles/brick/TileBrickFloor.java | 2 +- .../tile/tiles/brick/TileBrickPassage.java | 2 +- .../tile/tiles/brick/TileBrickSecretDoor.java | 6 +- .../world/tile/tiles/brick/TileBrickWall.java | 2 +- 56 files changed, 936 insertions(+), 420 deletions(-) create mode 100644 src/mightypork/rogue/world/events/WorldAscendRequest.java create mode 100644 src/mightypork/rogue/world/events/WorldAscendRequestListener.java create mode 100644 src/mightypork/rogue/world/events/WorldDescendRequest.java create mode 100644 src/mightypork/rogue/world/events/WorldDescendRequestListener.java create mode 100644 src/mightypork/rogue/world/gen/rooms/EntranceRoom.java create mode 100644 src/mightypork/rogue/world/gen/rooms/ExitRoom.java delete mode 100644 src/mightypork/rogue/world/level/LevelAccess.java delete mode 100644 src/mightypork/rogue/world/level/LevelReadAccess.java create mode 100644 src/mightypork/rogue/world/tile/render/OneFrameTileRenderer.java create mode 100644 src/mightypork/rogue/world/tile/render/TwoHighTileRenderer.java create mode 100644 src/mightypork/rogue/world/tile/tiles/TileBaseEntrance.java create mode 100644 src/mightypork/rogue/world/tile/tiles/TileBaseExit.java create mode 100644 src/mightypork/rogue/world/tile/tiles/TileBaseStairs.java create mode 100644 src/mightypork/rogue/world/tile/tiles/brick/TileBrickEntrance.java create mode 100644 src/mightypork/rogue/world/tile/tiles/brick/TileBrickExit.java diff --git a/res/img/tiles16.png b/res/img/tiles16.png index 750df85c162c253169b4a9892cd6a53789bbb31e..3cf477069a36727ec68dd2b487ea6d9d19341525 100644 GIT binary patch delta 9025 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 lq_UfY(^letyrS delta 8948 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 diff --git a/res/img/tiles16.xcf b/res/img/tiles16.xcf index fd1376374af37f1d19b3c60e225f793a80db69ab..a804fc9953f950114f778347765aa1da88c9aa34 100644 GIT binary patch delta 3135 zcmbuBU5p!7702hAY)N)}ckK9kzU=w%u06JA_QT&cPO~imyX(+x5*t@hvn`3U>ukLn z2z{LwgoKiZ2(OTcgisWO)R(GhBqYSg3*rHxK7e?x;H3|dqNoWgHfFQt+!=qwtq=k% z-MROkJLmk*`OWdzf4Pr-@=J8Pg8q2_R2$8FL{Z=Tb?@isSM?5Me;&Ye55_Tya(o|7 ze+J{j=`+VKD2lmAQN=BaTKh9at-l2Kgkao&@jV!O4?b`dYUY<+F2;pR$4V>Iv#E7Z zU{qpXrVc_(t99eLz1hcet;O@7xYwe%FzIgf_CZFGNc|6n- z^#s$cV)-J@X5YnMzib)iTCbKbx=wwifpccgvXB^AT*#kuW->!Vd9{QKg>y`)Gz?NM zmmr9a^R|mC6cjb4kk>~pfz6$rno=m}w##$O)Eu>gq$p;XobBSicKi07_us#LO&J+- zk+>9lo^vsrq%g!B1zrckhMp_?UCI)E@b&Jm|4*cA*28k5iIBOiZfcegI* z^SbQ=nCg!DK|&DHOxAXBcW&LIF=>Y-;4=Z+E*@IhRY>K7gs} zs2*r9V!C?sX7BFZn^#AeOn3Hj_qA^OQZ+WjjD={ZKFU9^=ov71SfwwD~tskCR#I(VoY!V4LkU5s48HNL+dzPl{GSah{^LW6HJ+n@y8_w)94%gfm z-YQ4E`)|BzmL3mQY^?Ku)mY*^byO!*ABW;3y(MGG0IEx2+YVIcM^xt%DA8v<_4*zm zz+#+;N;tJ2B6y$(sQjd6TJIS!ONr~{NOyE%oq)2V~UQ#c`yZh|@FuGcNh z9T1VEw3D?lI|*ju@@NeXrZHP(*!C&PmYq-ZvOyN)kn zw#zs?>&A6Q@BH~Q?FnQx9@BM$^HfoF3^_#`x}g)hXxm4SS)Xszy47lL0-1cj31t1W zbh6iLllrefJw0^6V?HD+)@tf`+8gpf^S0YnLKP0CsRmuuYMDgc8dIGo%?nh^W#aPa zHA0n5z0kZ?-edcucP%?m8$y)!v5}d>o<3TFn|7HftNTp&M3aaqq7eeCFYr z3&Tt5=xTL_TpU&NSQ1`14(jN{U~Zt>Q<6G75ujiX3+5%!TA%^EIEdx{T1fxV|G|$M z6-NaAr?`d#!R&5q@BIF^SGvEu8+q^B-?{PL+r5v`)^Ru>pN(F{5ioyaZ^*Uv-Qju^ z0{#NEelTro{g~_>iGFx-F{Qva?bB3*EF>k&@tgp&!bMdfB}riwsr!5^EODHw3JQ;S zhtLlxJRcMs0$SWpD2YTk;a!Z!BM|13l&XNc%8IHY^#11cnQ+&UBFvBr5K6nV45liB+Y!0^Q{W*O^pA}|j@bxE2670VH_W65NCs?xi?9oJ4}cHv3;KOrn4huq sIV~EM0RgE25Xd5@g`rJZhyeOX{!D~L1b%ghzJH>R0?#dd6H$YI0d+^HE&u=k delta 2278 zcmcJPT~FIq7{||XgEnG2PGVr#CIN@U5Qyyr2vuI7+L$KUirc|n)VocSW-KECpI}yZ z3l~V{3UwD15>lsWQp?q}eSlp}nzT<*(G9JWHr|pw$4&@=3auB5baLYV@$;Pj^W!hR z`2qj-4DT%B!)NzwjKBB4#Xnj$3O|Ri?Zb*7M176W!=GUN+@l8IYwXyV z#$__75XT#ZWJ~#W5NicFM6p4_goHN)rKsghX>T)$wJzuU?;gJ!%2=aezh&_nd|A1)f zz1tD#I+-qaE22V(NS1F$)NOJDk>+l0S^*-`1Q1PFl+}Z1(cRwO-QVAKJBT!Ed(+)? zzpy%pW{8lc+%woW14I+`<$9!kzFe>OA}W^`%Iy>pMCERZP8fM)q|E79Kfe;AfKll( zMk8{z%8H_T86#j+1xBTAjGzfSnpPP>fSVzTnQWoTj*hAvjOP)B#HgnUywckwWOSuT z!CqfCI!y?poIx2qj22e6w)`hgwpKfg3dYvDy>5SIbQtL%cs6C9!M+|a%2n=HB9-&| zl}d*Z^4^+7&HhGT<1TEiNUPaEcTry}(wIa2&+G4J_`N*`4qj@kFd~Ul%)mgNRtpm|QqsZB6gpQ}N06{| z9GvdSKni{Y)}d#Vq2KAJ>9%trDk%Q)%An*_iBpN@I0@cJ zL}@y3imOM0|7d0K4kg_2AFq7y0IC2eenm_-kZK^PS}45MuuQ1aR^8b-Z+ z)ZwgD*;+%w2XooX! zjw?rk7;;UvxrV-htI=FF`p6e$c##6~-bM&F;J;6-RY17a{c+GyoYq?V%;`%1kK!~B K4!` findPathRelative(Coord start, Coord end) { - return findPathRelative(start, end, false); + return findPathRelative(start, end, ignoreStart, ignoreEnd); } - public List findPathRelative(Coord start, Coord end, boolean ignoreEnd) + public List findPathRelative(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd) { - final List path = findPath(start, end, ignoreEnd); + final List path = findPath(start, end, ignoreStart, ignoreEnd); + if (path == null) return null; final List out = new ArrayList<>(); @@ -53,11 +57,11 @@ public abstract class PathFinder { public List findPath(Coord start, Coord end) { - return findPath(start, end, false); + return findPath(start, end, ignoreStart, ignoreEnd); } - public List findPath(Coord start, Coord end, boolean ignoreEnd) + public List findPath(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd) { final LinkedList open = new LinkedList<>(); final LinkedList closed = new LinkedList<>(); @@ -92,7 +96,7 @@ public abstract class PathFinder { for (final Step go : walkDirs) { final Coord c = current.pos.add(go); - if (!isAccessible(c) && !(c.equals(end) && ignoreEnd)) continue; + if (!isAccessible(c) && !(c.equals(end) && ignoreEnd) && !(c.equals(start) && ignoreStart)) continue; final Node a = new Node(c); a.g_cost = current.g_cost + getCost(c, a.pos); a.h_cost = (int) (heuristic.getCost(a.pos, end) * getMinCost()); @@ -203,6 +207,18 @@ public abstract class PathFinder { } + public void setIgnoreEnd(boolean ignoreEnd) + { + this.ignoreEnd = ignoreEnd; + } + + + public void setIgnoreStart(boolean ignoreStart) + { + this.ignoreStart = ignoreStart; + } + + /** * @return used heuristic */ diff --git a/src/mightypork/rogue/Res.java b/src/mightypork/rogue/Res.java index 947edd5..702675c 100644 --- a/src/mightypork/rogue/Res.java +++ b/src/mightypork/rogue/Res.java @@ -100,6 +100,8 @@ public final class Res { textures.addSheet("tile.brick.door.secret", grid.makeSheet(0, 3, 2, 1)); textures.addSheet("tile.brick.passage", grid.makeSheet(3, 2, 4, 1)); + textures.addQuad("tile.brick.stairs.up", grid.makeQuad(0, 6)); + textures.addQuad("tile.brick.stairs.down", grid.makeQuad(1, 6)); textures.addQuad("tile.shadow.n", grid.makeQuad(0, 7)); textures.addQuad("tile.shadow.s", grid.makeQuad(0, 7).flipY()); @@ -135,21 +137,33 @@ public final class Res { } - public static TxQuad getTxQuad(String key) + public static GLTexture getTexture(String key) { - return textures.getQuad(key); + return textures.getTexture(key); } - public static GLTexture getTexture(String key) + /** + * Get a texture sheet by key + * + * @param key + * @return sheet + */ + public static TxSheet txs(String key) { - return textures.getTexture(key); + return textures.getSheet(key); } - public static TxSheet sheet(String key) + /** + * Get a texture quad by key + * + * @param key + * @return quad + */ + public static TxQuad txq(String key) { - return textures.getSheet(key); + return textures.getQuad(key); } diff --git a/src/mightypork/rogue/screens/game/HudLayer.java b/src/mightypork/rogue/screens/game/HudLayer.java index 42a4be0..7f09a56 100644 --- a/src/mightypork/rogue/screens/game/HudLayer.java +++ b/src/mightypork/rogue/screens/game/HudLayer.java @@ -44,7 +44,7 @@ public class HudLayer extends ScreenLayer { final Num w = root.width(); final Num minWH = w.min(h).max(700); // avoid too small shrinking - final ImagePainter nav = new ImagePainter(Res.getTxQuad("panel")); + final ImagePainter nav = new ImagePainter(Res.txq("panel")); nav.setRect(root.bottomEdge().growUp(minWH.perc(7))); root.add(nav); @@ -52,8 +52,8 @@ public class HudLayer extends ScreenLayer { itemSlots.setRect(nav.growUp(nav.height()).move(nav.height().mul(0.2), nav.height().mul(-0.2))); root.add(itemSlots); - itemSlots.add(new NavItemSlot(Res.getTxQuad("meat"))); - itemSlots.add(new NavItemSlot(Res.getTxQuad("sword"))); + itemSlots.add(new NavItemSlot(Res.txq("meat"))); + itemSlots.add(new NavItemSlot(Res.txq("sword"))); final Rect shrunk = root.shrink(minWH.perc(3)); final Num displays_height = minWH.perc(6); @@ -62,9 +62,9 @@ public class HudLayer extends ScreenLayer { final HeartBar hearts = new HeartBar( playerHealthTotal, playerHealthActive, - Res.getTxQuad("heart_on"), - Res.getTxQuad("heart_half"), - Res.getTxQuad("heart_off"), + Res.txq("heart_on"), + Res.txq("heart_half"), + Res.txq("heart_off"), AlignX.LEFT); //@formatter:on diff --git a/src/mightypork/rogue/screens/game/NavItemSlot.java b/src/mightypork/rogue/screens/game/NavItemSlot.java index a11fcd7..8da5976 100644 --- a/src/mightypork/rogue/screens/game/NavItemSlot.java +++ b/src/mightypork/rogue/screens/game/NavItemSlot.java @@ -28,7 +28,7 @@ public class NavItemSlot extends ClickableComponent implements MouseMotionListen public NavItemSlot(TxQuad image) { this.image = image; - this.frame = Res.getTxQuad("item_frame"); + this.frame = Res.txq("item_frame"); final Rect ref = shrink(height().perc(8)); yOffset = new NumAnimated(0, Easing.LINEAR); diff --git a/src/mightypork/rogue/screens/menu/MenuLayer.java b/src/mightypork/rogue/screens/menu/MenuLayer.java index a1fc611..3a54c54 100644 --- a/src/mightypork/rogue/screens/menu/MenuLayer.java +++ b/src/mightypork/rogue/screens/menu/MenuLayer.java @@ -39,7 +39,7 @@ class MenuLayer extends ScreenLayer { root.add(layout); int r = 0; - final ImagePainter ip = new ImagePainter(Res.getTxQuad("logo")); + final ImagePainter ip = new ImagePainter(Res.txq("logo")); ip.keepAspectRatio(); layout.put(ip, r, 0, 5, 1); r += 6; diff --git a/src/mightypork/rogue/world/PlayerControl.java b/src/mightypork/rogue/world/PlayerControl.java index 0f57c62..a5ca196 100644 --- a/src/mightypork/rogue/world/PlayerControl.java +++ b/src/mightypork/rogue/world/PlayerControl.java @@ -8,7 +8,7 @@ import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Step; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.modules.EntityMoveListener; -import mightypork.rogue.world.level.LevelAccess; +import mightypork.rogue.world.level.Level; public abstract class PlayerControl { @@ -76,7 +76,7 @@ public abstract class PlayerControl { } - public LevelAccess getLevel() + public Level getLevel() { return getWorld().getCurrentLevel(); } diff --git a/src/mightypork/rogue/world/World.java b/src/mightypork/rogue/world/World.java index 1bdfc77..b81adbb 100644 --- a/src/mightypork/rogue/world/World.java +++ b/src/mightypork/rogue/world/World.java @@ -4,6 +4,7 @@ package mightypork.rogue.world; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Random; import mightypork.gamecore.eventbus.BusAccess; import mightypork.gamecore.eventbus.EventBus; @@ -15,7 +16,6 @@ import mightypork.gamecore.util.math.timing.Pauseable; import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.level.Level; -import mightypork.rogue.world.level.LevelAccess; /** @@ -134,7 +134,13 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea final Coord spawn = floor.getEnterPoint(); floor.forceFreeTile(spawn); - floor.addEntity(playerEntity, spawn); + final Random rand = new Random(seed + 71); + + while (!floor.addEntity(playerEntity, spawn)) { + spawn.x += -1 + rand.nextInt(3); + spawn.y += -1 + rand.nextInt(3); + } + floor.explore(spawn); playerInfo.setLevel(level); @@ -142,7 +148,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea } - public LevelAccess getCurrentLevel() + public Level getCurrentLevel() { return levels.get(playerInfo.getLevel()); } @@ -193,4 +199,40 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea return paused; } + + public boolean canAscend() + { + return playerInfo.getLevel() > 0; + } + + + public boolean canDescend() + { + return playerInfo.getLevel() < levels.size() - 1; + } + + + public void ascend() + { + if (!canAscend()) return; + + int lvl_num = playerInfo.getLevel(); + getCurrentLevel().removeEntity(playerEntity); + playerInfo.setLevel(lvl_num - 1); + getCurrentLevel().addEntity(playerEntity, getCurrentLevel().getExitPoint()); + getCurrentLevel().explore(playerEntity.getCoord()); + } + + + public void descend() + { + if (!canDescend()) return; + + int lvl_num = playerInfo.getLevel(); + getCurrentLevel().removeEntity(playerEntity); + playerInfo.setLevel(lvl_num + 1); + getCurrentLevel().addEntity(playerEntity, getCurrentLevel().getEnterPoint()); + getCurrentLevel().explore(playerEntity.getCoord()); + } + } diff --git a/src/mightypork/rogue/world/WorldCreator.java b/src/mightypork/rogue/world/WorldCreator.java index d51b036..31ce3a4 100644 --- a/src/mightypork/rogue/world/WorldCreator.java +++ b/src/mightypork/rogue/world/WorldCreator.java @@ -20,8 +20,10 @@ public class WorldCreator { final World w = new World(); w.setSeed(seed); - for (int i = 0; i < 7; i++) { - final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME); + int count = 6; + + for (int i = 1; i <= count; i++) { + final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME, i == count); w.addLevel(l); } diff --git a/src/mightypork/rogue/world/WorldProvider.java b/src/mightypork/rogue/world/WorldProvider.java index 751563c..1637d80 100644 --- a/src/mightypork/rogue/world/WorldProvider.java +++ b/src/mightypork/rogue/world/WorldProvider.java @@ -8,7 +8,7 @@ import mightypork.gamecore.eventbus.BusAccess; import mightypork.gamecore.eventbus.clients.RootBusNode; import mightypork.gamecore.util.ion.Ion; import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.level.LevelAccess; +import mightypork.rogue.world.level.Level; public class WorldProvider extends RootBusNode { @@ -85,7 +85,7 @@ public class WorldProvider extends RootBusNode { } - public LevelAccess getCurrentLevel() + public Level getCurrentLevel() { return getWorld().getCurrentLevel(); } diff --git a/src/mightypork/rogue/world/WorldRenderer.java b/src/mightypork/rogue/world/WorldRenderer.java index af53bf6..35779d6 100644 --- a/src/mightypork/rogue/world/WorldRenderer.java +++ b/src/mightypork/rogue/world/WorldRenderer.java @@ -12,7 +12,7 @@ import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.math.constraints.vect.VectConst; import mightypork.rogue.Res; import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.level.LevelAccess; +import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.render.TileRenderContext; @@ -29,7 +29,7 @@ public class WorldRenderer extends RectProxy { // can be changed private RectConst mapRect; - private LevelAccess activeLevel; + private Level activeLevel; private final Rect rightShadow; private final Rect leftShadow; @@ -57,7 +57,7 @@ public class WorldRenderer extends RectProxy { private void prepareRenderContextIfNeeded() { - final LevelAccess level = WorldProvider.get().getCurrentLevel(); + final Level level = WorldProvider.get().getCurrentLevel(); if (activeLevel == level) return; diff --git a/src/mightypork/rogue/world/entity/Entity.java b/src/mightypork/rogue/world/entity/Entity.java index 0f1b2ee..e87e7da 100644 --- a/src/mightypork/rogue/world/entity/Entity.java +++ b/src/mightypork/rogue/world/entity/Entity.java @@ -18,7 +18,7 @@ import mightypork.rogue.world.World; import mightypork.rogue.world.entity.modules.EntityModuleHealth; import mightypork.rogue.world.entity.modules.EntityModulePosition; import mightypork.rogue.world.entity.render.EntityRenderer; -import mightypork.rogue.world.level.LevelAccess; +import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.render.MapRenderContext; @@ -29,7 +29,7 @@ import mightypork.rogue.world.level.render.MapRenderContext; */ public abstract class Entity implements IonObjBundled, Updateable { - private LevelAccess level; + private Level level; private final EntityModel model; protected final Random rand = new Random(); @@ -120,7 +120,7 @@ public abstract class Entity implements IonObjBundled, Updateable { } - public void setLevel(LevelAccess level) + public void setLevel(Level level) { if (level != null) level.freeTile(getCoord()); @@ -130,7 +130,7 @@ public abstract class Entity implements IonObjBundled, Updateable { } - public final LevelAccess getLevel() + public final Level getLevel() { return level; } diff --git a/src/mightypork/rogue/world/entity/entities/MonsterAi.java b/src/mightypork/rogue/world/entity/entities/MonsterAi.java index e6b90ab..1dbc24c 100644 --- a/src/mightypork/rogue/world/entity/entities/MonsterAi.java +++ b/src/mightypork/rogue/world/entity/entities/MonsterAi.java @@ -87,6 +87,8 @@ public class MonsterAi extends EntityModule implements EntityMoveListener { }; + noDoorPf.setIgnoreEnd(true); + timerAttack.start(); timerFindPrey.start(); timerSleepStart.start(); @@ -211,7 +213,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener { //System.out.println("-- path would be: " + entity.getCoord() + "->" + prey.getCoord()); // check if reachable without leaving room - final List noDoorPath = noDoorPf.findPath(entity.getCoord(), prey.getCoord(), true); + final List noDoorPath = noDoorPf.findPath(entity.getCoord(), prey.getCoord()); if (noDoorPath == null) { //System.out.println("-- Could not navigate to prey, aborting."); @@ -273,7 +275,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener { { if (!isPreyValid(prey)) return null; - return entity.getPathFinder().findPathRelative(entity.getCoord(), prey.getCoord(), true); + return entity.getPathFinder().findPathRelative(entity.getCoord(), prey.getCoord(), false, true); } diff --git a/src/mightypork/rogue/world/entity/render/EntityRendererMobLR.java b/src/mightypork/rogue/world/entity/render/EntityRendererMobLR.java index 0ebd9ba..8675dba 100644 --- a/src/mightypork/rogue/world/entity/render/EntityRendererMobLR.java +++ b/src/mightypork/rogue/world/entity/render/EntityRendererMobLR.java @@ -35,7 +35,7 @@ public class EntityRendererMobLR extends EntityRenderer { public EntityRendererMobLR(Entity entity, String sheetKey) { this.entity = entity; - this.sheet = Res.sheet(sheetKey); + this.sheet = Res.txs(sheetKey); } diff --git a/src/mightypork/rogue/world/events/WorldAscendRequest.java b/src/mightypork/rogue/world/events/WorldAscendRequest.java new file mode 100644 index 0000000..eecfc1c --- /dev/null +++ b/src/mightypork/rogue/world/events/WorldAscendRequest.java @@ -0,0 +1,20 @@ +package mightypork.rogue.world.events; + + +import mightypork.gamecore.eventbus.BusEvent; + + +/** + * Player wants to go up + * + * @author MightyPork + */ +public class WorldAscendRequest extends BusEvent { + + @Override + protected void handleBy(WorldAscendRequestListener handler) + { + handler.onAscendRequest(); + } + +} diff --git a/src/mightypork/rogue/world/events/WorldAscendRequestListener.java b/src/mightypork/rogue/world/events/WorldAscendRequestListener.java new file mode 100644 index 0000000..94ed86f --- /dev/null +++ b/src/mightypork/rogue/world/events/WorldAscendRequestListener.java @@ -0,0 +1,10 @@ +package mightypork.rogue.world.events; + + +public interface WorldAscendRequestListener { + + /** + * Player clicked up-stairs + */ + void onAscendRequest(); +} diff --git a/src/mightypork/rogue/world/events/WorldDescendRequest.java b/src/mightypork/rogue/world/events/WorldDescendRequest.java new file mode 100644 index 0000000..1d00852 --- /dev/null +++ b/src/mightypork/rogue/world/events/WorldDescendRequest.java @@ -0,0 +1,15 @@ +package mightypork.rogue.world.events; + + +import mightypork.gamecore.eventbus.BusEvent; + + +public class WorldDescendRequest extends BusEvent { + + @Override + protected void handleBy(WorldDescendRequestListener handler) + { + handler.onDescendRequest(); + } + +} diff --git a/src/mightypork/rogue/world/events/WorldDescendRequestListener.java b/src/mightypork/rogue/world/events/WorldDescendRequestListener.java new file mode 100644 index 0000000..a71a496 --- /dev/null +++ b/src/mightypork/rogue/world/events/WorldDescendRequestListener.java @@ -0,0 +1,10 @@ +package mightypork.rogue.world.events; + + +public interface WorldDescendRequestListener { + + /** + * Player clicked down-stairs + */ + void onDescendRequest(); +} diff --git a/src/mightypork/rogue/world/gen/LevelGenerator.java b/src/mightypork/rogue/world/gen/LevelGenerator.java index 0442720..2c55f8d 100644 --- a/src/mightypork/rogue/world/gen/LevelGenerator.java +++ b/src/mightypork/rogue/world/gen/LevelGenerator.java @@ -21,7 +21,7 @@ public class LevelGenerator { public static final MapTheme DUNGEON_THEME = new ThemeBrick(); - public static Level build(World world, long seed, int complexity, MapTheme theme) + public static Level build(World world, long seed, int complexity, MapTheme theme, boolean lastLevel) { Log.f3("Generating level of complexity: " + complexity); @@ -32,14 +32,16 @@ public class LevelGenerator { final ScratchMap map = new ScratchMap(max_size, theme, rand); // start - map.addRoom(Rooms.BASIC); + map.addRoom(Rooms.ENTRANCE, true); for (int i = 0; i < 1 + complexity / 2 + rand.nextInt((int) (1 + complexity * 0.3)); i++) { - map.addRoom(Rooms.BASIC); - if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET); - if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END); + map.addRoom(Rooms.BASIC, false); + if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET, false); + if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END, false); } + if (!lastLevel) map.addRoom(Rooms.EXIT, true); + map.buildCorridors(); final Coord size = map.getNeededSize(); diff --git a/src/mightypork/rogue/world/gen/MapTheme.java b/src/mightypork/rogue/world/gen/MapTheme.java index e3704e1..d4be91c 100644 --- a/src/mightypork/rogue/world/gen/MapTheme.java +++ b/src/mightypork/rogue/world/gen/MapTheme.java @@ -24,4 +24,10 @@ public interface MapTheme { TileModel secretDoor(); + + + TileModel entrance(); + + + TileModel exit(); } diff --git a/src/mightypork/rogue/world/gen/ScratchMap.java b/src/mightypork/rogue/world/gen/ScratchMap.java index b1ca65b..1f9c622 100644 --- a/src/mightypork/rogue/world/gen/ScratchMap.java +++ b/src/mightypork/rogue/world/gen/ScratchMap.java @@ -14,7 +14,7 @@ import mightypork.gamecore.util.math.algo.Sides; import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.algo.pathfinding.Heuristic; import mightypork.gamecore.util.math.algo.pathfinding.PathFinder; -import mightypork.rogue.world.level.LevelAccess; +import mightypork.rogue.world.level.Level; import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.Tiles; @@ -43,6 +43,7 @@ public class ScratchMap { { if (!isIn(pos)) return false; final Tile t = get(pos); + if (t.isStairs()) return false; return t.isPotentiallyWalkable() || (t.genData.protection != TileProtectLevel.STRONG); } @@ -60,6 +61,7 @@ public class ScratchMap { case PASSAGE: return 10; + case STAIRS: case FLOOR: return 20; @@ -96,12 +98,19 @@ public class ScratchMap { }; + { + // needed for when the path starts / ends at stairs. + pathf.setIgnoreEnd(true); + pathf.setIgnoreStart(true); + } + Coord genMin; Coord genMax; private final MapTheme theme; private final Random rand; - private Coord enterPoint; + private final Coord enterPoint = new Coord(); + private final Coord exitPoint = new Coord(); private static final boolean FIX_GLITCHES = true; @@ -122,12 +131,14 @@ public class ScratchMap { } - public void addRoom(RoomBuilder rb) + public void addRoom(RoomBuilder rb, boolean critical) { final Coord center = Coord.make(0, 0); int failed = 0; + int failed_total = 0; + while (true) { final int sizeX = genMax.x - genMin.x; @@ -138,24 +149,20 @@ public class ScratchMap { switch (rand.nextInt(4)) { case 0: - center.x += 1 + rand.nextInt(4); + center.x += 1 + rand.nextInt(critical ? 6 : 4); break; case 1: - center.x -= 1 + rand.nextInt(4); + center.x -= 1 + rand.nextInt(critical ? 6 : 4); break; case 2: - center.y += 1 + rand.nextInt(4); + center.y += 1 + rand.nextInt(critical ? 6 : 4); break; case 3: - center.y -= 1 + rand.nextInt(4); + center.y -= 1 + rand.nextInt(critical ? 6 : 4); } final RoomDesc rd = rb.buildToFit(this, theme, rand, center); if (rd != null) { - if (rooms.isEmpty()) { - enterPoint = center.copy(); - } - rooms.add(rd); genMin.x = Math.min(genMin.x, rd.min.x); @@ -163,6 +170,7 @@ public class ScratchMap { genMax.x = Math.max(genMax.x, rd.max.x); genMax.y = Math.max(genMax.y, rd.max.y); + clampBounds(); nodes.add(center); Log.f3("placed room: " + rd.min + " -> " + rd.max); @@ -170,10 +178,28 @@ public class ScratchMap { return; } else { failed++; + failed_total++; if (failed > 200) { Log.w("Faild to build room."); - return; + if (critical) { + + genMin.x -= 5; + genMin.y -= 5; + genMax.x += 5; + genMax.y += 5; + clampBounds(); + + failed = 0; + continue; + + } else { + return; + } + } + + if (failed_total > 1000) { + throw new RuntimeException("Generation error - could not place critical room."); } } } @@ -181,6 +207,15 @@ public class ScratchMap { } + private void clampBounds() + { + genMin.x = Calc.clamp(genMin.x, 0, width - 1); + genMin.y = Calc.clamp(genMin.y, 0, height - 1); + genMax.x = Calc.clamp(genMax.x, 0, width - 1); + genMax.y = Calc.clamp(genMax.y, 0, height - 1); + } + + public boolean isIn(Coord pos) { return pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height; @@ -320,9 +355,10 @@ public class ScratchMap { genMax.x = Math.max(genMax.x, c.x); genMax.y = Math.max(genMax.y, c.y); + clampBounds(); final Tile current = get(c); - if (!current.isNull() && (current.isPotentiallyWalkable())) continue; // floor already, let it be + if (!current.isNull() && (current.isPotentiallyWalkable() || current.isStairs())) continue; // floor already, let it be if (i == 0 && j == 0) { set(c, theme.floor()); @@ -410,7 +446,7 @@ public class ScratchMap { } - public void writeToLevel(LevelAccess level) + public void writeToLevel(Level level) { // make sure no walkable are at edges. final Coord c = Coord.make(0, 0); @@ -503,5 +539,21 @@ 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); + + final Coord exit = new Coord(exitPoint.x - genMin.x, exitPoint.y - genMin.y); + level.setExitPoint(exit); + } + + + public void setEntrance(Coord pos) + { + enterPoint.setTo(pos); + } + + + public void setExit(Coord pos) + { + exitPoint.setTo(pos); } } diff --git a/src/mightypork/rogue/world/gen/rooms/AbstractRectRoom.java b/src/mightypork/rogue/world/gen/rooms/AbstractRectRoom.java index 534af06..0bdb265 100644 --- a/src/mightypork/rogue/world/gen/rooms/AbstractRectRoom.java +++ b/src/mightypork/rogue/world/gen/rooms/AbstractRectRoom.java @@ -34,8 +34,8 @@ public abstract class AbstractRectRoom implements RoomBuilder { if (!map.isClear(min.add(-1, -1), max)) return null; - map.fill(min, max, theme.floor()); - map.border(min, max, theme.wall()); + map.fill(min, max, getFloor(theme)); + map.border(min, max, getWall(theme)); map.protect(min, max, getWallProtectionLevel()); placeDoors(map, theme, rand, min, max); @@ -46,12 +46,24 @@ public abstract class AbstractRectRoom implements RoomBuilder { } + protected TileModel getWall(MapTheme theme) + { + return theme.wall(); + } + + + protected TileModel getFloor(MapTheme theme) + { + return theme.floor(); + } + + protected void placeDoors(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) { final int width = max.x - min.x; final int height = max.y - min.y; - for (int i = 0, j = 0; i <= getDoorCount(rand) && j < 100; j++) { // j is to prevent inf loop + for (int i = 0, j = 0; i < getDoorCount(rand) && j < 100; j++) { // j is to prevent inf loop final Coord door = min.copy(); switch (rand.nextInt(4)) { case 0: diff --git a/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java b/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java new file mode 100644 index 0000000..dd80eeb --- /dev/null +++ b/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java @@ -0,0 +1,60 @@ +package mightypork.rogue.world.gen.rooms; + + +import java.util.Random; + +import mightypork.gamecore.util.math.algo.Coord; +import mightypork.rogue.world.gen.MapTheme; +import mightypork.rogue.world.gen.ScratchMap; +import mightypork.rogue.world.gen.TileProtectLevel; +import mightypork.rogue.world.tile.TileModel; + + +public class EntranceRoom extends AbstractRectRoom { + + @Override + protected Coord getInnerSize(Random rand) + { + return Coord.make(3 + rand.nextInt(2) * 2, 3 + rand.nextInt(2) * 3); + } + + + @Override + protected TileProtectLevel getWallProtectionLevel() + { + return TileProtectLevel.WEAK; + } + + + @Override + protected TileModel getDoorType(MapTheme theme, Random rand) + { + switch (rand.nextInt(5)) { + case 0: + case 1: + return theme.passage(); + case 2: + return theme.secretDoor(); + default: + return theme.door(); + } + } + + + @Override + protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) + { + final Coord c = Coord.make((max.x + min.x) / 2, (max.y + min.y) / 2); + map.set(c, theme.entrance()); + map.protect(c, c, TileProtectLevel.STRONG); + map.setEntrance(c.add(1, 0)); + } + + + @Override + protected int getDoorCount(Random rand) + { + return 1 + rand.nextInt(4); + } + +} diff --git a/src/mightypork/rogue/world/gen/rooms/ExitRoom.java b/src/mightypork/rogue/world/gen/rooms/ExitRoom.java new file mode 100644 index 0000000..4d9e97b --- /dev/null +++ b/src/mightypork/rogue/world/gen/rooms/ExitRoom.java @@ -0,0 +1,52 @@ +package mightypork.rogue.world.gen.rooms; + + +import java.util.Random; + +import mightypork.gamecore.util.math.algo.Coord; +import mightypork.rogue.world.gen.MapTheme; +import mightypork.rogue.world.gen.ScratchMap; +import mightypork.rogue.world.gen.TileProtectLevel; +import mightypork.rogue.world.tile.TileModel; + + +public class ExitRoom extends AbstractRectRoom { + + @Override + protected Coord getInnerSize(Random rand) + { + return Coord.make(3, 3); + } + + + @Override + protected TileProtectLevel getWallProtectionLevel() + { + return TileProtectLevel.NONE; + } + + + @Override + protected TileModel getDoorType(MapTheme theme, Random rand) + { + return null; + } + + + @Override + protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) + { + final Coord c = Coord.make((max.x + min.x) / 2, (max.y + min.y) / 2); + map.set(c, theme.exit()); + map.protect(c, c, TileProtectLevel.STRONG); + map.setExit(c.add(-1, 0)); + } + + + @Override + protected int getDoorCount(Random rand) + { + return 0; + } + +} diff --git a/src/mightypork/rogue/world/gen/rooms/Rooms.java b/src/mightypork/rogue/world/gen/rooms/Rooms.java index 1a3add8..5a02c90 100644 --- a/src/mightypork/rogue/world/gen/rooms/Rooms.java +++ b/src/mightypork/rogue/world/gen/rooms/Rooms.java @@ -9,4 +9,6 @@ public class Rooms { public static final RoomBuilder BASIC = new BasicRoom(); public static final RoomBuilder SECRET = new SecretRoom(); public static final RoomBuilder DEAD_END = new DeadEndRoom(); + public static final RoomBuilder ENTRANCE = new EntranceRoom(); + public static final RoomBuilder EXIT = new ExitRoom(); } diff --git a/src/mightypork/rogue/world/gen/themes/ThemeBrick.java b/src/mightypork/rogue/world/gen/themes/ThemeBrick.java index 1695c10..830ff67 100644 --- a/src/mightypork/rogue/world/gen/themes/ThemeBrick.java +++ b/src/mightypork/rogue/world/gen/themes/ThemeBrick.java @@ -42,4 +42,18 @@ public class ThemeBrick implements MapTheme { { return Tiles.BRICK_HIDDEN_DOOR; } + + + @Override + public TileModel entrance() + { + return Tiles.BRICK_ENTRANCE; + } + + + @Override + public TileModel exit() + { + return Tiles.BRICK_EXIT; + } } diff --git a/src/mightypork/rogue/world/gui/MapView.java b/src/mightypork/rogue/world/gui/MapView.java index 08e391b..2144a51 100644 --- a/src/mightypork/rogue/world/gui/MapView.java +++ b/src/mightypork/rogue/world/gui/MapView.java @@ -13,14 +13,21 @@ 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; import mightypork.gamecore.util.math.Easing; import mightypork.gamecore.util.math.algo.Coord; +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.vect.Vect; +import mightypork.gamecore.util.math.timing.TimedTask; import mightypork.rogue.world.PlayerControl; +import mightypork.rogue.world.World; import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.WorldRenderer; +import mightypork.rogue.world.events.WorldAscendRequestListener; +import mightypork.rogue.world.events.WorldDescendRequestListener; import mightypork.rogue.world.gui.interaction.MapInteractionPlugin; @@ -29,7 +36,10 @@ import mightypork.rogue.world.gui.interaction.MapInteractionPlugin; * * @author MightyPork */ -public class MapView extends InputComponent implements DelegatingClient, KeyListener, MouseButtonListener, Updateable { +public class MapView extends InputComponent implements DelegatingClient, KeyListener, MouseButtonListener, Updateable, WorldAscendRequestListener, + WorldDescendRequestListener { + + private static final double transition_time = 0.8; protected final WorldRenderer worldRenderer; public final PlayerControl playerControl; @@ -38,6 +48,36 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList private final NumAnimated zoom = new NumAnimated(0, Easing.SINE_BOTH); private boolean zoom_in = true; + private NumAnimated descFadeAnim = new NumAnimated(0); + private Color blackColor = RGB.BLACK.withAlpha(descFadeAnim); + + private int descDir = 0; + + private TimedTask timerDesc1 = new TimedTask() { + + @Override + public void run() + { + descFadeAnim.fadeOut(transition_time); + timerDesc2.start(transition_time); + if (descDir == 1) { + WorldProvider.get().getWorld().descend(); + } else { + WorldProvider.get().getWorld().ascend(); + } + } + }; + + private TimedTask timerDesc2 = new TimedTask() { + + @Override + public void run() + { + WorldProvider.get().getWorld().resume(); + } + }; + + private final Num tileSize; @@ -70,6 +110,8 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList protected void renderComponent() { worldRenderer.render(); + + Render.quadColor(this, blackColor); } @@ -114,10 +156,6 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList @Override public void receive(KeyEvent event) { - for (final MapInteractionPlugin p : plugins) { - if (p.onKey(event.getKey(), event.isDown())) break; - } - if (event.getKey() == Keys.Z && event.isDown()) { if (zoom_in) { zoom.fadeIn(); @@ -147,5 +185,47 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList public void update(double delta) { zoom.update(delta); + descFadeAnim.update(delta); + timerDesc1.update(delta); + timerDesc2.update(delta); + } + + + @Override + public void onAscendRequest() + { + if(descFadeAnim.isInProgress()) return; + + World w = WorldProvider.get().getWorld(); + + if (w.canAscend()) { + descDir = -1; + startDescAnim(); + } + } + + + private void startDescAnim() + { + WorldProvider.get().getWorld().pause(); + + timerDesc2.stop(); + timerDesc1.start(transition_time); + descFadeAnim.setTo(0); + descFadeAnim.fadeIn(transition_time); + } + + + @Override + public void onDescendRequest() + { + if(descFadeAnim.isInProgress()) return; + + World w = WorldProvider.get().getWorld(); + + if (w.canDescend()) { + descDir = 1; + startDescAnim(); + } } } diff --git a/src/mightypork/rogue/world/gui/Minimap.java b/src/mightypork/rogue/world/gui/Minimap.java index 524956a..4a611c9 100644 --- a/src/mightypork/rogue/world/gui/Minimap.java +++ b/src/mightypork/rogue/world/gui/Minimap.java @@ -14,7 +14,7 @@ import mightypork.gamecore.util.math.constraints.rect.mutable.RectMutable; import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.level.LevelReadAccess; +import mightypork.rogue.world.level.Level; import mightypork.rogue.world.tile.Tile; import org.lwjgl.opengl.GL11; @@ -33,7 +33,7 @@ public class Minimap extends InputComponent implements MouseButtonListener { { Color.pushAlpha(translucency); - final LevelReadAccess lvl = WorldProvider.get().getCurrentLevel(); + final Level lvl = WorldProvider.get().getCurrentLevel(); unit = (int) Math.min(Math.max(2, Math.ceil((height().value() / 2) / (lvl.getHeight() + 2))), 10); final Entity e = WorldProvider.get().getPlayerEntity(); @@ -89,7 +89,7 @@ public class Minimap extends InputComponent implements MouseButtonListener { @Override public void receive(MouseButtonEvent event) { - if (event.isOver(bounds) && event.getButton() == 0) { + if (event.isOver(bounds) && event.getButton() == 1) { if (event.isUp()) { final Vect relative = event.getPos().sub(bounds.origin()); final Coord actual = Coord.make(relative.xi() / unit, relative.yi() / unit); diff --git a/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java b/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java index f5b539d..92ee542 100644 --- a/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java +++ b/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java @@ -1,16 +1,20 @@ package mightypork.rogue.world.gui.interaction; +import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.input.InputSystem; import mightypork.gamecore.input.Keys; +import mightypork.gamecore.input.events.KeyEvent; +import mightypork.gamecore.input.events.KeyListener; import mightypork.gamecore.util.math.algo.Sides; import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.rogue.world.entity.entities.PlayerEntity; +import mightypork.rogue.world.events.PlayerStepEndListener; import mightypork.rogue.world.gui.MapView; -public class MIPKeyboard extends MapInteractionPlugin { +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 Step[] sides = { Sides.W, Sides.E, Sides.N, Sides.S }; @@ -37,23 +41,21 @@ public class MIPKeyboard extends MapInteractionPlugin { @Override - public boolean onKey(int key, boolean down) + public void receive(KeyEvent evt) { - if (down) return false; // not interested + if (evt.isDown() || mapView.playerControl.getPlayerEntity().pos.isMoving()) return; // not interested for (int i = 0; i < 4; i++) { - if (key == keys[i]) { - return mapView.playerControl.clickTile(sides[i]); + if (evt.getKey() == keys[i]) { + mapView.playerControl.clickTile(sides[i]); } } - - return false; } private boolean walkByKey() { - if (mapView.playerControl.getPlayerEntity().pos.isMoving()) return false; + if (mapView.playerControl.getPlayerEntity().pos.getProgress()<0.8) return false; for (int i = 0; i < 4; i++) { if (InputSystem.isKeyDown(keys[i])) { diff --git a/src/mightypork/rogue/world/gui/interaction/MIPMouse.java b/src/mightypork/rogue/world/gui/interaction/MIPMouse.java index d19f893..b4c3903 100644 --- a/src/mightypork/rogue/world/gui/interaction/MIPMouse.java +++ b/src/mightypork/rogue/world/gui/interaction/MIPMouse.java @@ -1,19 +1,20 @@ package mightypork.rogue.world.gui.interaction; +import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.input.InputSystem; -import mightypork.gamecore.input.Keys; import mightypork.gamecore.util.math.Calc.Deg; import mightypork.gamecore.util.math.Polar; import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Sides; import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.rogue.world.entity.entities.PlayerEntity; +import mightypork.rogue.world.events.PlayerStepEndListener; import mightypork.rogue.world.gui.MapView; import mightypork.rogue.world.tile.Tile; -public class MIPMouse extends MapInteractionPlugin { +public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListener, Updateable { private static final int BTN = 0; // left @@ -27,13 +28,12 @@ public class MIPMouse extends MapInteractionPlugin { @Override public void update(double delta) { - if (!InputSystem.isKeyDown(Keys.L_SHIFT)) return; - final Vect pos = InputSystem.getMousePos(); + if (!pos.isInside(mapView)) return; if (InputSystem.isMouseButtonDown(BTN)) { if (mouseWalk(pos)) return; - if (troToNav(pos)) return; + if (mapView.playerControl.getPlayerEntity().pos.isMoving() && troToNav(pos)) return; } } @@ -41,13 +41,14 @@ public class MIPMouse extends MapInteractionPlugin { @Override public boolean onClick(Vect mouse, int button, boolean down) { - if (button != BTN) return false; final Coord pos = mapView.toWorldPos(mouse); final Tile t = mapView.playerControl.getLevel().getTile(pos); - if (t.onClick()) return true; + if (button == BTN && !down && t.onClick()) { + return true; + } - if (!down && t.isWalkable()) { + if (button == 1 && !down && t.isWalkable()) { if (troToNav(mouse)) return true; return mouseWalk(mouse); } @@ -97,24 +98,15 @@ public class MIPMouse extends MapInteractionPlugin { return false; } - - @Override - public boolean onKey(int key, boolean down) - { - return false; - } - - @Override public void onStepFinished(PlayerEntity player) { - if (!InputSystem.isKeyDown(Keys.L_SHIFT)) return; - final Vect pos = InputSystem.getMousePos(); + if (!pos.isInside(mapView)) return; if (InputSystem.isMouseButtonDown(BTN)) { if (mouseWalk(pos)) return; - if (troToNav(pos)) return; + if (mapView.playerControl.getPlayerEntity().pos.isMoving() && troToNav(pos)) return; } } diff --git a/src/mightypork/rogue/world/gui/interaction/MapInteractionPlugin.java b/src/mightypork/rogue/world/gui/interaction/MapInteractionPlugin.java index ceaa54d..cc8c08b 100644 --- a/src/mightypork/rogue/world/gui/interaction/MapInteractionPlugin.java +++ b/src/mightypork/rogue/world/gui/interaction/MapInteractionPlugin.java @@ -2,12 +2,14 @@ package mightypork.rogue.world.gui.interaction; import mightypork.gamecore.eventbus.events.Updateable; +import mightypork.gamecore.input.events.KeyEvent; +import mightypork.gamecore.input.events.KeyListener; import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.rogue.world.events.PlayerStepEndListener; import mightypork.rogue.world.gui.MapView; -public abstract class MapInteractionPlugin implements Updateable, PlayerStepEndListener { +public abstract class MapInteractionPlugin { protected final MapView mapView; @@ -20,12 +22,4 @@ public abstract class MapInteractionPlugin implements Updateable, PlayerStepEndL public abstract boolean onClick(Vect mouse, int button, boolean down); - - - public abstract boolean onKey(int key, boolean down); - - - @Override - public abstract void update(double delta); - } diff --git a/src/mightypork/rogue/world/item/items/ItemMeat.java b/src/mightypork/rogue/world/item/items/ItemMeat.java index f616305..688a81c 100644 --- a/src/mightypork/rogue/world/item/items/ItemMeat.java +++ b/src/mightypork/rogue/world/item/items/ItemMeat.java @@ -19,7 +19,7 @@ public class ItemMeat extends Item { @Override protected ItemRenderer makeRenderer() { - return new QuadItemRenderer(Res.getTxQuad("item.meat")); + return new QuadItemRenderer(Res.txq("item.meat")); } } diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index 111f850..2046f9c 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -8,6 +8,7 @@ import mightypork.gamecore.eventbus.BusAccess; import mightypork.gamecore.eventbus.EventBus; import mightypork.gamecore.eventbus.clients.DelegatingClient; import mightypork.gamecore.eventbus.clients.ToggleableClient; +import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.logging.Log; import mightypork.gamecore.util.ion.IonBundle; import mightypork.gamecore.util.ion.IonInput; @@ -34,7 +35,7 @@ import mightypork.rogue.world.tile.Tiles; * * @author MightyPork */ -public class Level implements BusAccess, DelegatingClient, ToggleableClient, LevelAccess, IonObjBinary { +public class Level implements BusAccess, Updateable, DelegatingClient, ToggleableClient, IonObjBinary { public static final int ION_MARK = 53; @@ -42,6 +43,7 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev private World world; private final Coord enterPoint = Coord.zero(); + private final Coord exitPoint = Coord.zero(); /** Array of tiles [y][x] */ private Tile[][] tiles; @@ -75,7 +77,11 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * Fill whole map with tile type + * + * @param model tile model + */ public void fill(TileModel model) { for (final Coord c = Coord.zero(); c.x < size.x; c.x++) { @@ -86,7 +92,12 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * Ge tile at X,Y + * + * @param pos + * @return tile + */ public final Tile getTile(Coord pos) { if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) return Tiles.NULL.createTile(); // out of range @@ -95,7 +106,12 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * Set tile at pos + * + * @param pos tile pos + * @param tile the tile instance to set + */ public final void setTile(Coord pos, Tile tile) { if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) { @@ -110,28 +126,38 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * @return map width in tiles + */ public final int getWidth() { return size.x; } - @Override + /** + * @return map height in tiles + */ public final int getHeight() { return size.y; } - @Override + /** + * Set level seed (used for visuals; the seed used for generation) + * + * @param seed seed + */ public void setSeed(long seed) { this.seed = seed; } - @Override + /** + * @return map seed + */ public long getSeed() { return seed; @@ -146,6 +172,7 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev seed = ib.get("seed", 0L); ib.loadBundled("size", size); ib.loadBundled("enter_point", enterPoint); + ib.loadBundled("exit_point", exitPoint); // -- binary data -- @@ -178,6 +205,7 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev ib.put("seed", seed); ib.putBundled("size", size); ib.putBundled("enter_point", enterPoint); + ib.putBundled("exit_point", exitPoint); out.writeBundle(ib); // -- binary data -- @@ -222,7 +250,9 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * @return level-specific noise generator + */ public NoiseGen getNoiseGen() { if (noiseGen == null) { @@ -233,14 +263,25 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * Get entity by ID + * + * @param eid entity ID + * @return the entity, or null + */ public Entity getEntity(int eid) { return entityMap.get(eid); } - @Override + /** + * Try to add entity at given pos + * + * @param entity the entity + * @param pos pos + * @return true if added (false if void, wall etc) + */ public boolean addEntity(Entity entity, Coord pos) { final Tile t = getTile(pos); @@ -265,14 +306,22 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * Remove an entity from the level, if present + * + * @param entity entity + */ public void removeEntity(Entity entity) { removeEntity(entity.getEntityId()); } - @Override + /** + * Remove an entity from the level, if present + * + * @param eid entity id + */ public void removeEntity(int eid) { final Entity removed = entityMap.remove(eid); @@ -283,7 +332,12 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * Check tile walkability + * + * @param pos tile coord + * @return true if the tile is walkable by entity + */ public boolean isWalkable(Coord pos) { final Tile t = getTile(pos); @@ -293,9 +347,10 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev /** - * Mark tile as occupied by an entity + * Mark tile as occupied (entity entered) + * + * @param pos tile pos */ - @Override public void occupyTile(Coord pos) { getTile(pos).setOccupied(true); @@ -303,58 +358,99 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev /** - * Mark tile as free (no longet occupied) + * Mark tile as free (entity left) + * + * @param pos tile pos */ - @Override public void freeTile(Coord pos) { getTile(pos).setOccupied(false); } - @Override + /** + * Check entity on tile + * + * @param pos tile coord + * @return true if some entity is standing there + */ public boolean isOccupied(Coord pos) { return getTile(pos).isOccupied(); } - @Override - public Collection getEntities() - { - return entitySet; - } - - - @Override + /** + * Set level entry point + * + * @param pos pos where the player appears upon descending to this level + */ public void setEnterPoint(Coord pos) { this.enterPoint.setTo(pos); } - @Override + /** + * Get location where the player appears upon descending to this level + * + * @return pos + */ public Coord getEnterPoint() { return enterPoint; } - @Override + /** + * Set level exit point + * + * @param pos pos where the player appears upon ascending to this level + */ + public void setExitPoint(Coord pos) + { + this.exitPoint.setTo(pos); + } + + + /** + * Get location where the player appears upon ascending to this level + * + * @return pos + */ + public Coord getExitPoint() + { + return exitPoint; + } + + + /** + * Get the level's world + * + * @return world + */ public World getWorld() { return world; } - @Override + /** + * Assign a world + * + * @param world new world + */ public void setWorld(World world) { this.world = world; } - @Override + /** + * Mark tile and surrounding area as explored + * + * @param center center the explored tile + */ public void explore(Coord center) { final Collection filled = new HashSet<>(); @@ -406,7 +502,15 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev }; - @Override + /** + * Get entity of type closest to coord + * + * @param self the querying entity - to provide position, and to be excluded + * from the search. + * @param type wanted entity type + * @param radius search radius; -1 for unlimited. + * @return + */ public Entity getClosestEntity(Entity self, EntityType type, double radius) { Entity closest = null; @@ -430,6 +534,11 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } + /** + * Free a tile. If entity is present, remove it. + * + * @param pos the tile pos + */ public void forceFreeTile(Coord pos) { if (getTile(pos).isOccupied()) { @@ -450,20 +559,41 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev } - @Override + /** + * Check if entity is in the level + * + * @param entity entity + * @return is present + */ public boolean isEntityPresent(Entity entity) { return entitySet.contains(entity); } - @Override + /** + * Check if entity is in the level + * + * @param eid entity ID + * @return true if present + */ public boolean isEntityPresent(int eid) { return entityMap.containsKey(eid); } + /** + * Get entity collection (for rendering) + * + * @return entities + */ + public Collection getEntities() + { + return entitySet; + } + + @Override public EventBus getEventBus() { diff --git a/src/mightypork/rogue/world/level/LevelAccess.java b/src/mightypork/rogue/world/level/LevelAccess.java deleted file mode 100644 index 29dee0d..0000000 --- a/src/mightypork/rogue/world/level/LevelAccess.java +++ /dev/null @@ -1,109 +0,0 @@ -package mightypork.rogue.world.level; - - -import mightypork.gamecore.eventbus.events.Updateable; -import mightypork.gamecore.util.math.algo.Coord; -import mightypork.rogue.world.World; -import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.tile.Tile; -import mightypork.rogue.world.tile.TileModel; - - -/** - * Level full access - * - * @author MightyPork - */ -public interface LevelAccess extends LevelReadAccess, Updateable { - - - /** - * Mark tile and surrounding area as explored - * - * @param center center the explored tile - */ - public abstract void explore(Coord center); - - - /** - * Assign a world - * - * @param world new world - */ - public abstract void setWorld(World world); - - - /** - * Set level entry point - * - * @param pos pos where the player enters - */ - public abstract void setEnterPoint(Coord pos); - - - /** - * Mark tile as free (entity left) - * - * @param pos tile pos - */ - public abstract void freeTile(Coord pos); - - - /** - * Mark tile as occupied (entity entered) - * - * @param pos tile pos - */ - public abstract void occupyTile(Coord pos); - - - /** - * Remove an entity from the level, if present - * - * @param eid entity id - */ - public abstract void removeEntity(int eid); - - - /** - * Remove an entity from the level, if present - * - * @param entity entity - */ - public abstract void removeEntity(Entity entity); - - - /** - * Set level seed (used for visuals; the seed used for generation) - * - * @param seed seed - */ - public abstract void setSeed(long seed); - - - /** - * Set tile at pos - * - * @param pos tile pos - * @param tile the tile instance to set - */ - public abstract void setTile(Coord pos, Tile tile); - - - /** - * Fill whole map with tile type - * - * @param model tile model - */ - public abstract void fill(TileModel model); - - - /** - * Try to add entity at given pos - * - * @param entity the entity - * @param pos pos - * @return true if added (false if void, wall etc) - */ - public abstract boolean addEntity(Entity entity, Coord pos); -} diff --git a/src/mightypork/rogue/world/level/LevelReadAccess.java b/src/mightypork/rogue/world/level/LevelReadAccess.java deleted file mode 100644 index e9b34ed..0000000 --- a/src/mightypork/rogue/world/level/LevelReadAccess.java +++ /dev/null @@ -1,127 +0,0 @@ -package mightypork.rogue.world.level; - - -import java.util.Collection; - -import mightypork.gamecore.util.math.algo.Coord; -import mightypork.gamecore.util.math.noise.NoiseGen; -import mightypork.rogue.world.World; -import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.entity.EntityType; -import mightypork.rogue.world.tile.Tile; - - -public interface LevelReadAccess { - - /** - * Ge tile at X,Y - * - * @param pos - * @return tile - */ - Tile getTile(Coord pos); - - - /** - * @return map width in tiles - */ - int getWidth(); - - - /** - * @return map height in tiles - */ - int getHeight(); - - - /** - * @return map seed - */ - long getSeed(); - - - /** - * @return level-specific noise generator - */ - NoiseGen getNoiseGen(); - - - /** - * Check if entity is in the level - * - * @param entity entity - * @return is present - */ - boolean isEntityPresent(Entity entity); - - - /** - * Check if entity is in the level - * - * @param eid entity ID - * @return true if present - */ - boolean isEntityPresent(int eid); - - - /** - * Get entity of type closest to coord - * - * @param self the querying entity - to provide position, and to be excluded - * from the search. - * @param type wanted entity type - * @param radius search radius; -1 for unlimited. - * @return - */ - Entity getClosestEntity(Entity self, EntityType type, double radius); - - - /** - * Get the level's world - * - * @return world - */ - World getWorld(); - - - /** - * Get location where the player enters the level - * - * @return pos - */ - Coord getEnterPoint(); - - - /** - * Check entity on tile - * - * @param pos tile coord - * @return true if some entity is standing there - */ - boolean isOccupied(Coord pos); - - - /** - * Check tile walkability - * - * @param pos tile coord - * @return true if the tile is walkable by entity - */ - boolean isWalkable(Coord pos); - - - /** - * Get entity by ID - * - * @param eid entity ID - * @return the entity, or null - */ - Entity getEntity(int eid); - - - /** - * @return all entities - */ - Collection getEntities(); - -} diff --git a/src/mightypork/rogue/world/level/render/EntityRenderContext.java b/src/mightypork/rogue/world/level/render/EntityRenderContext.java index cd183a9..16c06bd 100644 --- a/src/mightypork/rogue/world/level/render/EntityRenderContext.java +++ b/src/mightypork/rogue/world/level/render/EntityRenderContext.java @@ -2,12 +2,12 @@ package mightypork.rogue.world.level.render; import mightypork.gamecore.util.math.constraints.rect.Rect; -import mightypork.rogue.world.level.LevelReadAccess; +import mightypork.rogue.world.level.Level; public class EntityRenderContext extends MapRenderContext { - public EntityRenderContext(LevelReadAccess map, Rect drawArea) + public EntityRenderContext(Level map, Rect drawArea) { super(map, drawArea); } diff --git a/src/mightypork/rogue/world/level/render/MapRenderContext.java b/src/mightypork/rogue/world/level/render/MapRenderContext.java index a08b70a..0e9b28c 100644 --- a/src/mightypork/rogue/world/level/render/MapRenderContext.java +++ b/src/mightypork/rogue/world/level/render/MapRenderContext.java @@ -4,18 +4,18 @@ package mightypork.rogue.world.level.render; import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.builders.TiledRect; -import mightypork.rogue.world.level.LevelReadAccess; +import mightypork.rogue.world.level.Level; import mightypork.rogue.world.tile.Tile; public abstract class MapRenderContext { - protected final LevelReadAccess map; + protected final Level map; protected final TiledRect tiler; private final Rect mapRect; - public MapRenderContext(LevelReadAccess map, Rect drawArea) + public MapRenderContext(Level map, Rect drawArea) { this.map = map; diff --git a/src/mightypork/rogue/world/level/render/TileRenderContext.java b/src/mightypork/rogue/world/level/render/TileRenderContext.java index f2472fd..6bc7db6 100644 --- a/src/mightypork/rogue/world/level/render/TileRenderContext.java +++ b/src/mightypork/rogue/world/level/render/TileRenderContext.java @@ -6,7 +6,7 @@ import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound; import mightypork.gamecore.util.math.noise.NoiseGen; -import mightypork.rogue.world.level.LevelReadAccess; +import mightypork.rogue.world.level.Level; import mightypork.rogue.world.tile.Tile; @@ -21,7 +21,7 @@ public final class TileRenderContext extends MapRenderContext implements RectBou private final NoiseGen noise; - public TileRenderContext(LevelReadAccess map, Rect drawArea) + public TileRenderContext(Level map, Rect drawArea) { super(map, drawArea); diff --git a/src/mightypork/rogue/world/tile/Tile.java b/src/mightypork/rogue/world/tile/Tile.java index daeb817..6177872 100644 --- a/src/mightypork/rogue/world/tile/Tile.java +++ b/src/mightypork/rogue/world/tile/Tile.java @@ -4,6 +4,8 @@ package mightypork.rogue.world.tile; import java.io.IOException; import java.util.Random; +import mightypork.gamecore.eventbus.BusAccess; +import mightypork.gamecore.eventbus.EventBus; import mightypork.gamecore.logging.Log; import mightypork.gamecore.util.annot.DefaultImpl; import mightypork.gamecore.util.ion.IonInput; @@ -12,7 +14,7 @@ import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.math.color.Color; import mightypork.rogue.world.World; import mightypork.rogue.world.item.Item; -import mightypork.rogue.world.level.LevelAccess; +import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.render.TileRenderContext; @@ -21,7 +23,7 @@ import mightypork.rogue.world.level.render.TileRenderContext; * * @author MightyPork */ -public abstract class Tile implements IonObjBlob { +public abstract class Tile implements BusAccess, IonObjBlob { // tmp extras public final TileGenData genData = new TileGenData(); @@ -35,7 +37,7 @@ public abstract class Tile implements IonObjBlob { protected boolean occupied; protected boolean explored; - protected LevelAccess level; + protected Level level; private TileRenderer renderer; @@ -157,6 +159,12 @@ public abstract class Tile implements IonObjBlob { } + public final boolean isStairs() + { + return getType() == TileType.STAIRS; + } + + @DefaultImpl public void updateTile(double delta) { @@ -244,13 +252,13 @@ public abstract class Tile implements IonObjBlob { } - public void setLevel(LevelAccess level) + public void setLevel(Level level) { this.level = level; } - public LevelAccess getLevel() + public Level getLevel() { return level; } @@ -261,4 +269,11 @@ public abstract class Tile implements IonObjBlob { return level.getWorld(); } + + @Override + public EventBus getEventBus() + { + return level.getEventBus(); + } + } diff --git a/src/mightypork/rogue/world/tile/TileRenderer.java b/src/mightypork/rogue/world/tile/TileRenderer.java index 8a304dc..5e55d91 100644 --- a/src/mightypork/rogue/world/tile/TileRenderer.java +++ b/src/mightypork/rogue/world/tile/TileRenderer.java @@ -44,23 +44,23 @@ public abstract class TileRenderer implements Updateable { this.tile = tile; if (!inited) { - SH_N = Res.getTxQuad("tile.shadow.n"); - SH_S = Res.getTxQuad("tile.shadow.s"); - SH_E = Res.getTxQuad("tile.shadow.e"); - SH_W = Res.getTxQuad("tile.shadow.w"); - SH_NW = Res.getTxQuad("tile.shadow.nw"); - SH_NE = Res.getTxQuad("tile.shadow.ne"); - SH_SW = Res.getTxQuad("tile.shadow.sw"); - SH_SE = Res.getTxQuad("tile.shadow.se"); + SH_N = Res.txq("tile.shadow.n"); + SH_S = Res.txq("tile.shadow.s"); + SH_E = Res.txq("tile.shadow.e"); + SH_W = Res.txq("tile.shadow.w"); + SH_NW = Res.txq("tile.shadow.nw"); + SH_NE = Res.txq("tile.shadow.ne"); + SH_SW = Res.txq("tile.shadow.sw"); + SH_SE = Res.txq("tile.shadow.se"); - UFOG_N = Res.getTxQuad("tile.ufog.n"); - UFOG_S = Res.getTxQuad("tile.ufog.s"); - UFOG_E = Res.getTxQuad("tile.ufog.e"); - UFOG_W = Res.getTxQuad("tile.ufog.w"); - UFOG_NW = Res.getTxQuad("tile.ufog.nw"); - UFOG_NE = Res.getTxQuad("tile.ufog.ne"); - UFOG_SW = Res.getTxQuad("tile.ufog.sw"); - UFOG_SE = Res.getTxQuad("tile.ufog.se"); + UFOG_N = Res.txq("tile.ufog.n"); + UFOG_S = Res.txq("tile.ufog.s"); + UFOG_E = Res.txq("tile.ufog.e"); + UFOG_W = Res.txq("tile.ufog.w"); + UFOG_NW = Res.txq("tile.ufog.nw"); + UFOG_NE = Res.txq("tile.ufog.ne"); + UFOG_SW = Res.txq("tile.ufog.sw"); + UFOG_SE = Res.txq("tile.ufog.se"); } } diff --git a/src/mightypork/rogue/world/tile/TileType.java b/src/mightypork/rogue/world/tile/TileType.java index 75fa196..4c1a8d6 100644 --- a/src/mightypork/rogue/world/tile/TileType.java +++ b/src/mightypork/rogue/world/tile/TileType.java @@ -22,7 +22,9 @@ public enum TileType /** Door/gate tile */ DOOR(PAL16.NEWPOOP, true), /** Passage (ie secret door) */ - PASSAGE(RGB.GRAY, true); + PASSAGE(RGB.GRAY, true), + /** Stairs */ + STAIRS(RGB.CYAN, false); private final Color mapColor; private final boolean potentiallyWalkable; diff --git a/src/mightypork/rogue/world/tile/Tiles.java b/src/mightypork/rogue/world/tile/Tiles.java index a373cfe..33bf083 100644 --- a/src/mightypork/rogue/world/tile/Tiles.java +++ b/src/mightypork/rogue/world/tile/Tiles.java @@ -6,11 +6,7 @@ import java.io.IOException; import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonOutput; import mightypork.rogue.world.tile.tiles.NullTile; -import mightypork.rogue.world.tile.tiles.brick.TileBrickDoor; -import mightypork.rogue.world.tile.tiles.brick.TileBrickFloor; -import mightypork.rogue.world.tile.tiles.brick.TileBrickPassage; -import mightypork.rogue.world.tile.tiles.brick.TileBrickSecretDoor; -import mightypork.rogue.world.tile.tiles.brick.TileBrickWall; +import mightypork.rogue.world.tile.tiles.brick.*; /** @@ -29,6 +25,8 @@ public final class Tiles { public static final TileModel BRICK_DOOR = new TileModel(12, TileBrickDoor.class); public static final TileModel BRICK_PASSAGE = new TileModel(13, TileBrickPassage.class); public static final TileModel BRICK_HIDDEN_DOOR = new TileModel(14, TileBrickSecretDoor.class); + public static final TileModel BRICK_ENTRANCE = new TileModel(15, TileBrickEntrance.class); + public static final TileModel BRICK_EXIT = new TileModel(16, TileBrickExit.class); public static void register(int id, TileModel model) diff --git a/src/mightypork/rogue/world/tile/render/OneFrameTileRenderer.java b/src/mightypork/rogue/world/tile/render/OneFrameTileRenderer.java new file mode 100644 index 0000000..b9d1547 --- /dev/null +++ b/src/mightypork/rogue/world/tile/render/OneFrameTileRenderer.java @@ -0,0 +1,33 @@ +package mightypork.rogue.world.tile.render; + + +import mightypork.gamecore.render.Render; +import mightypork.gamecore.resources.textures.TxQuad; +import mightypork.rogue.world.level.render.TileRenderContext; +import mightypork.rogue.world.tile.Tile; +import mightypork.rogue.world.tile.TileRenderer; + + +/** + * Tile that spans across two tiles visually (two-high) + * + * @author MightyPork + */ +public class OneFrameTileRenderer extends TileRenderer { + + private final TxQuad txq; + + + public OneFrameTileRenderer(Tile tile, TxQuad txq) + { + super(tile); + this.txq = txq; + } + + + @Override + public void renderTile(TileRenderContext context) + { + Render.quadTextured(context.getRect(), txq); + } +} diff --git a/src/mightypork/rogue/world/tile/render/TwoHighTileRenderer.java b/src/mightypork/rogue/world/tile/render/TwoHighTileRenderer.java new file mode 100644 index 0000000..32b4b32 --- /dev/null +++ b/src/mightypork/rogue/world/tile/render/TwoHighTileRenderer.java @@ -0,0 +1,35 @@ +package mightypork.rogue.world.tile.render; + + +import mightypork.gamecore.render.Render; +import mightypork.gamecore.resources.textures.TxQuad; +import mightypork.gamecore.util.math.constraints.rect.Rect; +import mightypork.rogue.world.level.render.TileRenderContext; +import mightypork.rogue.world.tile.Tile; +import mightypork.rogue.world.tile.TileRenderer; + + +/** + * Tile that spans across two tiles visually (two-high) + * + * @author MightyPork + */ +public class TwoHighTileRenderer extends TileRenderer { + + private final TxQuad txq; + + + public TwoHighTileRenderer(Tile tile, TxQuad txq) + { + super(tile); + this.txq = txq; + } + + + @Override + public void renderTile(TileRenderContext context) + { + final Rect rect = context.getRect(); + Render.quadTextured(rect.growUp(rect.height()), txq); + } +} diff --git a/src/mightypork/rogue/world/tile/tiles/TileBaseEntrance.java b/src/mightypork/rogue/world/tile/tiles/TileBaseEntrance.java new file mode 100644 index 0000000..ea9117e --- /dev/null +++ b/src/mightypork/rogue/world/tile/tiles/TileBaseEntrance.java @@ -0,0 +1,34 @@ +package mightypork.rogue.world.tile.tiles; + + +import mightypork.gamecore.util.math.algo.Coord; +import mightypork.rogue.world.events.WorldAscendRequest; +import mightypork.rogue.world.tile.TileModel; + + +public abstract class TileBaseEntrance extends TileBaseStairs { + + public TileBaseEntrance(TileModel model) + { + super(model); + } + + + @Override + public boolean onClick() + { + Coord plpos = getWorld().getPlayerEntity().getCoord(); + if(!plpos.equals(getLevel().getEnterPoint())) return false; + + getEventBus().send(new WorldAscendRequest()); + + return true; + } + + + @Override + public boolean doesCastShadow() + { + return false; + } +} diff --git a/src/mightypork/rogue/world/tile/tiles/TileBaseExit.java b/src/mightypork/rogue/world/tile/tiles/TileBaseExit.java new file mode 100644 index 0000000..5f0bf98 --- /dev/null +++ b/src/mightypork/rogue/world/tile/tiles/TileBaseExit.java @@ -0,0 +1,34 @@ +package mightypork.rogue.world.tile.tiles; + + +import mightypork.gamecore.util.math.algo.Coord; +import mightypork.rogue.world.events.WorldDescendRequest; +import mightypork.rogue.world.tile.TileModel; + + +public abstract class TileBaseExit extends TileBaseStairs { + + public TileBaseExit(TileModel model) + { + super(model); + } + + + @Override + public boolean onClick() + { + Coord plpos = getWorld().getPlayerEntity().getCoord(); + if(!plpos.equals(getLevel().getExitPoint())) return false; + + getEventBus().send(new WorldDescendRequest()); + + return true; + } + + + @Override + public boolean doesCastShadow() + { + return false; + } +} diff --git a/src/mightypork/rogue/world/tile/tiles/TileBaseStairs.java b/src/mightypork/rogue/world/tile/tiles/TileBaseStairs.java new file mode 100644 index 0000000..22e7196 --- /dev/null +++ b/src/mightypork/rogue/world/tile/tiles/TileBaseStairs.java @@ -0,0 +1,22 @@ +package mightypork.rogue.world.tile.tiles; + + +import mightypork.rogue.world.tile.TileModel; +import mightypork.rogue.world.tile.TileType; + + +public abstract class TileBaseStairs extends TileSolid { + + public TileBaseStairs(TileModel model) + { + super(model); + } + + + @Override + public TileType getType() + { + return TileType.STAIRS; + } + +} diff --git a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickDoor.java b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickDoor.java index 7dd6d07..ab61d57 100644 --- a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickDoor.java +++ b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickDoor.java @@ -13,9 +13,9 @@ public class TileBrickDoor extends TileBaseDoor { //@formatter:off super( model, - Res.sheet("tile.brick.door.locked"), - Res.sheet("tile.brick.door.closed"), - Res.sheet("tile.brick.door.open") + Res.txs("tile.brick.door.locked"), + Res.txs("tile.brick.door.closed"), + Res.txs("tile.brick.door.open") ); //@formatter:on } diff --git a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickEntrance.java b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickEntrance.java new file mode 100644 index 0000000..0c8a74b --- /dev/null +++ b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickEntrance.java @@ -0,0 +1,25 @@ +package mightypork.rogue.world.tile.tiles.brick; + + +import mightypork.rogue.Res; +import mightypork.rogue.world.tile.TileModel; +import mightypork.rogue.world.tile.TileRenderer; +import mightypork.rogue.world.tile.render.OneFrameTileRenderer; +import mightypork.rogue.world.tile.tiles.TileBaseEntrance; + + +public class TileBrickEntrance extends TileBaseEntrance { + + public TileBrickEntrance(TileModel model) + { + super(model); + } + + + @Override + protected TileRenderer makeRenderer() + { + return new OneFrameTileRenderer(this, Res.txq("tile.brick.stairs.up")); + } + +} diff --git a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickExit.java b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickExit.java new file mode 100644 index 0000000..7e19882 --- /dev/null +++ b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickExit.java @@ -0,0 +1,25 @@ +package mightypork.rogue.world.tile.tiles.brick; + + +import mightypork.rogue.Res; +import mightypork.rogue.world.tile.TileModel; +import mightypork.rogue.world.tile.TileRenderer; +import mightypork.rogue.world.tile.render.OneFrameTileRenderer; +import mightypork.rogue.world.tile.tiles.TileBaseExit; + + +public class TileBrickExit extends TileBaseExit { + + public TileBrickExit(TileModel model) + { + super(model); + } + + + @Override + protected TileRenderer makeRenderer() + { + return new OneFrameTileRenderer(this, Res.txq("tile.brick.stairs.down")); + } + +} diff --git a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickFloor.java b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickFloor.java index 4368f19..3722f4d 100644 --- a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickFloor.java +++ b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickFloor.java @@ -10,7 +10,7 @@ public class TileBrickFloor extends TileBaseFloor { public TileBrickFloor(TileModel model) { - super(model, Res.sheet("tile.brick.floor")); + super(model, Res.txs("tile.brick.floor")); } } diff --git a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickPassage.java b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickPassage.java index f0f5029..2f255b9 100644 --- a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickPassage.java +++ b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickPassage.java @@ -10,7 +10,7 @@ public class TileBrickPassage extends TileBasePassage { public TileBrickPassage(TileModel model) { - super(model, Res.sheet("tile.brick.passage")); + super(model, Res.txs("tile.brick.passage")); } } diff --git a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickSecretDoor.java b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickSecretDoor.java index ee32310..ba599be 100644 --- a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickSecretDoor.java +++ b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickSecretDoor.java @@ -13,9 +13,9 @@ public class TileBrickSecretDoor extends TileBaseSecretDoor { //@formatter:off super( model, - Res.sheet("tile.brick.door.secret"), - Res.sheet("tile.brick.door.closed"), - Res.sheet("tile.brick.door.open") + Res.txs("tile.brick.door.secret"), + Res.txs("tile.brick.door.closed"), + Res.txs("tile.brick.door.open") ); //@formatter:on diff --git a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickWall.java b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickWall.java index 0c751e0..d5cdb3a 100644 --- a/src/mightypork/rogue/world/tile/tiles/brick/TileBrickWall.java +++ b/src/mightypork/rogue/world/tile/tiles/brick/TileBrickWall.java @@ -10,7 +10,7 @@ public class TileBrickWall extends TileBaseWall { public TileBrickWall(TileModel model) { - super(model, Res.sheet("tile.brick.wall")); + super(model, Res.txs("tile.brick.wall")); } }