rewritten tile system, added intial flood fill system

v5stable
Ondřej Hruška 10 years ago
parent 307d8d2b10
commit 7b862cb5c8
  1. 2
      src/mightypork/rogue/App.java
  2. 2
      src/mightypork/rogue/screens/gamescreen/world/Minimap.java
  3. 2
      src/mightypork/rogue/world/entity/models/PlayerModel.java
  4. 40
      src/mightypork/rogue/world/gen/ScratchMap.java
  5. 12
      src/mightypork/rogue/world/level/Level.java
  6. 4
      src/mightypork/rogue/world/level/render/TileRenderContext.java
  7. 21
      src/mightypork/rogue/world/pathfinding/FillContext.java
  8. 41
      src/mightypork/rogue/world/pathfinding/FloodFill.java
  9. 169
      src/mightypork/rogue/world/tile/Tile.java
  10. 54
      src/mightypork/rogue/world/tile/TileData.java
  11. 76
      src/mightypork/rogue/world/tile/TileModel.java
  12. 58
      src/mightypork/rogue/world/tile/TileRenderer.java
  13. 12
      src/mightypork/rogue/world/tile/TileType.java
  14. 65
      src/mightypork/rogue/world/tile/Tiles.java
  15. 53
      src/mightypork/rogue/world/tile/models/AbstractNullTile.java
  16. 62
      src/mightypork/rogue/world/tile/models/AbstractTile.java
  17. 50
      src/mightypork/rogue/world/tile/models/Floor.java
  18. 29
      src/mightypork/rogue/world/tile/models/NullTile.java
  19. 65
      src/mightypork/rogue/world/tile/models/SimpleDoor.java
  20. 55
      src/mightypork/rogue/world/tile/models/Wall.java
  21. 4
      src/mightypork/rogue/world/tile/renderers/DoorTileRenderer.java
  22. 2
      src/mightypork/rogue/world/tile/renderers/NullTileRenderer.java
  23. 58
      src/mightypork/rogue/world/tile/tiles/BasicTile.java
  24. 46
      src/mightypork/rogue/world/tile/tiles/DoorTile.java
  25. 45
      src/mightypork/rogue/world/tile/tiles/FloorTile.java
  26. 36
      src/mightypork/rogue/world/tile/tiles/LockedDoorTile.java
  27. 86
      src/mightypork/rogue/world/tile/tiles/NullTile.java
  28. 64
      src/mightypork/rogue/world/tile/tiles/TileWithItems.java
  29. 46
      src/mightypork/rogue/world/tile/tiles/WallTile.java
  30. 23
      src/mightypork/util/files/ion/IonBinary.java
  31. 31
      src/mightypork/util/files/ion/IonBinaryHeadless.java

