From 66adc1ffa9bfbdbff869539d0336c61615309564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Fri, 9 May 2014 23:22:10 +0200 Subject: [PATCH] world eventization & pause evt --- res/img/tiles16.png | Bin 8928 -> 9012 bytes res/img/tiles16.xcf | Bin 22740 -> 22740 bytes .../gamecore/eventbus/EventBus.java | 18 ++++- .../rogue/screens/game/ScreenGame.java | 16 ++++- .../rogue/screens/game/WorldLayer.java | 4 +- src/mightypork/rogue/world/PlayerControl.java | 26 ++++---- src/mightypork/rogue/world/World.java | 60 +++++++++++++---- src/mightypork/rogue/world/WorldCreator.java | 6 +- src/mightypork/rogue/world/entity/Entity.java | 2 +- .../world/entity/entities/PlayerEntity.java | 11 +++- .../entity/modules/EntityModulePosition.java | 2 + .../world/events/PlayerStepEndEvent.java | 28 ++++++++ .../world/events/PlayerStepEndListener.java | 10 +++ .../rogue/world/events/WorldPauseRequest.java | 27 ++++++++ .../rogue/world/gen/LevelGenerator.java | 2 +- src/mightypork/rogue/world/gui/MapView.java | 59 +++++++---------- .../world/gui/interaction/MIPKeyboard.java | 32 +++++---- .../rogue/world/gui/interaction/MIPMouse.java | 62 ++++++++++-------- .../gui/interaction/MapInteractionPlugin.java | 21 ++++-- src/mightypork/rogue/world/level/Level.java | 35 +++++++++- src/mightypork/rogue/world/tile/Tile.java | 28 +++++--- .../rogue/world/tile/tiles/NullTile.java | 2 +- .../rogue/world/tile/tiles/TileWithItems.java | 4 +- 23 files changed, 318 insertions(+), 137 deletions(-) create mode 100644 src/mightypork/rogue/world/events/PlayerStepEndEvent.java create mode 100644 src/mightypork/rogue/world/events/PlayerStepEndListener.java create mode 100644 src/mightypork/rogue/world/events/WorldPauseRequest.java diff --git a/res/img/tiles16.png b/res/img/tiles16.png index 1304e197fc544158df62494fc3252a3f06a05d48..750df85c162c253169b4a9892cd6a53789bbb31e 100644 GIT binary patch delta 8944 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 delta 8860 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 Ls%dNGGHLo3a9uNV delta 2477 zcmc&#%}*Og6lYDS6xMv27{>-8yMX`+cF9LWqSTI2+hisgH8uhKx$78vy{sFr6DT>P z;C!e7VyAJtt`b>MTg0K_R>XhMzahsSa;S0%k*aXO2JH6D+61H?dx*65%sjpKX5Mdp z?>8@3nU||f*3PW1I5VEBSbq$(HgfHG?(pvTjk7r)8WC!3c)!ygMYyj9kR| z5KO>QiaYQDT#jQ6K3TK9lFicSBBX%{%^-V1I4jGdEW!weg6I)dgGMZ=hAr&CIF4&E zV@{Rh;IWzgP{&w%^3h+K)SXOjc{wL#m`o|ROiRd&NK$epNity=!LXeh2}?;PStPkI zOu$l-oa6v0OGHBegynRGMi(IsOlXFrFHADYq?D9k1VcgcNvc63l~ltPaS|etTEbXT zWeGesGau?0YjQn+Fq2l6mXuhUNtcu*T0+_-2#Ki#O7k#+VOw$WLV`&Yk;20SETxzo z9YEz6(jWj~X)#Tsi;xB;G(%#XN9jaDNC+^3p&*P4szD=^RKpgsBNRimh%zAt9-HY8 zb&NGvV^f1}5gFtIgJ>!w|dyl#e@{7{fOS%r7{wNw4p(Z`3rFkM=QrJBAkO_Gk8PekIG3 z=>2;Sp8uMbvas&yu~@aIP7O4i`PBBgMVF^;GAGKOAeOPuXXOHZ{1glwCS$+0t*wt8 zIC1QxsZ|8Obufz_0Y?HJ_qZ>FpU9kYqoe&Cw4Vbzy>O1A*&xAO&*+Q&Y;$w>K?`Hq zW)02sFzYH9d~hK%HF|UALGU-gVilq}9C8boo8YlLj=qfE=CH+Rva*NTy4l92qb$Rg z)lvY6$VDzPA;hrP>$@DCXI)v`f& z>hMk+JJ$Z_Jfzhv&q@3GZVMWCPGP!q5lHi9h9{~JT(1fNtWQ}P>qfJ+ujhEL%{JJf zBXqkYPpCe)-N}kPz}iA7FlZaJ0R;w+sBRn3@RD!Ig(ED%J2R9AzqTaB8l+6QEwnj z9w&Lp#F*YyXwcBWYE3N?L~l~5agt##>{_%Oo+M7C+;2EXE9d-=7H*Aw{mp&<5+Gq_ z%dsuvVpRnXUupZ$1`EG$-0Fc=2dCY=H9 z_B{#}U5&Zp5soa%yacr0fB&>zxDaVqZeyZY!9}M7w+3CkR@(yU_Q3)oTt{{!;#@m> zVwSzIG#lHeL0ceZU|`a8qKac>LU);K!yR< zX0=&+tya(j1i>31d@;KdA^4)8e+9ep*-(3GMp;@6UJZXcJNv`)M?yM1qW~EOX!ipd ztWI;QLN`uuLSig{;@Im6`hDmztUHWq^Y^gFPaONi)GC16I+%sA2nzehU85cjEx_8y z7*%%kuoZStzfG#acH|sIwJ8L8Ai&~3dO**-u0j*^Km1O1OSe=0UtqnL`(%MSnZLB`V~~H04WVB zU7`PP?Z`;QbB{%;8=zHvf?hBD^mO*>{6ZDJJr=!(uktWWOoseu{-z2aCDD*rwBXUILpw1zSuK74>gXSXI%-nd)_(?STK>mxXC)s|?lpC- J&7UV-{{mn|N`(Lb diff --git a/src/mightypork/gamecore/eventbus/EventBus.java b/src/mightypork/gamecore/eventbus/EventBus.java index 57b5497..b850e32 100644 --- a/src/mightypork/gamecore/eventbus/EventBus.java +++ b/src/mightypork/gamecore/eventbus/EventBus.java @@ -91,7 +91,11 @@ final public class EventBus implements Destroyable, BusAccess { } if (evt != null) { - dispatch(evt.getEvent()); + try { + dispatch(evt.getEvent()); + } catch (final Throwable t) { + Log.w(logMark + "Error while dispatching event: " + t); + } } } } @@ -137,6 +141,8 @@ final public class EventBus implements Destroyable, BusAccess { /** Messages queued for delivery */ private final DelayQueue sendQueue = new DelayQueue<>(); + private volatile boolean sendingDirect = false; + /** * Make a new bus and start it's queue thread. @@ -335,9 +341,19 @@ final public class EventBus implements Destroyable, BusAccess { { assertLive(); + if (sendingDirect) { + Log.w("Cannot send a direct event in response to another."); + sendQueued(event); + return; + } + + sendingDirect = true; + clients.setBuffering(true); doDispatch(clients, event); clients.setBuffering(false); + + sendingDirect = false; } diff --git a/src/mightypork/rogue/screens/game/ScreenGame.java b/src/mightypork/rogue/screens/game/ScreenGame.java index b10b742..626ea73 100644 --- a/src/mightypork/rogue/screens/game/ScreenGame.java +++ b/src/mightypork/rogue/screens/game/ScreenGame.java @@ -8,6 +8,7 @@ import mightypork.gamecore.gui.screens.LayeredScreen; import mightypork.gamecore.input.KeyStroke; import mightypork.gamecore.input.Keys; import mightypork.rogue.world.WorldProvider; +import mightypork.rogue.world.events.WorldPauseRequest; public class ScreenGame extends LayeredScreen { @@ -23,7 +24,7 @@ public class ScreenGame extends LayeredScreen { addLayer(new HudLayer(this)); addLayer(new WorldLayer(this)); - bindKey(new KeyStroke(Keys.N), new Runnable() { + bindKey(new KeyStroke(Keys.L_CONTROL, Keys.N), new Runnable() { @Override public void run() @@ -31,6 +32,19 @@ public class ScreenGame extends LayeredScreen { WorldProvider.get().createWorld(rand.nextLong()); } }); + + final Runnable pauseIt = new Runnable() { + + @Override + public void run() + { + getEventBus().send(new WorldPauseRequest()); + } + }; + + //pause key + bindKey(new KeyStroke(Keys.L_CONTROL, Keys.P), pauseIt); + bindKey(new KeyStroke(Keys.PAUSE), pauseIt); } diff --git a/src/mightypork/rogue/screens/game/WorldLayer.java b/src/mightypork/rogue/screens/game/WorldLayer.java index 35af5aa..aa2d67c 100644 --- a/src/mightypork/rogue/screens/game/WorldLayer.java +++ b/src/mightypork/rogue/screens/game/WorldLayer.java @@ -23,8 +23,8 @@ public class WorldLayer extends ScreenLayer { worldView = new MapView(); // map input plugins - worldView.addPlugin(new MIPKeyboard()); - worldView.addPlugin(new MIPMouse()); + worldView.addPlugin(new MIPKeyboard(worldView)); + worldView.addPlugin(new MIPMouse(worldView)); // size of lower navbar final Num lownav = root.width().min(root.height()).max(700).perc(7); diff --git a/src/mightypork/rogue/world/PlayerControl.java b/src/mightypork/rogue/world/PlayerControl.java index e0607d7..0f57c62 100644 --- a/src/mightypork/rogue/world/PlayerControl.java +++ b/src/mightypork/rogue/world/PlayerControl.java @@ -18,6 +18,11 @@ public abstract class PlayerControl { private World lastWorld; + /** + * Implementing classes should return a world instance from this method. + * + * @return + */ protected abstract World provideWorld(); @@ -25,12 +30,6 @@ public abstract class PlayerControl { { final World newWorld = provideWorld(); - if (newWorld != lastWorld) { - for (final EntityMoveListener eml : playerMoveListeners) { - newWorld.getPlayerEntity().pos.addMoveListener(eml); - } - } - lastWorld = newWorld; return newWorld; @@ -77,15 +76,6 @@ public abstract class PlayerControl { } - public void addMoveListener(EntityMoveListener eml) - { - playerMoveListeners.add(eml); - if (getPlayerEntity() != null) { - getPlayerEntity().pos.addMoveListener(eml); - } - } - - public LevelAccess getLevel() { return getWorld().getCurrentLevel(); @@ -104,6 +94,12 @@ public abstract class PlayerControl { } + /** + * Click tile on player's side + * + * @param side + * @return + */ public boolean clickTile(Step side) { return clickTile(getCoord().add(side)); diff --git a/src/mightypork/rogue/world/World.java b/src/mightypork/rogue/world/World.java index fdbea3f..1bdfc77 100644 --- a/src/mightypork/rogue/world/World.java +++ b/src/mightypork/rogue/world/World.java @@ -3,12 +3,15 @@ package mightypork.rogue.world; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import mightypork.gamecore.eventbus.BusAccess; import mightypork.gamecore.eventbus.EventBus; -import mightypork.gamecore.eventbus.events.Updateable; +import mightypork.gamecore.eventbus.clients.DelegatingClient; import mightypork.gamecore.util.ion.IonBundle; import mightypork.gamecore.util.ion.IonObjBundled; +import mightypork.gamecore.util.math.algo.Coord; +import mightypork.gamecore.util.math.timing.Pauseable; import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.level.Level; @@ -20,7 +23,7 @@ import mightypork.rogue.world.level.LevelAccess; * * @author MightyPork */ -public class World implements BusAccess, IonObjBundled, Updateable { +public class World implements DelegatingClient, BusAccess, IonObjBundled, Pauseable { private final ArrayList levels = new ArrayList<>(); @@ -35,6 +38,23 @@ public class World implements BusAccess, IonObjBundled, Updateable { /** Next entity ID */ private int eid; + private boolean paused; + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Collection getChildClients() + { + return levels; + } + + + @Override + public boolean doesDelegate() + { + return !paused; + } + @Override public void load(IonBundle in) throws IOException @@ -74,13 +94,6 @@ public class World implements BusAccess, IonObjBundled, Updateable { } - @Override - public void update(double delta) - { - getCurrentLevel().update(delta); - } - - public void setSeed(long seed) { this.seed = seed; @@ -117,8 +130,12 @@ public class World implements BusAccess, IonObjBundled, Updateable { } playerEntity = Entities.PLAYER.createEntity(playerEid); - floor.addEntity(playerEntity, floor.getEnterPoint()); - floor.explore(playerEntity.getCoord()); + + final Coord spawn = floor.getEnterPoint(); + + floor.forceFreeTile(spawn); + floor.addEntity(playerEntity, spawn); + floor.explore(spawn); playerInfo.setLevel(level); playerInfo.setEID(playerEid); @@ -155,4 +172,25 @@ public class World implements BusAccess, IonObjBundled, Updateable { return bus.getEventBus(); } + + @Override + public void pause() + { + paused = true; + } + + + @Override + public void resume() + { + paused = false; + } + + + @Override + public boolean isPaused() + { + return paused; + } + } diff --git a/src/mightypork/rogue/world/WorldCreator.java b/src/mightypork/rogue/world/WorldCreator.java index 9f405d3..d51b036 100644 --- a/src/mightypork/rogue/world/WorldCreator.java +++ b/src/mightypork/rogue/world/WorldCreator.java @@ -19,9 +19,9 @@ public class WorldCreator { final World w = new World(); w.setSeed(seed); - - for(int i=0; i<7; i++) { - Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME); + + for (int i = 0; i < 7; i++) { + final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME); w.addLevel(l); } diff --git a/src/mightypork/rogue/world/entity/Entity.java b/src/mightypork/rogue/world/entity/Entity.java index f00c966..0f1b2ee 100644 --- a/src/mightypork/rogue/world/entity/Entity.java +++ b/src/mightypork/rogue/world/entity/Entity.java @@ -23,7 +23,7 @@ import mightypork.rogue.world.level.render.MapRenderContext; /** - * World entity (mob or player) + * World entity (mob or player). Entities are attached to the event bus. * * @author MightyPork */ diff --git a/src/mightypork/rogue/world/entity/entities/PlayerEntity.java b/src/mightypork/rogue/world/entity/entities/PlayerEntity.java index aa7c725..c6f519c 100644 --- a/src/mightypork/rogue/world/entity/entities/PlayerEntity.java +++ b/src/mightypork/rogue/world/entity/entities/PlayerEntity.java @@ -12,6 +12,7 @@ import mightypork.rogue.world.entity.modules.EntityMoveListener; import mightypork.rogue.world.entity.render.EntityRenderer; import mightypork.rogue.world.entity.render.EntityRendererMobLR; import mightypork.rogue.world.events.PlayerKilledEvent; +import mightypork.rogue.world.events.PlayerStepEndEvent; public class PlayerEntity extends Entity { @@ -32,12 +33,14 @@ public class PlayerEntity extends Entity { public void onStepFinished() { entity.getLevel().explore(entity.pos.getCoord()); + fireEvt(); } @Override public void onPathFinished() { + fireEvt(); } @@ -47,6 +50,12 @@ public class PlayerEntity extends Entity { } + private void fireEvt() + { + getWorld().getEventBus().send(new PlayerStepEndEvent(PlayerEntity.this)); + } + + @Override public boolean isModuleSaved() { @@ -86,7 +95,7 @@ public class PlayerEntity extends Entity { } return super.getCost(from, to); - }; + } }; } diff --git a/src/mightypork/rogue/world/entity/modules/EntityModulePosition.java b/src/mightypork/rogue/world/entity/modules/EntityModulePosition.java index c09a396..c7a421f 100644 --- a/src/mightypork/rogue/world/entity/modules/EntityModulePosition.java +++ b/src/mightypork/rogue/world/entity/modules/EntityModulePosition.java @@ -184,6 +184,8 @@ public class EntityModulePosition extends EntityModule { /** * Add a move listener. If already present, do nothing. + * + * @param listener the listener */ public void addMoveListener(EntityMoveListener listener) { diff --git a/src/mightypork/rogue/world/events/PlayerStepEndEvent.java b/src/mightypork/rogue/world/events/PlayerStepEndEvent.java new file mode 100644 index 0000000..f07f5c5 --- /dev/null +++ b/src/mightypork/rogue/world/events/PlayerStepEndEvent.java @@ -0,0 +1,28 @@ +package mightypork.rogue.world.events; + + +import mightypork.gamecore.eventbus.BusEvent; +import mightypork.gamecore.eventbus.event_flags.UnloggedEvent; +import mightypork.rogue.world.entity.entities.PlayerEntity; + + +@UnloggedEvent +public class PlayerStepEndEvent extends BusEvent { + + private final PlayerEntity player; + + + public PlayerStepEndEvent(PlayerEntity player) + { + super(); + this.player = player; + } + + + @Override + protected void handleBy(PlayerStepEndListener handler) + { + handler.onStepFinished(player); + } + +} diff --git a/src/mightypork/rogue/world/events/PlayerStepEndListener.java b/src/mightypork/rogue/world/events/PlayerStepEndListener.java new file mode 100644 index 0000000..9ff97c3 --- /dev/null +++ b/src/mightypork/rogue/world/events/PlayerStepEndListener.java @@ -0,0 +1,10 @@ +package mightypork.rogue.world.events; + + +import mightypork.rogue.world.entity.entities.PlayerEntity; + + +public interface PlayerStepEndListener { + + void onStepFinished(PlayerEntity player); +} diff --git a/src/mightypork/rogue/world/events/WorldPauseRequest.java b/src/mightypork/rogue/world/events/WorldPauseRequest.java new file mode 100644 index 0000000..30980a5 --- /dev/null +++ b/src/mightypork/rogue/world/events/WorldPauseRequest.java @@ -0,0 +1,27 @@ +package mightypork.rogue.world.events; + + +import mightypork.gamecore.eventbus.BusEvent; +import mightypork.rogue.world.World; + + +/** + * Toggle world pause state + * + * @author MightyPork + */ +public class WorldPauseRequest extends BusEvent { + + + @Override + protected void handleBy(World handler) + { + // toggle paused state + if (!handler.isPaused()) { + handler.pause(); + } else { + handler.resume(); + } + } + +} diff --git a/src/mightypork/rogue/world/gen/LevelGenerator.java b/src/mightypork/rogue/world/gen/LevelGenerator.java index 22f1960..0442720 100644 --- a/src/mightypork/rogue/world/gen/LevelGenerator.java +++ b/src/mightypork/rogue/world/gen/LevelGenerator.java @@ -23,7 +23,7 @@ public class LevelGenerator { public static Level build(World world, long seed, int complexity, MapTheme theme) { - Log.f3("Generating level of complexity: "+complexity); + Log.f3("Generating level of complexity: " + complexity); final Random rand = new Random(seed + 13); diff --git a/src/mightypork/rogue/world/gui/MapView.java b/src/mightypork/rogue/world/gui/MapView.java index 2d81064..08e391b 100644 --- a/src/mightypork/rogue/world/gui/MapView.java +++ b/src/mightypork/rogue/world/gui/MapView.java @@ -1,9 +1,11 @@ package mightypork.rogue.world.gui; +import java.util.Collection; import java.util.LinkedHashSet; import java.util.Set; +import mightypork.gamecore.eventbus.clients.DelegatingClient; import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.gui.components.InputComponent; import mightypork.gamecore.input.Keys; @@ -19,7 +21,6 @@ import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.rogue.world.PlayerControl; import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.WorldRenderer; -import mightypork.rogue.world.entity.modules.EntityMoveListener; import mightypork.rogue.world.gui.interaction.MapInteractionPlugin; @@ -28,10 +29,10 @@ import mightypork.rogue.world.gui.interaction.MapInteractionPlugin; * * @author MightyPork */ -public class MapView extends InputComponent implements KeyListener, MouseButtonListener, EntityMoveListener, Updateable { +public class MapView extends InputComponent implements DelegatingClient, KeyListener, MouseButtonListener, Updateable { protected final WorldRenderer worldRenderer; - private final PlayerControl pc; + public final PlayerControl playerControl; private final Set plugins = new LinkedHashSet<>(); private final NumAnimated zoom = new NumAnimated(0, Easing.SINE_BOTH); @@ -40,12 +41,26 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL private final Num tileSize; + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Collection getChildClients() + { + return plugins; + } + + + @Override + public boolean doesDelegate() + { + return true; + } + + public MapView() { this.tileSize = height().min(width()).div(10).max(32).mul(Num.make(1).sub(zoom.mul(0.5))); this.worldRenderer = new WorldRenderer(this, tileSize); - pc = WorldProvider.get().getPlayerControl(); - pc.addMoveListener(this); + playerControl = WorldProvider.get().getPlayerControl(); zoom.setDefaultDuration(0.5); } @@ -70,40 +85,13 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL } - @Override - public void onStepFinished() - { - for (final MapInteractionPlugin p : plugins) { - if (p.onStepEnd(this, pc)) break; - } - } - - - @Override - public void onPathFinished() - { - for (final MapInteractionPlugin p : plugins) { - if (p.onStepEnd(this, pc)) break; - } - } - - - @Override - public void onPathInterrupted() - { - for (final MapInteractionPlugin p : plugins) { - if (p.onStepEnd(this, pc)) break; - } - } - - @Override public void receive(MouseButtonEvent event) { if (!event.isOver(this)) return; for (final MapInteractionPlugin p : plugins) { - if (p.onClick(this, pc, event.getPos(), event.getButton(), event.isDown())) { + if (p.onClick(event.getPos(), event.getButton(), event.isDown())) { event.consume(); break; } @@ -127,7 +115,7 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL public void receive(KeyEvent event) { for (final MapInteractionPlugin p : plugins) { - if (p.onKey(this, pc, event.getKey(), event.isDown())) break; + if (p.onKey(event.getKey(), event.isDown())) break; } if (event.getKey() == Keys.Z && event.isDown()) { @@ -158,9 +146,6 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL @Override public void update(double delta) { - for (final MapInteractionPlugin p : plugins) { - p.update(this, pc, delta); - } zoom.update(delta); } } diff --git a/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java b/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java index 6a40e32..f5b539d 100644 --- a/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java +++ b/src/mightypork/rogue/world/gui/interaction/MIPKeyboard.java @@ -6,38 +6,44 @@ import mightypork.gamecore.input.Keys; import mightypork.gamecore.util.math.algo.Sides; import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.constraints.vect.Vect; -import mightypork.rogue.world.PlayerControl; +import mightypork.rogue.world.entity.entities.PlayerEntity; import mightypork.rogue.world.gui.MapView; -public class MIPKeyboard implements MapInteractionPlugin { +public class MIPKeyboard extends MapInteractionPlugin { private static final int[] keys = { Keys.LEFT, Keys.RIGHT, Keys.UP, Keys.DOWN }; private static final Step[] sides = { Sides.W, Sides.E, Sides.N, Sides.S }; + public MIPKeyboard(MapView mapView) + { + super(mapView); + } + + @Override - public boolean onStepEnd(MapView view, PlayerControl player) + public void onStepFinished(PlayerEntity player) { - return walkByKey(player); + walkByKey(); } @Override - public boolean onClick(MapView view, PlayerControl player, Vect mouse, int button, boolean down) + public boolean onClick(Vect mouse, int button, boolean down) { return false; } @Override - public boolean onKey(MapView view, PlayerControl player, int key, boolean down) + public boolean onKey(int key, boolean down) { if (down) return false; // not interested for (int i = 0; i < 4; i++) { if (key == keys[i]) { - return player.clickTile(sides[i]); + return mapView.playerControl.clickTile(sides[i]); } } @@ -45,16 +51,16 @@ public class MIPKeyboard implements MapInteractionPlugin { } - private boolean walkByKey(PlayerControl pc) + private boolean walkByKey() { - if (pc.getPlayerEntity().pos.isMoving()) return false; + if (mapView.playerControl.getPlayerEntity().pos.isMoving()) return false; for (int i = 0; i < 4; i++) { if (InputSystem.isKeyDown(keys[i])) { final Step side = sides[i]; - if (pc.canGo(side)) { - pc.go(side); + if (mapView.playerControl.canGo(side)) { + mapView.playerControl.go(side); return true; } else { return false; @@ -66,8 +72,8 @@ public class MIPKeyboard implements MapInteractionPlugin { @Override - public void update(MapView mapView, PlayerControl pc, double delta) + public void update(double delta) { - walkByKey(pc); + walkByKey(); } } diff --git a/src/mightypork/rogue/world/gui/interaction/MIPMouse.java b/src/mightypork/rogue/world/gui/interaction/MIPMouse.java index 1621f31..d19f893 100644 --- a/src/mightypork/rogue/world/gui/interaction/MIPMouse.java +++ b/src/mightypork/rogue/world/gui/interaction/MIPMouse.java @@ -8,66 +8,72 @@ import mightypork.gamecore.util.math.Polar; import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Sides; import mightypork.gamecore.util.math.constraints.vect.Vect; -import mightypork.rogue.world.PlayerControl; +import mightypork.rogue.world.entity.entities.PlayerEntity; import mightypork.rogue.world.gui.MapView; import mightypork.rogue.world.tile.Tile; -public class MIPMouse implements MapInteractionPlugin { +public class MIPMouse extends MapInteractionPlugin { private static final int BTN = 0; // left + public MIPMouse(MapView mapView) + { + super(mapView); + } + + @Override - public void update(MapView view, PlayerControl pc, double delta) + public void update(double delta) { if (!InputSystem.isKeyDown(Keys.L_SHIFT)) return; final Vect pos = InputSystem.getMousePos(); if (InputSystem.isMouseButtonDown(BTN)) { - if (mouseWalk(view, pc, pos)) return; - if (troToNav(view, pc, pos)) return; + if (mouseWalk(pos)) return; + if (troToNav(pos)) return; } } @Override - public boolean onClick(MapView view, PlayerControl pc, Vect mouse, int button, boolean down) + public boolean onClick(Vect mouse, int button, boolean down) { if (button != BTN) return false; - final Coord pos = view.toWorldPos(mouse); - final Tile t = pc.getLevel().getTile(pos); + final Coord pos = mapView.toWorldPos(mouse); + final Tile t = mapView.playerControl.getLevel().getTile(pos); if (t.onClick()) return true; if (!down && t.isWalkable()) { - if (troToNav(view, pc, mouse)) return true; - return mouseWalk(view, pc, mouse); + if (troToNav(mouse)) return true; + return mouseWalk(mouse); } return false; } - private boolean troToNav(MapView view, PlayerControl pc, Vect mouse) + private boolean troToNav(Vect mouse) { - final Coord plpos = pc.getCoord(); - final Coord clicked = view.toWorldPos(mouse); + final Coord plpos = mapView.playerControl.getCoord(); + final Coord clicked = mapView.toWorldPos(mouse); if (clicked.equals(plpos)) return false; - final Tile t = pc.getLevel().getTile(clicked); + final Tile t = mapView.playerControl.getLevel().getTile(clicked); if (!t.isWalkable() || !t.isExplored()) return false; - pc.navigateTo(clicked); + mapView.playerControl.navigateTo(clicked); return true; } - private boolean mouseWalk(MapView view, PlayerControl pc, Vect pos) + private boolean mouseWalk(Vect pos) { - final Coord plpos = pc.getCoord(); - final Coord clicked = view.toWorldPos(pos); + final Coord plpos = mapView.playerControl.getCoord(); + final Coord clicked = mapView.toWorldPos(pos); if (clicked.equals(plpos)) return false; final Polar p = Polar.fromCoord(clicked.x - plpos.x, clicked.y - plpos.y); @@ -76,16 +82,16 @@ public class MIPMouse implements MapInteractionPlugin { switch (dir) { case 0: - return pc.tryGo(Sides.E); + return mapView.playerControl.tryGo(Sides.E); case 1: - return pc.tryGo(Sides.S); + return mapView.playerControl.tryGo(Sides.S); case 2: - return pc.tryGo(Sides.W); + return mapView.playerControl.tryGo(Sides.W); case 3: - return pc.tryGo(Sides.N); + return mapView.playerControl.tryGo(Sides.N); } return false; @@ -93,25 +99,23 @@ public class MIPMouse implements MapInteractionPlugin { @Override - public boolean onKey(MapView view, PlayerControl player, int key, boolean down) + public boolean onKey(int key, boolean down) { return false; } @Override - public boolean onStepEnd(MapView view, PlayerControl pc) + public void onStepFinished(PlayerEntity player) { - if (!InputSystem.isKeyDown(Keys.L_SHIFT)) return false; + if (!InputSystem.isKeyDown(Keys.L_SHIFT)) return; final Vect pos = InputSystem.getMousePos(); if (InputSystem.isMouseButtonDown(BTN)) { - if (mouseWalk(view, pc, pos)) return true; - if (troToNav(view, pc, pos)) return true; + if (mouseWalk(pos)) return; + if (troToNav(pos)) return; } - - return false; } } diff --git a/src/mightypork/rogue/world/gui/interaction/MapInteractionPlugin.java b/src/mightypork/rogue/world/gui/interaction/MapInteractionPlugin.java index 041d290..ceaa54d 100644 --- a/src/mightypork/rogue/world/gui/interaction/MapInteractionPlugin.java +++ b/src/mightypork/rogue/world/gui/interaction/MapInteractionPlugin.java @@ -1,22 +1,31 @@ package mightypork.rogue.world.gui.interaction; +import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.util.math.constraints.vect.Vect; -import mightypork.rogue.world.PlayerControl; +import mightypork.rogue.world.events.PlayerStepEndListener; import mightypork.rogue.world.gui.MapView; -public interface MapInteractionPlugin { +public abstract class MapInteractionPlugin implements Updateable, PlayerStepEndListener { - boolean onStepEnd(MapView mapView, PlayerControl player); + protected final MapView mapView; - boolean onClick(MapView mapView, PlayerControl player, Vect mouse, int button, boolean down); + public MapInteractionPlugin(MapView mapView) + { + super(); + this.mapView = mapView; + } - boolean onKey(MapView mapView, PlayerControl player, int key, boolean down); + public abstract boolean onClick(Vect mouse, int button, boolean down); - void update(MapView mapView, PlayerControl pc, double delta); + public abstract boolean onKey(int key, boolean down); + + + @Override + public abstract void update(double delta); } diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index 1bc9e9d..111f850 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -6,6 +6,8 @@ import java.util.*; import mightypork.gamecore.eventbus.BusAccess; import mightypork.gamecore.eventbus.EventBus; +import mightypork.gamecore.eventbus.clients.DelegatingClient; +import mightypork.gamecore.eventbus.clients.ToggleableClient; import mightypork.gamecore.logging.Log; import mightypork.gamecore.util.ion.IonBundle; import mightypork.gamecore.util.ion.IonInput; @@ -21,6 +23,7 @@ import mightypork.rogue.world.World; import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.EntityType; +import mightypork.rogue.world.entity.entities.PlayerEntity; import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.Tiles; @@ -31,7 +34,7 @@ import mightypork.rogue.world.tile.Tiles; * * @author MightyPork */ -public class Level implements BusAccess, LevelAccess, IonObjBinary { +public class Level implements BusAccess, DelegatingClient, ToggleableClient, LevelAccess, IonObjBinary { public static final int ION_MARK = 53; @@ -46,6 +49,8 @@ public class Level implements BusAccess, LevelAccess, IonObjBinary { private final Map entityMap = new HashMap<>(); private final Set entitySet = new HashSet<>(); + private int playerCount = 0; + /** Level seed (used for generation and tile variation) */ public long seed; @@ -201,14 +206,13 @@ public class Level implements BusAccess, LevelAccess, IonObjBinary { // 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(delta); + getTile(c).updateTile(delta); } } final List toRemove = new ArrayList<>(); for (final Entity e : entitySet) { - e.update(delta); if (e.isDead() && e.canRemoveCorpse()) toRemove.add(e); } @@ -249,6 +253,7 @@ public class Level implements BusAccess, LevelAccess, IonObjBinary { entityMap.put(entity.getEntityId(), entity); entitySet.add(entity); + if (entity instanceof PlayerEntity) playerCount++; // join to level & world entity.setLevel(this); @@ -271,6 +276,8 @@ public class Level implements BusAccess, LevelAccess, IonObjBinary { public void removeEntity(int eid) { final Entity removed = entityMap.remove(eid); + if (removed == null) throw new NullPointerException("No such entity in level: " + eid); + if (removed instanceof PlayerEntity) playerCount--; entitySet.remove(removed); freeTile(removed.getCoord()); } @@ -462,4 +469,26 @@ public class Level implements BusAccess, LevelAccess, IonObjBinary { { return world.getEventBus(); } + + + @Override + public boolean isListening() + { + return playerCount > 0; + } + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Collection getChildClients() + { + return entitySet; + } + + + @Override + public boolean doesDelegate() + { + return isListening(); + } } diff --git a/src/mightypork/rogue/world/tile/Tile.java b/src/mightypork/rogue/world/tile/Tile.java index 406ee4d..daeb817 100644 --- a/src/mightypork/rogue/world/tile/Tile.java +++ b/src/mightypork/rogue/world/tile/Tile.java @@ -56,14 +56,7 @@ public abstract class Tile implements IonObjBlob { { if (!isExplored()) return; - if (renderer == null) { - renderer = makeRenderer(); - } - - if (renderer == null) { - Log.w("No renderer for tile " + Log.str(this)); - return; - } + initRenderer(); renderer.renderTile(context); @@ -73,6 +66,20 @@ public abstract class Tile implements IonObjBlob { } + private void initRenderer() + { + if (renderer == null) { + renderer = makeRenderer(); + + if (renderer == /*still*/null) { + Log.w("No renderer for tile " + Log.str(this)); + renderer = TileRenderer.NONE; + return; + } + } + } + + protected abstract TileRenderer makeRenderer(); @@ -151,9 +158,10 @@ public abstract class Tile implements IonObjBlob { @DefaultImpl - public void update(double delta) + public void updateTile(double delta) { - makeRenderer().update(delta); + initRenderer(); + renderer.update(delta); } diff --git a/src/mightypork/rogue/world/tile/tiles/NullTile.java b/src/mightypork/rogue/world/tile/tiles/NullTile.java index 5d1241e..353004e 100644 --- a/src/mightypork/rogue/world/tile/tiles/NullTile.java +++ b/src/mightypork/rogue/world/tile/tiles/NullTile.java @@ -25,7 +25,7 @@ public class NullTile extends Tile { @Override - public void update(double delta) + public void updateTile(double delta) { } diff --git a/src/mightypork/rogue/world/tile/tiles/TileWithItems.java b/src/mightypork/rogue/world/tile/tiles/TileWithItems.java index 88c9e52..c3ba64d 100644 --- a/src/mightypork/rogue/world/tile/tiles/TileWithItems.java +++ b/src/mightypork/rogue/world/tile/tiles/TileWithItems.java @@ -37,9 +37,9 @@ public abstract class TileWithItems extends Tile { @Override - public void update(double delta) + public void updateTile(double delta) { - super.update(delta); + super.updateTile(delta); itemRenderer.update(delta); }