+PK event, + graphics for stairs

v5stable
Ondřej Hruška 11 years ago
parent 1796c2858c
commit 1121c31509
  1. BIN
      res/img/dudes.xcf
  2. BIN
      res/img/tiles16.png
  3. BIN
      res/img/tiles16.xcf
  4. 9
      src/mightypork/gamecore/eventbus/EventBus.java
  5. 2
      src/mightypork/gamecore/gui/components/painters/ImagePainter.java
  6. 1
      src/mightypork/gamecore/util/math/constraints/rect/Rect.java
  7. 1
      src/mightypork/rogue/App.java
  8. 8
      src/mightypork/rogue/screens/game/HeartBar.java
  9. 4
      src/mightypork/rogue/screens/game/HudLayer.java
  10. 7
      src/mightypork/rogue/screens/menu/MenuLayer.java
  11. 8
      src/mightypork/rogue/world/PlayerControl.java
  12. 45
      src/mightypork/rogue/world/World.java
  13. 9
      src/mightypork/rogue/world/WorldCreator.java
  14. 5
      src/mightypork/rogue/world/WorldProvider.java
  15. 6
      src/mightypork/rogue/world/WorldRenderer.java
  16. 30
      src/mightypork/rogue/world/entity/Entity.java
  17. 2
      src/mightypork/rogue/world/entity/entities/MonsterAi.java
  18. 28
      src/mightypork/rogue/world/entity/entities/PlayerEntity.java
  19. 4
      src/mightypork/rogue/world/entity/entities/RatEntity.java
  20. 2
      src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java
  21. 2
      src/mightypork/rogue/world/entity/render/EntityRenderer.java
  22. 16
      src/mightypork/rogue/world/entity/render/EntityRendererMobLR.java
  23. 14
      src/mightypork/rogue/world/events/PlayerKilledEvent.java
  24. 7
      src/mightypork/rogue/world/events/PlayerKilledListener.java
  25. 15
      src/mightypork/rogue/world/gen/LevelGenerator.java
  26. 4
      src/mightypork/rogue/world/gen/ScratchMap.java
  27. 13
      src/mightypork/rogue/world/gui/MapView.java
  28. 4
      src/mightypork/rogue/world/gui/Minimap.java
  29. 2
      src/mightypork/rogue/world/gui/interaction/MIPMouse.java
  30. 6
      src/mightypork/rogue/world/item/Item.java
  31. 2
      src/mightypork/rogue/world/item/ItemModel.java
  32. 7
      src/mightypork/rogue/world/item/items/ItemMeat.java
  33. 8
      src/mightypork/rogue/world/item/render/QuadItemRenderer.java
  34. 116
      src/mightypork/rogue/world/level/Level.java
  35. 109
      src/mightypork/rogue/world/level/LevelAccess.java
  36. 127
      src/mightypork/rogue/world/level/LevelReadAccess.java
  37. 47
      src/mightypork/rogue/world/level/MapAccess.java
  38. 4
      src/mightypork/rogue/world/level/render/EntityRenderContext.java
  39. 10
      src/mightypork/rogue/world/level/render/MapRenderContext.java
  40. 4
      src/mightypork/rogue/world/level/render/TileRenderContext.java
  41. 5
      src/mightypork/rogue/world/tile/DroppedItemRenderer.java
  42. 32
      src/mightypork/rogue/world/tile/Tile.java
  43. 2
      src/mightypork/rogue/world/tile/TileRenderer.java
  44. 2
      src/mightypork/rogue/world/tile/render/BasicTileRenderer.java
  45. 2
      src/mightypork/rogue/world/tile/render/DoorTileRenderer.java
  46. 2
      src/mightypork/rogue/world/tile/render/NullTileRenderer.java
  47. 3
      src/mightypork/rogue/world/tile/tiles/NullTile.java
  48. 2
      src/mightypork/rogue/world/tile/tiles/TileBaseDoor.java
  49. 2
      src/mightypork/rogue/world/tile/tiles/TileBaseFloor.java
  50. 2
      src/mightypork/rogue/world/tile/tiles/TileBasePassage.java
  51. 3
      src/mightypork/rogue/world/tile/tiles/TileBaseSecretDoor.java
  52. 2
      src/mightypork/rogue/world/tile/tiles/TileBaseWall.java
  53. 6
      src/mightypork/rogue/world/tile/tiles/TileWithItems.java

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

