123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- package me.hammerle.supersnuvi.gamelogic;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.LinkedList;
- import java.util.function.Consumer;
- import me.hammerle.snuviscript.code.Script;
- import me.hammerle.supersnuvi.Game;
- import me.hammerle.supersnuvi.entity.Entity;
- import me.hammerle.supersnuvi.entity.EntityBuilder;
- import me.hammerle.supersnuvi.rendering.Light;
- import me.hammerle.supersnuvi.rendering.TileUpdater;
- import me.hammerle.supersnuvi.tiles.Tile;
- import me.hammerle.supersnuvi.util.Utils;
- public abstract class Level
- {
- // level data
- private final TileUpdater tileUpdater = new TileUpdater();
- // entity related
- private final HashMap<Integer, Entity> entities = new HashMap<>();
- private final LinkedList<Entity> spawnQueue = new LinkedList<>();
- private Entity hero = null;
- private int entityCounter = 0;
- // controlling
- private boolean shouldReset = false;
- private boolean done = false;
- // lighting
- private float red = 1.0f;
- private float green = 1.0f;
- private float blue = 1.0f;
- private final Light[] lights = new Light[32];
-
- public Level()
- {
- for(int i = 0; i < lights.length; i++)
- {
- lights[i] = new Light();
- }
- }
-
- // -------------------------------------------------------------------------
- // level data
- // -------------------------------------------------------------------------
-
- public abstract LevelData getData();
-
- public String getName()
- {
- return "Unknown";
- }
-
- public String getFileName()
- {
- return "Unknown";
- }
-
- public final TileUpdater getTileUpdater()
- {
- return tileUpdater;
- }
-
- // -------------------------------------------------------------------------
- // level stats
- // -------------------------------------------------------------------------
-
- public int getCurrentBottles()
- {
- return 0;
- }
-
- public int getMaxBottles()
- {
- return 0;
- }
-
- public void addBottles(int bottles)
- {
- }
-
- public float getTime()
- {
- return 0;
- }
-
- public void addMessage(String message)
- {
- }
-
- public String getMessage()
- {
- return null;
- }
-
- // -------------------------------------------------------------------------
- // entity related
- // -------------------------------------------------------------------------
-
- public final Entity getHero()
- {
- return hero;
- }
-
- public final void setHero(Entity hero)
- {
- this.hero = hero;
- }
-
- public final void removeEntities()
- {
- entities.clear();
- }
-
- public final void spawnEntity(Entity ent)
- {
- spawnQueue.add(ent);
- }
-
- public final void tickEntities()
- {
- entities.values().removeIf(ent ->
- {
- ent.tick(this);
- if((ent.getHealth().isDead() && !ent.isAnimated()) || (ent.getY() > getData().getHeight() * Tile.SIZE))
- {
- ent.onDespawn();
- callEvent("entity_despawn", (sc) ->
- {
- sc.setVar("entity", ent);
- }, null);
- return true;
- }
- return false;
- });
- entities.values().forEach(ent -> ent.tickCollision(this));
- int loops = 20;
- int changes = 1;
- while(changes > 0)
- {
- loops--;
- if(loops == 0)
- {
- System.out.println(System.nanoTime() + " Loop end reached ...");
- break;
- }
- changes = 0;
- for(Entity ent : entities.values())
- {
- changes += ent.move(this);
- }
- }
- if(!spawnQueue.isEmpty())
- {
- spawnQueue.forEach(ent ->
- {
- entities.put(entityCounter++, ent);
- callEvent("entity_spawn", (sc) ->
- {
- sc.setVar("entity", ent);
- }, null);
- });
- spawnQueue.clear();
- }
- }
-
- public final void forEachCollidingEntity(Entity ent, Consumer<Entity> c)
- {
- float minX = ent.getX() - Entity.STEP;
- float minY = ent.getY() - Entity.STEP;
- float maxX = ent.getX() + ent.getWidth() + Entity.STEP;
- float maxY = ent.getY() + ent.getHeight() + Entity.STEP;
- entities.values().stream().filter(other -> ent != other && other.isColliding(minX, minY, maxX, maxY)).forEach(c);
- }
-
- public final void forEachEntity(Consumer<Entity> c)
- {
- entities.values().forEach(c);
- }
-
- public final Collection<Entity> getEntities()
- {
- return entities.values();
- }
-
- public final Collection<Entity> getEntitiesInQueue()
- {
- return spawnQueue;
- }
-
- // -------------------------------------------------------------------------
- // controlling
- // -------------------------------------------------------------------------
-
- public abstract void tick();
-
- public final void finishLevel()
- {
- shouldReset = true;
- done = true;
- }
-
- public final boolean isFinished()
- {
- return done;
- }
-
- public final boolean shouldReset()
- {
- return shouldReset;
- }
-
- public final void scheduleReset()
- {
- shouldReset = true;
- }
-
- public final void reset()
- {
- // reset lights
- for(Light l : lights)
- {
- l.reset();
- }
-
- onReset();
- shouldReset = false;
- done = false;
-
- // spawn entities
- getData().forEachEntity((x, y, tile) ->
- {
- if(tile > 0)
- {
- Entity ent = EntityBuilder.fromId(tile, this, Utils.toCoord(x), Utils.toCoord(y));
- if(ent != null)
- {
- entities.put(entityCounter++, ent);
- }
- }
- }, 0, getData().getWidth(), 0, getData().getHeight());
- }
-
- protected void onReset()
- {
- };
-
- // -------------------------------------------------------------------------
- // collision
- // -------------------------------------------------------------------------
-
- public Tile getInteractionTile(int x, int y)
- {
- int i = getData().getInteractionTile(x, y);
- if(i == -1)
- {
- return Game.FALLBACK_TILE;
- }
- return Game.get().getTile(i);
- }
-
- // -------------------------------------------------------------------------
- // scripting
- // -------------------------------------------------------------------------
-
- public void callEvent(String name, Consumer<Script> before, Consumer<Script> after)
- {
- }
-
- public final void callEvent(String name)
- {
- callEvent(name, null, null);
- }
-
- // -------------------------------------------------------------------------
- // lighting
- // -------------------------------------------------------------------------
-
- public final void setAmbientLight(float r, float g, float b)
- {
- red = r;
- green = g;
- blue = b;
- }
-
- public final float getAmbientRed()
- {
- return red;
- }
-
- public final float getAmbientGreen()
- {
- return green;
- }
-
- public final float getAmbientBlue()
- {
- return blue;
- }
-
- public Light getLight(int index)
- {
- return lights[index];
- }
- }
|