From ffffbefefe6c24b8bfd1f7d57a80768a3fdb3f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Fri, 25 Apr 2014 00:27:49 +0200 Subject: [PATCH] Mega-awesome world generator improvement & DOORS!!! --- res/img/tiles16.png | Bin 4614 -> 4791 bytes res/img/tiles16.xcf | Bin 11969 -> 13470 bytes .../gamecore/render/DisplaySystem.java | 7 +- src/mightypork/rogue/App.java | 2 +- src/mightypork/rogue/Res.java | 2 +- .../screens/test_cat_sound/ScreenTestCat.java | 5 +- src/mightypork/rogue/world/entity/Entity.java | 13 +- .../rogue/world/gen/LevelGenerator.java | 8 +- .../rogue/world/gen/ScratchMap.java | 168 +++++++++++++++--- src/mightypork/rogue/world/gen/Theme.java | 2 +- .../rogue/world/gen/rooms/DeadEndRoom.java | 28 +++ .../rogue/world/gen/rooms/SimpleRectRoom.java | 28 ++- .../rogue/world/gen/themes/ThemeDungeon.java | 4 +- src/mightypork/rogue/world/level/Level.java | 2 +- src/mightypork/rogue/world/tile/Tile.java | 39 +++- .../world/tile/{models => }/TileModel.java | 18 +- .../tile/{renderers => }/TileRenderer.java | 4 +- src/mightypork/rogue/world/tile/Tiles.java | 7 +- .../world/tile/models/AbstractNullTile.java | 2 +- .../{SimpleTile.java => AbstractTile.java} | 24 ++- .../rogue/world/tile/models/Floor.java | 19 +- .../rogue/world/tile/models/NullFloor.java | 12 +- .../rogue/world/tile/models/NullWall.java | 12 +- .../rogue/world/tile/models/SimpleDoor.java | 36 +++- .../rogue/world/tile/models/Wall.java | 20 ++- .../tile/renderers/BasicTileRenderer.java | 1 + .../world/tile/renderers/DoorRenderer.java | 5 +- .../world/tile/renderers/FloorRenderer.java | 2 +- .../tile/renderers/NullTileRenderer.java | 1 + 29 files changed, 377 insertions(+), 94 deletions(-) create mode 100644 src/mightypork/rogue/world/gen/rooms/DeadEndRoom.java rename src/mightypork/rogue/world/tile/{models => }/TileModel.java (79%) rename src/mightypork/rogue/world/tile/{renderers => }/TileRenderer.java (88%) rename src/mightypork/rogue/world/tile/models/{SimpleTile.java => AbstractTile.java} (60%) diff --git a/res/img/tiles16.png b/res/img/tiles16.png index b32c953a40e6dd9d67ab9218bddaf635a5df3942..33366238edd02c2cb4a43bf343a9cb9610d43f94 100644 GIT binary patch literal 4791 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 W4$JPopTC+X0l?2*Xx2QjkNO{2)`MIC literal 4614 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 Dqq7U1 delta 956 zcmZ9Izl#$=6vy{XCKr!GIc&ACx-xqpmg>JCSj#S3sr4*d3^RK;GmvE);j}erqKQRB z4u3QjR{jmb2}y0E1dedb48FHXfkxq1y7Rx(rV`Fgkx(^B;mSl$Fnb)1$^5`YG5XbAa5St_ogZJ_bCLzfFx;sv#5JD1HuS*1`0 zif>6=SoBblP_PP%PU!Qp%n$N(&A!!fF@>qmr(J#~S9n41xz1%X*G_Acf#zEh=MFt|Bov&+ zq7(X}s)~amU9qoqoKIlliwPw*PglNmu3{Au?U)PN(c5Hug>enl1&La0lBlmY)vgAe zu5eN_?Gd4k*A+={#&yP+@Z&VJU&N{y6ts??xBlQdvgL3Y#zOWa7(NPy>Npl42*3zT z7!mR_Ataa4j9}zVhc0JQ;03v7I+x8%8Yxi*l5a_z8T62mP%sjUPUtfsvV$yLvd?v# zjbZGwF(o!jmwsf7U;>FW%miuZZL+<>xCC)Qq7gPp)R!Bvt3jqqoRmy@L}=rsAPLTx h&KMJZoQAGvQDlP**Riax9iD!;d%s7kd2w|6#y^# 40) { + if (failed > 150) { Log.w("Faild to build room."); return; } @@ -186,8 +189,8 @@ public class ScratchMap { if (!isIn(min) || !isIn(max)) throw new IndexOutOfBoundsException("Tile(s) not in map: " + min + " , " + max); final Coord c = Coord.make(0, 0); - for (c.y = min.y; c.y <= max.y; c.y++) - for (c.x = min.x; c.x <= max.x; c.x++) + for (c.x = min.x; c.x <= max.x; c.x++) + for (c.y = min.y; c.y <= max.y; c.y++) set(c, tm.createTile()); } @@ -197,8 +200,8 @@ public class ScratchMap { if (!isIn(min) || !isIn(max)) throw new IndexOutOfBoundsException("Tile(s) not in map: " + min + " , " + max); final Coord c = Coord.make(0, 0); - for (c.y = min.y; c.y <= max.y; c.y++) { - for (c.x = min.x; c.x <= max.x; c.x++) { + for (c.x = min.x; c.x <= max.x; c.x++) { + for (c.y = min.y; c.y <= max.y; c.y++) { if (c.y > min.y && c.y < max.y && c.x > min.x && c.x < max.x) continue; @@ -210,11 +213,10 @@ public class ScratchMap { public void buildCorridors() { - for (final Coord door1 : nodes) { - for (final Coord door2 : nodes) { - if (door1 == door2) continue; - - buildCorridor(door1, door2); + Log.f3("Building corridors."); + for (int i = 0; i < nodes.size(); i++) { + for (int j = i + 1; j < nodes.size(); j++) { + buildCorridor(nodes.get(i), nodes.get(j)); } } } @@ -222,7 +224,7 @@ public class ScratchMap { private void buildCorridor(Coord node1, Coord node2) { - + //Log.f3("Finding path " + node1 + " -> " + node2); final List steps = pathFinder.findPath(node1, node2); if (steps == null) { @@ -251,7 +253,7 @@ public class ScratchMap { genMax.y = Math.max(genMax.y, c.y); final Tile current = get(c); - if (!current.getModel().isNullTile() && current.isWalkable()) continue; // floor already, let it be + if (!current.isNull() && (current.isPotentiallyWalkable())) continue; // floor already, let it be if (i == 0 && j == 0) { set(c, theme.floor()); @@ -269,10 +271,132 @@ public class ScratchMap { } + private int countBits(byte b) + { + int c = 0; + for (int i = 0; i < 8; i++) { + c += (b >> i) & 1; + } + return c; + } + + public void writeToLevel(Level level) { - final Coord c1 = Coord.make(0, 0); + //@formatter:off + final Coord[] moves = { + Coord.make(-1, 0), + Coord.make(-1, -1), + Coord.make(0, -1), + Coord.make(1, -1), + Coord.make(1, 0), + Coord.make(1, 1), + Coord.make(0, 1), + Coord.make(-1, 1) + }; + //@formatter:on + + final byte cardinal = (byte) 0b10101010; + final byte diagonal = (byte) 0b01010101; + + // make sure no walkable are at edges. final Coord c = Coord.make(0, 0); + final Coord c1 = Coord.make(0, 0); + for (c.x = 0; c.x < width; c.x++) { + for (c.y = 0; c.y < height; c.y++) { + + final Tile t = get(c); + final boolean isNull = t.isNull(); + + final boolean isDoor = !isNull && t.isDoor(); + final boolean isFloor = !isNull && t.isFloor(); + final boolean isWall = !isNull && t.isWall(); + + // bitmasks + byte walls = 0; + byte nils = 0; + byte doors = 0; + byte floors = 0; + + // gather info + for (int i = 0; i <= 7; i++) { + final Coord cc = c.add(moves[i]); + + if (!isIn(cc)) { + nils |= 1 << (7 - i); + continue; + } + + final Tile t2 = get(cc); + + if (t2.isNull()) { + nils |= 1 << (7 - i); + continue; + } + + if (t2.isDoor()) { + doors |= 1 << (7 - i); + continue; + } + + if (t2.isWall()) { + walls |= 1 << (7 - i); + continue; + } + + floors |= 1 << (7 - i); + } + + boolean toWall = false; + boolean toFloor = false; + boolean toNull = false; + + if (isFloor && (nils & cardinal) != 0) { + toWall = true; // floor with adjacent cardinal null + } + + if (isNull && (floors & diagonal) != 0) { + toWall = true; // null with adjacent diagonal floor + } + + if (isWall && floors == 0) { + toNull = true; + } + + if (isDoor) { + do { + if (countBits((byte) (floors & cardinal)) < 2) { + toWall = true; + break; + } + + if (countBits((byte) (walls & cardinal)) > 2) { + toWall = true; + break; + } + + if (countBits((byte) (floors & cardinal)) > 2) { + toFloor = true; + break; + } + + if ((floors & 0b11100000) == 0b11100000) toWall = true; + if ((floors & 0b00111000) == 0b00111000) toWall = true; + if ((floors & 0b00001110) == 0b00001110) toWall = true; + if ((floors & 0b10000011) == 0b10000011) toWall = true; + } while (false); + } + + if (toWall) { + set(c, theme.wall()); + } else if (toFloor) { + set(c, theme.floor()); + } else if (toNull) { + set(c, Tiles.NULL_EMPTY); + } + } + } + for (c.x = genMin.x, c1.x = 0; c.x <= genMax.x; c.x++, c1.x++) { for (c.y = genMin.y, c1.y = 0; c.y <= genMax.y; c.y++, c1.y++) { level.setTile(get(c), c1.x, c1.y); diff --git a/src/mightypork/rogue/world/gen/Theme.java b/src/mightypork/rogue/world/gen/Theme.java index 4a4c7c2..1dba0f2 100644 --- a/src/mightypork/rogue/world/gen/Theme.java +++ b/src/mightypork/rogue/world/gen/Theme.java @@ -1,7 +1,7 @@ package mightypork.rogue.world.gen; -import mightypork.rogue.world.tile.models.TileModel; +import mightypork.rogue.world.tile.TileModel; /** diff --git a/src/mightypork/rogue/world/gen/rooms/DeadEndRoom.java b/src/mightypork/rogue/world/gen/rooms/DeadEndRoom.java new file mode 100644 index 0000000..085a588 --- /dev/null +++ b/src/mightypork/rogue/world/gen/rooms/DeadEndRoom.java @@ -0,0 +1,28 @@ +package mightypork.rogue.world.gen.rooms; + + +import java.util.Random; + +import mightypork.rogue.world.Coord; +import mightypork.rogue.world.gen.RoomBuilder; +import mightypork.rogue.world.gen.RoomDesc; +import mightypork.rogue.world.gen.ScratchMap; +import mightypork.rogue.world.gen.Theme; + + +public class DeadEndRoom implements RoomBuilder { + + @Override + public RoomDesc buildToFit(ScratchMap map, Theme theme, Random rand, Coord center) + { + final Coord min = new Coord(center.x - 1, center.y - 1); + final Coord max = new Coord(center.x + 1, center.y + 1); + + if (!map.isClear(min, max)) return null; + + map.fill(min, max, theme.floor()); + map.border(min, max, theme.wall()); + + return new RoomDesc(min, max); + } +} diff --git a/src/mightypork/rogue/world/gen/rooms/SimpleRectRoom.java b/src/mightypork/rogue/world/gen/rooms/SimpleRectRoom.java index db5a329..026efef 100644 --- a/src/mightypork/rogue/world/gen/rooms/SimpleRectRoom.java +++ b/src/mightypork/rogue/world/gen/rooms/SimpleRectRoom.java @@ -20,16 +20,38 @@ public class SimpleRectRoom implements RoomBuilder { final int height = 2 + rand.nextInt(2); final Coord min = new Coord(center.x - width, center.y - height); - final Coord max = new Coord(center.x + height, center.y + height); + final Coord max = new Coord(center.x + width, center.y + height); if (!map.isClear(min, max)) return null; map.fill(min, max, theme.floor()); map.border(min, max, theme.wall()); - // TODO place some doors + for (int i = 0; i < 2 + rand.nextInt(4); i++) { + final Coord d = min.copy(); + switch (rand.nextInt(4)) { + case 0: + d.y = min.y; + d.x += 1 + rand.nextInt((width - 1) * 2); + break; + case 1: + d.y = max.y; + d.x += 1 + rand.nextInt((width - 1) * 2); + break; + case 2: + d.x = min.x; + d.y += 1 + rand.nextInt((height - 1) * 2); + break; + case 3: + d.x = max.x; + d.y += 1 + rand.nextInt((height - 1) * 2); + break; + } + + map.set(d, theme.door()); + } - return new RoomDesc(min.add(-1, -1), max.add(1, 1)); + return new RoomDesc(min.add(-1, -1), max); } } diff --git a/src/mightypork/rogue/world/gen/themes/ThemeDungeon.java b/src/mightypork/rogue/world/gen/themes/ThemeDungeon.java index 7376e3d..e608f61 100644 --- a/src/mightypork/rogue/world/gen/themes/ThemeDungeon.java +++ b/src/mightypork/rogue/world/gen/themes/ThemeDungeon.java @@ -2,8 +2,8 @@ package mightypork.rogue.world.gen.themes; import mightypork.rogue.world.gen.Theme; +import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.Tiles; -import mightypork.rogue.world.tile.models.TileModel; // basic dungeon theme @@ -26,7 +26,7 @@ public class ThemeDungeon implements Theme { @Override public TileModel door() { - return floor(); // TODO + return Tiles.DOOR; } } diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index 286dc46..b719a0a 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -12,8 +12,8 @@ import mightypork.rogue.world.World; import mightypork.rogue.world.WorldPos; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.tile.Tile; +import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.Tiles; -import mightypork.rogue.world.tile.models.TileModel; import mightypork.util.files.ion.IonBinary; import mightypork.util.files.ion.IonBundle; import mightypork.util.files.ion.IonInput; diff --git a/src/mightypork/rogue/world/tile/Tile.java b/src/mightypork/rogue/world/tile/Tile.java index dac0fce..a0e8a79 100644 --- a/src/mightypork/rogue/world/tile/Tile.java +++ b/src/mightypork/rogue/world/tile/Tile.java @@ -7,8 +7,6 @@ import java.util.Stack; import mightypork.rogue.world.item.Item; import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.render.TileRenderContext; -import mightypork.rogue.world.tile.models.TileModel; -import mightypork.rogue.world.tile.renderers.TileRenderer; import mightypork.util.files.ion.IonBinary; import mightypork.util.files.ion.IonBundle; import mightypork.util.files.ion.IonInput; @@ -144,6 +142,18 @@ public final class Tile implements IonBinary { } + public boolean isDoor() + { + return model.isDoor(); + } + + + public boolean isNull() + { + return model.isNullTile(); + } + + public TileModel getModel() { return model; @@ -156,6 +166,12 @@ public final class Tile implements IonBinary { } + public boolean doesCastShadow() + { + return model.doesCastShadow(); + } + + @Override public short getIonMark() { @@ -173,4 +189,23 @@ public final class Tile implements IonBinary { { this.occupied = occupied; } + + + public boolean isWall() + { + return model.isWall(); + } + + + public boolean isFloor() + { + return model.isFloor(); + } + + + public boolean isPotentiallyWalkable() + { + return model.isPotentiallyWalkable(); + } + } diff --git a/src/mightypork/rogue/world/tile/models/TileModel.java b/src/mightypork/rogue/world/tile/TileModel.java similarity index 79% rename from src/mightypork/rogue/world/tile/models/TileModel.java rename to src/mightypork/rogue/world/tile/TileModel.java index 66d7b3c..c35ea66 100644 --- a/src/mightypork/rogue/world/tile/models/TileModel.java +++ b/src/mightypork/rogue/world/tile/TileModel.java @@ -1,10 +1,7 @@ -package mightypork.rogue.world.tile.models; +package mightypork.rogue.world.tile; import mightypork.rogue.world.level.Level; -import mightypork.rogue.world.tile.Tile; -import mightypork.rogue.world.tile.Tiles; -import mightypork.rogue.world.tile.renderers.TileRenderer; /** @@ -48,6 +45,12 @@ public abstract class TileModel { public abstract boolean isDoor(); + public abstract boolean isWall(); + + + public abstract boolean isFloor(); + + public abstract boolean doesCastShadow(); @@ -74,4 +77,11 @@ public abstract class TileModel { */ public abstract boolean hasDroppedItems(); + + /** + * @return true if walkable at some conditions (ie. floor, hidden door, + * locked door etc) + */ + public abstract boolean isPotentiallyWalkable(); + } diff --git a/src/mightypork/rogue/world/tile/renderers/TileRenderer.java b/src/mightypork/rogue/world/tile/TileRenderer.java similarity index 88% rename from src/mightypork/rogue/world/tile/renderers/TileRenderer.java rename to src/mightypork/rogue/world/tile/TileRenderer.java index 1960353..71a48c0 100644 --- a/src/mightypork/rogue/world/tile/renderers/TileRenderer.java +++ b/src/mightypork/rogue/world/tile/TileRenderer.java @@ -1,9 +1,9 @@ -package mightypork.rogue.world.tile.renderers; +package mightypork.rogue.world.tile; import mightypork.rogue.world.item.Item; import mightypork.rogue.world.level.render.TileRenderContext; -import mightypork.rogue.world.tile.DroppedItemRenderer; +import mightypork.rogue.world.tile.renderers.NullTileRenderer; /** diff --git a/src/mightypork/rogue/world/tile/Tiles.java b/src/mightypork/rogue/world/tile/Tiles.java index 9308eb5..79a54bf 100644 --- a/src/mightypork/rogue/world/tile/Tiles.java +++ b/src/mightypork/rogue/world/tile/Tiles.java @@ -1,7 +1,11 @@ package mightypork.rogue.world.tile; -import mightypork.rogue.world.tile.models.*; +import mightypork.rogue.world.tile.models.Floor; +import mightypork.rogue.world.tile.models.NullFloor; +import mightypork.rogue.world.tile.models.NullWall; +import mightypork.rogue.world.tile.models.SimpleDoor; +import mightypork.rogue.world.tile.models.Wall; import mightypork.rogue.world.tile.renderers.FloorRenderer; import mightypork.rogue.world.tile.renderers.WallRenderer; @@ -17,7 +21,6 @@ public final class Tiles { public static final TileModel NULL_SOLID = new NullWall(0); public static final TileModel NULL_EMPTY = new NullFloor(1); - public static final TileModel NULL_EMPTY_RESERVED = new NullFloor(2); public static final TileModel FLOOR_DARK = new Floor(10).setRenderer(new FloorRenderer("tile.floor.dark")); public static final TileModel WALL_BRICK = new Wall(11).setRenderer(new WallRenderer("tile.wall.brick")); diff --git a/src/mightypork/rogue/world/tile/models/AbstractNullTile.java b/src/mightypork/rogue/world/tile/models/AbstractNullTile.java index d9610b9..6719760 100644 --- a/src/mightypork/rogue/world/tile/models/AbstractNullTile.java +++ b/src/mightypork/rogue/world/tile/models/AbstractNullTile.java @@ -9,7 +9,7 @@ import mightypork.rogue.world.tile.Tile; * * @author MightyPork */ -public abstract class AbstractNullTile extends SimpleTile { +public abstract class AbstractNullTile extends AbstractTile { private Tile inst; diff --git a/src/mightypork/rogue/world/tile/models/SimpleTile.java b/src/mightypork/rogue/world/tile/models/AbstractTile.java similarity index 60% rename from src/mightypork/rogue/world/tile/models/SimpleTile.java rename to src/mightypork/rogue/world/tile/models/AbstractTile.java index a78ef2b..9d6906c 100644 --- a/src/mightypork/rogue/world/tile/models/SimpleTile.java +++ b/src/mightypork/rogue/world/tile/models/AbstractTile.java @@ -3,6 +3,7 @@ package mightypork.rogue.world.tile.models; import mightypork.rogue.world.level.Level; import mightypork.rogue.world.tile.Tile; +import mightypork.rogue.world.tile.TileModel; import mightypork.util.annotations.DefaultImpl; @@ -11,16 +12,19 @@ import mightypork.util.annotations.DefaultImpl; * * @author MightyPork */ -public abstract class SimpleTile extends TileModel { +public abstract class AbstractTile extends TileModel { - public SimpleTile(int id) + public AbstractTile(int id) { super(id); } @Override - public abstract boolean isWalkable(Tile tile); + public boolean isWalkable(Tile tile) + { + return isPotentiallyWalkable(); + } @Override @@ -30,6 +34,20 @@ public abstract class SimpleTile extends TileModel { } + @Override + public boolean isWall() + { + return false; + } + + + @Override + public boolean isFloor() + { + return false; + } + + @Override public boolean hasMetadata() { diff --git a/src/mightypork/rogue/world/tile/models/Floor.java b/src/mightypork/rogue/world/tile/models/Floor.java index 9c287d7..304c061 100644 --- a/src/mightypork/rogue/world/tile/models/Floor.java +++ b/src/mightypork/rogue/world/tile/models/Floor.java @@ -1,15 +1,7 @@ package mightypork.rogue.world.tile.models; -import mightypork.rogue.world.tile.Tile; - - -/** - * Template for floor tiles with no metadata - * - * @author MightyPork - */ -public class Floor extends SimpleTile { +public class Floor extends AbstractTile { public Floor(int id) { @@ -18,7 +10,7 @@ public class Floor extends SimpleTile { @Override - public boolean isWalkable(Tile tile) + public boolean isPotentiallyWalkable() { return true; } @@ -36,4 +28,11 @@ public class Floor extends SimpleTile { { return false; } + + + @Override + public boolean isFloor() + { + return true; + } } diff --git a/src/mightypork/rogue/world/tile/models/NullFloor.java b/src/mightypork/rogue/world/tile/models/NullFloor.java index ff45067..f0583e0 100644 --- a/src/mightypork/rogue/world/tile/models/NullFloor.java +++ b/src/mightypork/rogue/world/tile/models/NullFloor.java @@ -1,9 +1,6 @@ package mightypork.rogue.world.tile.models; -import mightypork.rogue.world.tile.Tile; - - public class NullFloor extends AbstractNullTile { public NullFloor(int id) @@ -13,7 +10,14 @@ public class NullFloor extends AbstractNullTile { @Override - public boolean isWalkable(Tile tile) + public boolean isFloor() + { + return true; + } + + + @Override + public boolean isPotentiallyWalkable() { return true; } diff --git a/src/mightypork/rogue/world/tile/models/NullWall.java b/src/mightypork/rogue/world/tile/models/NullWall.java index 72bcc14..76fb197 100644 --- a/src/mightypork/rogue/world/tile/models/NullWall.java +++ b/src/mightypork/rogue/world/tile/models/NullWall.java @@ -1,9 +1,6 @@ package mightypork.rogue.world.tile.models; -import mightypork.rogue.world.tile.Tile; - - public class NullWall extends AbstractNullTile { public NullWall(int id) @@ -13,8 +10,15 @@ public class NullWall extends AbstractNullTile { @Override - public boolean isWalkable(Tile tile) + public boolean isPotentiallyWalkable() { return false; } + + + @Override + public boolean isWall() + { + return true; + } } diff --git a/src/mightypork/rogue/world/tile/models/SimpleDoor.java b/src/mightypork/rogue/world/tile/models/SimpleDoor.java index bb40bec..63a89c5 100644 --- a/src/mightypork/rogue/world/tile/models/SimpleDoor.java +++ b/src/mightypork/rogue/world/tile/models/SimpleDoor.java @@ -5,12 +5,7 @@ import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.renderers.DoorRenderer; -/** - * Template for floor tiles with no metadata - * - * @author MightyPork - */ -public class SimpleDoor extends Wall { +public class SimpleDoor extends AbstractTile { public SimpleDoor(int id) { @@ -20,15 +15,42 @@ public class SimpleDoor extends Wall { @Override - public boolean isWalkable(Tile tile) + public boolean isPotentiallyWalkable() { return true; } + @Override + public boolean isWalkable(Tile tile) + { + return !isLocked(tile); + } + + + protected boolean isLocked(Tile tile) + { + return false; + } + + @Override public boolean isDoor() { return true; } + + + @Override + public boolean doesCastShadow() + { + return true; + } + + + @Override + public boolean hasDroppedItems() + { + return false; + } } diff --git a/src/mightypork/rogue/world/tile/models/Wall.java b/src/mightypork/rogue/world/tile/models/Wall.java index cffd915..20abb98 100644 --- a/src/mightypork/rogue/world/tile/models/Wall.java +++ b/src/mightypork/rogue/world/tile/models/Wall.java @@ -1,15 +1,12 @@ package mightypork.rogue.world.tile.models; -import mightypork.rogue.world.tile.Tile; - - /** * Template for wall tiles with no metadata * * @author MightyPork */ -public class Wall extends SimpleTile { +public class Wall extends AbstractTile { public Wall(int id) { @@ -18,23 +15,30 @@ public class Wall extends SimpleTile { @Override - public boolean isWalkable(Tile tile) + public final boolean hasDroppedItems() { return false; } @Override - public boolean hasDroppedItems() + public final boolean doesCastShadow() { - return false; + return true; } @Override - public boolean doesCastShadow() + public final boolean isWall() { return true; } + + @Override + public final boolean isPotentiallyWalkable() + { + return false; + } + } diff --git a/src/mightypork/rogue/world/tile/renderers/BasicTileRenderer.java b/src/mightypork/rogue/world/tile/renderers/BasicTileRenderer.java index 48a0381..31e3193 100644 --- a/src/mightypork/rogue/world/tile/renderers/BasicTileRenderer.java +++ b/src/mightypork/rogue/world/tile/renderers/BasicTileRenderer.java @@ -5,6 +5,7 @@ import mightypork.gamecore.render.Render; import mightypork.gamecore.render.textures.TxSheet; import mightypork.rogue.Res; import mightypork.rogue.world.level.render.TileRenderContext; +import mightypork.rogue.world.tile.TileRenderer; import mightypork.util.math.constraints.rect.Rect; diff --git a/src/mightypork/rogue/world/tile/renderers/DoorRenderer.java b/src/mightypork/rogue/world/tile/renderers/DoorRenderer.java index b19e77b..8bbadd7 100644 --- a/src/mightypork/rogue/world/tile/renderers/DoorRenderer.java +++ b/src/mightypork/rogue/world/tile/renderers/DoorRenderer.java @@ -6,6 +6,7 @@ import mightypork.gamecore.render.textures.TxQuad; import mightypork.rogue.Res; import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.tile.Tile; +import mightypork.rogue.world.tile.TileRenderer; import mightypork.util.math.constraints.rect.Rect; @@ -29,9 +30,9 @@ public class DoorRenderer extends TileRenderer { final Rect rect = context.getRect(); if (t.isOccupied()) { - Render.quadTextured(rect, closed); - } else { Render.quadTextured(rect, open); + } else { + Render.quadTextured(rect, closed); } } diff --git a/src/mightypork/rogue/world/tile/renderers/FloorRenderer.java b/src/mightypork/rogue/world/tile/renderers/FloorRenderer.java index e57d432..fe23492 100644 --- a/src/mightypork/rogue/world/tile/renderers/FloorRenderer.java +++ b/src/mightypork/rogue/world/tile/renderers/FloorRenderer.java @@ -54,7 +54,7 @@ public class FloorRenderer extends BasicTileRenderer { final Tile t2 = context.getAdjacentTile(x, y); - if (t2.getModel().doesCastShadow()) { + if (t2.doesCastShadow()) { trd.shadows |= 1 << move; } diff --git a/src/mightypork/rogue/world/tile/renderers/NullTileRenderer.java b/src/mightypork/rogue/world/tile/renderers/NullTileRenderer.java index 4280f53..d19a424 100644 --- a/src/mightypork/rogue/world/tile/renderers/NullTileRenderer.java +++ b/src/mightypork/rogue/world/tile/renderers/NullTileRenderer.java @@ -2,6 +2,7 @@ package mightypork.rogue.world.tile.renderers; import mightypork.rogue.world.level.render.TileRenderContext; +import mightypork.rogue.world.tile.TileRenderer; public class NullTileRenderer extends TileRenderer {