@ -22,7 +22,7 @@ import mightypork.gamecore.logging.Log;
* *
* @author MightyPork * @author MightyPork
*/ */
final public class EventBus implements Destroyable { final public class EventBus implements Destroyable, BusAccess {
/** /**
* Queued event holder * Queued event holder
@ -384,4 +384,11 @@ final public class EventBus implements Destroyable {
return true; return true;
} }
@Override
public EventBus getEventBus()
{
return this; // just for compatibility use-case
}
} }

@ -17,7 +17,7 @@ public class ImagePainter extends VisualComponent {
private final TxQuad txQuad; private final TxQuad txQuad;
private boolean aspratio = false; private boolean aspratio = false;
private Rect asprRect; private final Rect asprRect;
/** /**

@ -920,6 +920,7 @@ public abstract class Rect implements RectBound, Digestable<RectDigest> {
return p_axis_v != null ? p_axis_v : (p_axis_v = topCenter().expand(Num.ZERO, Num.ZERO, Num.ZERO, height())); return p_axis_v != null ? p_axis_v : (p_axis_v = topCenter().expand(Num.ZERO, Num.ZERO, Num.ZERO, height()));
} }
public Rect axisH() public Rect axisH()
{ {
return p_axis_h != null ? p_axis_h : (p_axis_h = centerLeft().expand(Num.ZERO, width(), Num.ZERO, Num.ZERO)); return p_axis_h != null ? p_axis_h : (p_axis_h = centerLeft().expand(Num.ZERO, width(), Num.ZERO, Num.ZERO));

@ -25,7 +25,6 @@ import mightypork.rogue.screens.game.ScreenGame;
import mightypork.rogue.screens.menu.ScreenMainMenu; import mightypork.rogue.screens.menu.ScreenMainMenu;
import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy; import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy;
import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.WorldProvider;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;

@ -15,8 +15,8 @@ public class HeartBar extends VisualComponent {
private final TxQuad img_on; private final TxQuad img_on;
private final TxQuad img_off; private final TxQuad img_off;
private final TxQuad img_half; private final TxQuad img_half;
private Num total; private final Num total;
private Num active; private final Num active;
NumVar index = new NumVar(0); NumVar index = new NumVar(0);
Rect heart; Rect heart;
@ -63,9 +63,9 @@ public class HeartBar extends VisualComponent {
for (int i = 0; i < total.value(); i++) { for (int i = 0; i < total.value(); i++) {
index.setTo(i); index.setTo(i);
double rem = active.value()-i; final double rem = active.value() - i;
Render.quadTextured(heart, (rem>0.6 ? img_on : rem>0.25 ? img_half: img_off)); Render.quadTextured(heart, (rem > 0.6 ? img_on : rem > 0.25 ? img_half : img_off));
} }
} }

@ -17,7 +17,7 @@ import mightypork.rogue.world.gui.Minimap;
public class HudLayer extends ScreenLayer { public class HudLayer extends ScreenLayer {
private Num playerHealthTotal = new Num() { private final Num playerHealthTotal = new Num() {
@Override @Override
public double value() public double value()
@ -26,7 +26,7 @@ public class HudLayer extends ScreenLayer {
} }
}; };
private Num playerHealthActive = new Num() { private final Num playerHealthActive = new Num() {
@Override @Override
public double value() public double value()

@ -2,21 +2,16 @@ package mightypork.rogue.screens.menu;
import mightypork.gamecore.gui.Action; import mightypork.gamecore.gui.Action;
import mightypork.gamecore.gui.AlignX;
import mightypork.gamecore.gui.components.layout.GridLayout; import mightypork.gamecore.gui.components.layout.GridLayout;
import mightypork.gamecore.gui.components.painters.ImagePainter; import mightypork.gamecore.gui.components.painters.ImagePainter;
import mightypork.gamecore.gui.components.painters.QuadPainter; import mightypork.gamecore.gui.components.painters.QuadPainter;
import mightypork.gamecore.gui.components.painters.TextPainter;
import mightypork.gamecore.gui.events.CrossfadeRequest; import mightypork.gamecore.gui.events.CrossfadeRequest;
import mightypork.gamecore.gui.screens.Screen; import mightypork.gamecore.gui.screens.Screen;
import mightypork.gamecore.gui.screens.ScreenLayer; import mightypork.gamecore.gui.screens.ScreenLayer;
import mightypork.gamecore.util.math.color.Color; import mightypork.gamecore.util.math.color.Color;
import mightypork.gamecore.util.math.color.pal.COMMODORE;
import mightypork.gamecore.util.math.color.pal.PAL16; import mightypork.gamecore.util.math.color.pal.PAL16;
import mightypork.gamecore.util.math.color.pal.RGB;
import mightypork.gamecore.util.math.constraints.num.Num; import mightypork.gamecore.util.math.constraints.num.Num;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.vect.Vect;
import mightypork.rogue.Res; import mightypork.rogue.Res;
@ -44,7 +39,7 @@ class MenuLayer extends ScreenLayer {
root.add(layout); root.add(layout);
int r = 0; int r = 0;
ImagePainter ip = new ImagePainter(Res.getTxQuad("logo")); final ImagePainter ip = new ImagePainter(Res.getTxQuad("logo"));
ip.keepAspectRatio(); ip.keepAspectRatio();
layout.put(ip, r, 0, 5, 1); layout.put(ip, r, 0, 5, 1);
r += 6; r += 6;

@ -8,7 +8,7 @@ import mightypork.gamecore.util.math.algo.Coord;
import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.algo.Step;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.entity.modules.EntityMoveListener; import mightypork.rogue.world.entity.modules.EntityMoveListener;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.LevelAccess;
public abstract class PlayerControl { public abstract class PlayerControl {
@ -35,7 +35,7 @@ public abstract class PlayerControl {
return newWorld; return newWorld;
}; }
public Entity getPlayerEntity() public Entity getPlayerEntity()
@ -86,7 +86,7 @@ public abstract class PlayerControl {
} }
public Level getLevel() public LevelAccess getLevel()
{ {
return getWorld().getCurrentLevel(); return getWorld().getCurrentLevel();
} }
@ -114,7 +114,7 @@ public abstract class PlayerControl {
{ {
if (pos.dist(getCoord()) > 8) return false; // too far if (pos.dist(getCoord()) > 8) return false; // too far
return getLevel().getTile(pos).onClick(getWorld()); return getLevel().getTile(pos).onClick();
} }

@ -4,12 +4,15 @@ package mightypork.rogue.world;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import mightypork.gamecore.eventbus.BusAccess;
import mightypork.gamecore.eventbus.EventBus;
import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.eventbus.events.Updateable;
import mightypork.gamecore.util.ion.IonBundle; import mightypork.gamecore.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonObjBundled; import mightypork.gamecore.util.ion.IonObjBundled;
import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entities;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.LevelAccess;
/** /**
@ -17,13 +20,15 @@ import mightypork.rogue.world.level.Level;
* *
* @author MightyPork * @author MightyPork
*/ */
public class World implements IonObjBundled, Updateable { public class World implements BusAccess, IonObjBundled, Updateable {
private final ArrayList<Level> levels = new ArrayList<>(); private final ArrayList<Level> levels = new ArrayList<>();
private final PlayerInfo playerInfo = new PlayerInfo(); private final PlayerInfo playerInfo = new PlayerInfo();
private Entity playerEntity; private Entity playerEntity;
private BusAccess bus;
/** World seed */ /** World seed */
private long seed; private long seed;
@ -34,8 +39,8 @@ public class World implements IonObjBundled, Updateable {
@Override @Override
public void load(IonBundle in) throws IOException public void load(IonBundle in) throws IOException
{ {
seed = in.get("seed", 0L); seed = in.get("seed", seed);
eid = in.get("next_eid", 0); eid = in.get("next_eid", eid);
in.loadSequence("levels", levels); in.loadSequence("levels", levels);
// join levels to world // join levels to world
@ -46,7 +51,9 @@ public class World implements IonObjBundled, Updateable {
in.loadBundled("player", playerInfo); in.loadBundled("player", playerInfo);
playerEntity = levels.get(playerInfo.getLevel()).getEntity(playerInfo.getEID()); playerEntity = levels.get(playerInfo.getLevel()).getEntity(playerInfo.getEID());
if (playerEntity == null) throw new RuntimeException("Player entity not found in the world."); if (playerEntity == null) {
throw new RuntimeException("Player entity not found in the world.");
}
} }
@ -104,16 +111,21 @@ public class World implements IonObjBundled, Updateable {
// make entity // make entity
final int playerEid = getNewEID(); final int playerEid = getNewEID();
final Level floor = levels.get(level);
if (floor == null) {
throw new IndexOutOfBoundsException("No such level: " + level);
}
playerEntity = Entities.PLAYER.createEntity(playerEid); playerEntity = Entities.PLAYER.createEntity(playerEid);
playerEntity.setCoord(levels.get(level).getEnterPoint()); floor.addEntity(playerEntity, floor.getEnterPoint());
levels.get(level).addEntity(playerEntity); floor.explore(playerEntity.getCoord());
playerInfo.setLevel(level); playerInfo.setLevel(level);
playerInfo.setEID(playerEid); playerInfo.setEID(playerEid);
} }
public Level getCurrentLevel() public LevelAccess getCurrentLevel()
{ {
return levels.get(playerInfo.getLevel()); return levels.get(playerInfo.getLevel());
} }
@ -124,4 +136,23 @@ public class World implements IonObjBundled, Updateable {
return playerEntity; return playerEntity;
} }
/**
* Attach to an event bus
*
* @param bus event bus
*/
public void assignBus(BusAccess bus)
{
this.bus = bus;
}
@Override
public EventBus getEventBus()
{
if (bus == null) throw new NullPointerException("World doesn't have a bus assigned.");
return bus.getEventBus();
}
} }

@ -20,13 +20,10 @@ public class WorldCreator {
final World w = new World(); final World w = new World();
w.setSeed(seed); w.setSeed(seed);
Level l; for(int i=0; i<7; i++) {
Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME);
// TODO real algorithm
// first level
l = LevelGenerator.build(w, rand.nextLong(), 1, LevelGenerator.DUNGEON_THEME); //
w.addLevel(l); w.addLevel(l);
}
w.createPlayer(0); w.createPlayer(0);

@ -8,7 +8,7 @@ import mightypork.gamecore.eventbus.BusAccess;
import mightypork.gamecore.eventbus.clients.RootBusNode; import mightypork.gamecore.eventbus.clients.RootBusNode;
import mightypork.gamecore.util.ion.Ion; import mightypork.gamecore.util.ion.Ion;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.LevelAccess;
public class WorldProvider extends RootBusNode { public class WorldProvider extends RootBusNode {
@ -67,6 +67,7 @@ public class WorldProvider extends RootBusNode {
if (world != null) removeChildClient(world); if (world != null) removeChildClient(world);
world = newWorld; world = newWorld;
world.assignBus(this); // connect to bus (for event dispatching)
addChildClient(world); addChildClient(world);
} }
@ -84,7 +85,7 @@ public class WorldProvider extends RootBusNode {
} }
public Level getCurrentLevel() public LevelAccess getCurrentLevel()
{ {
return getWorld().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.gamecore.util.math.constraints.vect.VectConst;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.LevelAccess;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
@ -29,7 +29,7 @@ public class WorldRenderer extends RectProxy {
// can be changed // can be changed
private RectConst mapRect; private RectConst mapRect;
private Level activeLevel; private LevelAccess activeLevel;
private final Rect rightShadow; private final Rect rightShadow;
private final Rect leftShadow; private final Rect leftShadow;
@ -57,7 +57,7 @@ public class WorldRenderer extends RectProxy {
private void prepareRenderContextIfNeeded() private void prepareRenderContextIfNeeded()
{ {
final Level level = WorldProvider.get().getCurrentLevel(); final LevelAccess level = WorldProvider.get().getCurrentLevel();
if (activeLevel == level) return; if (activeLevel == level) return;

@ -17,8 +17,8 @@ import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
import mightypork.rogue.world.World; import mightypork.rogue.world.World;
import mightypork.rogue.world.entity.modules.EntityModuleHealth; import mightypork.rogue.world.entity.modules.EntityModuleHealth;
import mightypork.rogue.world.entity.modules.EntityModulePosition; import mightypork.rogue.world.entity.modules.EntityModulePosition;
import mightypork.rogue.world.entity.renderers.EntityRenderer; import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.LevelAccess;
import mightypork.rogue.world.level.render.MapRenderContext; 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 { public abstract class Entity implements IonObjBundled, Updateable {
private Level level; private LevelAccess level;
private final EntityModel model; private final EntityModel model;
protected final Random rand = new Random(); protected final Random rand = new Random();
@ -120,7 +120,7 @@ public abstract class Entity implements IonObjBundled, Updateable {
} }
public void setLevel(Level level) public void setLevel(LevelAccess level)
{ {
if (level != null) level.freeTile(getCoord()); if (level != null) level.freeTile(getCoord());
@ -130,7 +130,7 @@ public abstract class Entity implements IonObjBundled, Updateable {
} }
public final Level getLevel() public final LevelAccess getLevel()
{ {
return level; return level;
} }
@ -225,6 +225,15 @@ public abstract class Entity implements IonObjBundled, Updateable {
} }
/**
* Called after the corpse has been cleaned from level.
*/
@DefaultImpl
public void onCorpseRemoved()
{
}
/** /**
* Receive damage from an attacker.<br> * Receive damage from an attacker.<br>
* The entity can decide whether to dodge, reduce damage etc. * The entity can decide whether to dodge, reduce damage etc.
@ -239,9 +248,20 @@ public abstract class Entity implements IonObjBundled, Updateable {
} }
/**
* Set how long after being killed is the corpse elligible for removal
*
* @param despawnDelay (secs)
*/
public void setDespawnDelay(double despawnDelay) public void setDespawnDelay(double despawnDelay)
{ {
this.despawnDelay = despawnDelay; this.despawnDelay = despawnDelay;
} }
public double getDespawnDelay()
{
return despawnDelay;
}
} }

@ -179,7 +179,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
if (chasing && !entity.pos.isMoving()) { if (chasing && !entity.pos.isMoving()) {
final Entity prey = getPreyEntity(); final Entity prey = getPreyEntity();
if(prey==null) { if (prey == null) {
// prey killed and cleaned from level // prey killed and cleaned from level
stopChasing(); stopChasing();
return; return;

@ -9,9 +9,9 @@ import mightypork.rogue.world.entity.EntityModule;
import mightypork.rogue.world.entity.EntityPathFinder; import mightypork.rogue.world.entity.EntityPathFinder;
import mightypork.rogue.world.entity.EntityType; import mightypork.rogue.world.entity.EntityType;
import mightypork.rogue.world.entity.modules.EntityMoveListener; import mightypork.rogue.world.entity.modules.EntityMoveListener;
import mightypork.rogue.world.entity.renderers.EntityRenderer; import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.entity.renderers.EntityRendererMobLR; import mightypork.rogue.world.entity.render.EntityRendererMobLR;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.events.PlayerKilledEvent;
public class PlayerEntity extends Entity { public class PlayerEntity extends Entity {
@ -82,7 +82,7 @@ public class PlayerEntity extends Entity {
public int getCost(Coord from, Coord to) public int getCost(Coord from, Coord to)
{ {
if (!getLevel().getTile(pos.getCoord()).isExplored()) { if (!getLevel().getTile(pos.getCoord()).isExplored()) {
return 1000; return 1000; // avoid unexplored, but allow them if there's no other way
} }
return super.getCost(from, to); return super.getCost(from, to);
@ -94,14 +94,6 @@ public class PlayerEntity extends Entity {
} }
@Override
public void setLevel(Level level)
{
super.setLevel(level);
ai.onStepFinished(); // explore start area
}
@Override @Override
protected EntityRenderer getRenderer() protected EntityRenderer getRenderer()
{ {
@ -119,9 +111,11 @@ public class PlayerEntity extends Entity {
return EntityType.PLAYER; return EntityType.PLAYER;
} }
// @Override
// public void receiveAttack(Entity attacker, int attackStrength) @Override
// { public void onKilled()
// // FIXME ignore attack {
// } // send kill event to listeners (GUI?)
getWorld().getEventBus().sendDelayed(new PlayerKilledEvent(), getDespawnDelay());
}
} }

@ -6,8 +6,8 @@ import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.entity.EntityModel; import mightypork.rogue.world.entity.EntityModel;
import mightypork.rogue.world.entity.EntityPathFinder; import mightypork.rogue.world.entity.EntityPathFinder;
import mightypork.rogue.world.entity.EntityType; import mightypork.rogue.world.entity.EntityType;
import mightypork.rogue.world.entity.renderers.EntityRenderer; import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.entity.renderers.EntityRendererMobLR; import mightypork.rogue.world.entity.render.EntityRendererMobLR;
public class RatEntity extends Entity { public class RatEntity extends Entity {

@ -108,7 +108,7 @@ public class EntityModuleHealth extends EntityModule {
@Override @Override
public void update(double delta) public void update(double delta)
{ {
if(timeSinceLastDamage < 3600) timeSinceLastDamage += delta; if (timeSinceLastDamage < 3600) timeSinceLastDamage += delta;
} }

@ -1,4 +1,4 @@
package mightypork.rogue.world.entity.renderers; package mightypork.rogue.world.entity.render;
import mightypork.rogue.world.level.render.MapRenderContext; import mightypork.rogue.world.level.render.MapRenderContext;

@ -1,16 +1,12 @@
package mightypork.rogue.world.entity.renderers; package mightypork.rogue.world.entity.render;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;
import mightypork.gamecore.resources.textures.TxQuad; import mightypork.gamecore.resources.textures.TxQuad;
import mightypork.gamecore.resources.textures.TxSheet; import mightypork.gamecore.resources.textures.TxSheet;
import mightypork.gamecore.util.math.Calc; import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.Easing;
import mightypork.gamecore.util.math.color.Color; 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.Num;
import mightypork.gamecore.util.math.constraints.num.NumConst;
import mightypork.gamecore.util.math.constraints.num.mutable.NumAnimated;
import mightypork.gamecore.util.math.constraints.num.mutable.NumVar; import mightypork.gamecore.util.math.constraints.num.mutable.NumVar;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.math.constraints.vect.Vect;
@ -31,9 +27,9 @@ public class EntityRendererMobLR extends EntityRenderer {
protected final Entity entity; protected final Entity entity;
private NumVar animRedVar = Num.makeVar(0); private final NumVar animRedVar = Num.makeVar(0);
private Color hue = Color.rgb(Num.ONE, animRedVar, animRedVar); private final Color hue = Color.rgb(Num.ONE, animRedVar, animRedVar);
public EntityRendererMobLR(Entity entity, String sheetKey) public EntityRendererMobLR(Entity entity, String sheetKey)
@ -46,7 +42,7 @@ public class EntityRendererMobLR extends EntityRenderer {
@Override @Override
public void render(MapRenderContext context) public void render(MapRenderContext context)
{ {
double hurtTime = entity.health.getTimeSinceLastDamage(); final double hurtTime = entity.health.getTimeSinceLastDamage();
TxQuad q = sheet.getQuad(Calc.frag(entity.pos.getProgress())); TxQuad q = sheet.getQuad(Calc.frag(entity.pos.getProgress()));
@ -56,7 +52,7 @@ public class EntityRendererMobLR extends EntityRenderer {
final double w = tileRect.width().value(); final double w = tileRect.width().value();
final Vect visualPos = entity.pos.getVisualPos(); final Vect visualPos = entity.pos.getVisualPos();
double hurtOffset = (1 - Calc.clamp(hurtTime / 0.1, 0, 1)) * (entity.isDead() ? 0.3 : 0.05); final double hurtOffset = (1 - Calc.clamp(hurtTime / 0.1, 0, 1)) * (entity.isDead() ? 0.3 : 0.05);
Rect spriteRect = Rect.make(visualPos.x() * w, (visualPos.y() - hurtOffset) * w, w, w); Rect spriteRect = Rect.make(visualPos.x() * w, (visualPos.y() - hurtOffset) * w, w, w);
@ -72,7 +68,7 @@ public class EntityRendererMobLR extends EntityRenderer {
Render.rotateZ(Calc.clamp(hurtTime / 0.3, 0, 1) * 90); Render.rotateZ(Calc.clamp(hurtTime / 0.3, 0, 1) * 90);
} }
double hw = spriteRect.width().half().value(); final double hw = spriteRect.width().half().value();
Render.quadTextured(Vect.ZERO.expand(hw, hw, hw, hw), q, hue.withAlpha(entity.isDead() ? 1 - hurtTime / 3 : 1)); Render.quadTextured(Vect.ZERO.expand(hw, hw, hw, hw), q, hue.withAlpha(entity.isDead() ? 1 - hurtTime / 3 : 1));
Render.popMatrix(); Render.popMatrix();

@ -0,0 +1,14 @@
package mightypork.rogue.world.events;
import mightypork.gamecore.eventbus.BusEvent;
public class PlayerKilledEvent extends BusEvent<PlayerKilledListener> {
@Override
protected void handleBy(PlayerKilledListener handler)
{
handler.onPlayerKilled();
}
}

@ -0,0 +1,7 @@
package mightypork.rogue.world.events;
public interface PlayerKilledListener {
void onPlayerKilled();
}

@ -3,6 +3,7 @@ package mightypork.rogue.world.gen;
import java.util.Random; import java.util.Random;
import mightypork.gamecore.logging.Log;
import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Coord;
import mightypork.rogue.world.World; import mightypork.rogue.world.World;
import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entities;
@ -22,6 +23,8 @@ public class LevelGenerator {
public static Level build(World world, long seed, int complexity, MapTheme theme) public static Level build(World world, long seed, int complexity, MapTheme theme)
{ {
Log.f3("Generating level of complexity: "+complexity);
final Random rand = new Random(seed + 13); final Random rand = new Random(seed + 13);
final int max_size = 128; final int max_size = 128;
@ -31,7 +34,7 @@ public class LevelGenerator {
// start // start
map.addRoom(Rooms.BASIC); map.addRoom(Rooms.BASIC);
for (int i = 0; i < 2 + complexity / 2 + rand.nextInt((int) (1 + complexity * 0.3)); i++) { for (int i = 0; i < 1 + complexity / 2 + rand.nextInt((int) (1 + complexity * 0.3)); i++) {
map.addRoom(Rooms.BASIC); map.addRoom(Rooms.BASIC);
if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET); if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET);
if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END); if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END);
@ -48,7 +51,7 @@ public class LevelGenerator {
// spawn rats // spawn rats
final Coord pos = Coord.make(0, 0); final Coord pos = Coord.make(0, 0);
for (int i = 0; i < 4+complexity + rand.nextInt(1+complexity); i++) { for (int i = 0; i < 3 + complexity + rand.nextInt(1 + complexity); i++) {
final Entity e = Entities.RAT.createEntity(world); final Entity e = Entities.RAT.createEntity(world);
@ -60,16 +63,16 @@ public class LevelGenerator {
} }
} }
for (int i = 0; i < 4+complexity + rand.nextInt(1+complexity); i++) { for (int i = 0; i < 4 + complexity + rand.nextInt(1 + complexity); i++) {
Item meat = Items.MEAT.createItem(); final Item meat = Items.MEAT.createItem();
for (int j = 0; j < 20; j++) { for (int j = 0; j < 20; j++) {
pos.x = rand.nextInt(lvl.getWidth()); pos.x = rand.nextInt(lvl.getWidth());
pos.y = rand.nextInt(lvl.getHeight()); pos.y = rand.nextInt(lvl.getHeight());
Tile t = lvl.getTile(pos); final Tile t = lvl.getTile(pos);
if(t.dropItem(meat)) break; if (t.dropItem(meat)) break;
} }
} }

@ -14,7 +14,7 @@ import mightypork.gamecore.util.math.algo.Sides;
import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.algo.Step;
import mightypork.gamecore.util.math.algo.pathfinding.Heuristic; import mightypork.gamecore.util.math.algo.pathfinding.Heuristic;
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder; import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.LevelAccess;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.Tiles; import mightypork.rogue.world.tile.Tiles;
@ -410,7 +410,7 @@ public class ScratchMap {
} }
public void writeToLevel(Level level) public void writeToLevel(LevelAccess level)
{ {
// make sure no walkable are at edges. // make sure no walkable are at edges.
final Coord c = Coord.make(0, 0); final Coord c = Coord.make(0, 0);

@ -35,6 +35,7 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL
private final Set<MapInteractionPlugin> plugins = new LinkedHashSet<>(); private final Set<MapInteractionPlugin> plugins = new LinkedHashSet<>();
private final NumAnimated zoom = new NumAnimated(0, Easing.SINE_BOTH); private final NumAnimated zoom = new NumAnimated(0, Easing.SINE_BOTH);
private boolean zoom_in = true;
private final Num tileSize; private final Num tileSize;
@ -112,9 +113,11 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL
final int delta = event.getWheelDelta(); final int delta = event.getWheelDelta();
if (!zoom.isFinished()) return; if (!zoom.isFinished()) return;
if (delta < 0) { if (delta < 0) {
zoom.fadeOut();
} else {
zoom.fadeIn(); zoom.fadeIn();
zoom_in = false;
} else {
zoom.fadeOut();
zoom_in = true;
} }
} }
} }
@ -127,11 +130,13 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL
if (p.onKey(this, pc, event.getKey(), event.isDown())) break; if (p.onKey(this, pc, event.getKey(), event.isDown())) break;
} }
if (event.getKey() == Keys.Z) { if (event.getKey() == Keys.Z && event.isDown()) {
if (event.isDown()) { if (zoom_in) {
zoom.fadeIn(); zoom.fadeIn();
zoom_in = false;
} else { } else {
zoom.fadeOut(); zoom.fadeOut();
zoom_in = true;
} }
} }

@ -14,7 +14,7 @@ import mightypork.gamecore.util.math.constraints.rect.mutable.RectMutable;
import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.math.constraints.vect.Vect;
import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.WorldProvider;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.LevelReadAccess;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@ -33,7 +33,7 @@ public class Minimap extends InputComponent implements MouseButtonListener {
{ {
Color.pushAlpha(translucency); Color.pushAlpha(translucency);
final Level lvl = WorldProvider.get().getCurrentLevel(); final LevelReadAccess lvl = WorldProvider.get().getCurrentLevel();
unit = (int) Math.min(Math.max(2, Math.ceil((height().value() / 2) / (lvl.getHeight() + 2))), 10); unit = (int) Math.min(Math.max(2, Math.ceil((height().value() / 2) / (lvl.getHeight() + 2))), 10);
final Entity e = WorldProvider.get().getPlayerEntity(); final Entity e = WorldProvider.get().getPlayerEntity();

@ -39,7 +39,7 @@ public class MIPMouse implements MapInteractionPlugin {
final Coord pos = view.toWorldPos(mouse); final Coord pos = view.toWorldPos(mouse);
final Tile t = pc.getLevel().getTile(pos); final Tile t = pc.getLevel().getTile(pos);
if (t.onClick(pc.getWorld())) return true; if (t.onClick()) return true;
if (!down && t.isWalkable()) { if (!down && t.isWalkable()) {
if (troToNav(view, pc, mouse)) return true; if (troToNav(view, pc, mouse)) return true;

@ -8,7 +8,6 @@ import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonObjBlob; import mightypork.gamecore.util.ion.IonObjBlob;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
public abstract class Item implements IonObjBlob { public abstract class Item implements IonObjBlob {
@ -17,7 +16,8 @@ public abstract class Item implements IonObjBlob {
private ItemRenderer renderer; private ItemRenderer renderer;
public Item(ItemModel model) { public Item(ItemModel model)
{
this.model = model; this.model = model;
} }
@ -29,7 +29,7 @@ public abstract class Item implements IonObjBlob {
} }
renderer.render(rect); renderer.render(rect);
}; }
protected abstract ItemRenderer makeRenderer(); protected abstract ItemRenderer makeRenderer();

@ -6,6 +6,7 @@ import java.io.IOException;
import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
/** /**
* Item model (builder) * Item model (builder)
* *
@ -54,4 +55,3 @@ public final class ItemModel {
tile.save(out); tile.save(out);
} }
} }

@ -1,18 +1,21 @@
package mightypork.rogue.world.item.items; package mightypork.rogue.world.item.items;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.item.ItemModel; import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer; import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.rendr.QuadItemRenderer; import mightypork.rogue.world.item.render.QuadItemRenderer;
public class ItemMeat extends Item { public class ItemMeat extends Item {
public ItemMeat(ItemModel model) { public ItemMeat(ItemModel model)
{
super(model); super(model);
} }
@Override @Override
protected ItemRenderer makeRenderer() protected ItemRenderer makeRenderer()
{ {

@ -1,4 +1,4 @@
package mightypork.rogue.world.item.rendr; package mightypork.rogue.world.item.render;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;
@ -13,12 +13,14 @@ public class QuadItemRenderer extends ItemRenderer {
private final TxQuad txq; private final TxQuad txq;
public QuadItemRenderer(TxQuad txq) { public QuadItemRenderer(TxQuad txq)
{
this.txq = txq; this.txq = txq;
} }
public QuadItemRenderer(TxSheet txs) { public QuadItemRenderer(TxSheet txs)
{
this.txq = txs.getQuad(0); this.txq = txs.getQuad(0);
} }

@ -4,8 +4,8 @@ package mightypork.rogue.world.level;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import javax.print.attribute.standard.MediaSize.ISO; import mightypork.gamecore.eventbus.BusAccess;
import mightypork.gamecore.eventbus.EventBus;
import mightypork.gamecore.logging.Log; import mightypork.gamecore.logging.Log;
import mightypork.gamecore.util.ion.IonBundle; import mightypork.gamecore.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonInput;
@ -31,7 +31,7 @@ import mightypork.rogue.world.tile.Tiles;
* *
* @author MightyPork * @author MightyPork
*/ */
public class Level implements MapAccess, IonObjBinary { public class Level implements BusAccess, LevelAccess, IonObjBinary {
public static final int ION_MARK = 53; public static final int ION_MARK = 53;
@ -70,12 +70,7 @@ public class Level implements MapAccess, IonObjBinary {
} }
public void fill(short id) @Override
{
fill(Tiles.get(id));
}
public void fill(TileModel model) public void fill(TileModel model)
{ {
for (final Coord c = Coord.zero(); c.x < size.x; c.x++) { for (final Coord c = Coord.zero(); c.x < size.x; c.x++) {
@ -95,18 +90,7 @@ public class Level implements MapAccess, IonObjBinary {
} }
public final void setTile(Coord pos, TileModel model) @Override
{
setTile(pos, model.createTile());
}
public final void setTile(Coord pos, int tileId)
{
setTile(pos, Tiles.create(tileId));
}
public final void setTile(Coord pos, Tile tile) public final void setTile(Coord pos, Tile tile)
{ {
if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) { if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) {
@ -115,6 +99,9 @@ public class Level implements MapAccess, IonObjBinary {
} }
tiles[pos.y][pos.x] = tile; tiles[pos.y][pos.x] = tile;
// assign level (tile logic may need it)
tile.setLevel(this);
} }
@ -132,6 +119,7 @@ public class Level implements MapAccess, IonObjBinary {
} }
@Override
public void setSeed(long seed) public void setSeed(long seed)
{ {
this.seed = seed; this.seed = seed;
@ -207,23 +195,24 @@ public class Level implements MapAccess, IonObjBinary {
} }
@Override
public void update(double delta) public void update(double delta)
{ {
// just update them all // just update them all
for (final Coord c = Coord.zero(); c.x < size.x; c.x++) { for (final Coord c = Coord.zero(); c.x < size.x; c.x++) {
for (c.y = 0; c.y < size.y; c.y++) { for (c.y = 0; c.y < size.y; c.y++) {
getTile(c).update(this, delta); getTile(c).update(delta);
} }
} }
List<Entity> toRemove = new ArrayList<>(); final List<Entity> toRemove = new ArrayList<>();
for (final Entity e : entitySet) { for (final Entity e : entitySet) {
e.update(delta); e.update(delta);
if (e.isDead() && e.canRemoveCorpse()) toRemove.add(e); if (e.isDead() && e.canRemoveCorpse()) toRemove.add(e);
} }
for (Entity e : toRemove) { for (final Entity e : toRemove) {
removeEntity(e); removeEntity(e);
} }
} }
@ -240,37 +229,22 @@ public class Level implements MapAccess, IonObjBinary {
} }
@Override
public Entity getEntity(int eid) public Entity getEntity(int eid)
{ {
return entityMap.get(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) public boolean addEntity(Entity entity, Coord pos)
{ {
final Tile t = getTile(pos); final Tile t = getTile(pos);
if (!t.isWalkable() || isOccupied(pos)) return false; if (!t.isWalkable() || t.isOccupied()) return false;
addEntity(entity);
entity.setCoord(pos);
return true;
}
public void addEntity(Entity entity)
{
if (entityMap.containsKey(entity.getEntityId())) { if (entityMap.containsKey(entity.getEntityId())) {
Log.w("Entity already in level."); Log.w("Entity already in level.");
return; return false;
} }
entityMap.put(entity.getEntityId(), entity); entityMap.put(entity.getEntityId(), entity);
@ -279,15 +253,21 @@ public class Level implements MapAccess, IonObjBinary {
// join to level & world // join to level & world
entity.setLevel(this); entity.setLevel(this);
occupyTile(entity.getCoord()); occupyTile(entity.getCoord());
entity.setCoord(pos);
return true;
} }
@Override
public void removeEntity(Entity entity) public void removeEntity(Entity entity)
{ {
removeEntity(entity.getEntityId()); removeEntity(entity.getEntityId());
} }
@Override
public void removeEntity(int eid) public void removeEntity(int eid)
{ {
final Entity removed = entityMap.remove(eid); final Entity removed = entityMap.remove(eid);
@ -296,6 +276,7 @@ public class Level implements MapAccess, IonObjBinary {
} }
@Override
public boolean isWalkable(Coord pos) public boolean isWalkable(Coord pos)
{ {
final Tile t = getTile(pos); final Tile t = getTile(pos);
@ -307,6 +288,7 @@ public class Level implements MapAccess, IonObjBinary {
/** /**
* Mark tile as occupied by an entity * Mark tile as occupied by an entity
*/ */
@Override
public void occupyTile(Coord pos) public void occupyTile(Coord pos)
{ {
getTile(pos).setOccupied(true); getTile(pos).setOccupied(true);
@ -316,52 +298,56 @@ public class Level implements MapAccess, IonObjBinary {
/** /**
* Mark tile as free (no longet occupied) * Mark tile as free (no longet occupied)
*/ */
@Override
public void freeTile(Coord pos) public void freeTile(Coord pos)
{ {
getTile(pos).setOccupied(false); getTile(pos).setOccupied(false);
} }
/** @Override
* @param pos tile coord
* @return true if something is standing there.
*/
public boolean isOccupied(Coord pos) public boolean isOccupied(Coord pos)
{ {
return getTile(pos).isOccupied(); return getTile(pos).isOccupied();
} }
@Override
public Collection<Entity> getEntities() public Collection<Entity> getEntities()
{ {
return entitySet; return entitySet;
} }
@Override
public void setEnterPoint(Coord pos) public void setEnterPoint(Coord pos)
{ {
this.enterPoint.setTo(pos); this.enterPoint.setTo(pos);
} }
@Override
public Coord getEnterPoint() public Coord getEnterPoint()
{ {
return enterPoint; return enterPoint;
} }
@Override
public World getWorld() public World getWorld()
{ {
return world; return world;
} }
@Override
public void setWorld(World world) public void setWorld(World world)
{ {
this.world = world; this.world = world;
} }
@Override
public void explore(Coord center) public void explore(Coord center)
{ {
final Collection<Coord> filled = new HashSet<>(); final Collection<Coord> filled = new HashSet<>();
@ -413,6 +399,7 @@ public class Level implements MapAccess, IonObjBinary {
}; };
@Override
public Entity getClosestEntity(Entity self, EntityType type, double radius) public Entity getClosestEntity(Entity self, EntityType type, double radius)
{ {
Entity closest = null; Entity closest = null;
@ -436,8 +423,43 @@ public class Level implements MapAccess, IonObjBinary {
} }
public void forceFreeTile(Coord pos)
{
if (getTile(pos).isOccupied()) {
final Set<Entity> toButcher = new HashSet<>();
for (final Entity e : entitySet) {
if (e.getCoord().equals(pos)) {
toButcher.add(e);
break;
}
}
for (final Entity e : toButcher) {
removeEntity(e);
freeTile(pos);
}
}
}
@Override
public boolean isEntityPresent(Entity entity) public boolean isEntityPresent(Entity entity)
{ {
return entitySet.contains(entity); return entitySet.contains(entity);
} }
@Override
public boolean isEntityPresent(int eid)
{
return entityMap.containsKey(eid);
}
@Override
public EventBus getEventBus()
{
return world.getEventBus();
}
} }

@ -0,0 +1,109 @@
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);
}

@ -0,0 +1,127 @@
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();
}

@ -1,47 +0,0 @@
package mightypork.rogue.world.level;
import mightypork.gamecore.util.math.algo.Coord;
import mightypork.gamecore.util.math.noise.NoiseGen;
import mightypork.rogue.world.tile.Tile;
/**
* Access interface for a level map.
*
* @author MightyPork
*/
public interface MapAccess {
/**
* 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();
}

@ -2,12 +2,12 @@ package mightypork.rogue.world.level.render;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.rogue.world.level.MapAccess; import mightypork.rogue.world.level.LevelReadAccess;
public class EntityRenderContext extends MapRenderContext { public class EntityRenderContext extends MapRenderContext {
public EntityRenderContext(MapAccess map, Rect drawArea) public EntityRenderContext(LevelReadAccess map, Rect drawArea)
{ {
super(map, 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.algo.Coord;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.rect.builders.TiledRect; import mightypork.gamecore.util.math.constraints.rect.builders.TiledRect;
import mightypork.rogue.world.level.MapAccess; import mightypork.rogue.world.level.LevelReadAccess;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
public abstract class MapRenderContext { public abstract class MapRenderContext {
protected final MapAccess map; protected final LevelReadAccess map;
protected final TiledRect tiler; protected final TiledRect tiler;
private final Rect mapRect; private final Rect mapRect;
public MapRenderContext(MapAccess map, Rect drawArea) public MapRenderContext(LevelReadAccess map, Rect drawArea)
{ {
this.map = map; this.map = map;
@ -35,7 +35,9 @@ public abstract class MapRenderContext {
return mapRect; return mapRect;
} }
public Tile getTile(Coord pos) {
public Tile getTile(Coord pos)
{
return map.getTile(pos); return map.getTile(pos);
} }
} }

@ -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.Rect;
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound; import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
import mightypork.gamecore.util.math.noise.NoiseGen; import mightypork.gamecore.util.math.noise.NoiseGen;
import mightypork.rogue.world.level.MapAccess; import mightypork.rogue.world.level.LevelReadAccess;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
@ -21,7 +21,7 @@ public final class TileRenderContext extends MapRenderContext implements RectBou
private final NoiseGen noise; private final NoiseGen noise;
public TileRenderContext(MapAccess map, Rect drawArea) public TileRenderContext(LevelReadAccess map, Rect drawArea)
{ {
super(map, drawArea); super(map, drawArea);

@ -16,9 +16,8 @@ public class DroppedItemRenderer {
// prepared constraints, to avoid re-building each frame // prepared constraints, to avoid re-building each frame
private final RectBoundAdapter tileRectAdapter = new RectBoundAdapter(); private final RectBoundAdapter tileRectAdapter = new RectBoundAdapter();
private final Rect itemRect = tileRectAdapter private final Rect itemRect = tileRectAdapter.shrink(tileRectAdapter.height().perc(10)).moveY(itemAnim.neg().mul(tileRectAdapter.height().mul(0.2)));
.shrink(tileRectAdapter.height().perc(10))
.moveY(itemAnim.neg().mul(tileRectAdapter.height().mul(0.2)));
public Animator getItemAnim() public Animator getItemAnim()
{ {

@ -12,7 +12,7 @@ import mightypork.gamecore.util.ion.IonOutput;
import mightypork.gamecore.util.math.color.Color; import mightypork.gamecore.util.math.color.Color;
import mightypork.rogue.world.World; import mightypork.rogue.world.World;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.LevelAccess;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
@ -35,6 +35,8 @@ public abstract class Tile implements IonObjBlob {
protected boolean occupied; protected boolean occupied;
protected boolean explored; protected boolean explored;
protected LevelAccess level;
private TileRenderer renderer; private TileRenderer renderer;
@ -46,6 +48,8 @@ public abstract class Tile implements IonObjBlob {
/** /**
* Render the tile, using the main texture sheet. * Render the tile, using the main texture sheet.
*
* @param context rendering ctx
*/ */
@DefaultImpl @DefaultImpl
public void renderTile(TileRenderContext context) public void renderTile(TileRenderContext context)
@ -56,8 +60,8 @@ public abstract class Tile implements IonObjBlob {
renderer = makeRenderer(); renderer = makeRenderer();
} }
if(renderer == null) { if (renderer == null) {
Log.w("No renderer for tile "+Log.str(this)); Log.w("No renderer for tile " + Log.str(this));
return; return;
} }
@ -147,7 +151,7 @@ public abstract class Tile implements IonObjBlob {
@DefaultImpl @DefaultImpl
public void update(Level level, double delta) public void update(double delta)
{ {
makeRenderer().update(delta); makeRenderer().update(delta);
} }
@ -226,9 +230,27 @@ public abstract class Tile implements IonObjBlob {
* @return true if the tile is interactive and did something. * @return true if the tile is interactive and did something.
*/ */
@DefaultImpl @DefaultImpl
public boolean onClick(World world) public boolean onClick()
{ {
return false; return false;
} }
public void setLevel(LevelAccess level)
{
this.level = level;
}
public LevelAccess getLevel()
{
return level;
}
protected World getWorld()
{
return level.getWorld();
}
} }

@ -8,7 +8,7 @@ import mightypork.gamecore.util.math.algo.Sides;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.renderers.NullTileRenderer; import mightypork.rogue.world.tile.render.NullTileRenderer;
/** /**

@ -1,4 +1,4 @@
package mightypork.rogue.world.tile.renderers; package mightypork.rogue.world.tile.render;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;

@ -1,4 +1,4 @@
package mightypork.rogue.world.tile.renderers; package mightypork.rogue.world.tile.render;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;

@ -1,4 +1,4 @@
package mightypork.rogue.world.tile.renderers; package mightypork.rogue.world.tile.render;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;

@ -2,7 +2,6 @@ package mightypork.rogue.world.tile.tiles;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
@ -26,7 +25,7 @@ public class NullTile extends Tile {
@Override @Override
public void update(Level level, double delta) public void update(double delta)
{ {
} }

@ -9,7 +9,7 @@ import mightypork.gamecore.util.ion.IonOutput;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileRenderer; import mightypork.rogue.world.tile.TileRenderer;
import mightypork.rogue.world.tile.TileType; import mightypork.rogue.world.tile.TileType;
import mightypork.rogue.world.tile.renderers.DoorTileRenderer; import mightypork.rogue.world.tile.render.DoorTileRenderer;
public abstract class TileBaseDoor extends TileSolid { public abstract class TileBaseDoor extends TileSolid {

@ -5,7 +5,7 @@ import mightypork.gamecore.resources.textures.TxSheet;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileRenderer; import mightypork.rogue.world.tile.TileRenderer;
import mightypork.rogue.world.tile.TileType; import mightypork.rogue.world.tile.TileType;
import mightypork.rogue.world.tile.renderers.BasicTileRenderer; import mightypork.rogue.world.tile.render.BasicTileRenderer;
public abstract class TileBaseFloor extends TileWithItems { public abstract class TileBaseFloor extends TileWithItems {

@ -5,7 +5,7 @@ import mightypork.gamecore.resources.textures.TxSheet;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileRenderer; import mightypork.rogue.world.tile.TileRenderer;
import mightypork.rogue.world.tile.TileType; import mightypork.rogue.world.tile.TileType;
import mightypork.rogue.world.tile.renderers.BasicTileRenderer; import mightypork.rogue.world.tile.render.BasicTileRenderer;
/** /**

@ -8,7 +8,6 @@ import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.gamecore.util.math.color.Color; import mightypork.gamecore.util.math.color.Color;
import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.color.pal.RGB;
import mightypork.rogue.world.World;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileType; import mightypork.rogue.world.tile.TileType;
@ -25,7 +24,7 @@ public abstract class TileBaseSecretDoor extends TileBaseDoor {
@Override @Override
public boolean onClick(World world) public boolean onClick()
{ {
if (!locked) return false; if (!locked) return false;

@ -4,7 +4,7 @@ package mightypork.rogue.world.tile.tiles;
import mightypork.gamecore.resources.textures.TxSheet; import mightypork.gamecore.resources.textures.TxSheet;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileType; import mightypork.rogue.world.tile.TileType;
import mightypork.rogue.world.tile.renderers.BasicTileRenderer; import mightypork.rogue.world.tile.render.BasicTileRenderer;
public abstract class TileBaseWall extends TileSolid { public abstract class TileBaseWall extends TileSolid {

@ -8,8 +8,6 @@ import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.item.Items; import mightypork.rogue.world.item.Items;
import mightypork.rogue.world.item.items.ItemMeat;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.DroppedItemRenderer; import mightypork.rogue.world.tile.DroppedItemRenderer;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
@ -39,9 +37,9 @@ public abstract class TileWithItems extends Tile {
@Override @Override
public void update(Level level, double delta) public void update(double delta)
{ {
super.update(level, delta); super.update(delta);
itemRenderer.update(delta); itemRenderer.update(delta);
} }

Loading…
Cancel
Save