@ -25,7 +25,6 @@ import mightypork.rogue.screens.test_render.ScreenTestRender;
import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.tile.Tile;
import mightypork.util.control.eventbus.BusEvent;
import mightypork.util.control.eventbus.EventBus;
import mightypork.util.files.ion.Ion;
@ -107,7 +106,6 @@ public final class App extends BaseApp {
@Override
protected void preInit()
{
Ion.registerBinary(Tile.ION_MARK, Tile.class);
Ion.registerBinary(Item.ION_MARK, Item.class);
Ion.registerBinary(Level.ION_MARK, Level.class);
Ion.registerBinary(Entity.ION_MARK, Entity.class);

@ -64,7 +64,7 @@ public class Minimap extends InputComponent implements MouseButtonListener {
for (pos.x = 0, point.x = tl.xi(); pos.x < lw; pos.x++, point.x += unit) {
final Tile t = lvl.getTile(pos);
if (t.isNull() || !t.data.explored) continue;
if (t.isNull() || !t.isExplored()) continue;
final Color clr = t.getMapColor();

@ -86,7 +86,7 @@ public class PlayerModel extends EntityModel {
@Override
public int getPathCost(Entity entity, Coord from, Coord to)
{
if (!entity.getLevel().getTile(entity.getCoord()).data.explored) {
if (!entity.getLevel().getTile(entity.getCoord()).isExplored()) {
return 1000;
}

@ -15,6 +15,7 @@ import mightypork.rogue.world.pathfinding.PathFinder;
import mightypork.rogue.world.pathfinding.PathFindingContext;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileType;
import mightypork.rogue.world.tile.Tiles;
import mightypork.util.logging.Log;
import mightypork.util.math.Calc;
@ -43,14 +44,24 @@ public class ScratchMap {
{
final Tile t = get(pos);
if (t.isNull()) return 60;
if (t.isDoor()) return 10; // door
if (t.isFloor()) return 20; // floor
if (t.isWall() && t.genData.isProtected) return 1000;
return 100; // wall
switch (t.getType()) {
case NULL:
return 60;
case DOOR:
return 10;
case FLOOR:
return 20;
case WALL:
if (t.genData.isProtected) return 1000;
return 100;
default:
throw new RuntimeException("Unknown tile type: " + t.getType());
}
}
@ -79,7 +90,8 @@ public class ScratchMap {
private static final boolean FIX_GLITCHES = true;
public ScratchMap(int max_size, Theme theme, Random rand) {
public ScratchMap(int max_size, Theme theme, Random rand)
{
map = new Tile[max_size][max_size];
genMin = Coord.make((max_size / 2) - 1, (max_size / 2) - 1);
@ -161,9 +173,7 @@ public class ScratchMap {
public Tile get(Coord pos)
{
if (!isIn(pos)) {
throw new IndexOutOfBoundsException("Tile not in map: " + pos);
}
if (!isIn(pos)) { throw new IndexOutOfBoundsException("Tile not in map: " + pos); }
return map[pos.y][pos.x];
}
@ -177,9 +187,7 @@ public class ScratchMap {
public boolean set(Coord pos, Tile tile)
{
if (!isIn(pos)) {
throw new IndexOutOfBoundsException("Tile not in map: " + pos);
}
if (!isIn(pos)) { throw new IndexOutOfBoundsException("Tile not in map: " + pos); }
map[pos.y][pos.x] = tile;
return true;
@ -295,7 +303,7 @@ public class ScratchMap {
final Tile current = get(c);
if (!current.isNull() && (current.isPotentiallyWalkable())) continue; // floor already, let it be
if (i == 0 && j == 0) {
set(c, theme.floor());
} else {

@ -100,7 +100,7 @@ public class Level implements MapAccess, IonBinary {
public final void setTile(Coord pos, int tileId)
{
setTile(pos, new Tile(tileId));
setTile(pos, Tiles.create(tileId));
}
@ -163,10 +163,7 @@ public class Level implements MapAccess, IonBinary {
// load tiles
for (final Coord c = Coord.zero(); c.x < size.x; c.x++) {
for (c.y = 0; c.y < size.y; c.y++) {
// no mark
final Tile tile = new Tile();
tile.load(in);
setTile(c, tile);
setTile(c, Tiles.loadTile(in));
}
}
@ -192,8 +189,7 @@ public class Level implements MapAccess, IonBinary {
for (final Coord c = Coord.zero(); c.x < size.x; c.x++) {
for (c.y = 0; c.y < size.y; c.y++) {
// no mark to save space
getTile(c).save(out);
Tiles.saveTile(out, getTile(c));
}
}
}
@ -333,7 +329,7 @@ public class Level implements MapAccess, IonBinary {
if (Calc.dist(coord.x, coord.y, c.x, c.y) > radius) continue;
final Tile t = getTile(c);
if (!t.isNull()) {
t.data.explored = true;
t.setExplored();
}
}
}

@ -24,7 +24,7 @@ public final class TileRenderContext extends MapRenderContext implements RectBou
{
super(map, drawArea);
this.tiler.setOverlap(0.01); // avoid gaps (rounding error?)
//this.tiler.setOverlap(0.02); // avoid gaps (rounding error?)
this.noise = map.getNoiseGen();
}
@ -69,7 +69,7 @@ public final class TileRenderContext extends MapRenderContext implements RectBou
public void renderItems()
{
map.getTile(pos).renderItems(this);
map.getTile(pos).renderExtra(this);
}

@ -0,0 +1,21 @@
package mightypork.rogue.world.pathfinding;
import mightypork.rogue.world.Coord;
public interface FillContext {
boolean canEnter(Coord pos);
boolean canSpread(Coord pos);
/**
* Get the max distance filled form start point. Use -1 for unlimited range.
*
* @return max distance
*/
int getMaxDistance();
}

@ -0,0 +1,41 @@
package mightypork.rogue.world.pathfinding;
import java.util.*;
import mightypork.rogue.world.Coord;
public class FloodFill {
private static final Coord[] spread = { Coord.make(0, -1), Coord.make(0, 1), Coord.make(1, 0), Coord.make(-1, 0) };
public static final Collection<Coord> fill(Coord start, FillContext context)
{
Set<Coord> filled = new HashSet<>();
Stack<Coord> active = new Stack<>();
int maxDist = context.getMaxDistance();
active.push(start);
while (!active.isEmpty()) {
Coord current = active.pop();
filled.add(current);
for (Coord spr : spread) {
Coord next = current.add(spr);
if (next.dist(start) > maxDist) continue;
if (context.canSpread(next)) {
active.push(next);
}
}
}
return filled;
}
}

@ -8,6 +8,7 @@ import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.util.files.ion.IonBinary;
import mightypork.util.files.ion.IonBinaryHeadless;
import mightypork.util.files.ion.IonInput;
import mightypork.util.files.ion.IonOutput;
import mightypork.util.math.color.Color;
@ -18,211 +19,129 @@ import mightypork.util.math.color.Color;
*
* @author MightyPork
*/
public final class Tile implements IonBinary {
public static final short ION_MARK = 50;
private TileModel model;
private TileRenderer renderer;
private int id;
private final Stack<Item> items = new Stack<>();
/** persistent field for model, reflected by renderer */
public final TileData data = new TileData();
public abstract class Tile implements IonBinaryHeadless {
// tmp extras
public final TileRenderData renderData = new TileRenderData();
public final TileGenData genData = new TileGenData();
// temporary flag for map.
private boolean occupied;
public Tile(int id) {
this(Tiles.get(id));
}
protected final TileRenderer renderer;
public final int id;
public Tile(TileModel model) {
setModel(model);
}
protected final Stack<Item> items = new Stack<>();
public Tile() {
}
// temporary flag for map.
protected boolean occupied;
protected boolean explored;
private void setModel(TileModel model)
public Tile(int id, TileRenderer renderer)
{
this.model = model;
this.id = model.id;
this.renderer = model.renderer;
this.id = id;
this.renderer = renderer;
}
/**
* Render the tile alone (must not use other than the main map texture)
* Render the tile, using the main texture sheet.
*/
public void renderTile(TileRenderContext context)
{
renderer.render(context);
if (hasItems()) {
renderer.renderItemOnTile(items.peek(), context);
}
}
public abstract void renderTile(TileRenderContext context);
/**
* Render items
* Render extra stuff (ie. dropped items).<br>
* Called after the whole map is rendered using renderTile.
*
* @param context
*/
public void renderItems(TileRenderContext context)
{
if (hasItems()) {
renderer.renderItemOnTile(items.peek(), context);
}
}
public abstract void renderExtra(TileRenderContext context);
@Override
public void save(IonOutput out) throws IOException
{
out.writeIntByte(id);
if (model.hasDroppedItems()) {
out.writeSequence(items);
}
data.save(out);
out.writeBoolean(explored);
}
@Override
public void load(IonInput in) throws IOException
{
id = in.readIntByte();
// if model changed
if (model == null || id != model.id) {
setModel(Tiles.get(id));
}
if (model.hasDroppedItems()) {
in.readSequence(items);
}
data.load(in);
explored = in.readBoolean();
}
/**
* Update tile logic state (on server)
*
* @param level the level
* @param delta delta time
*/
public void update(Level level, double delta)
public final boolean isOccupied()
{
model.update(this, level, delta);
return occupied;
}
public boolean isWalkable()
public final void setOccupied(boolean occupied)
{
return model.isWalkable(this);
this.occupied = occupied;
}
public boolean isDoor()
public final boolean isExplored()
{
return model.isDoor();
return explored;
}
public boolean isNull()
public void setExplored()
{
return model.isNullTile();
explored = true;
}
public TileModel getModel()
public final boolean isNull()
{
return model;
return getType() == TileType.NULL;
}
public boolean hasItems()
public final boolean isWall()
{
return model.hasDroppedItems() && !items.isEmpty();
return getType() == TileType.WALL;
}
public boolean doesCastShadow()
public final boolean isFloor()
{
return model.doesCastShadow();
return getType() == TileType.FLOOR;
}
@Override
public short getIonMark()
public final boolean isDoor()
{
return ION_MARK;
return getType() == TileType.DOOR;
}
public boolean isOccupied()
{
return occupied;
}
public abstract void update(Level level, double delta);
public void setOccupied(boolean occupied)
{
this.occupied = occupied;
}
public abstract boolean isWalkable();
public boolean isWall()
{
return model.isWall();
}
public abstract boolean isPotentiallyWalkable();
public boolean isFloor()
{
return model.isFloor();
}
public abstract TileType getType();
public boolean isPotentiallyWalkable()
{
return model.isPotentiallyWalkable();
}
public abstract boolean canHaveItems();
public Color getMapColor()
{
return model.getMapColor(this);
}
public abstract boolean doesCastShadow();
public boolean isExplored()
{
return data.explored;
}
public abstract boolean doesReceiveShadow();
public void explore()
{
data.explored = true;
}
public boolean doesReceiveShadow()
{
return model.doesReceiveShadow();
}
public abstract Color getMapColor();
}

@ -1,54 +0,0 @@
package mightypork.rogue.world.tile;
import java.io.IOException;
import mightypork.util.error.YouFuckedUpException;
import mightypork.util.files.ion.IonBinary;
import mightypork.util.files.ion.IonBundle;
import mightypork.util.files.ion.IonInput;
import mightypork.util.files.ion.IonOutput;
public class TileData implements IonBinary {
private static final byte BIT_EXPLORED = 1 << 0;
private static final byte BIT_LOCKED = 1 << 1;
public boolean explored = false;
public boolean locked = false;
public final IonBundle extra = new IonBundle();
@Override
public void load(IonInput in) throws IOException
{
final byte flags = in.readByte();
in.readBundle(extra);
explored = (flags & BIT_EXPLORED) != 0;
locked = (flags & BIT_LOCKED) != 0;
}
@Override
public void save(IonOutput out) throws IOException
{
byte flags = 0;
if (explored) flags |= BIT_EXPLORED;
if (locked) flags |= BIT_LOCKED;
out.writeByte(flags);
out.writeBundle(extra);
}
@Override
public short getIonMark()
{
throw new YouFuckedUpException("TileData is not to be read from ION using mark.");
}
}

@ -1,8 +1,9 @@
package mightypork.rogue.world.tile;
import mightypork.rogue.world.level.Level;
import mightypork.util.math.color.Color;
import java.io.IOException;
import mightypork.util.files.ion.IonInput;
import mightypork.util.files.ion.IonOutput;
/**
@ -10,79 +11,46 @@ import mightypork.util.math.color.Color;
*
* @author MightyPork
*/
public abstract class TileModel {
public final class TileModel {
/** Model ID */
public final int id;
public TileRenderer renderer = TileRenderer.NONE;
public final TileRenderer renderer;
public final Class<? extends Tile> tileClass;
public TileModel(int id)
public TileModel(int id, Class<? extends Tile> tile, TileRenderer renderer)
{
Tiles.register(id, this);
this.id = id;
}
public TileModel setRenderer(TileRenderer renderer)
{
this.renderer = renderer;
return this;
this.tileClass = tile;
}
/**
* @return new tile of this type; if 100% invariant, can return cached one.
* @return new tile of this type
*/
public Tile createTile()
{
return new Tile(this);
try {
return tileClass.getConstructor(int.class, TileRenderer.class).newInstance(id, renderer);
} catch (Exception e) {
throw new RuntimeException("Could not instantiate a tile.", e);
}
}
public abstract boolean isWalkable(Tile tile);
public abstract boolean isDoor();
public abstract boolean isWall();
public abstract boolean isFloor();
public abstract boolean doesCastShadow();
public abstract boolean doesReceiveShadow();
public boolean isNullTile()
public Tile loadTile(IonInput in) throws IOException
{
return false;
Tile t = createTile();
t.load(in);
return t;
}
/**
* Update tile in world
*/
public abstract void update(Tile tile, Level level, double delta);
/**
* @return true if this item can have dropped items
*/
public abstract boolean hasDroppedItems();
/**
* @return true if walkable at some conditions (ie. floor, hidden door,
* locked door etc)
*/
public abstract boolean isPotentiallyWalkable();
public abstract Color getMapColor(Tile tile);
public void saveTile(IonOutput out, Tile tile) throws IOException
{
tile.save(out);
}
}

@ -4,9 +4,7 @@ import mightypork.gamecore.render.Render;
import mightypork.gamecore.render.textures.TxQuad;
import mightypork.rogue.Res;
import mightypork.rogue.world.Sides;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.renderers.NullTileRenderer;
import mightypork.util.math.constraints.rect.Rect;
@ -17,16 +15,12 @@ import mightypork.util.math.constraints.rect.Rect;
*/
public abstract class TileRenderer {
public static final TileRenderer NONE = new NullTileRenderer();
private static TxQuad SH_N, SH_S, SH_E, SH_W, SH_NW, SH_NE, SH_SW, SH_SE;
private static TxQuad UFOG_N, UFOG_S, UFOG_E, UFOG_W, UFOG_NW, UFOG_NE, UFOG_SW, UFOG_SE;
private static boolean inited;
private DroppedItemRenderer itemRenderer;
public TileRenderer() {
if (!inited) {
@ -51,41 +45,10 @@ public abstract class TileRenderer {
}
/**
* Update tile renderer
*
* @param delta delta time
*/
public void update(double delta)
{
if (itemRenderer != null) {
itemRenderer.update(delta);
}
}
/**
* Render the tile.
*
* @param context
*/
public final void render(TileRenderContext context)
{
Tile t = context.getTile();
if (t.isNull() || !t.isExplored()) return;
renderTile(context);
if (t.doesReceiveShadow()) renderShadows(context);
renderUFog(context);
}
protected abstract void renderTile(TileRenderContext context);
public abstract void renderTile(TileRenderContext context);
protected void renderShadows(TileRenderContext context)
public void renderShadows(TileRenderContext context)
{
final TileRenderData trd = context.getTile().renderData;
@ -96,7 +59,7 @@ public abstract class TileRenderer {
for (int i = 0; i < 8; i++) {
final Tile t2 = context.getAdjacentTile(Sides.get(i));
if (t2.doesCastShadow()) {
if (!t2.isNull() && t2.doesCastShadow()) {
trd.shadows |= Sides.bit(i);
}
}
@ -120,9 +83,8 @@ public abstract class TileRenderer {
}
protected void renderUFog(TileRenderContext context)
{
public void renderUnexploredFog(TileRenderContext context)
{
// TODO cache in tile, update neighbouring tiles upon "explored" flag changed.
byte ufog = 0;
@ -150,14 +112,4 @@ public abstract class TileRenderer {
if ((ufog & Sides.S) != 0) Render.quadTextured(rect, UFOG_S);
if ((ufog & Sides.SE_CORNER) == Sides.SE) Render.quadTextured(rect, UFOG_SE);
}
public void renderItemOnTile(Item item, TileRenderContext context)
{
if (itemRenderer == null) {
itemRenderer = new DroppedItemRenderer();
}
itemRenderer.render(item, context);
}
}

@ -0,0 +1,12 @@
package mightypork.rogue.world.tile;
/**
* Kinds of tiles
*
* @author MightyPork
*/
public enum TileType
{
NULL, FLOOR, WALL, DOOR;
}

@ -1,11 +1,18 @@
package mightypork.rogue.world.tile;
import mightypork.rogue.world.tile.models.Floor;
import mightypork.rogue.world.tile.models.NullTile;
import mightypork.rogue.world.tile.models.SimpleDoor;
import mightypork.rogue.world.tile.models.Wall;
import java.io.IOException;
import mightypork.rogue.world.tile.renderers.BasicTileRenderer;
import mightypork.rogue.world.tile.renderers.DoorTileRenderer;
import mightypork.rogue.world.tile.renderers.NullTileRenderer;
import mightypork.rogue.world.tile.tiles.DoorTile;
import mightypork.rogue.world.tile.tiles.FloorTile;
import mightypork.rogue.world.tile.tiles.NullTile;
import mightypork.rogue.world.tile.tiles.WallTile;
import mightypork.util.files.ion.IonInput;
import mightypork.util.files.ion.IonOutput;
/**
* Tile registry
@ -16,28 +23,12 @@ public final class Tiles {
private static final TileModel[] tiles = new TileModel[256];
public static final TileModel NULL = new NullTile(0);
public static final TileModel FLOOR_DARK = new Floor(10).setRenderer(new BasicTileRenderer("tile.floor.dark"));
public static final TileModel WALL_BRICK = new Wall(11).setRenderer(new BasicTileRenderer("tile.wall.brick"));
public static final TileModel DOOR = new SimpleDoor(12);
public static final TileModel NULL = new TileModel(0, NullTile.class, new NullTileRenderer());
// public static final TileModel BRICK_FLOOR_VINES = new Floor(2).setTexture("tile.floor.mossy_bricks");
// public static final TileModel BRICK_WALL_VINES = new Wall(3).setTexture("tile.wall.mossy_bricks");
//
// public static final TileModel BRICK_FLOOR_RECT = new Floor(4).setTexture("tile.floor.rect_bricks");
// public static final TileModel BRICK_WALL_SMALL = new Wall(5).setTexture("tile.wall.small_bricks");
//
// public static final TileModel SANDSTONE_FLOOR = new Floor(6).setTexture("tile.floor.sandstone");
// public static final TileModel SANDSTONE_WALL = new Wall(7).setTexture("tile.wall.sandstone");
//
// public static final TileModel BRCOBBLE_FLOOR = new Floor(8).setTexture("tile.floor.brown_cobble");
// public static final TileModel BRCOBBLE_WALL = new Wall(9).setTexture("tile.wall.brown_cobble");
//
// public static final TileModel CRYSTAL_FLOOR = new Floor(10).setTexture("tile.floor.crystal");
// public static final TileModel CRYSTAL_WALL = new Wall(11).setTexture("tile.wall.crystal");
public static final TileModel FLOOR_DARK = new TileModel(10, FloorTile.class, new BasicTileRenderer("tile.floor.dark"));
public static final TileModel WALL_BRICK = new TileModel(11, WallTile.class, new BasicTileRenderer("tile.wall.brick"));
public static final TileModel DOOR = new TileModel(12, DoorTile.class, new DoorTileRenderer("tile.door.closed", "tile.door.open"));
public static void register(int id, TileModel model)
{
@ -57,4 +48,28 @@ public final class Tiles {
return m;
}
public static Tile loadTile(IonInput in) throws IOException
{
int id = in.readIntByte();
TileModel model = get(id);
return model.loadTile(in);
}
public static void saveTile(IonOutput out, Tile tile) throws IOException
{
out.writeIntByte(tile.id);
TileModel model = get(tile.id);
model.saveTile(out, tile);
}
public static Tile create(int tileId)
{
return get(tileId).createTile();
}
}

@ -1,53 +0,0 @@
package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
/**
* Null tile
*
* @author MightyPork
*/
public abstract class AbstractNullTile extends AbstractTile {
private Tile inst;
public AbstractNullTile(int id)
{
super(id);
}
@Override
public boolean isNullTile()
{
return true;
}
@Override
public Tile createTile()
{
if (inst == null) {
inst = new Tile(this);
}
return inst;
}
@Override
public boolean hasDroppedItems()
{
return false;
}
@Override
public boolean doesCastShadow()
{
return false;
}
}

@ -1,62 +0,0 @@
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;
/**
* Basic implementation of a tile.
*
* @author MightyPork
*/
public abstract class AbstractTile extends TileModel {
public AbstractTile(int id)
{
super(id);
}
@Override
public boolean isWalkable(Tile tile)
{
return isPotentiallyWalkable();
}
@Override
public boolean isDoor()
{
return false;
}
@Override
public boolean isWall()
{
return false;
}
@Override
public boolean isFloor()
{
return false;
}
@Override
public boolean doesReceiveShadow()
{
return isFloor();
}
@Override
@DefaultImpl
public void update(Tile tile, Level level, double delta)
{
}
}

@ -1,50 +0,0 @@
package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
import mightypork.util.math.color.Color;
import mightypork.util.math.color.RGB;
public class Floor extends AbstractTile {
public Floor(int id)
{
super(id);
}
@Override
public boolean isPotentiallyWalkable()
{
return true;
}
@Override
public boolean hasDroppedItems()
{
return true;
}
@Override
public boolean doesCastShadow()
{
return false;
}
@Override
public boolean isFloor()
{
return true;
}
@Override
public Color getMapColor(Tile tile)
{
return RGB.GRAY_DARK;
}
}

@ -1,29 +0,0 @@
package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
import mightypork.util.math.color.Color;
import mightypork.util.math.color.RGB;
public class NullTile extends AbstractNullTile {
public NullTile(int id)
{
super(id);
}
@Override
public boolean isPotentiallyWalkable()
{
return false;
}
@Override
public Color getMapColor(Tile tile)
{
return RGB.NONE;
}
}

@ -1,65 +0,0 @@
package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.renderers.DoorRenderer;
import mightypork.util.math.color.Color;
import mightypork.util.math.color.PAL16;
public class SimpleDoor extends AbstractTile {
public SimpleDoor(int id)
{
super(id);
setRenderer(new DoorRenderer("tile.door.closed", "tile.door.open"));
}
@Override
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;
}
@Override
public Color getMapColor(Tile tile)
{
return PAL16.NEWPOOP;
}
}

@ -1,55 +0,0 @@
package mightypork.rogue.world.tile.models;
import mightypork.rogue.world.tile.Tile;
import mightypork.util.math.color.Color;
import mightypork.util.math.color.RGB;
/**
* Template for wall tiles with no metadata
*
* @author MightyPork
*/
public class Wall extends AbstractTile {
public Wall(int id)
{
super(id);
}
@Override
public final boolean hasDroppedItems()
{
return false;
}
@Override
public final boolean doesCastShadow()
{
return true;
}
@Override
public final boolean isWall()
{
return true;
}
@Override
public final boolean isPotentiallyWalkable()
{
return false;
}
@Override
public Color getMapColor(Tile tile)
{
return RGB.GRAY_LIGHT;
}
}

@ -10,13 +10,13 @@ import mightypork.rogue.world.tile.TileRenderer;
import mightypork.util.math.constraints.rect.Rect;
public class DoorRenderer extends TileRenderer {
public class DoorTileRenderer extends TileRenderer {
private final TxQuad closed;
private final TxQuad open;
public DoorRenderer(String quadClosed, String quadOpen)
public DoorTileRenderer(String quadClosed, String quadOpen)
{
this.closed = Res.getTxQuad(quadClosed);
this.open = Res.getTxQuad(quadOpen);

@ -8,7 +8,7 @@ import mightypork.rogue.world.tile.TileRenderer;
public class NullTileRenderer extends TileRenderer {
@Override
protected void renderTile(TileRenderContext context)
public void renderTile(TileRenderContext context)
{
}

@ -0,0 +1,58 @@
package mightypork.rogue.world.tile.tiles;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.util.annotations.DefaultImpl;
public abstract class BasicTile extends Tile {
public BasicTile(int id, TileRenderer renderer)
{
super(id, renderer);
}
@Override
public boolean isWalkable()
{
return isPotentiallyWalkable();
}
@Override
public void renderTile(TileRenderContext context)
{
if (!isExplored()) return;
renderer.renderTile(context);
if (doesReceiveShadow()) renderer.renderShadows(context);
renderer.renderUnexploredFog(context);
}
@Override
@DefaultImpl
public void renderExtra(TileRenderContext context)
{
}
@Override
@DefaultImpl
public void update(Level level, double delta)
{
}
@Override
public boolean doesReceiveShadow()
{
return !doesCastShadow();
}
}

@ -0,0 +1,46 @@
package mightypork.rogue.world.tile.tiles;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.rogue.world.tile.TileType;
import mightypork.util.math.color.Color;
import mightypork.util.math.color.PAL16;
public class DoorTile extends BasicTile {
public DoorTile(int id, TileRenderer renderer)
{
super(id, renderer);
}
@Override
public boolean isPotentiallyWalkable()
{
return true;
}
@Override
public TileType getType()
{
return TileType.DOOR;
}
@Override
public boolean canHaveItems()
{
return false;
}
@Override
public boolean doesCastShadow()
{
return true;
}
@Override
public Color getMapColor()
{
return PAL16.NEWPOOP;
}
}

@ -0,0 +1,45 @@
package mightypork.rogue.world.tile.tiles;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.rogue.world.tile.TileType;
import mightypork.util.math.color.Color;
import mightypork.util.math.color.RGB;
public class FloorTile extends TileWithItems {
public FloorTile(int id, TileRenderer renderer)
{
super(id, renderer);
}
@Override
public boolean isPotentiallyWalkable()
{
return true;
}
@Override
public TileType getType()
{
return TileType.FLOOR;
}
@Override
public boolean doesCastShadow()
{
return false;
}
@Override
public Color getMapColor()
{
return RGB.GRAY_DARK;
}
}

@ -0,0 +1,36 @@
package mightypork.rogue.world.tile.tiles;
import java.io.IOException;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.util.files.ion.IonInput;
import mightypork.util.files.ion.IonOutput;
public class LockedDoorTile extends DoorTile {
public boolean locked = true;
public LockedDoorTile(int id, TileRenderer renderer)
{
super(id, renderer);
}
@Override
public void load(IonInput in) throws IOException
{
super.load(in);
locked = in.readBoolean();
}
@Override
public void save(IonOutput out) throws IOException
{
super.save(out);
out.writeBoolean(locked);
}
}

@ -0,0 +1,86 @@
package mightypork.rogue.world.tile.tiles;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.rogue.world.tile.TileType;
import mightypork.util.math.color.Color;
import mightypork.util.math.color.RGB;
public class NullTile extends Tile {
public NullTile(int id, TileRenderer renderer)
{
super(id, renderer);
}
@Override
public void update(Level level, double delta)
{
}
@Override
public void renderTile(TileRenderContext context)
{
}
@Override
public void renderExtra(TileRenderContext context)
{
}
@Override
public boolean isWalkable()
{
return false;
}
@Override
public boolean isPotentiallyWalkable()
{
return false;
}
@Override
public TileType getType()
{
return TileType.NULL;
}
@Override
public boolean canHaveItems()
{
return false;
}
@Override
public boolean doesCastShadow()
{
return false;
}
@Override
public boolean doesReceiveShadow()
{
return false;
}
@Override
public Color getMapColor()
{
return RGB.NONE;
}
}

@ -0,0 +1,64 @@
package mightypork.rogue.world.tile.tiles;
import java.io.IOException;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.DroppedItemRenderer;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.util.files.ion.IonInput;
import mightypork.util.files.ion.IonOutput;
public abstract class TileWithItems extends BasicTile {
private DroppedItemRenderer itemRenderer = new DroppedItemRenderer();
public TileWithItems(int id, TileRenderer renderer)
{
super(id, renderer);
}
@Override
public void renderExtra(TileRenderContext context)
{
if (!items.isEmpty()) {
itemRenderer.render(items.peek(), context);
}
}
@Override
public void update(Level level, double delta)
{
itemRenderer.update(delta);
}
@Override
public boolean canHaveItems()
{
return true;
}
@Override
public void save(IonOutput out) throws IOException
{
super.save(out);
out.writeSequence(items);
}
@Override
public void load(IonInput in) throws IOException
{
super.load(in);
in.readSequence(items);
}
}

@ -0,0 +1,46 @@
package mightypork.rogue.world.tile.tiles;
import mightypork.rogue.world.tile.TileRenderer;
import mightypork.rogue.world.tile.TileType;
import mightypork.util.math.color.Color;
import mightypork.util.math.color.RGB;
public class WallTile extends BasicTile {
public WallTile(int id, TileRenderer renderer)
{
super(id, renderer);
}
@Override
public boolean isPotentiallyWalkable()
{
return false;
}
@Override
public TileType getType()
{
return TileType.WALL;
}
@Override
public boolean canHaveItems()
{
return false;
}
@Override
public boolean doesCastShadow()
{
return true;
}
@Override
public Color getMapColor()
{
return RGB.GRAY_LIGHT;
}
}

@ -5,30 +5,11 @@ import java.io.IOException;
/**
* Binary ion object
* Binary ion object, with a mark = saveable / loadable on it's own
*
* @author MightyPork
*/
public interface IonBinary {
/**
* Load data from the input stream.
*
* @param in input stream
* @throws IOException
*/
void load(IonInput in) throws IOException;
/**
* Store data to output stream (in such way that the load method will later
* be able to read it).
*
* @param out Output stream
* @throws IOException
*/
void save(IonOutput out) throws IOException;
public interface IonBinary extends IonBinaryHeadless {
/**
* Get Ion mark byte.

@ -0,0 +1,31 @@
package mightypork.util.files.ion;
import java.io.IOException;
/**
* Binary ion object, with no mark = cannot be loaded on it's own
*
* @author MightyPork
*/
public interface IonBinaryHeadless {
/**
* Load data from the input stream.
*
* @param in input stream
* @throws IOException
*/
void load(IonInput in) throws IOException;
/**
* Store data to output stream (in such way that the load method will later
* be able to read it).
*
* @param out Output stream
* @throws IOException
*/
void save(IonOutput out) throws IOException;
}
Loading…
Cancel
Save