Mega-awesome world generator improvement & DOORS!!!

v5stable
Ondřej Hruška 11 years ago
parent eef373eb24
commit ffffbefefe
  1. BIN
      res/img/tiles16.png
  2. BIN
      res/img/tiles16.xcf
  3. 7
      src/mightypork/gamecore/render/DisplaySystem.java
  4. 2
      src/mightypork/rogue/App.java
  5. 2
      src/mightypork/rogue/Res.java
  6. 5
      src/mightypork/rogue/screens/test_cat_sound/ScreenTestCat.java
  7. 13
      src/mightypork/rogue/world/entity/Entity.java
  8. 8
      src/mightypork/rogue/world/gen/LevelGenerator.java
  9. 164
      src/mightypork/rogue/world/gen/ScratchMap.java
  10. 2
      src/mightypork/rogue/world/gen/Theme.java
  11. 28
      src/mightypork/rogue/world/gen/rooms/DeadEndRoom.java
  12. 28
      src/mightypork/rogue/world/gen/rooms/SimpleRectRoom.java
  13. 4
      src/mightypork/rogue/world/gen/themes/ThemeDungeon.java
  14. 2
      src/mightypork/rogue/world/level/Level.java
  15. 39
      src/mightypork/rogue/world/tile/Tile.java
  16. 18
      src/mightypork/rogue/world/tile/TileModel.java
  17. 4
      src/mightypork/rogue/world/tile/TileRenderer.java
  18. 7
      src/mightypork/rogue/world/tile/Tiles.java
  19. 2
      src/mightypork/rogue/world/tile/models/AbstractNullTile.java
  20. 24
      src/mightypork/rogue/world/tile/models/AbstractTile.java
  21. 19
      src/mightypork/rogue/world/tile/models/Floor.java
  22. 12
      src/mightypork/rogue/world/tile/models/NullFloor.java
  23. 12
      src/mightypork/rogue/world/tile/models/NullWall.java
  24. 36
      src/mightypork/rogue/world/tile/models/SimpleDoor.java
  25. 20
      src/mightypork/rogue/world/tile/models/Wall.java
  26. 1
      src/mightypork/rogue/world/tile/renderers/BasicTileRenderer.java
  27. 5
      src/mightypork/rogue/world/tile/renderers/DoorRenderer.java
  28. 2
      src/mightypork/rogue/world/tile/renderers/FloorRenderer.java
  29. 1
      src/mightypork/rogue/world/tile/renderers/NullTileRenderer.java

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

