package pathgame.tilemap; import java.util.function.Function; import pathgame.gameplay.Player; /** Base class for tiles. Tiles are registered on construction. * * @author kajetan */ public class Tile { public static class TileBuilder { private int energyCost = 2; private float forestReplaceChance = 1.0f; private Function speedUp = (p) -> 0; private boolean canHostTown = true; private boolean blocksMovement = false; private TileType type = TileType.LAND; private boolean canHostPath = false; private boolean path = false; private TileRenderType renderType = TileRenderType.NORMAL; private TileBuilder() { } public static TileBuilder create() { return new TileBuilder(); } public TileBuilder setEnergyCost(int energyCost) { this.energyCost = energyCost; return this; } public TileBuilder setForestReplaceChance(float forestReplaceChance) { this.forestReplaceChance = forestReplaceChance; return this; } public TileBuilder setSpeedUp(Function speedUp) { this.speedUp = speedUp; return this; } public TileBuilder noTown() { this.canHostTown = false; return this; } public TileBuilder noMovement() { this.blocksMovement = true; return this; } public TileBuilder setType(TileType type) { this.type = type; return this; } public TileBuilder pathHost() { this.canHostPath = true; return this; } public TileBuilder path() { this.path = true; return this; } public TileBuilder setRenderType(TileRenderType type) { this.renderType = type; return this; } public Tile build() { return new Tile(energyCost, forestReplaceChance, speedUp, canHostTown, blocksMovement, type, canHostPath, path, renderType); } } private static int idCounter = 0; private static Tile[] tiles = new Tile[8]; private static int addTile(Tile t) { if(idCounter >= tiles.length) { Tile[] newTiles = new Tile[tiles.length * 2]; System.arraycopy(tiles, 0, newTiles, 0, tiles.length); tiles = newTiles; } tiles[idCounter] = t; return idCounter++; } /** Returns a tile from the given id or null if the id is invalid. * * @param id the id of the tile * @return a tile from the given id or null if the id is invalid */ public static Tile fromId(int id) { if(id < 0 || id >= idCounter) { return null; } return tiles[id]; } private final int id; private final int energyCost; private final float forestReplaceChance; private final Function speedUp; private final boolean canHostTown; private final boolean blocksMovement; private final TileType type; private final boolean canHostPath; private final boolean path; private final TileRenderType renderType; protected Tile(int energyCost, float forestReplaceChance, Function speedUp, boolean canHostTown, boolean blocksMovement, TileType type, boolean canHostPath, boolean path, TileRenderType renderType) { id = addTile(this); this.energyCost = energyCost; this.forestReplaceChance = forestReplaceChance; this.speedUp = speedUp; this.canHostTown = canHostTown; this.blocksMovement = blocksMovement; this.type = type; this.canHostPath = canHostPath; this.path = path; this.renderType = renderType; } /** Returns the id of the tile. * * @return the id of the tile */ public final int getId() { return id; } public int getEnergyCost(Player p) { return energyCost - speedUp.apply(p); } /** Returns the chance that this tile is replaced by forest. * * @return the chance that this tile is replaced by forest */ public float getForestReplaceChance() { return forestReplaceChance; } /** Returns true if this tile can be replaced by a town. * * @return true if this tile can be replaced by a town */ public boolean canHostTown() { return canHostTown; } /** Called when the player fully enters a tile. * * @param p the player * @param map the current tilemap * @param x the x coordinate of the tile * @param y the y coordinate of the tile */ public void onEnter(Player p, TileMap map, int x, int y) { } /** Called when the player leaves a tile. * * @param p the player * @param map the current tilemap * @param x the x coordinate of the tile * @param y the y coordinate of the tile */ public void onLeave(Player p, TileMap map, int x, int y) { } /** Returns true if this tile blocks movement. * * @param p the player * @return true if this tile blocks movement */ public boolean isBlockingMovement(Player p) { return blocksMovement || (p.isSailing() && type == TileType.LAND) || (!p.isSailing() && type == TileType.DEEP_WATER); } /** Returns the type of the tile. * * @return the type of the tile */ public TileType getType() { return type; } /** Returns true if this tile can be replaced by a path. * * @return true if this tile can be replaced by a path */ public boolean canHostPath() { return canHostPath; } /** Returns true if this tile is a path. * * @return true if this tile is a path */ public boolean isPath() { return path; } /** Returns the rendering type for overlays. * * @return the rendering type for overlays */ public TileRenderType getRenderType() { return renderType; } /** Called when the player stands on that tile. * * @param p the player * @param map the current tilemap * @param x the x coordinate of the tile * @param y the y coordinate of the tile */ public void isStandingOn(Player p, TileMap map, int x, int y) { } }