+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. 6
      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. 28
      src/mightypork/rogue/world/entity/entities/PlayerEntity.java
  18. 4
      src/mightypork/rogue/world/entity/entities/RatEntity.java
  19. 2
      src/mightypork/rogue/world/entity/render/EntityRenderer.java
  20. 16
      src/mightypork/rogue/world/entity/render/EntityRendererMobLR.java
  21. 14
      src/mightypork/rogue/world/events/PlayerKilledEvent.java
  22. 7
      src/mightypork/rogue/world/events/PlayerKilledListener.java
  23. 11
      src/mightypork/rogue/world/gen/LevelGenerator.java
  24. 4
      src/mightypork/rogue/world/gen/ScratchMap.java
  25. 13
      src/mightypork/rogue/world/gui/MapView.java
  26. 4
      src/mightypork/rogue/world/gui/Minimap.java
  27. 2
      src/mightypork/rogue/world/gui/interaction/MIPMouse.java
  28. 6
      src/mightypork/rogue/world/item/Item.java
  29. 2
      src/mightypork/rogue/world/item/ItemModel.java
  30. 7
      src/mightypork/rogue/world/item/items/ItemMeat.java
  31. 8
      src/mightypork/rogue/world/item/render/QuadItemRenderer.java
  32. 116
      src/mightypork/rogue/world/level/Level.java
  33. 109
      src/mightypork/rogue/world/level/LevelAccess.java
  34. 127
      src/mightypork/rogue/world/level/LevelReadAccess.java
  35. 47
      src/mightypork/rogue/world/level/MapAccess.java
  36. 4
      src/mightypork/rogue/world/level/render/EntityRenderContext.java
  37. 10
      src/mightypork/rogue/world/level/render/MapRenderContext.java
  38. 4
      src/mightypork/rogue/world/level/render/TileRenderContext.java
  39. 5
      src/mightypork/rogue/world/tile/DroppedItemRenderer.java
  40. 28
      src/mightypork/rogue/world/tile/Tile.java
  41. 2
      src/mightypork/rogue/world/tile/TileRenderer.java
  42. 2
      src/mightypork/rogue/world/tile/render/BasicTileRenderer.java
  43. 2
      src/mightypork/rogue/world/tile/render/DoorTileRenderer.java
  44. 2
      src/mightypork/rogue/world/tile/render/NullTileRenderer.java
  45. 3
      src/mightypork/rogue/world/tile/tiles/NullTile.java
  46. 2
      src/mightypork/rogue/world/tile/tiles/TileBaseDoor.java
  47. 2
      src/mightypork/rogue/world/tile/tiles/TileBaseFloor.java
  48. 2
      src/mightypork/rogue/world/tile/tiles/TileBasePassage.java
  49. 3
      src/mightypork/rogue/world/tile/tiles/TileBaseSecretDoor.java
  50. 2
      src/mightypork/rogue/world/tile/tiles/TileBaseWall.java
  51. 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