@ -63,8 +63,7 @@ public class DisplaySystem extends AppModule implements RectBound {
@Override @Override
protected void deinit() protected void deinit()
{ {
// causes weird visual glitch Display.destroy();
// Display.destroy();
} }
@ -155,8 +154,8 @@ public class DisplaySystem extends AppModule implements RectBound {
public Screenshot takeScreenshot() public Screenshot takeScreenshot()
{ {
glReadBuffer(GL_FRONT); glReadBuffer(GL_FRONT);
final int width = Display.getDisplayMode().getWidth(); final int width = Display.getWidth();
final int height = Display.getDisplayMode().getHeight(); final int height = Display.getHeight();
final int bpp = 4; final int bpp = 4;
final ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp); final ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

@ -83,7 +83,7 @@ public final class App extends BaseApp {
screens.addOverlay(new FpsOverlay(this)); screens.addOverlay(new FpsOverlay(this));
screens.addOverlay(new CrossfadeOverlay(this)); screens.addOverlay(new CrossfadeOverlay(this));
screens.showScreen("main_menu"); screens.showScreen("game_screen");//main_menu
} }

@ -110,7 +110,7 @@ public final class Res {
{ {
sounds.addEffect("gui.shutter", "/res/audio/shutter.ogg", 1, 1); sounds.addEffect("gui.shutter", "/res/audio/shutter.ogg", 1, 1);
sounds.addLoop("test.wilderness", "/res/audio/wilderness.ogg", 1, 1, 3, 3); //sounds.addLoop("test.wilderness", "/res/audio/wilderness.ogg", 1, 1, 3, 3);
} }

@ -5,7 +5,6 @@ import mightypork.gamecore.control.AppAccess;
import mightypork.gamecore.gui.screens.LayeredScreen; import mightypork.gamecore.gui.screens.LayeredScreen;
import mightypork.gamecore.input.KeyStroke; import mightypork.gamecore.input.KeyStroke;
import mightypork.gamecore.input.Keys; import mightypork.gamecore.input.Keys;
import mightypork.rogue.Res;
import mightypork.rogue.events.ActionRequest; import mightypork.rogue.events.ActionRequest;
import mightypork.rogue.events.ActionRequest.RequestType; import mightypork.rogue.events.ActionRequest.RequestType;
@ -34,14 +33,14 @@ public class ScreenTestCat extends LayeredScreen {
protected void onScreenEnter() protected void onScreenEnter()
{ {
getSoundSystem().fadeOutAllLoops(); getSoundSystem().fadeOutAllLoops();
Res.getLoop("test.wilderness").fadeIn(); //Res.getLoop("test.wilderness").fadeIn();
} }
@Override @Override
protected void onScreenLeave() protected void onScreenLeave()
{ {
Res.getLoop("test.wilderness").fadeOut(); //Res.getLoop("test.wilderness").fadeOut();
} }

@ -33,6 +33,7 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener {
public static final int ION_MARK = 52; public static final int ION_MARK = 52;
private final WorldPos position = new WorldPos(); // saved private final WorldPos position = new WorldPos(); // saved
private final WorldPos lastPosition = new WorldPos();
/** Entity ID */ /** Entity ID */
private int eid = 0; // saved private int eid = 0; // saved
@ -56,13 +57,13 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener {
public Entity(int eid, WorldPos pos, EntityModel entityModel) public Entity(int eid, WorldPos pos, EntityModel entityModel)
{ {
this.eid = eid; this.eid = eid;
this.position.setTo(pos); setPosition(pos);
setModel(entityModel); setModel(entityModel);
} }
private void setModel(EntityModel entityModel) protected final void setModel(EntityModel entityModel)
{ {
// replace listener // replace listener
if (model != null) moveListeners.remove(model); if (model != null) moveListeners.remove(model);
@ -151,15 +152,16 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener {
} }
public void setPosition(WorldPos pos) public final void setPosition(WorldPos pos)
{ {
position.setTo(pos); setPosition(pos.x, pos.y);
} }
public void setPosition(int x, int y) public void setPosition(int x, int y)
{ {
position.setTo(x, y); position.setTo(x, y);
lastPosition.setTo(x, y);
cancelPath(); // discard remaining steps cancelPath(); // discard remaining steps
} }
@ -176,6 +178,7 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener {
if (walking && position.isFinished()) { if (walking && position.isFinished()) {
walking = false; walking = false;
level.freeTile(lastPosition.x, lastPosition.y);
onStepFinished(this, world, level); onStepFinished(this, world, level);
@ -202,9 +205,9 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener {
if (step.x != 0) renderData.lastXDir = step.x; if (step.x != 0) renderData.lastXDir = step.x;
if (step.y != 0) renderData.lastYDir = step.y; if (step.y != 0) renderData.lastYDir = step.y;
lastPosition.setTo(position);
position.walk(step.x, step.y, getStepTime()); position.walk(step.x, step.y, getStepTime());
level.occupyTile(projX, projY); level.occupyTile(projX, projY);
level.freeTile(position.x, position.y);
} }
} }

@ -4,6 +4,7 @@ package mightypork.rogue.world.gen;
import java.util.Random; import java.util.Random;
import mightypork.rogue.world.Coord; import mightypork.rogue.world.Coord;
import mightypork.rogue.world.gen.rooms.DeadEndRoom;
import mightypork.rogue.world.gen.rooms.SimpleRectRoom; import mightypork.rogue.world.gen.rooms.SimpleRectRoom;
import mightypork.rogue.world.gen.themes.ThemeDungeon; import mightypork.rogue.world.gen.themes.ThemeDungeon;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
@ -14,6 +15,7 @@ public class LevelGenerator {
public static final Theme DUNGEON_THEME = new ThemeDungeon(); public static final Theme DUNGEON_THEME = new ThemeDungeon();
public static final RoomBuilder ROOM_SQUARE = new SimpleRectRoom(); public static final RoomBuilder ROOM_SQUARE = new SimpleRectRoom();
private static final RoomBuilder DEAD_END = new DeadEndRoom();
public static Level build(long seed, Theme theme) public static Level build(long seed, Theme theme)
@ -27,10 +29,14 @@ public class LevelGenerator {
// start // start
map.addRoom(ROOM_SQUARE); map.addRoom(ROOM_SQUARE);
for (int i = 0; i < 6 + rand.nextInt(6); i++) { for (int i = 0; i < 5 + rand.nextInt(8); i++) {
map.addRoom(ROOM_SQUARE); map.addRoom(ROOM_SQUARE);
} }
for (int i = 0; i < 5 + rand.nextInt(6); i++) {
map.addRoom(DEAD_END);
}
map.buildCorridors(); map.buildCorridors();
final Coord size = map.getNeededSize(); final Coord size = map.getNeededSize();

@ -11,8 +11,8 @@ import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.pathfinding.PathCostProvider; import mightypork.rogue.world.pathfinding.PathCostProvider;
import mightypork.rogue.world.pathfinding.PathFinder; import mightypork.rogue.world.pathfinding.PathFinder;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.Tiles; import mightypork.rogue.world.tile.Tiles;
import mightypork.rogue.world.tile.models.TileModel;
import mightypork.util.logging.Log; import mightypork.util.logging.Log;
@ -39,9 +39,12 @@ public class ScratchMap {
{ {
final Tile t = get(pos); final Tile t = get(pos);
if (t.isWalkable()) return 10; if (t.isNull()) return 15;
return 100; // wall if (t.isDoor()) return 10; // door
if (t.isFloor()) return 20; // floor
return 400; // wall
} }
@ -89,21 +92,21 @@ public class ScratchMap {
final int sizeX = genMax.x - genMin.x; final int sizeX = genMax.x - genMin.x;
final int sizeY = genMax.y - genMin.y; final int sizeY = genMax.y - genMin.y;
center.x = genMin.x + rand.nextInt(sizeX + 1); center.x = genMin.x + rand.nextInt(sizeX);
center.y = genMin.y + rand.nextInt(sizeY + 1); center.y = genMin.y + rand.nextInt(sizeY);
switch (rand.nextInt(4)) { switch (rand.nextInt(4)) {
case 0: case 0:
center.x += 1 + rand.nextInt(3); center.x += 1 + rand.nextInt(5);
break; break;
case 1: case 1:
center.x -= 1 + rand.nextInt(3); center.x -= 1 + rand.nextInt(5);
break; break;
case 2: case 2:
center.y += 1 + rand.nextInt(3); center.y += 1 + rand.nextInt(5);
break; break;
case 3: case 3:
center.y -= 1 + rand.nextInt(3); center.y -= 1 + rand.nextInt(5);
} }
final RoomDesc rd = rb.buildToFit(this, theme, rand, center); final RoomDesc rd = rb.buildToFit(this, theme, rand, center);
@ -127,7 +130,7 @@ public class ScratchMap {
} else { } else {
failed++; failed++;
if (failed > 40) { if (failed > 150) {
Log.w("Faild to build room."); Log.w("Faild to build room.");
return; return;
} }
@ -186,8 +189,8 @@ public class ScratchMap {
if (!isIn(min) || !isIn(max)) throw new IndexOutOfBoundsException("Tile(s) not in map: " + min + " , " + max); if (!isIn(min) || !isIn(max)) throw new IndexOutOfBoundsException("Tile(s) not in map: " + min + " , " + max);
final Coord c = Coord.make(0, 0); 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()); 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); if (!isIn(min) || !isIn(max)) throw new IndexOutOfBoundsException("Tile(s) not in map: " + min + " , " + max);
final Coord c = Coord.make(0, 0); 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; 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() public void buildCorridors()
{ {
for (final Coord door1 : nodes) { Log.f3("Building corridors.");
for (final Coord door2 : nodes) { for (int i = 0; i < nodes.size(); i++) {
if (door1 == door2) continue; for (int j = i + 1; j < nodes.size(); j++) {
buildCorridor(nodes.get(i), nodes.get(j));
buildCorridor(door1, door2);
} }
} }
} }
@ -222,7 +224,7 @@ public class ScratchMap {
private void buildCorridor(Coord node1, Coord node2) private void buildCorridor(Coord node1, Coord node2)
{ {
//Log.f3("Finding path " + node1 + " -> " + node2);
final List<Coord> steps = pathFinder.findPath(node1, node2); final List<Coord> steps = pathFinder.findPath(node1, node2);
if (steps == null) { if (steps == null) {
@ -251,7 +253,7 @@ public class ScratchMap {
genMax.y = Math.max(genMax.y, c.y); genMax.y = Math.max(genMax.y, c.y);
final Tile current = get(c); 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) { if (i == 0 && j == 0) {
set(c, theme.floor()); 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) 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 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.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++) { for (c.y = genMin.y, c1.y = 0; c.y <= genMax.y; c.y++, c1.y++) {
level.setTile(get(c), c1.x, c1.y); level.setTile(get(c), c1.x, c1.y);

@ -1,7 +1,7 @@
package mightypork.rogue.world.gen; package mightypork.rogue.world.gen;
import mightypork.rogue.world.tile.models.TileModel; import mightypork.rogue.world.tile.TileModel;
/** /**

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

@ -20,16 +20,38 @@ public class SimpleRectRoom implements RoomBuilder {
final int height = 2 + rand.nextInt(2); final int height = 2 + rand.nextInt(2);
final Coord min = new Coord(center.x - width, center.y - height); 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; if (!map.isClear(min, max)) return null;
map.fill(min, max, theme.floor()); map.fill(min, max, theme.floor());
map.border(min, max, theme.wall()); 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);
} }
} }

@ -2,8 +2,8 @@ package mightypork.rogue.world.gen.themes;
import mightypork.rogue.world.gen.Theme; import mightypork.rogue.world.gen.Theme;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.Tiles; import mightypork.rogue.world.tile.Tiles;
import mightypork.rogue.world.tile.models.TileModel;
// basic dungeon theme // basic dungeon theme
@ -26,7 +26,7 @@ public class ThemeDungeon implements Theme {
@Override @Override
public TileModel door() public TileModel door()
{ {
return floor(); // TODO return Tiles.DOOR;
} }
} }

@ -12,8 +12,8 @@ import mightypork.rogue.world.World;
import mightypork.rogue.world.WorldPos; import mightypork.rogue.world.WorldPos;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.Tiles; import mightypork.rogue.world.tile.Tiles;
import mightypork.rogue.world.tile.models.TileModel;
import mightypork.util.files.ion.IonBinary; import mightypork.util.files.ion.IonBinary;
import mightypork.util.files.ion.IonBundle; import mightypork.util.files.ion.IonBundle;
import mightypork.util.files.ion.IonInput; import mightypork.util.files.ion.IonInput;

@ -7,8 +7,6 @@ import java.util.Stack;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.TileRenderContext; 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.IonBinary;
import mightypork.util.files.ion.IonBundle; import mightypork.util.files.ion.IonBundle;
import mightypork.util.files.ion.IonInput; 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() public TileModel getModel()
{ {
return model; return model;
@ -156,6 +166,12 @@ public final class Tile implements IonBinary {
} }
public boolean doesCastShadow()
{
return model.doesCastShadow();
}
@Override @Override
public short getIonMark() public short getIonMark()
{ {
@ -173,4 +189,23 @@ public final class Tile implements IonBinary {
{ {
this.occupied = occupied; this.occupied = occupied;
} }
public boolean isWall()
{
return model.isWall();
}
public boolean isFloor()
{
return model.isFloor();
}
public boolean isPotentiallyWalkable()
{
return model.isPotentiallyWalkable();
}
} }

@ -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.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 isDoor();
public abstract boolean isWall();
public abstract boolean isFloor();
public abstract boolean doesCastShadow(); public abstract boolean doesCastShadow();
@ -74,4 +77,11 @@ public abstract class TileModel {
*/ */
public abstract boolean hasDroppedItems(); public abstract boolean hasDroppedItems();
/**
* @return true if walkable at some conditions (ie. floor, hidden door,
* locked door etc)
*/
public abstract boolean isPotentiallyWalkable();
} }

@ -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.item.Item;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.DroppedItemRenderer; import mightypork.rogue.world.tile.renderers.NullTileRenderer;
/** /**

@ -1,7 +1,11 @@
package mightypork.rogue.world.tile; 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.FloorRenderer;
import mightypork.rogue.world.tile.renderers.WallRenderer; 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_SOLID = new NullWall(0);
public static final TileModel NULL_EMPTY = new NullFloor(1); 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 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")); public static final TileModel WALL_BRICK = new Wall(11).setRenderer(new WallRenderer("tile.wall.brick"));

@ -9,7 +9,7 @@ import mightypork.rogue.world.tile.Tile;
* *
* @author MightyPork * @author MightyPork
*/ */
public abstract class AbstractNullTile extends SimpleTile { public abstract class AbstractNullTile extends AbstractTile {
private Tile inst; private Tile inst;

@ -3,6 +3,7 @@ package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel;
import mightypork.util.annotations.DefaultImpl; import mightypork.util.annotations.DefaultImpl;
@ -11,16 +12,19 @@ import mightypork.util.annotations.DefaultImpl;
* *
* @author MightyPork * @author MightyPork
*/ */
public abstract class SimpleTile extends TileModel { public abstract class AbstractTile extends TileModel {
public SimpleTile(int id) public AbstractTile(int id)
{ {
super(id); super(id);
} }
@Override @Override
public abstract boolean isWalkable(Tile tile); public boolean isWalkable(Tile tile)
{
return isPotentiallyWalkable();
}
@Override @Override
@ -30,6 +34,20 @@ public abstract class SimpleTile extends TileModel {
} }
@Override
public boolean isWall()
{
return false;
}
@Override
public boolean isFloor()
{
return false;
}
@Override @Override
public boolean hasMetadata() public boolean hasMetadata()
{ {

@ -1,15 +1,7 @@
package mightypork.rogue.world.tile.models; package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile; public class Floor extends AbstractTile {
/**
* Template for floor tiles with no metadata
*
* @author MightyPork
*/
public class Floor extends SimpleTile {
public Floor(int id) public Floor(int id)
{ {
@ -18,7 +10,7 @@ public class Floor extends SimpleTile {
@Override @Override
public boolean isWalkable(Tile tile) public boolean isPotentiallyWalkable()
{ {
return true; return true;
} }
@ -36,4 +28,11 @@ public class Floor extends SimpleTile {
{ {
return false; return false;
} }
@Override
public boolean isFloor()
{
return true;
}
} }

@ -1,9 +1,6 @@
package mightypork.rogue.world.tile.models; package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
public class NullFloor extends AbstractNullTile { public class NullFloor extends AbstractNullTile {
public NullFloor(int id) public NullFloor(int id)
@ -13,7 +10,14 @@ public class NullFloor extends AbstractNullTile {
@Override @Override
public boolean isWalkable(Tile tile) public boolean isFloor()
{
return true;
}
@Override
public boolean isPotentiallyWalkable()
{ {
return true; return true;
} }

@ -1,9 +1,6 @@
package mightypork.rogue.world.tile.models; package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
public class NullWall extends AbstractNullTile { public class NullWall extends AbstractNullTile {
public NullWall(int id) public NullWall(int id)
@ -13,8 +10,15 @@ public class NullWall extends AbstractNullTile {
@Override @Override
public boolean isWalkable(Tile tile) public boolean isPotentiallyWalkable()
{ {
return false; return false;
} }
@Override
public boolean isWall()
{
return true;
}
} }

@ -5,12 +5,7 @@ import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.renderers.DoorRenderer; import mightypork.rogue.world.tile.renderers.DoorRenderer;
/** public class SimpleDoor extends AbstractTile {
* Template for floor tiles with no metadata
*
* @author MightyPork
*/
public class SimpleDoor extends Wall {
public SimpleDoor(int id) public SimpleDoor(int id)
{ {
@ -20,15 +15,42 @@ public class SimpleDoor extends Wall {
@Override @Override
public boolean isWalkable(Tile tile) public boolean isPotentiallyWalkable()
{ {
return true; return true;
} }
@Override
public boolean isWalkable(Tile tile)
{
return !isLocked(tile);
}
protected boolean isLocked(Tile tile)
{
return false;
}
@Override @Override
public boolean isDoor() public boolean isDoor()
{ {
return true; return true;
} }
@Override
public boolean doesCastShadow()
{
return true;
}
@Override
public boolean hasDroppedItems()
{
return false;
}
} }

@ -1,15 +1,12 @@
package mightypork.rogue.world.tile.models; package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
/** /**
* Template for wall tiles with no metadata * Template for wall tiles with no metadata
* *
* @author MightyPork * @author MightyPork
*/ */
public class Wall extends SimpleTile { public class Wall extends AbstractTile {
public Wall(int id) public Wall(int id)
{ {
@ -18,23 +15,30 @@ public class Wall extends SimpleTile {
@Override @Override
public boolean isWalkable(Tile tile) public final boolean hasDroppedItems()
{ {
return false; return false;
} }
@Override @Override
public boolean hasDroppedItems() public final boolean doesCastShadow()
{ {
return false; return true;
} }
@Override @Override
public boolean doesCastShadow() public final boolean isWall()
{ {
return true; return true;
} }
@Override
public final boolean isPotentiallyWalkable()
{
return false;
}
} }

@ -5,6 +5,7 @@ import mightypork.gamecore.render.Render;
import mightypork.gamecore.render.textures.TxSheet; import mightypork.gamecore.render.textures.TxSheet;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.util.math.constraints.rect.Rect; import mightypork.util.math.constraints.rect.Rect;

@ -6,6 +6,7 @@ import mightypork.gamecore.render.textures.TxQuad;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.util.math.constraints.rect.Rect; import mightypork.util.math.constraints.rect.Rect;
@ -29,9 +30,9 @@ public class DoorRenderer extends TileRenderer {
final Rect rect = context.getRect(); final Rect rect = context.getRect();
if (t.isOccupied()) { if (t.isOccupied()) {
Render.quadTextured(rect, closed);
} else {
Render.quadTextured(rect, open); Render.quadTextured(rect, open);
} else {
Render.quadTextured(rect, closed);
} }
} }

@ -54,7 +54,7 @@ public class FloorRenderer extends BasicTileRenderer {
final Tile t2 = context.getAdjacentTile(x, y); final Tile t2 = context.getAdjacentTile(x, y);
if (t2.getModel().doesCastShadow()) { if (t2.doesCastShadow()) {
trd.shadows |= 1 << move; trd.shadows |= 1 << move;
} }

@ -2,6 +2,7 @@ package mightypork.rogue.world.tile.renderers;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.TileRenderer;
public class NullTileRenderer extends TileRenderer { public class NullTileRenderer extends TileRenderer {

Loading…
Cancel
Save