125 lines
3.3 KiB
Java
Executable File
125 lines
3.3 KiB
Java
Executable File
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);
|
|
}
|
|
}
|
|
}
|