*/
final public class EventBus implements Destroyable {
final public class EventBus implements Destroyable, BusAccess {
/**
* Queued event holder
@ -384,4 +384,11 @@ final public class EventBus implements Destroyable {
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 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()));
}
public Rect axisH()
{
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.test_bouncyboxes.ScreenTestBouncy;
import mightypork.rogue.world.WorldProvider;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level;

@ -15,8 +15,8 @@ public class HeartBar extends VisualComponent {
private final TxQuad img_on;
private final TxQuad img_off;
private final TxQuad img_half;
private Num total;
private Num active;
private final Num total;
private final Num active;
NumVar index = new NumVar(0);
Rect heart;
@ -63,7 +63,7 @@ public class HeartBar extends VisualComponent {
for (int i = 0; i < total.value(); 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));
}

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

@ -2,21 +2,16 @@ package mightypork.rogue.screens.menu;
import mightypork.gamecore.gui.Action;
import mightypork.gamecore.gui.AlignX;
import mightypork.gamecore.gui.components.layout.GridLayout;
import mightypork.gamecore.gui.components.painters.ImagePainter;
import mightypork.gamecore.gui.components.painters.QuadPainter;
import mightypork.gamecore.gui.components.painters.TextPainter;
import mightypork.gamecore.gui.events.CrossfadeRequest;
import mightypork.gamecore.gui.screens.Screen;
import mightypork.gamecore.gui.screens.ScreenLayer;
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.RGB;
import mightypork.gamecore.util.math.constraints.num.Num;
import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.vect.Vect;
import mightypork.rogue.Res;
@ -44,7 +39,7 @@ class MenuLayer extends ScreenLayer {
root.add(layout);
int r = 0;
ImagePainter ip = new ImagePainter(Res.getTxQuad("logo"));
final ImagePainter ip = new ImagePainter(Res.getTxQuad("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.Level;
import mightypork.rogue.world.level.LevelAccess;
public abstract class PlayerControl {
@ -35,7 +35,7 @@ public abstract class PlayerControl {
return newWorld;
};
}
public Entity getPlayerEntity()
@ -86,7 +86,7 @@ public abstract class PlayerControl {
}
public Level getLevel()
public LevelAccess getLevel()
{
return getWorld().getCurrentLevel();
}
@ -114,7 +114,7 @@ public abstract class PlayerControl {
{
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.util.ArrayList;
import mightypork.gamecore.eventbus.BusAccess;
import mightypork.gamecore.eventbus.EventBus;
import mightypork.gamecore.eventbus.events.Updateable;
import mightypork.gamecore.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonObjBundled;
import mightypork.rogue.world.entity.Entities;
import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.LevelAccess;
/**
@ -17,13 +20,15 @@ import mightypork.rogue.world.level.Level;
*
* @author MightyPork
*/
public class World implements IonObjBundled, Updateable {
public class World implements BusAccess, IonObjBundled, Updateable {
private final ArrayList<Level> levels = new ArrayList<>();
private final PlayerInfo playerInfo = new PlayerInfo();
private Entity playerEntity;
private BusAccess bus;
/** World seed */
private long seed;
@ -34,8 +39,8 @@ public class World implements IonObjBundled, Updateable {
@Override
public void load(IonBundle in) throws IOException
{
seed = in.get("seed", 0L);
eid = in.get("next_eid", 0);
seed = in.get("seed", seed);
eid = in.get("next_eid", eid);
in.loadSequence("levels", levels);
// join levels to world
@ -46,7 +51,9 @@ public class World implements IonObjBundled, Updateable {
in.loadBundled("player", playerInfo);
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
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.setCoord(levels.get(level).getEnterPoint());
levels.get(level).addEntity(playerEntity);
floor.addEntity(playerEntity, floor.getEnterPoint());
floor.explore(playerEntity.getCoord());
playerInfo.setLevel(level);
playerInfo.setEID(playerEid);
}
public Level getCurrentLevel()
public LevelAccess getCurrentLevel()
{
return levels.get(playerInfo.getLevel());
}
@ -124,4 +136,23 @@ public class World implements IonObjBundled, Updateable {
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();
w.setSeed(seed);
Level l;
// TODO real algorithm
// first level
l = LevelGenerator.build(w, rand.nextLong(), 1, LevelGenerator.DUNGEON_THEME); //
for(int i=0; i<7; i++) {
Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME);
w.addLevel(l);
}
w.createPlayer(0);

@ -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.Level;
import mightypork.rogue.world.level.LevelAccess;
public class WorldProvider extends RootBusNode {
@ -67,6 +67,7 @@ public class WorldProvider extends RootBusNode {
if (world != null) removeChildClient(world);
world = newWorld;
world.assignBus(this); // connect to bus (for event dispatching)
addChildClient(world);
}
@ -84,7 +85,7 @@ public class WorldProvider extends RootBusNode {
}
public Level getCurrentLevel()
public LevelAccess 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.Level;
import mightypork.rogue.world.level.LevelAccess;
import mightypork.rogue.world.level.render.TileRenderContext;
@ -29,7 +29,7 @@ public class WorldRenderer extends RectProxy {
// can be changed
private RectConst mapRect;
private Level activeLevel;
private LevelAccess activeLevel;
private final Rect rightShadow;
private final Rect leftShadow;
@ -57,7 +57,7 @@ public class WorldRenderer extends RectProxy {
private void prepareRenderContextIfNeeded()
{
final Level level = WorldProvider.get().getCurrentLevel();
final LevelAccess level = WorldProvider.get().getCurrentLevel();
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.entity.modules.EntityModuleHealth;
import mightypork.rogue.world.entity.modules.EntityModulePosition;
import mightypork.rogue.world.entity.renderers.EntityRenderer;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.level.LevelAccess;
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 Level level;
private LevelAccess 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(Level level)
public void setLevel(LevelAccess level)
{
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;
}
@ -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>
* 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)
{
this.despawnDelay = despawnDelay;
}
public double getDespawnDelay()
{
return despawnDelay;
}
}

@ -9,9 +9,9 @@ import mightypork.rogue.world.entity.EntityModule;
import mightypork.rogue.world.entity.EntityPathFinder;
import mightypork.rogue.world.entity.EntityType;
import mightypork.rogue.world.entity.modules.EntityMoveListener;
import mightypork.rogue.world.entity.renderers.EntityRenderer;
import mightypork.rogue.world.entity.renderers.EntityRendererMobLR;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.entity.render.EntityRendererMobLR;
import mightypork.rogue.world.events.PlayerKilledEvent;
public class PlayerEntity extends Entity {
@ -82,7 +82,7 @@ public class PlayerEntity extends Entity {
public int getCost(Coord from, Coord to)
{
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);
@ -94,14 +94,6 @@ public class PlayerEntity extends Entity {
}
@Override
public void setLevel(Level level)
{
super.setLevel(level);
ai.onStepFinished(); // explore start area
}
@Override
protected EntityRenderer getRenderer()
{
@ -119,9 +111,11 @@ public class PlayerEntity extends Entity {
return EntityType.PLAYER;
}
// @Override
// public void receiveAttack(Entity attacker, int attackStrength)
// {
// // FIXME ignore attack
// }
@Override
public void onKilled()
{
// 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.EntityPathFinder;
import mightypork.rogue.world.entity.EntityType;
import mightypork.rogue.world.entity.renderers.EntityRenderer;
import mightypork.rogue.world.entity.renderers.EntityRendererMobLR;
import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.entity.render.EntityRendererMobLR;
public class RatEntity extends Entity {

@ -1,4 +1,4 @@
package mightypork.rogue.world.entity.renderers;
package mightypork.rogue.world.entity.render;
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.resources.textures.TxQuad;
import mightypork.gamecore.resources.textures.TxSheet;
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.pal.RGB;
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.rect.Rect;
import mightypork.gamecore.util.math.constraints.vect.Vect;
@ -31,9 +27,9 @@ public class EntityRendererMobLR extends EntityRenderer {
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)
@ -46,7 +42,7 @@ public class EntityRendererMobLR extends EntityRenderer {
@Override
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()));
@ -56,7 +52,7 @@ public class EntityRendererMobLR extends EntityRenderer {
final double w = tileRect.width().value();
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);
@ -72,7 +68,7 @@ public class EntityRendererMobLR extends EntityRenderer {
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.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 mightypork.gamecore.logging.Log;
import mightypork.gamecore.util.math.algo.Coord;
import mightypork.rogue.world.World;
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)
{
Log.f3("Generating level of complexity: "+complexity);
final Random rand = new Random(seed + 13);
final int max_size = 128;
@ -31,7 +34,7 @@ public class LevelGenerator {
// start
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);
if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET);
if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END);
@ -48,7 +51,7 @@ public class LevelGenerator {
// spawn rats
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);
@ -62,13 +65,13 @@ public class LevelGenerator {
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++) {
pos.x = rand.nextInt(lvl.getWidth());
pos.y = rand.nextInt(lvl.getHeight());
Tile t = lvl.getTile(pos);
final Tile t = lvl.getTile(pos);
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.pathfinding.Heuristic;
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.TileModel;
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.
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 NumAnimated zoom = new NumAnimated(0, Easing.SINE_BOTH);
private boolean zoom_in = true;
private final Num tileSize;
@ -112,9 +113,11 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL
final int delta = event.getWheelDelta();
if (!zoom.isFinished()) return;
if (delta < 0) {
zoom.fadeOut();
} else {
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 (event.getKey() == Keys.Z) {
if (event.isDown()) {
if (event.getKey() == Keys.Z && event.isDown()) {
if (zoom_in) {
zoom.fadeIn();
zoom_in = false;
} else {
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.rogue.world.WorldProvider;
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 org.lwjgl.opengl.GL11;
@ -33,7 +33,7 @@ public class Minimap extends InputComponent implements MouseButtonListener {
{
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);
final Entity e = WorldProvider.get().getPlayerEntity();

@ -39,7 +39,7 @@ public class MIPMouse implements MapInteractionPlugin {
final Coord pos = view.toWorldPos(mouse);
final Tile t = pc.getLevel().getTile(pos);
if (t.onClick(pc.getWorld())) return true;
if (t.onClick()) return true;
if (!down && t.isWalkable()) {
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.IonOutput;
import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
public abstract class Item implements IonObjBlob {
@ -17,7 +16,8 @@ public abstract class Item implements IonObjBlob {
private ItemRenderer renderer;
public Item(ItemModel model) {
public Item(ItemModel model)
{
this.model = model;
}
@ -29,7 +29,7 @@ public abstract class Item implements IonObjBlob {
}
renderer.render(rect);
};
}
protected abstract ItemRenderer makeRenderer();

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

@ -1,18 +1,21 @@
package mightypork.rogue.world.item.items;
import mightypork.rogue.Res;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.item.ItemModel;
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 ItemMeat(ItemModel model) {
public ItemMeat(ItemModel model)
{
super(model);
}
@Override
protected ItemRenderer makeRenderer()
{

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

@ -4,8 +4,8 @@ package mightypork.rogue.world.level;
import java.io.IOException;
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.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonInput;
@ -31,7 +31,7 @@ import mightypork.rogue.world.tile.Tiles;
*
* @author MightyPork
*/
public class Level implements MapAccess, IonObjBinary {
public class Level implements BusAccess, LevelAccess, IonObjBinary {
public static final int ION_MARK = 53;
@ -70,12 +70,7 @@ public class Level implements MapAccess, IonObjBinary {
}
public void fill(short id)
{
fill(Tiles.get(id));
}
@Override
public void fill(TileModel model)
{
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)
{
setTile(pos, model.createTile());
}
public final void setTile(Coord pos, int tileId)
{
setTile(pos, Tiles.create(tileId));
}
@Override
public final void setTile(Coord pos, Tile tile)
{
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;
// 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)
{
this.seed = seed;
@ -207,23 +195,24 @@ public class Level implements MapAccess, IonObjBinary {
}
@Override
public void update(double delta)
{
// just update them all
for (final Coord c = Coord.zero(); c.x < size.x; c.x++) {
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) {
e.update(delta);
if (e.isDead() && e.canRemoveCorpse()) toRemove.add(e);
}
for (Entity e : toRemove) {
for (final Entity e : toRemove) {
removeEntity(e);
}
}
@ -240,37 +229,22 @@ public class Level implements MapAccess, IonObjBinary {
}
@Override
public Entity getEntity(int eid)
{
return entityMap.get(eid);
}
/**
* Try to add entity at given pos
*
* @param entity the entity
* @param pos pos
* @return true if added (false if void, wall etc)
*/
@Override
public boolean addEntity(Entity entity, Coord pos)
{
final Tile t = getTile(pos);
if (!t.isWalkable() || isOccupied(pos)) return false;
addEntity(entity);
entity.setCoord(pos);
return true;
}
if (!t.isWalkable() || t.isOccupied()) return false;
public void addEntity(Entity entity)
{
if (entityMap.containsKey(entity.getEntityId())) {
Log.w("Entity already in level.");
return;
return false;
}
entityMap.put(entity.getEntityId(), entity);
@ -279,15 +253,21 @@ public class Level implements MapAccess, IonObjBinary {
// join to level & world
entity.setLevel(this);
occupyTile(entity.getCoord());
entity.setCoord(pos);
return true;
}
@Override
public void removeEntity(Entity entity)
{
removeEntity(entity.getEntityId());
}
@Override
public void removeEntity(int eid)
{
final Entity removed = entityMap.remove(eid);
@ -296,6 +276,7 @@ public class Level implements MapAccess, IonObjBinary {
}
@Override
public boolean isWalkable(Coord pos)
{
final Tile t = getTile(pos);
@ -307,6 +288,7 @@ public class Level implements MapAccess, IonObjBinary {
/**
* Mark tile as occupied by an entity
*/
@Override
public void occupyTile(Coord pos)
{
getTile(pos).setOccupied(true);
@ -316,52 +298,56 @@ public class Level implements MapAccess, IonObjBinary {
/**
* Mark tile as free (no longet occupied)
*/
@Override
public void freeTile(Coord pos)
{
getTile(pos).setOccupied(false);
}
/**
* @param pos tile coord
* @return true if something is standing there.
*/
@Override
public boolean isOccupied(Coord pos)
{
return getTile(pos).isOccupied();
}
@Override
public Collection<Entity> getEntities()
{
return entitySet;
}
@Override
public void setEnterPoint(Coord pos)
{
this.enterPoint.setTo(pos);
}
@Override
public Coord getEnterPoint()
{
return enterPoint;
}
@Override
public World getWorld()
{
return world;
}
@Override
public void setWorld(World world)
{
this.world = world;
}
@Override
public void explore(Coord center)
{
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)
{
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)
{
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.rogue.world.level.MapAccess;
import mightypork.rogue.world.level.LevelReadAccess;
public class EntityRenderContext extends MapRenderContext {
public EntityRenderContext(MapAccess map, Rect drawArea)
public EntityRenderContext(LevelReadAccess 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.MapAccess;
import mightypork.rogue.world.level.LevelReadAccess;
import mightypork.rogue.world.tile.Tile;
public abstract class MapRenderContext {
protected final MapAccess map;
protected final LevelReadAccess map;
protected final TiledRect tiler;
private final Rect mapRect;
public MapRenderContext(MapAccess map, Rect drawArea)
public MapRenderContext(LevelReadAccess map, Rect drawArea)
{
this.map = map;
@ -35,7 +35,9 @@ public abstract class MapRenderContext {
return mapRect;
}
public Tile getTile(Coord pos) {
public Tile getTile(Coord 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.proxy.RectBound;
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;
@ -21,7 +21,7 @@ public final class TileRenderContext extends MapRenderContext implements RectBou
private final NoiseGen noise;
public TileRenderContext(MapAccess map, Rect drawArea)
public TileRenderContext(LevelReadAccess map, Rect drawArea)
{
super(map, drawArea);

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

@ -12,7 +12,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.Level;
import mightypork.rogue.world.level.LevelAccess;
import mightypork.rogue.world.level.render.TileRenderContext;
@ -35,6 +35,8 @@ public abstract class Tile implements IonObjBlob {
protected boolean occupied;
protected boolean explored;
protected LevelAccess level;
private TileRenderer renderer;
@ -46,6 +48,8 @@ public abstract class Tile implements IonObjBlob {
/**
* Render the tile, using the main texture sheet.
*
* @param context rendering ctx
*/
@DefaultImpl
public void renderTile(TileRenderContext context)
@ -147,7 +151,7 @@ public abstract class Tile implements IonObjBlob {
@DefaultImpl
public void update(Level level, double delta)
public void update(double delta)
{
makeRenderer().update(delta);
}
@ -226,9 +230,27 @@ public abstract class Tile implements IonObjBlob {
* @return true if the tile is interactive and did something.
*/
@DefaultImpl
public boolean onClick(World world)
public boolean onClick()
{
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.rogue.Res;
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;

@ -1,4 +1,4 @@
package mightypork.rogue.world.tile.renderers;
package mightypork.rogue.world.tile.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;

@ -2,7 +2,6 @@ package mightypork.rogue.world.tile.tiles;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel;
@ -26,7 +25,7 @@ public class NullTile extends Tile {
@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.TileRenderer;
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 {

@ -5,7 +5,7 @@ import mightypork.gamecore.resources.textures.TxSheet;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileRenderer;
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 {

@ -5,7 +5,7 @@ import mightypork.gamecore.resources.textures.TxSheet;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileRenderer;
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.math.color.Color;
import mightypork.gamecore.util.math.color.pal.RGB;
import mightypork.rogue.world.World;
import mightypork.rogue.world.tile.TileModel;
import mightypork.rogue.world.tile.TileType;
@ -25,7 +24,7 @@ public abstract class TileBaseSecretDoor extends TileBaseDoor {
@Override
public boolean onClick(World world)
public boolean onClick()
{
if (!locked) return false;

@ -4,7 +4,7 @@ package mightypork.rogue.world.tile.tiles;
import mightypork.gamecore.resources.textures.TxSheet;
import mightypork.rogue.world.tile.TileModel;
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 {

@ -8,8 +8,6 @@ import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonOutput;
import mightypork.rogue.world.item.Item;
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.tile.DroppedItemRenderer;
import mightypork.rogue.world.tile.Tile;
@ -39,9 +37,9 @@ public abstract class TileWithItems extends Tile {
@Override
public void update(Level level, double delta)
public void update(double delta)
{
super.update(level, delta);
super.update(delta);
itemRenderer.update(delta);
}

Loading…
Cancel
Save