package projectzombie.display.lighting; import gl_engine.MathHelpers; import gl_engine.vec.Vec2i; import projectzombie.Main; import projectzombie.entity.Entity; import projectzombie.entity.player.EntityPlayer; import projectzombie.util.math.TileState; import projectzombie.world.chunk.Chunk; import projectzombie.world.chunk.ChunkEventHandler; import projectzombie.world.layer.Layer; public class DynamicLighting { public static int lightingMode = 0; public static void update() { if(!ChunkEventHandler.loaded) return; int r = Chunk.RENDER_DISTANCE; Layer layer = Main.world.getLayer(); EntityPlayer player = Main.player; // Copy every light source from the tile light sources for(int cx=-r;cx<=r;cx++) { for(int cy=-r;cy<=r;cy++) { // Get the chunk position and the chunk Chunk chunk = layer.chunks.get(new Vec2i( MathHelpers.floor(player.pos.x / 16) + cx, MathHelpers.floor(player.pos.y / 16) + cy)); // Loop over all the tiles for(int x=0;x<16;x++) { for(int y=0;y<16;y++) { // Reset the tiles light int id = new Vec2i(x, y).getId(Chunk.CHUNK_SIZE); chunk.setDynamicLightLevel(chunk.getLightLevel(id), id); } } } } // Loop over every entity to scan for light sources for(int cx=-r;cx<=r;cx++) { for(int cy=-r;cy<=r;cy++) { // Loop over all the entities Vec2i cpos = new Vec2i( cx + MathHelpers.floor(player.pos.x / 16), cy + MathHelpers.floor(player.pos.y / 16)); Chunk chunk = layer.chunks.get(cpos); // Create all the entity light sources for(Entity e : chunk.entities) { // Does this entity emit light if(e.emitsLight) { // Create some light addLightToTiles(layer, new Vec2i( MathHelpers.floor(e.pos.x), MathHelpers.floor(e.pos.y)), e.getLightLevel()); } } } } // Does the player emit light if(player.emitsLight) { addLightToTiles(layer, new Vec2i( MathHelpers.floor(player.pos.x), MathHelpers.floor(player.pos.y)), player.getLightLevel()); } } private static void addLightToTiles(Layer layer, Vec2i lpos, double light) { if( MathHelpers.floor(lpos.squareDistance(new Vec2i( MathHelpers.floor(Main.player.pos.x), MathHelpers.floor(Main.player.pos.y))) / 16) > Chunk.RENDER_DISTANCE) { return; } // Get the light pos id int lid = lpos.getId(Chunk.CHUNK_SIZE); // Get the light dissipation amount Chunk chunk = layer.getChunk(lpos); TileState bt = chunk.getBackTile(lid); TileState ft = chunk.getFrontTile(lid); double light_dissipation = MathHelpers.biggest( bt.tile.getLightDissipation(bt), ft.tile.getLightDissipation(ft)); // Calculate the light level double light_tile = chunk.getDynamicLightLevel(lid); if(light <= light_tile) { return; } // Merge the light and the light tile values chunk.setDynamicLightLevel(light, lid); // Get all the adjacent positions of the light tiles to flow onto Vec2i positions[] = { new Vec2i(lpos.x+1, lpos.y), new Vec2i(lpos.x-1, lpos.y), new Vec2i(lpos.x, lpos.y+1), new Vec2i(lpos.x, lpos.y-1) }; // Add the light to all the adjacent positions for(Vec2i position : positions) { addLightToTiles(layer, position, light - light_dissipation); } } }