Up/Down stairs, transition fade, improved controls.
This commit is contained in:
@@ -342,7 +342,7 @@ final public class EventBus implements Destroyable, BusAccess {
|
||||
assertLive();
|
||||
|
||||
if (sendingDirect) {
|
||||
Log.w("Cannot send a direct event in response to another.");
|
||||
Log.w(logMark + "Already dispatching, adding event to queue instead: " + Log.str(event));
|
||||
sendQueued(event);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,16 +25,20 @@ public abstract class PathFinder {
|
||||
public static final Heuristic CORNER_HEURISTIC = new ManhattanHeuristic();
|
||||
public static final Heuristic DIAGONAL_HEURISTIC = new DiagonalHeuristic();
|
||||
|
||||
private boolean ignoreStart;
|
||||
private boolean ignoreEnd;
|
||||
|
||||
|
||||
public List<Step> findPathRelative(Coord start, Coord end)
|
||||
{
|
||||
return findPathRelative(start, end, false);
|
||||
return findPathRelative(start, end, ignoreStart, ignoreEnd);
|
||||
}
|
||||
|
||||
|
||||
public List<Step> findPathRelative(Coord start, Coord end, boolean ignoreEnd)
|
||||
public List<Step> findPathRelative(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
|
||||
{
|
||||
final List<Coord> path = findPath(start, end, ignoreEnd);
|
||||
final List<Coord> path = findPath(start, end, ignoreStart, ignoreEnd);
|
||||
|
||||
if (path == null) return null;
|
||||
|
||||
final List<Step> out = new ArrayList<>();
|
||||
@@ -53,11 +57,11 @@ public abstract class PathFinder {
|
||||
|
||||
public List<Coord> findPath(Coord start, Coord end)
|
||||
{
|
||||
return findPath(start, end, false);
|
||||
return findPath(start, end, ignoreStart, ignoreEnd);
|
||||
}
|
||||
|
||||
|
||||
public List<Coord> findPath(Coord start, Coord end, boolean ignoreEnd)
|
||||
public List<Coord> findPath(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
|
||||
{
|
||||
final LinkedList<Node> open = new LinkedList<>();
|
||||
final LinkedList<Node> closed = new LinkedList<>();
|
||||
@@ -92,7 +96,7 @@ public abstract class PathFinder {
|
||||
for (final Step go : walkDirs) {
|
||||
|
||||
final Coord c = current.pos.add(go);
|
||||
if (!isAccessible(c) && !(c.equals(end) && ignoreEnd)) continue;
|
||||
if (!isAccessible(c) && !(c.equals(end) && ignoreEnd) && !(c.equals(start) && ignoreStart)) continue;
|
||||
final Node a = new Node(c);
|
||||
a.g_cost = current.g_cost + getCost(c, a.pos);
|
||||
a.h_cost = (int) (heuristic.getCost(a.pos, end) * getMinCost());
|
||||
@@ -203,6 +207,18 @@ public abstract class PathFinder {
|
||||
}
|
||||
|
||||
|
||||
public void setIgnoreEnd(boolean ignoreEnd)
|
||||
{
|
||||
this.ignoreEnd = ignoreEnd;
|
||||
}
|
||||
|
||||
|
||||
public void setIgnoreStart(boolean ignoreStart)
|
||||
{
|
||||
this.ignoreStart = ignoreStart;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return used heuristic
|
||||
*/
|
||||
|
||||
@@ -100,6 +100,8 @@ public final class Res {
|
||||
textures.addSheet("tile.brick.door.secret", grid.makeSheet(0, 3, 2, 1));
|
||||
|
||||
textures.addSheet("tile.brick.passage", grid.makeSheet(3, 2, 4, 1));
|
||||
textures.addQuad("tile.brick.stairs.up", grid.makeQuad(0, 6));
|
||||
textures.addQuad("tile.brick.stairs.down", grid.makeQuad(1, 6));
|
||||
|
||||
textures.addQuad("tile.shadow.n", grid.makeQuad(0, 7));
|
||||
textures.addQuad("tile.shadow.s", grid.makeQuad(0, 7).flipY());
|
||||
@@ -135,24 +137,36 @@ public final class Res {
|
||||
}
|
||||
|
||||
|
||||
public static TxQuad getTxQuad(String key)
|
||||
{
|
||||
return textures.getQuad(key);
|
||||
}
|
||||
|
||||
|
||||
public static GLTexture getTexture(String key)
|
||||
{
|
||||
return textures.getTexture(key);
|
||||
}
|
||||
|
||||
|
||||
public static TxSheet sheet(String key)
|
||||
/**
|
||||
* Get a texture sheet by key
|
||||
*
|
||||
* @param key
|
||||
* @return sheet
|
||||
*/
|
||||
public static TxSheet txs(String key)
|
||||
{
|
||||
return textures.getSheet(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a texture quad by key
|
||||
*
|
||||
* @param key
|
||||
* @return quad
|
||||
*/
|
||||
public static TxQuad txq(String key)
|
||||
{
|
||||
return textures.getQuad(key);
|
||||
}
|
||||
|
||||
|
||||
public static LoopPlayer getLoop(String key)
|
||||
{
|
||||
return sounds.getLoop(key);
|
||||
|
||||
@@ -44,7 +44,7 @@ public class HudLayer extends ScreenLayer {
|
||||
final Num w = root.width();
|
||||
final Num minWH = w.min(h).max(700); // avoid too small shrinking
|
||||
|
||||
final ImagePainter nav = new ImagePainter(Res.getTxQuad("panel"));
|
||||
final ImagePainter nav = new ImagePainter(Res.txq("panel"));
|
||||
nav.setRect(root.bottomEdge().growUp(minWH.perc(7)));
|
||||
root.add(nav);
|
||||
|
||||
@@ -52,8 +52,8 @@ public class HudLayer extends ScreenLayer {
|
||||
itemSlots.setRect(nav.growUp(nav.height()).move(nav.height().mul(0.2), nav.height().mul(-0.2)));
|
||||
root.add(itemSlots);
|
||||
|
||||
itemSlots.add(new NavItemSlot(Res.getTxQuad("meat")));
|
||||
itemSlots.add(new NavItemSlot(Res.getTxQuad("sword")));
|
||||
itemSlots.add(new NavItemSlot(Res.txq("meat")));
|
||||
itemSlots.add(new NavItemSlot(Res.txq("sword")));
|
||||
|
||||
final Rect shrunk = root.shrink(minWH.perc(3));
|
||||
final Num displays_height = minWH.perc(6);
|
||||
@@ -62,9 +62,9 @@ public class HudLayer extends ScreenLayer {
|
||||
final HeartBar hearts = new HeartBar(
|
||||
playerHealthTotal,
|
||||
playerHealthActive,
|
||||
Res.getTxQuad("heart_on"),
|
||||
Res.getTxQuad("heart_half"),
|
||||
Res.getTxQuad("heart_off"),
|
||||
Res.txq("heart_on"),
|
||||
Res.txq("heart_half"),
|
||||
Res.txq("heart_off"),
|
||||
AlignX.LEFT);
|
||||
//@formatter:on
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public class NavItemSlot extends ClickableComponent implements MouseMotionListen
|
||||
public NavItemSlot(TxQuad image)
|
||||
{
|
||||
this.image = image;
|
||||
this.frame = Res.getTxQuad("item_frame");
|
||||
this.frame = Res.txq("item_frame");
|
||||
|
||||
final Rect ref = shrink(height().perc(8));
|
||||
yOffset = new NumAnimated(0, Easing.LINEAR);
|
||||
|
||||
@@ -39,7 +39,7 @@ class MenuLayer extends ScreenLayer {
|
||||
root.add(layout);
|
||||
|
||||
int r = 0;
|
||||
final ImagePainter ip = new ImagePainter(Res.getTxQuad("logo"));
|
||||
final ImagePainter ip = new ImagePainter(Res.txq("logo"));
|
||||
ip.keepAspectRatio();
|
||||
layout.put(ip, r, 0, 5, 1);
|
||||
r += 6;
|
||||
|
||||
@@ -8,7 +8,7 @@ import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.gamecore.util.math.algo.Step;
|
||||
import mightypork.rogue.world.entity.Entity;
|
||||
import mightypork.rogue.world.entity.modules.EntityMoveListener;
|
||||
import mightypork.rogue.world.level.LevelAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
|
||||
|
||||
public abstract class PlayerControl {
|
||||
@@ -76,7 +76,7 @@ public abstract class PlayerControl {
|
||||
}
|
||||
|
||||
|
||||
public LevelAccess getLevel()
|
||||
public Level getLevel()
|
||||
{
|
||||
return getWorld().getCurrentLevel();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package mightypork.rogue.world;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.gamecore.eventbus.BusAccess;
|
||||
import mightypork.gamecore.eventbus.EventBus;
|
||||
@@ -15,7 +16,6 @@ import mightypork.gamecore.util.math.timing.Pauseable;
|
||||
import mightypork.rogue.world.entity.Entities;
|
||||
import mightypork.rogue.world.entity.Entity;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
import mightypork.rogue.world.level.LevelAccess;
|
||||
|
||||
|
||||
/**
|
||||
@@ -134,7 +134,13 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
||||
final Coord spawn = floor.getEnterPoint();
|
||||
|
||||
floor.forceFreeTile(spawn);
|
||||
floor.addEntity(playerEntity, spawn);
|
||||
final Random rand = new Random(seed + 71);
|
||||
|
||||
while (!floor.addEntity(playerEntity, spawn)) {
|
||||
spawn.x += -1 + rand.nextInt(3);
|
||||
spawn.y += -1 + rand.nextInt(3);
|
||||
}
|
||||
|
||||
floor.explore(spawn);
|
||||
|
||||
playerInfo.setLevel(level);
|
||||
@@ -142,7 +148,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
||||
}
|
||||
|
||||
|
||||
public LevelAccess getCurrentLevel()
|
||||
public Level getCurrentLevel()
|
||||
{
|
||||
return levels.get(playerInfo.getLevel());
|
||||
}
|
||||
@@ -193,4 +199,40 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
||||
return paused;
|
||||
}
|
||||
|
||||
|
||||
public boolean canAscend()
|
||||
{
|
||||
return playerInfo.getLevel() > 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean canDescend()
|
||||
{
|
||||
return playerInfo.getLevel() < levels.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
public void ascend()
|
||||
{
|
||||
if (!canAscend()) return;
|
||||
|
||||
int lvl_num = playerInfo.getLevel();
|
||||
getCurrentLevel().removeEntity(playerEntity);
|
||||
playerInfo.setLevel(lvl_num - 1);
|
||||
getCurrentLevel().addEntity(playerEntity, getCurrentLevel().getExitPoint());
|
||||
getCurrentLevel().explore(playerEntity.getCoord());
|
||||
}
|
||||
|
||||
|
||||
public void descend()
|
||||
{
|
||||
if (!canDescend()) return;
|
||||
|
||||
int lvl_num = playerInfo.getLevel();
|
||||
getCurrentLevel().removeEntity(playerEntity);
|
||||
playerInfo.setLevel(lvl_num + 1);
|
||||
getCurrentLevel().addEntity(playerEntity, getCurrentLevel().getEnterPoint());
|
||||
getCurrentLevel().explore(playerEntity.getCoord());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ public class WorldCreator {
|
||||
final World w = new World();
|
||||
w.setSeed(seed);
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME);
|
||||
int count = 6;
|
||||
|
||||
for (int i = 1; i <= count; i++) {
|
||||
final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME, i == count);
|
||||
w.addLevel(l);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import mightypork.gamecore.eventbus.BusAccess;
|
||||
import mightypork.gamecore.eventbus.clients.RootBusNode;
|
||||
import mightypork.gamecore.util.ion.Ion;
|
||||
import mightypork.rogue.world.entity.Entity;
|
||||
import mightypork.rogue.world.level.LevelAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
|
||||
|
||||
public class WorldProvider extends RootBusNode {
|
||||
@@ -85,7 +85,7 @@ public class WorldProvider extends RootBusNode {
|
||||
}
|
||||
|
||||
|
||||
public LevelAccess getCurrentLevel()
|
||||
public Level getCurrentLevel()
|
||||
{
|
||||
return getWorld().getCurrentLevel();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||
import mightypork.gamecore.util.math.constraints.vect.VectConst;
|
||||
import mightypork.rogue.Res;
|
||||
import mightypork.rogue.world.entity.Entity;
|
||||
import mightypork.rogue.world.level.LevelAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
import mightypork.rogue.world.level.render.TileRenderContext;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public class WorldRenderer extends RectProxy {
|
||||
|
||||
// can be changed
|
||||
private RectConst mapRect;
|
||||
private LevelAccess activeLevel;
|
||||
private Level activeLevel;
|
||||
|
||||
private final Rect rightShadow;
|
||||
private final Rect leftShadow;
|
||||
@@ -57,7 +57,7 @@ public class WorldRenderer extends RectProxy {
|
||||
|
||||
private void prepareRenderContextIfNeeded()
|
||||
{
|
||||
final LevelAccess level = WorldProvider.get().getCurrentLevel();
|
||||
final Level level = WorldProvider.get().getCurrentLevel();
|
||||
|
||||
if (activeLevel == level) return;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import mightypork.rogue.world.World;
|
||||
import mightypork.rogue.world.entity.modules.EntityModuleHealth;
|
||||
import mightypork.rogue.world.entity.modules.EntityModulePosition;
|
||||
import mightypork.rogue.world.entity.render.EntityRenderer;
|
||||
import mightypork.rogue.world.level.LevelAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
import mightypork.rogue.world.level.render.MapRenderContext;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import mightypork.rogue.world.level.render.MapRenderContext;
|
||||
*/
|
||||
public abstract class Entity implements IonObjBundled, Updateable {
|
||||
|
||||
private LevelAccess level;
|
||||
private Level level;
|
||||
private final EntityModel model;
|
||||
|
||||
protected final Random rand = new Random();
|
||||
@@ -120,7 +120,7 @@ public abstract class Entity implements IonObjBundled, Updateable {
|
||||
}
|
||||
|
||||
|
||||
public void setLevel(LevelAccess level)
|
||||
public void setLevel(Level level)
|
||||
{
|
||||
if (level != null) level.freeTile(getCoord());
|
||||
|
||||
@@ -130,7 +130,7 @@ public abstract class Entity implements IonObjBundled, Updateable {
|
||||
}
|
||||
|
||||
|
||||
public final LevelAccess getLevel()
|
||||
public final Level getLevel()
|
||||
{
|
||||
return level;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
|
||||
};
|
||||
|
||||
noDoorPf.setIgnoreEnd(true);
|
||||
|
||||
timerAttack.start();
|
||||
timerFindPrey.start();
|
||||
timerSleepStart.start();
|
||||
@@ -211,7 +213,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
//System.out.println("-- path would be: " + entity.getCoord() + "->" + prey.getCoord());
|
||||
|
||||
// check if reachable without leaving room
|
||||
final List<Coord> noDoorPath = noDoorPf.findPath(entity.getCoord(), prey.getCoord(), true);
|
||||
final List<Coord> noDoorPath = noDoorPf.findPath(entity.getCoord(), prey.getCoord());
|
||||
|
||||
if (noDoorPath == null) {
|
||||
//System.out.println("-- Could not navigate to prey, aborting.");
|
||||
@@ -273,7 +275,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
||||
{
|
||||
if (!isPreyValid(prey)) return null;
|
||||
|
||||
return entity.getPathFinder().findPathRelative(entity.getCoord(), prey.getCoord(), true);
|
||||
return entity.getPathFinder().findPathRelative(entity.getCoord(), prey.getCoord(), false, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class EntityRendererMobLR extends EntityRenderer {
|
||||
public EntityRendererMobLR(Entity entity, String sheetKey)
|
||||
{
|
||||
this.entity = entity;
|
||||
this.sheet = Res.sheet(sheetKey);
|
||||
this.sheet = Res.txs(sheetKey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package mightypork.rogue.world.events;
|
||||
|
||||
|
||||
import mightypork.gamecore.eventbus.BusEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Player wants to go up
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class WorldAscendRequest extends BusEvent<WorldAscendRequestListener> {
|
||||
|
||||
@Override
|
||||
protected void handleBy(WorldAscendRequestListener handler)
|
||||
{
|
||||
handler.onAscendRequest();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package mightypork.rogue.world.events;
|
||||
|
||||
|
||||
public interface WorldAscendRequestListener {
|
||||
|
||||
/**
|
||||
* Player clicked up-stairs
|
||||
*/
|
||||
void onAscendRequest();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package mightypork.rogue.world.events;
|
||||
|
||||
|
||||
import mightypork.gamecore.eventbus.BusEvent;
|
||||
|
||||
|
||||
public class WorldDescendRequest extends BusEvent<WorldDescendRequestListener> {
|
||||
|
||||
@Override
|
||||
protected void handleBy(WorldDescendRequestListener handler)
|
||||
{
|
||||
handler.onDescendRequest();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package mightypork.rogue.world.events;
|
||||
|
||||
|
||||
public interface WorldDescendRequestListener {
|
||||
|
||||
/**
|
||||
* Player clicked down-stairs
|
||||
*/
|
||||
void onDescendRequest();
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public class LevelGenerator {
|
||||
public static final MapTheme DUNGEON_THEME = new ThemeBrick();
|
||||
|
||||
|
||||
public static Level build(World world, long seed, int complexity, MapTheme theme)
|
||||
public static Level build(World world, long seed, int complexity, MapTheme theme, boolean lastLevel)
|
||||
{
|
||||
Log.f3("Generating level of complexity: " + complexity);
|
||||
|
||||
@@ -32,14 +32,16 @@ public class LevelGenerator {
|
||||
final ScratchMap map = new ScratchMap(max_size, theme, rand);
|
||||
|
||||
// start
|
||||
map.addRoom(Rooms.BASIC);
|
||||
map.addRoom(Rooms.ENTRANCE, true);
|
||||
|
||||
for (int i = 0; i < 1 + complexity / 2 + rand.nextInt((int) (1 + complexity * 0.3)); i++) {
|
||||
map.addRoom(Rooms.BASIC);
|
||||
if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET);
|
||||
if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END);
|
||||
map.addRoom(Rooms.BASIC, false);
|
||||
if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET, false);
|
||||
if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END, false);
|
||||
}
|
||||
|
||||
if (!lastLevel) map.addRoom(Rooms.EXIT, true);
|
||||
|
||||
map.buildCorridors();
|
||||
|
||||
final Coord size = map.getNeededSize();
|
||||
|
||||
@@ -24,4 +24,10 @@ public interface MapTheme {
|
||||
|
||||
|
||||
TileModel secretDoor();
|
||||
|
||||
|
||||
TileModel entrance();
|
||||
|
||||
|
||||
TileModel exit();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import mightypork.gamecore.util.math.algo.Sides;
|
||||
import mightypork.gamecore.util.math.algo.Step;
|
||||
import mightypork.gamecore.util.math.algo.pathfinding.Heuristic;
|
||||
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
||||
import mightypork.rogue.world.level.LevelAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
import mightypork.rogue.world.tile.Tiles;
|
||||
@@ -43,6 +43,7 @@ public class ScratchMap {
|
||||
{
|
||||
if (!isIn(pos)) return false;
|
||||
final Tile t = get(pos);
|
||||
if (t.isStairs()) return false;
|
||||
return t.isPotentiallyWalkable() || (t.genData.protection != TileProtectLevel.STRONG);
|
||||
}
|
||||
|
||||
@@ -60,6 +61,7 @@ public class ScratchMap {
|
||||
case PASSAGE:
|
||||
return 10;
|
||||
|
||||
case STAIRS:
|
||||
case FLOOR:
|
||||
return 20;
|
||||
|
||||
@@ -96,12 +98,19 @@ public class ScratchMap {
|
||||
|
||||
};
|
||||
|
||||
{
|
||||
// needed for when the path starts / ends at stairs.
|
||||
pathf.setIgnoreEnd(true);
|
||||
pathf.setIgnoreStart(true);
|
||||
}
|
||||
|
||||
Coord genMin;
|
||||
Coord genMax;
|
||||
|
||||
private final MapTheme theme;
|
||||
private final Random rand;
|
||||
private Coord enterPoint;
|
||||
private final Coord enterPoint = new Coord();
|
||||
private final Coord exitPoint = new Coord();
|
||||
|
||||
private static final boolean FIX_GLITCHES = true;
|
||||
|
||||
@@ -122,12 +131,14 @@ public class ScratchMap {
|
||||
}
|
||||
|
||||
|
||||
public void addRoom(RoomBuilder rb)
|
||||
public void addRoom(RoomBuilder rb, boolean critical)
|
||||
{
|
||||
final Coord center = Coord.make(0, 0);
|
||||
|
||||
int failed = 0;
|
||||
|
||||
int failed_total = 0;
|
||||
|
||||
while (true) {
|
||||
|
||||
final int sizeX = genMax.x - genMin.x;
|
||||
@@ -138,24 +149,20 @@ public class ScratchMap {
|
||||
|
||||
switch (rand.nextInt(4)) {
|
||||
case 0:
|
||||
center.x += 1 + rand.nextInt(4);
|
||||
center.x += 1 + rand.nextInt(critical ? 6 : 4);
|
||||
break;
|
||||
case 1:
|
||||
center.x -= 1 + rand.nextInt(4);
|
||||
center.x -= 1 + rand.nextInt(critical ? 6 : 4);
|
||||
break;
|
||||
case 2:
|
||||
center.y += 1 + rand.nextInt(4);
|
||||
center.y += 1 + rand.nextInt(critical ? 6 : 4);
|
||||
break;
|
||||
case 3:
|
||||
center.y -= 1 + rand.nextInt(4);
|
||||
center.y -= 1 + rand.nextInt(critical ? 6 : 4);
|
||||
}
|
||||
|
||||
final RoomDesc rd = rb.buildToFit(this, theme, rand, center);
|
||||
if (rd != null) {
|
||||
if (rooms.isEmpty()) {
|
||||
enterPoint = center.copy();
|
||||
}
|
||||
|
||||
rooms.add(rd);
|
||||
|
||||
genMin.x = Math.min(genMin.x, rd.min.x);
|
||||
@@ -163,6 +170,7 @@ public class ScratchMap {
|
||||
|
||||
genMax.x = Math.max(genMax.x, rd.max.x);
|
||||
genMax.y = Math.max(genMax.y, rd.max.y);
|
||||
clampBounds();
|
||||
|
||||
nodes.add(center);
|
||||
Log.f3("placed room: " + rd.min + " -> " + rd.max);
|
||||
@@ -170,10 +178,28 @@ public class ScratchMap {
|
||||
return;
|
||||
} else {
|
||||
failed++;
|
||||
failed_total++;
|
||||
|
||||
if (failed > 200) {
|
||||
Log.w("Faild to build room.");
|
||||
return;
|
||||
if (critical) {
|
||||
|
||||
genMin.x -= 5;
|
||||
genMin.y -= 5;
|
||||
genMax.x += 5;
|
||||
genMax.y += 5;
|
||||
clampBounds();
|
||||
|
||||
failed = 0;
|
||||
continue;
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed_total > 1000) {
|
||||
throw new RuntimeException("Generation error - could not place critical room.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +207,15 @@ public class ScratchMap {
|
||||
}
|
||||
|
||||
|
||||
private void clampBounds()
|
||||
{
|
||||
genMin.x = Calc.clamp(genMin.x, 0, width - 1);
|
||||
genMin.y = Calc.clamp(genMin.y, 0, height - 1);
|
||||
genMax.x = Calc.clamp(genMax.x, 0, width - 1);
|
||||
genMax.y = Calc.clamp(genMax.y, 0, height - 1);
|
||||
}
|
||||
|
||||
|
||||
public boolean isIn(Coord pos)
|
||||
{
|
||||
return pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height;
|
||||
@@ -320,9 +355,10 @@ public class ScratchMap {
|
||||
|
||||
genMax.x = Math.max(genMax.x, c.x);
|
||||
genMax.y = Math.max(genMax.y, c.y);
|
||||
clampBounds();
|
||||
|
||||
final Tile current = get(c);
|
||||
if (!current.isNull() && (current.isPotentiallyWalkable())) continue; // floor already, let it be
|
||||
if (!current.isNull() && (current.isPotentiallyWalkable() || current.isStairs())) continue; // floor already, let it be
|
||||
|
||||
if (i == 0 && j == 0) {
|
||||
set(c, theme.floor());
|
||||
@@ -410,7 +446,7 @@ public class ScratchMap {
|
||||
}
|
||||
|
||||
|
||||
public void writeToLevel(LevelAccess level)
|
||||
public void writeToLevel(Level level)
|
||||
{
|
||||
// make sure no walkable are at edges.
|
||||
final Coord c = Coord.make(0, 0);
|
||||
@@ -503,5 +539,21 @@ public class ScratchMap {
|
||||
|
||||
final Coord entrance = new Coord(enterPoint.x - genMin.x, enterPoint.y - genMin.y);
|
||||
level.setEnterPoint(entrance);
|
||||
System.out.println("Entrance = " + entrance + ", original: " + enterPoint + ", minG=" + genMin + ", maxG=" + genMax);
|
||||
|
||||
final Coord exit = new Coord(exitPoint.x - genMin.x, exitPoint.y - genMin.y);
|
||||
level.setExitPoint(exit);
|
||||
}
|
||||
|
||||
|
||||
public void setEntrance(Coord pos)
|
||||
{
|
||||
enterPoint.setTo(pos);
|
||||
}
|
||||
|
||||
|
||||
public void setExit(Coord pos)
|
||||
{
|
||||
exitPoint.setTo(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ public abstract class AbstractRectRoom implements RoomBuilder {
|
||||
|
||||
if (!map.isClear(min.add(-1, -1), max)) return null;
|
||||
|
||||
map.fill(min, max, theme.floor());
|
||||
map.border(min, max, theme.wall());
|
||||
map.fill(min, max, getFloor(theme));
|
||||
map.border(min, max, getWall(theme));
|
||||
map.protect(min, max, getWallProtectionLevel());
|
||||
|
||||
placeDoors(map, theme, rand, min, max);
|
||||
@@ -46,12 +46,24 @@ public abstract class AbstractRectRoom implements RoomBuilder {
|
||||
}
|
||||
|
||||
|
||||
protected TileModel getWall(MapTheme theme)
|
||||
{
|
||||
return theme.wall();
|
||||
}
|
||||
|
||||
|
||||
protected TileModel getFloor(MapTheme theme)
|
||||
{
|
||||
return theme.floor();
|
||||
}
|
||||
|
||||
|
||||
protected void placeDoors(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
|
||||
{
|
||||
final int width = max.x - min.x;
|
||||
final int height = max.y - min.y;
|
||||
|
||||
for (int i = 0, j = 0; i <= getDoorCount(rand) && j < 100; j++) { // j is to prevent inf loop
|
||||
for (int i = 0, j = 0; i < getDoorCount(rand) && j < 100; j++) { // j is to prevent inf loop
|
||||
final Coord door = min.copy();
|
||||
switch (rand.nextInt(4)) {
|
||||
case 0:
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package mightypork.rogue.world.gen.rooms;
|
||||
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.rogue.world.gen.MapTheme;
|
||||
import mightypork.rogue.world.gen.ScratchMap;
|
||||
import mightypork.rogue.world.gen.TileProtectLevel;
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
|
||||
|
||||
public class EntranceRoom extends AbstractRectRoom {
|
||||
|
||||
@Override
|
||||
protected Coord getInnerSize(Random rand)
|
||||
{
|
||||
return Coord.make(3 + rand.nextInt(2) * 2, 3 + rand.nextInt(2) * 3);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TileProtectLevel getWallProtectionLevel()
|
||||
{
|
||||
return TileProtectLevel.WEAK;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TileModel getDoorType(MapTheme theme, Random rand)
|
||||
{
|
||||
switch (rand.nextInt(5)) {
|
||||
case 0:
|
||||
case 1:
|
||||
return theme.passage();
|
||||
case 2:
|
||||
return theme.secretDoor();
|
||||
default:
|
||||
return theme.door();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
|
||||
{
|
||||
final Coord c = Coord.make((max.x + min.x) / 2, (max.y + min.y) / 2);
|
||||
map.set(c, theme.entrance());
|
||||
map.protect(c, c, TileProtectLevel.STRONG);
|
||||
map.setEntrance(c.add(1, 0));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getDoorCount(Random rand)
|
||||
{
|
||||
return 1 + rand.nextInt(4);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package mightypork.rogue.world.gen.rooms;
|
||||
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.rogue.world.gen.MapTheme;
|
||||
import mightypork.rogue.world.gen.ScratchMap;
|
||||
import mightypork.rogue.world.gen.TileProtectLevel;
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
|
||||
|
||||
public class ExitRoom extends AbstractRectRoom {
|
||||
|
||||
@Override
|
||||
protected Coord getInnerSize(Random rand)
|
||||
{
|
||||
return Coord.make(3, 3);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TileProtectLevel getWallProtectionLevel()
|
||||
{
|
||||
return TileProtectLevel.NONE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TileModel getDoorType(MapTheme theme, Random rand)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
|
||||
{
|
||||
final Coord c = Coord.make((max.x + min.x) / 2, (max.y + min.y) / 2);
|
||||
map.set(c, theme.exit());
|
||||
map.protect(c, c, TileProtectLevel.STRONG);
|
||||
map.setExit(c.add(-1, 0));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getDoorCount(Random rand)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,4 +9,6 @@ public class Rooms {
|
||||
public static final RoomBuilder BASIC = new BasicRoom();
|
||||
public static final RoomBuilder SECRET = new SecretRoom();
|
||||
public static final RoomBuilder DEAD_END = new DeadEndRoom();
|
||||
public static final RoomBuilder ENTRANCE = new EntranceRoom();
|
||||
public static final RoomBuilder EXIT = new ExitRoom();
|
||||
}
|
||||
|
||||
@@ -42,4 +42,18 @@ public class ThemeBrick implements MapTheme {
|
||||
{
|
||||
return Tiles.BRICK_HIDDEN_DOOR;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TileModel entrance()
|
||||
{
|
||||
return Tiles.BRICK_ENTRANCE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TileModel exit()
|
||||
{
|
||||
return Tiles.BRICK_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,21 @@ import mightypork.gamecore.input.events.KeyEvent;
|
||||
import mightypork.gamecore.input.events.KeyListener;
|
||||
import mightypork.gamecore.input.events.MouseButtonEvent;
|
||||
import mightypork.gamecore.input.events.MouseButtonListener;
|
||||
import mightypork.gamecore.render.Render;
|
||||
import mightypork.gamecore.util.math.Easing;
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.gamecore.util.math.color.Color;
|
||||
import mightypork.gamecore.util.math.color.pal.RGB;
|
||||
import mightypork.gamecore.util.math.constraints.num.Num;
|
||||
import mightypork.gamecore.util.math.constraints.num.mutable.NumAnimated;
|
||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||
import mightypork.gamecore.util.math.timing.TimedTask;
|
||||
import mightypork.rogue.world.PlayerControl;
|
||||
import mightypork.rogue.world.World;
|
||||
import mightypork.rogue.world.WorldProvider;
|
||||
import mightypork.rogue.world.WorldRenderer;
|
||||
import mightypork.rogue.world.events.WorldAscendRequestListener;
|
||||
import mightypork.rogue.world.events.WorldDescendRequestListener;
|
||||
import mightypork.rogue.world.gui.interaction.MapInteractionPlugin;
|
||||
|
||||
|
||||
@@ -29,7 +36,10 @@ import mightypork.rogue.world.gui.interaction.MapInteractionPlugin;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class MapView extends InputComponent implements DelegatingClient, KeyListener, MouseButtonListener, Updateable {
|
||||
public class MapView extends InputComponent implements DelegatingClient, KeyListener, MouseButtonListener, Updateable, WorldAscendRequestListener,
|
||||
WorldDescendRequestListener {
|
||||
|
||||
private static final double transition_time = 0.8;
|
||||
|
||||
protected final WorldRenderer worldRenderer;
|
||||
public final PlayerControl playerControl;
|
||||
@@ -38,6 +48,36 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList
|
||||
private final NumAnimated zoom = new NumAnimated(0, Easing.SINE_BOTH);
|
||||
private boolean zoom_in = true;
|
||||
|
||||
private NumAnimated descFadeAnim = new NumAnimated(0);
|
||||
private Color blackColor = RGB.BLACK.withAlpha(descFadeAnim);
|
||||
|
||||
private int descDir = 0;
|
||||
|
||||
private TimedTask timerDesc1 = new TimedTask() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
descFadeAnim.fadeOut(transition_time);
|
||||
timerDesc2.start(transition_time);
|
||||
if (descDir == 1) {
|
||||
WorldProvider.get().getWorld().descend();
|
||||
} else {
|
||||
WorldProvider.get().getWorld().ascend();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private TimedTask timerDesc2 = new TimedTask() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
WorldProvider.get().getWorld().resume();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final Num tileSize;
|
||||
|
||||
|
||||
@@ -70,6 +110,8 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList
|
||||
protected void renderComponent()
|
||||
{
|
||||
worldRenderer.render();
|
||||
|
||||
Render.quadColor(this, blackColor);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,10 +156,6 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList
|
||||
@Override
|
||||
public void receive(KeyEvent event)
|
||||
{
|
||||
for (final MapInteractionPlugin p : plugins) {
|
||||
if (p.onKey(event.getKey(), event.isDown())) break;
|
||||
}
|
||||
|
||||
if (event.getKey() == Keys.Z && event.isDown()) {
|
||||
if (zoom_in) {
|
||||
zoom.fadeIn();
|
||||
@@ -147,5 +185,47 @@ public class MapView extends InputComponent implements DelegatingClient, KeyList
|
||||
public void update(double delta)
|
||||
{
|
||||
zoom.update(delta);
|
||||
descFadeAnim.update(delta);
|
||||
timerDesc1.update(delta);
|
||||
timerDesc2.update(delta);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAscendRequest()
|
||||
{
|
||||
if(descFadeAnim.isInProgress()) return;
|
||||
|
||||
World w = WorldProvider.get().getWorld();
|
||||
|
||||
if (w.canAscend()) {
|
||||
descDir = -1;
|
||||
startDescAnim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void startDescAnim()
|
||||
{
|
||||
WorldProvider.get().getWorld().pause();
|
||||
|
||||
timerDesc2.stop();
|
||||
timerDesc1.start(transition_time);
|
||||
descFadeAnim.setTo(0);
|
||||
descFadeAnim.fadeIn(transition_time);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDescendRequest()
|
||||
{
|
||||
if(descFadeAnim.isInProgress()) return;
|
||||
|
||||
World w = WorldProvider.get().getWorld();
|
||||
|
||||
if (w.canDescend()) {
|
||||
descDir = 1;
|
||||
startDescAnim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import mightypork.gamecore.util.math.constraints.rect.mutable.RectMutable;
|
||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||
import mightypork.rogue.world.WorldProvider;
|
||||
import mightypork.rogue.world.entity.Entity;
|
||||
import mightypork.rogue.world.level.LevelReadAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -33,7 +33,7 @@ public class Minimap extends InputComponent implements MouseButtonListener {
|
||||
{
|
||||
Color.pushAlpha(translucency);
|
||||
|
||||
final LevelReadAccess lvl = WorldProvider.get().getCurrentLevel();
|
||||
final Level lvl = WorldProvider.get().getCurrentLevel();
|
||||
unit = (int) Math.min(Math.max(2, Math.ceil((height().value() / 2) / (lvl.getHeight() + 2))), 10);
|
||||
|
||||
final Entity e = WorldProvider.get().getPlayerEntity();
|
||||
@@ -89,7 +89,7 @@ public class Minimap extends InputComponent implements MouseButtonListener {
|
||||
@Override
|
||||
public void receive(MouseButtonEvent event)
|
||||
{
|
||||
if (event.isOver(bounds) && event.getButton() == 0) {
|
||||
if (event.isOver(bounds) && event.getButton() == 1) {
|
||||
if (event.isUp()) {
|
||||
final Vect relative = event.getPos().sub(bounds.origin());
|
||||
final Coord actual = Coord.make(relative.xi() / unit, relative.yi() / unit);
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
package mightypork.rogue.world.gui.interaction;
|
||||
|
||||
|
||||
import mightypork.gamecore.eventbus.events.Updateable;
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.input.Keys;
|
||||
import mightypork.gamecore.input.events.KeyEvent;
|
||||
import mightypork.gamecore.input.events.KeyListener;
|
||||
import mightypork.gamecore.util.math.algo.Sides;
|
||||
import mightypork.gamecore.util.math.algo.Step;
|
||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||
import mightypork.rogue.world.entity.entities.PlayerEntity;
|
||||
import mightypork.rogue.world.events.PlayerStepEndListener;
|
||||
import mightypork.rogue.world.gui.MapView;
|
||||
|
||||
|
||||
public class MIPKeyboard extends MapInteractionPlugin {
|
||||
public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndListener, KeyListener, Updateable {
|
||||
|
||||
private static final int[] keys = { Keys.LEFT, Keys.RIGHT, Keys.UP, Keys.DOWN };
|
||||
private static final Step[] sides = { Sides.W, Sides.E, Sides.N, Sides.S };
|
||||
@@ -37,23 +41,21 @@ public class MIPKeyboard extends MapInteractionPlugin {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onKey(int key, boolean down)
|
||||
public void receive(KeyEvent evt)
|
||||
{
|
||||
if (down) return false; // not interested
|
||||
if (evt.isDown() || mapView.playerControl.getPlayerEntity().pos.isMoving()) return; // not interested
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (key == keys[i]) {
|
||||
return mapView.playerControl.clickTile(sides[i]);
|
||||
if (evt.getKey() == keys[i]) {
|
||||
mapView.playerControl.clickTile(sides[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean walkByKey()
|
||||
{
|
||||
if (mapView.playerControl.getPlayerEntity().pos.isMoving()) return false;
|
||||
if (mapView.playerControl.getPlayerEntity().pos.getProgress()<0.8) return false;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (InputSystem.isKeyDown(keys[i])) {
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package mightypork.rogue.world.gui.interaction;
|
||||
|
||||
|
||||
import mightypork.gamecore.eventbus.events.Updateable;
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.input.Keys;
|
||||
import mightypork.gamecore.util.math.Calc.Deg;
|
||||
import mightypork.gamecore.util.math.Polar;
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.gamecore.util.math.algo.Sides;
|
||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||
import mightypork.rogue.world.entity.entities.PlayerEntity;
|
||||
import mightypork.rogue.world.events.PlayerStepEndListener;
|
||||
import mightypork.rogue.world.gui.MapView;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
|
||||
|
||||
public class MIPMouse extends MapInteractionPlugin {
|
||||
public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListener, Updateable {
|
||||
|
||||
private static final int BTN = 0; // left
|
||||
|
||||
@@ -27,13 +28,12 @@ public class MIPMouse extends MapInteractionPlugin {
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
if (!InputSystem.isKeyDown(Keys.L_SHIFT)) return;
|
||||
|
||||
final Vect pos = InputSystem.getMousePos();
|
||||
if (!pos.isInside(mapView)) return;
|
||||
|
||||
if (InputSystem.isMouseButtonDown(BTN)) {
|
||||
if (mouseWalk(pos)) return;
|
||||
if (troToNav(pos)) return;
|
||||
if (mapView.playerControl.getPlayerEntity().pos.isMoving() && troToNav(pos)) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,13 +41,14 @@ public class MIPMouse extends MapInteractionPlugin {
|
||||
@Override
|
||||
public boolean onClick(Vect mouse, int button, boolean down)
|
||||
{
|
||||
if (button != BTN) return false;
|
||||
final Coord pos = mapView.toWorldPos(mouse);
|
||||
final Tile t = mapView.playerControl.getLevel().getTile(pos);
|
||||
|
||||
if (t.onClick()) return true;
|
||||
if (button == BTN && !down && t.onClick()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!down && t.isWalkable()) {
|
||||
if (button == 1 && !down && t.isWalkable()) {
|
||||
if (troToNav(mouse)) return true;
|
||||
return mouseWalk(mouse);
|
||||
}
|
||||
@@ -97,24 +98,15 @@ public class MIPMouse extends MapInteractionPlugin {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onKey(int key, boolean down)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStepFinished(PlayerEntity player)
|
||||
{
|
||||
if (!InputSystem.isKeyDown(Keys.L_SHIFT)) return;
|
||||
|
||||
final Vect pos = InputSystem.getMousePos();
|
||||
if (!pos.isInside(mapView)) return;
|
||||
|
||||
if (InputSystem.isMouseButtonDown(BTN)) {
|
||||
if (mouseWalk(pos)) return;
|
||||
if (troToNav(pos)) return;
|
||||
if (mapView.playerControl.getPlayerEntity().pos.isMoving() && troToNav(pos)) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@ package mightypork.rogue.world.gui.interaction;
|
||||
|
||||
|
||||
import mightypork.gamecore.eventbus.events.Updateable;
|
||||
import mightypork.gamecore.input.events.KeyEvent;
|
||||
import mightypork.gamecore.input.events.KeyListener;
|
||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||
import mightypork.rogue.world.events.PlayerStepEndListener;
|
||||
import mightypork.rogue.world.gui.MapView;
|
||||
|
||||
|
||||
public abstract class MapInteractionPlugin implements Updateable, PlayerStepEndListener {
|
||||
public abstract class MapInteractionPlugin {
|
||||
|
||||
protected final MapView mapView;
|
||||
|
||||
@@ -20,12 +22,4 @@ public abstract class MapInteractionPlugin implements Updateable, PlayerStepEndL
|
||||
|
||||
|
||||
public abstract boolean onClick(Vect mouse, int button, boolean down);
|
||||
|
||||
|
||||
public abstract boolean onKey(int key, boolean down);
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void update(double delta);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public class ItemMeat extends Item {
|
||||
@Override
|
||||
protected ItemRenderer makeRenderer()
|
||||
{
|
||||
return new QuadItemRenderer(Res.getTxQuad("item.meat"));
|
||||
return new QuadItemRenderer(Res.txq("item.meat"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import mightypork.gamecore.eventbus.BusAccess;
|
||||
import mightypork.gamecore.eventbus.EventBus;
|
||||
import mightypork.gamecore.eventbus.clients.DelegatingClient;
|
||||
import mightypork.gamecore.eventbus.clients.ToggleableClient;
|
||||
import mightypork.gamecore.eventbus.events.Updateable;
|
||||
import mightypork.gamecore.logging.Log;
|
||||
import mightypork.gamecore.util.ion.IonBundle;
|
||||
import mightypork.gamecore.util.ion.IonInput;
|
||||
@@ -34,7 +35,7 @@ import mightypork.rogue.world.tile.Tiles;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Level implements BusAccess, DelegatingClient, ToggleableClient, LevelAccess, IonObjBinary {
|
||||
public class Level implements BusAccess, Updateable, DelegatingClient, ToggleableClient, IonObjBinary {
|
||||
|
||||
public static final int ION_MARK = 53;
|
||||
|
||||
@@ -42,6 +43,7 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
private World world;
|
||||
|
||||
private final Coord enterPoint = Coord.zero();
|
||||
private final Coord exitPoint = Coord.zero();
|
||||
|
||||
/** Array of tiles [y][x] */
|
||||
private Tile[][] tiles;
|
||||
@@ -75,7 +77,11 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Fill whole map with tile type
|
||||
*
|
||||
* @param model tile model
|
||||
*/
|
||||
public void fill(TileModel model)
|
||||
{
|
||||
for (final Coord c = Coord.zero(); c.x < size.x; c.x++) {
|
||||
@@ -86,7 +92,12 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Ge tile at X,Y
|
||||
*
|
||||
* @param pos
|
||||
* @return tile
|
||||
*/
|
||||
public final Tile getTile(Coord pos)
|
||||
{
|
||||
if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) return Tiles.NULL.createTile(); // out of range
|
||||
@@ -95,7 +106,12 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Set tile at pos
|
||||
*
|
||||
* @param pos tile pos
|
||||
* @param tile the tile instance to set
|
||||
*/
|
||||
public final void setTile(Coord pos, Tile tile)
|
||||
{
|
||||
if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) {
|
||||
@@ -110,28 +126,38 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* @return map width in tiles
|
||||
*/
|
||||
public final int getWidth()
|
||||
{
|
||||
return size.x;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* @return map height in tiles
|
||||
*/
|
||||
public final int getHeight()
|
||||
{
|
||||
return size.y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Set level seed (used for visuals; the seed used for generation)
|
||||
*
|
||||
* @param seed seed
|
||||
*/
|
||||
public void setSeed(long seed)
|
||||
{
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* @return map seed
|
||||
*/
|
||||
public long getSeed()
|
||||
{
|
||||
return seed;
|
||||
@@ -146,6 +172,7 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
seed = ib.get("seed", 0L);
|
||||
ib.loadBundled("size", size);
|
||||
ib.loadBundled("enter_point", enterPoint);
|
||||
ib.loadBundled("exit_point", exitPoint);
|
||||
|
||||
// -- binary data --
|
||||
|
||||
@@ -178,6 +205,7 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
ib.put("seed", seed);
|
||||
ib.putBundled("size", size);
|
||||
ib.putBundled("enter_point", enterPoint);
|
||||
ib.putBundled("exit_point", exitPoint);
|
||||
out.writeBundle(ib);
|
||||
|
||||
// -- binary data --
|
||||
@@ -222,7 +250,9 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* @return level-specific noise generator
|
||||
*/
|
||||
public NoiseGen getNoiseGen()
|
||||
{
|
||||
if (noiseGen == null) {
|
||||
@@ -233,14 +263,25 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Get entity by ID
|
||||
*
|
||||
* @param eid entity ID
|
||||
* @return the entity, or null
|
||||
*/
|
||||
public Entity getEntity(int eid)
|
||||
{
|
||||
return entityMap.get(eid);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Try to add entity at given pos
|
||||
*
|
||||
* @param entity the entity
|
||||
* @param pos pos
|
||||
* @return true if added (false if void, wall etc)
|
||||
*/
|
||||
public boolean addEntity(Entity entity, Coord pos)
|
||||
{
|
||||
final Tile t = getTile(pos);
|
||||
@@ -265,14 +306,22 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Remove an entity from the level, if present
|
||||
*
|
||||
* @param entity entity
|
||||
*/
|
||||
public void removeEntity(Entity entity)
|
||||
{
|
||||
removeEntity(entity.getEntityId());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Remove an entity from the level, if present
|
||||
*
|
||||
* @param eid entity id
|
||||
*/
|
||||
public void removeEntity(int eid)
|
||||
{
|
||||
final Entity removed = entityMap.remove(eid);
|
||||
@@ -283,7 +332,12 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Check tile walkability
|
||||
*
|
||||
* @param pos tile coord
|
||||
* @return true if the tile is walkable by entity
|
||||
*/
|
||||
public boolean isWalkable(Coord pos)
|
||||
{
|
||||
final Tile t = getTile(pos);
|
||||
@@ -293,9 +347,10 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
|
||||
|
||||
/**
|
||||
* Mark tile as occupied by an entity
|
||||
* Mark tile as occupied (entity entered)
|
||||
*
|
||||
* @param pos tile pos
|
||||
*/
|
||||
@Override
|
||||
public void occupyTile(Coord pos)
|
||||
{
|
||||
getTile(pos).setOccupied(true);
|
||||
@@ -303,58 +358,99 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
|
||||
|
||||
/**
|
||||
* Mark tile as free (no longet occupied)
|
||||
* Mark tile as free (entity left)
|
||||
*
|
||||
* @param pos tile pos
|
||||
*/
|
||||
@Override
|
||||
public void freeTile(Coord pos)
|
||||
{
|
||||
getTile(pos).setOccupied(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Check entity on tile
|
||||
*
|
||||
* @param pos tile coord
|
||||
* @return true if some entity is standing there
|
||||
*/
|
||||
public boolean isOccupied(Coord pos)
|
||||
{
|
||||
return getTile(pos).isOccupied();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<Entity> getEntities()
|
||||
{
|
||||
return entitySet;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Set level entry point
|
||||
*
|
||||
* @param pos pos where the player appears upon descending to this level
|
||||
*/
|
||||
public void setEnterPoint(Coord pos)
|
||||
{
|
||||
this.enterPoint.setTo(pos);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Get location where the player appears upon descending to this level
|
||||
*
|
||||
* @return pos
|
||||
*/
|
||||
public Coord getEnterPoint()
|
||||
{
|
||||
return enterPoint;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Set level exit point
|
||||
*
|
||||
* @param pos pos where the player appears upon ascending to this level
|
||||
*/
|
||||
public void setExitPoint(Coord pos)
|
||||
{
|
||||
this.exitPoint.setTo(pos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get location where the player appears upon ascending to this level
|
||||
*
|
||||
* @return pos
|
||||
*/
|
||||
public Coord getExitPoint()
|
||||
{
|
||||
return exitPoint;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the level's world
|
||||
*
|
||||
* @return world
|
||||
*/
|
||||
public World getWorld()
|
||||
{
|
||||
return world;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Assign a world
|
||||
*
|
||||
* @param world new world
|
||||
*/
|
||||
public void setWorld(World world)
|
||||
{
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Mark tile and surrounding area as explored
|
||||
*
|
||||
* @param center center the explored tile
|
||||
*/
|
||||
public void explore(Coord center)
|
||||
{
|
||||
final Collection<Coord> filled = new HashSet<>();
|
||||
@@ -406,7 +502,15 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Get entity of type closest to coord
|
||||
*
|
||||
* @param self the querying entity - to provide position, and to be excluded
|
||||
* from the search.
|
||||
* @param type wanted entity type
|
||||
* @param radius search radius; -1 for unlimited.
|
||||
* @return
|
||||
*/
|
||||
public Entity getClosestEntity(Entity self, EntityType type, double radius)
|
||||
{
|
||||
Entity closest = null;
|
||||
@@ -430,6 +534,11 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free a tile. If entity is present, remove it.
|
||||
*
|
||||
* @param pos the tile pos
|
||||
*/
|
||||
public void forceFreeTile(Coord pos)
|
||||
{
|
||||
if (getTile(pos).isOccupied()) {
|
||||
@@ -450,20 +559,41 @@ public class Level implements BusAccess, DelegatingClient, ToggleableClient, Lev
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Check if entity is in the level
|
||||
*
|
||||
* @param entity entity
|
||||
* @return is present
|
||||
*/
|
||||
public boolean isEntityPresent(Entity entity)
|
||||
{
|
||||
return entitySet.contains(entity);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Check if entity is in the level
|
||||
*
|
||||
* @param eid entity ID
|
||||
* @return true if present
|
||||
*/
|
||||
public boolean isEntityPresent(int eid)
|
||||
{
|
||||
return entityMap.containsKey(eid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get entity collection (for rendering)
|
||||
*
|
||||
* @return entities
|
||||
*/
|
||||
public Collection<Entity> getEntities()
|
||||
{
|
||||
return entitySet;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventBus getEventBus()
|
||||
{
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
package mightypork.rogue.world.level;
|
||||
|
||||
|
||||
import mightypork.gamecore.eventbus.events.Updateable;
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.rogue.world.World;
|
||||
import mightypork.rogue.world.entity.Entity;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
|
||||
|
||||
/**
|
||||
* Level full access
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface LevelAccess extends LevelReadAccess, Updateable {
|
||||
|
||||
|
||||
/**
|
||||
* Mark tile and surrounding area as explored
|
||||
*
|
||||
* @param center center the explored tile
|
||||
*/
|
||||
public abstract void explore(Coord center);
|
||||
|
||||
|
||||
/**
|
||||
* Assign a world
|
||||
*
|
||||
* @param world new world
|
||||
*/
|
||||
public abstract void setWorld(World world);
|
||||
|
||||
|
||||
/**
|
||||
* Set level entry point
|
||||
*
|
||||
* @param pos pos where the player enters
|
||||
*/
|
||||
public abstract void setEnterPoint(Coord pos);
|
||||
|
||||
|
||||
/**
|
||||
* Mark tile as free (entity left)
|
||||
*
|
||||
* @param pos tile pos
|
||||
*/
|
||||
public abstract void freeTile(Coord pos);
|
||||
|
||||
|
||||
/**
|
||||
* Mark tile as occupied (entity entered)
|
||||
*
|
||||
* @param pos tile pos
|
||||
*/
|
||||
public abstract void occupyTile(Coord pos);
|
||||
|
||||
|
||||
/**
|
||||
* Remove an entity from the level, if present
|
||||
*
|
||||
* @param eid entity id
|
||||
*/
|
||||
public abstract void removeEntity(int eid);
|
||||
|
||||
|
||||
/**
|
||||
* Remove an entity from the level, if present
|
||||
*
|
||||
* @param entity entity
|
||||
*/
|
||||
public abstract void removeEntity(Entity entity);
|
||||
|
||||
|
||||
/**
|
||||
* Set level seed (used for visuals; the seed used for generation)
|
||||
*
|
||||
* @param seed seed
|
||||
*/
|
||||
public abstract void setSeed(long seed);
|
||||
|
||||
|
||||
/**
|
||||
* Set tile at pos
|
||||
*
|
||||
* @param pos tile pos
|
||||
* @param tile the tile instance to set
|
||||
*/
|
||||
public abstract void setTile(Coord pos, Tile tile);
|
||||
|
||||
|
||||
/**
|
||||
* Fill whole map with tile type
|
||||
*
|
||||
* @param model tile model
|
||||
*/
|
||||
public abstract void fill(TileModel model);
|
||||
|
||||
|
||||
/**
|
||||
* Try to add entity at given pos
|
||||
*
|
||||
* @param entity the entity
|
||||
* @param pos pos
|
||||
* @return true if added (false if void, wall etc)
|
||||
*/
|
||||
public abstract boolean addEntity(Entity entity, Coord pos);
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
package mightypork.rogue.world.level;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.gamecore.util.math.noise.NoiseGen;
|
||||
import mightypork.rogue.world.World;
|
||||
import mightypork.rogue.world.entity.Entity;
|
||||
import mightypork.rogue.world.entity.EntityType;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
|
||||
|
||||
public interface LevelReadAccess {
|
||||
|
||||
/**
|
||||
* Ge tile at X,Y
|
||||
*
|
||||
* @param pos
|
||||
* @return tile
|
||||
*/
|
||||
Tile getTile(Coord pos);
|
||||
|
||||
|
||||
/**
|
||||
* @return map width in tiles
|
||||
*/
|
||||
int getWidth();
|
||||
|
||||
|
||||
/**
|
||||
* @return map height in tiles
|
||||
*/
|
||||
int getHeight();
|
||||
|
||||
|
||||
/**
|
||||
* @return map seed
|
||||
*/
|
||||
long getSeed();
|
||||
|
||||
|
||||
/**
|
||||
* @return level-specific noise generator
|
||||
*/
|
||||
NoiseGen getNoiseGen();
|
||||
|
||||
|
||||
/**
|
||||
* Check if entity is in the level
|
||||
*
|
||||
* @param entity entity
|
||||
* @return is present
|
||||
*/
|
||||
boolean isEntityPresent(Entity entity);
|
||||
|
||||
|
||||
/**
|
||||
* Check if entity is in the level
|
||||
*
|
||||
* @param eid entity ID
|
||||
* @return true if present
|
||||
*/
|
||||
boolean isEntityPresent(int eid);
|
||||
|
||||
|
||||
/**
|
||||
* Get entity of type closest to coord
|
||||
*
|
||||
* @param self the querying entity - to provide position, and to be excluded
|
||||
* from the search.
|
||||
* @param type wanted entity type
|
||||
* @param radius search radius; -1 for unlimited.
|
||||
* @return
|
||||
*/
|
||||
Entity getClosestEntity(Entity self, EntityType type, double radius);
|
||||
|
||||
|
||||
/**
|
||||
* Get the level's world
|
||||
*
|
||||
* @return world
|
||||
*/
|
||||
World getWorld();
|
||||
|
||||
|
||||
/**
|
||||
* Get location where the player enters the level
|
||||
*
|
||||
* @return pos
|
||||
*/
|
||||
Coord getEnterPoint();
|
||||
|
||||
|
||||
/**
|
||||
* Check entity on tile
|
||||
*
|
||||
* @param pos tile coord
|
||||
* @return true if some entity is standing there
|
||||
*/
|
||||
boolean isOccupied(Coord pos);
|
||||
|
||||
|
||||
/**
|
||||
* Check tile walkability
|
||||
*
|
||||
* @param pos tile coord
|
||||
* @return true if the tile is walkable by entity
|
||||
*/
|
||||
boolean isWalkable(Coord pos);
|
||||
|
||||
|
||||
/**
|
||||
* Get entity by ID
|
||||
*
|
||||
* @param eid entity ID
|
||||
* @return the entity, or null
|
||||
*/
|
||||
Entity getEntity(int eid);
|
||||
|
||||
|
||||
/**
|
||||
* @return all entities
|
||||
*/
|
||||
Collection<Entity> getEntities();
|
||||
|
||||
}
|
||||
@@ -2,12 +2,12 @@ package mightypork.rogue.world.level.render;
|
||||
|
||||
|
||||
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
||||
import mightypork.rogue.world.level.LevelReadAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
|
||||
|
||||
public class EntityRenderContext extends MapRenderContext {
|
||||
|
||||
public EntityRenderContext(LevelReadAccess map, Rect drawArea)
|
||||
public EntityRenderContext(Level map, Rect drawArea)
|
||||
{
|
||||
super(map, drawArea);
|
||||
}
|
||||
|
||||
@@ -4,18 +4,18 @@ package mightypork.rogue.world.level.render;
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
||||
import mightypork.gamecore.util.math.constraints.rect.builders.TiledRect;
|
||||
import mightypork.rogue.world.level.LevelReadAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
|
||||
|
||||
public abstract class MapRenderContext {
|
||||
|
||||
protected final LevelReadAccess map;
|
||||
protected final Level map;
|
||||
protected final TiledRect tiler;
|
||||
private final Rect mapRect;
|
||||
|
||||
|
||||
public MapRenderContext(LevelReadAccess map, Rect drawArea)
|
||||
public MapRenderContext(Level map, Rect drawArea)
|
||||
{
|
||||
this.map = map;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import mightypork.gamecore.util.math.algo.Step;
|
||||
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
||||
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
|
||||
import mightypork.gamecore.util.math.noise.NoiseGen;
|
||||
import mightypork.rogue.world.level.LevelReadAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public final class TileRenderContext extends MapRenderContext implements RectBou
|
||||
private final NoiseGen noise;
|
||||
|
||||
|
||||
public TileRenderContext(LevelReadAccess map, Rect drawArea)
|
||||
public TileRenderContext(Level map, Rect drawArea)
|
||||
{
|
||||
super(map, drawArea);
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ package mightypork.rogue.world.tile;
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.gamecore.eventbus.BusAccess;
|
||||
import mightypork.gamecore.eventbus.EventBus;
|
||||
import mightypork.gamecore.logging.Log;
|
||||
import mightypork.gamecore.util.annot.DefaultImpl;
|
||||
import mightypork.gamecore.util.ion.IonInput;
|
||||
@@ -12,7 +14,7 @@ import mightypork.gamecore.util.ion.IonOutput;
|
||||
import mightypork.gamecore.util.math.color.Color;
|
||||
import mightypork.rogue.world.World;
|
||||
import mightypork.rogue.world.item.Item;
|
||||
import mightypork.rogue.world.level.LevelAccess;
|
||||
import mightypork.rogue.world.level.Level;
|
||||
import mightypork.rogue.world.level.render.TileRenderContext;
|
||||
|
||||
|
||||
@@ -21,7 +23,7 @@ import mightypork.rogue.world.level.render.TileRenderContext;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class Tile implements IonObjBlob {
|
||||
public abstract class Tile implements BusAccess, IonObjBlob {
|
||||
|
||||
// tmp extras
|
||||
public final TileGenData genData = new TileGenData();
|
||||
@@ -35,7 +37,7 @@ public abstract class Tile implements IonObjBlob {
|
||||
protected boolean occupied;
|
||||
protected boolean explored;
|
||||
|
||||
protected LevelAccess level;
|
||||
protected Level level;
|
||||
|
||||
private TileRenderer renderer;
|
||||
|
||||
@@ -157,6 +159,12 @@ public abstract class Tile implements IonObjBlob {
|
||||
}
|
||||
|
||||
|
||||
public final boolean isStairs()
|
||||
{
|
||||
return getType() == TileType.STAIRS;
|
||||
}
|
||||
|
||||
|
||||
@DefaultImpl
|
||||
public void updateTile(double delta)
|
||||
{
|
||||
@@ -244,13 +252,13 @@ public abstract class Tile implements IonObjBlob {
|
||||
}
|
||||
|
||||
|
||||
public void setLevel(LevelAccess level)
|
||||
public void setLevel(Level level)
|
||||
{
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
|
||||
public LevelAccess getLevel()
|
||||
public Level getLevel()
|
||||
{
|
||||
return level;
|
||||
}
|
||||
@@ -261,4 +269,11 @@ public abstract class Tile implements IonObjBlob {
|
||||
return level.getWorld();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventBus getEventBus()
|
||||
{
|
||||
return level.getEventBus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,23 +44,23 @@ public abstract class TileRenderer implements Updateable {
|
||||
this.tile = tile;
|
||||
|
||||
if (!inited) {
|
||||
SH_N = Res.getTxQuad("tile.shadow.n");
|
||||
SH_S = Res.getTxQuad("tile.shadow.s");
|
||||
SH_E = Res.getTxQuad("tile.shadow.e");
|
||||
SH_W = Res.getTxQuad("tile.shadow.w");
|
||||
SH_NW = Res.getTxQuad("tile.shadow.nw");
|
||||
SH_NE = Res.getTxQuad("tile.shadow.ne");
|
||||
SH_SW = Res.getTxQuad("tile.shadow.sw");
|
||||
SH_SE = Res.getTxQuad("tile.shadow.se");
|
||||
SH_N = Res.txq("tile.shadow.n");
|
||||
SH_S = Res.txq("tile.shadow.s");
|
||||
SH_E = Res.txq("tile.shadow.e");
|
||||
SH_W = Res.txq("tile.shadow.w");
|
||||
SH_NW = Res.txq("tile.shadow.nw");
|
||||
SH_NE = Res.txq("tile.shadow.ne");
|
||||
SH_SW = Res.txq("tile.shadow.sw");
|
||||
SH_SE = Res.txq("tile.shadow.se");
|
||||
|
||||
UFOG_N = Res.getTxQuad("tile.ufog.n");
|
||||
UFOG_S = Res.getTxQuad("tile.ufog.s");
|
||||
UFOG_E = Res.getTxQuad("tile.ufog.e");
|
||||
UFOG_W = Res.getTxQuad("tile.ufog.w");
|
||||
UFOG_NW = Res.getTxQuad("tile.ufog.nw");
|
||||
UFOG_NE = Res.getTxQuad("tile.ufog.ne");
|
||||
UFOG_SW = Res.getTxQuad("tile.ufog.sw");
|
||||
UFOG_SE = Res.getTxQuad("tile.ufog.se");
|
||||
UFOG_N = Res.txq("tile.ufog.n");
|
||||
UFOG_S = Res.txq("tile.ufog.s");
|
||||
UFOG_E = Res.txq("tile.ufog.e");
|
||||
UFOG_W = Res.txq("tile.ufog.w");
|
||||
UFOG_NW = Res.txq("tile.ufog.nw");
|
||||
UFOG_NE = Res.txq("tile.ufog.ne");
|
||||
UFOG_SW = Res.txq("tile.ufog.sw");
|
||||
UFOG_SE = Res.txq("tile.ufog.se");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ public enum TileType
|
||||
/** Door/gate tile */
|
||||
DOOR(PAL16.NEWPOOP, true),
|
||||
/** Passage (ie secret door) */
|
||||
PASSAGE(RGB.GRAY, true);
|
||||
PASSAGE(RGB.GRAY, true),
|
||||
/** Stairs */
|
||||
STAIRS(RGB.CYAN, false);
|
||||
|
||||
private final Color mapColor;
|
||||
private final boolean potentiallyWalkable;
|
||||
|
||||
@@ -6,11 +6,7 @@ import java.io.IOException;
|
||||
import mightypork.gamecore.util.ion.IonInput;
|
||||
import mightypork.gamecore.util.ion.IonOutput;
|
||||
import mightypork.rogue.world.tile.tiles.NullTile;
|
||||
import mightypork.rogue.world.tile.tiles.brick.TileBrickDoor;
|
||||
import mightypork.rogue.world.tile.tiles.brick.TileBrickFloor;
|
||||
import mightypork.rogue.world.tile.tiles.brick.TileBrickPassage;
|
||||
import mightypork.rogue.world.tile.tiles.brick.TileBrickSecretDoor;
|
||||
import mightypork.rogue.world.tile.tiles.brick.TileBrickWall;
|
||||
import mightypork.rogue.world.tile.tiles.brick.*;
|
||||
|
||||
|
||||
/**
|
||||
@@ -29,6 +25,8 @@ public final class Tiles {
|
||||
public static final TileModel BRICK_DOOR = new TileModel(12, TileBrickDoor.class);
|
||||
public static final TileModel BRICK_PASSAGE = new TileModel(13, TileBrickPassage.class);
|
||||
public static final TileModel BRICK_HIDDEN_DOOR = new TileModel(14, TileBrickSecretDoor.class);
|
||||
public static final TileModel BRICK_ENTRANCE = new TileModel(15, TileBrickEntrance.class);
|
||||
public static final TileModel BRICK_EXIT = new TileModel(16, TileBrickExit.class);
|
||||
|
||||
|
||||
public static void register(int id, TileModel model)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package mightypork.rogue.world.tile.render;
|
||||
|
||||
|
||||
import mightypork.gamecore.render.Render;
|
||||
import mightypork.gamecore.resources.textures.TxQuad;
|
||||
import mightypork.rogue.world.level.render.TileRenderContext;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
import mightypork.rogue.world.tile.TileRenderer;
|
||||
|
||||
|
||||
/**
|
||||
* Tile that spans across two tiles visually (two-high)
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class OneFrameTileRenderer extends TileRenderer {
|
||||
|
||||
private final TxQuad txq;
|
||||
|
||||
|
||||
public OneFrameTileRenderer(Tile tile, TxQuad txq)
|
||||
{
|
||||
super(tile);
|
||||
this.txq = txq;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void renderTile(TileRenderContext context)
|
||||
{
|
||||
Render.quadTextured(context.getRect(), txq);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package mightypork.rogue.world.tile.render;
|
||||
|
||||
|
||||
import mightypork.gamecore.render.Render;
|
||||
import mightypork.gamecore.resources.textures.TxQuad;
|
||||
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
||||
import mightypork.rogue.world.level.render.TileRenderContext;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
import mightypork.rogue.world.tile.TileRenderer;
|
||||
|
||||
|
||||
/**
|
||||
* Tile that spans across two tiles visually (two-high)
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TwoHighTileRenderer extends TileRenderer {
|
||||
|
||||
private final TxQuad txq;
|
||||
|
||||
|
||||
public TwoHighTileRenderer(Tile tile, TxQuad txq)
|
||||
{
|
||||
super(tile);
|
||||
this.txq = txq;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void renderTile(TileRenderContext context)
|
||||
{
|
||||
final Rect rect = context.getRect();
|
||||
Render.quadTextured(rect.growUp(rect.height()), txq);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package mightypork.rogue.world.tile.tiles;
|
||||
|
||||
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.rogue.world.events.WorldAscendRequest;
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
|
||||
|
||||
public abstract class TileBaseEntrance extends TileBaseStairs {
|
||||
|
||||
public TileBaseEntrance(TileModel model)
|
||||
{
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onClick()
|
||||
{
|
||||
Coord plpos = getWorld().getPlayerEntity().getCoord();
|
||||
if(!plpos.equals(getLevel().getEnterPoint())) return false;
|
||||
|
||||
getEventBus().send(new WorldAscendRequest());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean doesCastShadow()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package mightypork.rogue.world.tile.tiles;
|
||||
|
||||
|
||||
import mightypork.gamecore.util.math.algo.Coord;
|
||||
import mightypork.rogue.world.events.WorldDescendRequest;
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
|
||||
|
||||
public abstract class TileBaseExit extends TileBaseStairs {
|
||||
|
||||
public TileBaseExit(TileModel model)
|
||||
{
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onClick()
|
||||
{
|
||||
Coord plpos = getWorld().getPlayerEntity().getCoord();
|
||||
if(!plpos.equals(getLevel().getExitPoint())) return false;
|
||||
|
||||
getEventBus().send(new WorldDescendRequest());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean doesCastShadow()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package mightypork.rogue.world.tile.tiles;
|
||||
|
||||
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
import mightypork.rogue.world.tile.TileType;
|
||||
|
||||
|
||||
public abstract class TileBaseStairs extends TileSolid {
|
||||
|
||||
public TileBaseStairs(TileModel model)
|
||||
{
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TileType getType()
|
||||
{
|
||||
return TileType.STAIRS;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,9 +13,9 @@ public class TileBrickDoor extends TileBaseDoor {
|
||||
//@formatter:off
|
||||
super(
|
||||
model,
|
||||
Res.sheet("tile.brick.door.locked"),
|
||||
Res.sheet("tile.brick.door.closed"),
|
||||
Res.sheet("tile.brick.door.open")
|
||||
Res.txs("tile.brick.door.locked"),
|
||||
Res.txs("tile.brick.door.closed"),
|
||||
Res.txs("tile.brick.door.open")
|
||||
);
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package mightypork.rogue.world.tile.tiles.brick;
|
||||
|
||||
|
||||
import mightypork.rogue.Res;
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
import mightypork.rogue.world.tile.TileRenderer;
|
||||
import mightypork.rogue.world.tile.render.OneFrameTileRenderer;
|
||||
import mightypork.rogue.world.tile.tiles.TileBaseEntrance;
|
||||
|
||||
|
||||
public class TileBrickEntrance extends TileBaseEntrance {
|
||||
|
||||
public TileBrickEntrance(TileModel model)
|
||||
{
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TileRenderer makeRenderer()
|
||||
{
|
||||
return new OneFrameTileRenderer(this, Res.txq("tile.brick.stairs.up"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package mightypork.rogue.world.tile.tiles.brick;
|
||||
|
||||
|
||||
import mightypork.rogue.Res;
|
||||
import mightypork.rogue.world.tile.TileModel;
|
||||
import mightypork.rogue.world.tile.TileRenderer;
|
||||
import mightypork.rogue.world.tile.render.OneFrameTileRenderer;
|
||||
import mightypork.rogue.world.tile.tiles.TileBaseExit;
|
||||
|
||||
|
||||
public class TileBrickExit extends TileBaseExit {
|
||||
|
||||
public TileBrickExit(TileModel model)
|
||||
{
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TileRenderer makeRenderer()
|
||||
{
|
||||
return new OneFrameTileRenderer(this, Res.txq("tile.brick.stairs.down"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public class TileBrickFloor extends TileBaseFloor {
|
||||
|
||||
public TileBrickFloor(TileModel model)
|
||||
{
|
||||
super(model, Res.sheet("tile.brick.floor"));
|
||||
super(model, Res.txs("tile.brick.floor"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public class TileBrickPassage extends TileBasePassage {
|
||||
|
||||
public TileBrickPassage(TileModel model)
|
||||
{
|
||||
super(model, Res.sheet("tile.brick.passage"));
|
||||
super(model, Res.txs("tile.brick.passage"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ public class TileBrickSecretDoor extends TileBaseSecretDoor {
|
||||
//@formatter:off
|
||||
super(
|
||||
model,
|
||||
Res.sheet("tile.brick.door.secret"),
|
||||
Res.sheet("tile.brick.door.closed"),
|
||||
Res.sheet("tile.brick.door.open")
|
||||
Res.txs("tile.brick.door.secret"),
|
||||
Res.txs("tile.brick.door.closed"),
|
||||
Res.txs("tile.brick.door.open")
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ public class TileBrickWall extends TileBaseWall {
|
||||
|
||||
public TileBrickWall(TileModel model)
|
||||
{
|
||||
super(model, Res.sheet("tile.brick.wall"));
|
||||
super(model, Res.txs("tile.brick.wall"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user