262 lines
6.5 KiB
Java
262 lines
6.5 KiB
Java
package shootergame.world.chunk;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Random;
|
|
|
|
import shootergame.display.Camera;
|
|
import shootergame.entity.Entity;
|
|
import shootergame.entity.EntityAlive;
|
|
import shootergame.entity.particle.ParticleBreak;
|
|
import shootergame.init.Tiles;
|
|
import shootergame.tiles.Tile;
|
|
import shootergame.util.math.MathHelpers;
|
|
import shootergame.util.math.TileState;
|
|
import shootergame.util.math.range.Range2i;
|
|
import shootergame.util.math.vec.Vec2d;
|
|
import shootergame.util.math.vec.Vec2i;
|
|
import shootergame.world.layer.Layer;
|
|
|
|
public class Chunk
|
|
{
|
|
public static final Range2i CHUNK_SIZE = new Range2i(16, 16);
|
|
public static final Chunk CHUNK_EMPTY = new ChunkEmpty();
|
|
public static final int CHUNK_INDEX = CHUNK_SIZE.mx * CHUNK_SIZE.my;
|
|
public static final int SIMULATION_DISTANCE = 5;
|
|
|
|
private Tile tiles_back[] = new Tile[CHUNK_INDEX];
|
|
private Tile tiles_front[] = new Tile[CHUNK_INDEX];
|
|
private byte tiles_front_meta[] = new byte[CHUNK_INDEX];
|
|
private byte tiles_back_meta[] = new byte[CHUNK_INDEX];
|
|
private byte tiles_lighting_r[] = new byte[CHUNK_INDEX];
|
|
private byte tiles_lighting_g[] = new byte[CHUNK_INDEX];
|
|
private byte tiles_lighting_b[] = new byte[CHUNK_INDEX];
|
|
public ArrayList<Entity> entities = new ArrayList<Entity>();
|
|
private Layer layer;
|
|
private Vec2i c_pos;
|
|
|
|
public Chunk(Layer layer, Vec2i c_pos, Random rand)
|
|
{
|
|
// Set some specified values
|
|
this.layer = layer;
|
|
this.c_pos = c_pos;
|
|
|
|
// Loop over all the tiles in the chunk
|
|
for(int i=0;i<CHUNK_INDEX;i++)
|
|
{
|
|
// Make all these tiles void
|
|
tiles_back[i] = Tiles.VOID;
|
|
tiles_front[i] = Tiles.VOID;
|
|
tiles_back_meta[i] = 0;
|
|
tiles_front_meta[i] = 0;
|
|
tiles_lighting_b[i] = 0;
|
|
tiles_lighting_g[i] = 0;
|
|
tiles_lighting_r[i] = 0;
|
|
}
|
|
}
|
|
|
|
public void render(Camera camera)
|
|
{
|
|
// Loop over all the tiles
|
|
for(int i=0;i<CHUNK_INDEX;i++)
|
|
{
|
|
// Get the tile pos
|
|
Vec2i t_pos = Vec2i.fromId(CHUNK_SIZE, i);
|
|
|
|
// Render the tiles
|
|
TileState tsb = getBackTile(i);
|
|
TileState tsf = getFrontTile(i);
|
|
tiles_back[i].doRender(new Vec2d(t_pos.x + c_pos.x * 16, t_pos.y + c_pos.y * 16), camera, tsb);
|
|
tiles_front[i].doRender(new Vec2d(t_pos.x + c_pos.x * 16, t_pos.y + c_pos.y * 16), camera, tsf);
|
|
}
|
|
|
|
// Render all the entities
|
|
for(int i=0;i<entities.size();i++) {
|
|
Entity e = entities.get(i);
|
|
e.doRender(e.pos, camera);
|
|
}
|
|
}
|
|
|
|
public void spawnEntity(Entity e) {
|
|
e.chunk = this;
|
|
entities.add(e);
|
|
}
|
|
|
|
public void tickEntities()
|
|
{
|
|
// Loop over every entitiy
|
|
for(int i=0;i<entities.size();i++)
|
|
{
|
|
// Get the entity and tick it
|
|
Entity e = entities.get(i);
|
|
e.tick(this, layer);
|
|
}
|
|
}
|
|
|
|
public void checkEntities()
|
|
{
|
|
// Loop over every entity
|
|
for(int i=0;i<entities.size();i++)
|
|
{
|
|
// Get the entitiy
|
|
Entity e = entities.get(i);
|
|
|
|
// is this entity alive
|
|
if(e instanceof EntityAlive)
|
|
{
|
|
// Get the alive entity
|
|
EntityAlive ea = (EntityAlive)e;
|
|
|
|
// Kill the entity if it should be dead and continue to the next loop iteration
|
|
if(ea.getHealth() < 0) {
|
|
entities.remove(i);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Has the entity left the chunk
|
|
int cx = c_pos.x * CHUNK_SIZE.mx;
|
|
int cy = c_pos.y * CHUNK_SIZE.my;
|
|
double px = e.pos.x;
|
|
double py = e.pos.y;
|
|
if(px > cx + CHUNK_SIZE.mx || px < cx || py > cy + CHUNK_SIZE.my || py < cy)
|
|
{
|
|
// Process the entity by layer and remove the entity from the array
|
|
layer.spawnEntity(e);
|
|
entities.remove(i);
|
|
i -= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setBackTile(TileState tile, Vec2i pos)
|
|
{
|
|
// Get the id
|
|
Vec2i cpos = new Vec2i(0, 0);
|
|
cpos.x = MathHelpers.mod(pos.x, CHUNK_SIZE.mx);
|
|
cpos.y = MathHelpers.mod(pos.y, CHUNK_SIZE.my);
|
|
int id = cpos.getId(CHUNK_SIZE);
|
|
|
|
setBackTile(tile, id);
|
|
}
|
|
|
|
public void setBackTile(TileState tile, int id)
|
|
{
|
|
// Set the back tile
|
|
this.tiles_back[id] = tile.tile;
|
|
this.tiles_back_meta[id] = tile.meta;
|
|
}
|
|
|
|
public void setFrontTile(TileState tile, Vec2i pos)
|
|
{
|
|
// Get the id
|
|
Vec2i cpos = new Vec2i(0, 0);
|
|
cpos.x = MathHelpers.mod(pos.x, CHUNK_SIZE.mx);
|
|
cpos.y = MathHelpers.mod(pos.y, CHUNK_SIZE.my);
|
|
int id = cpos.getId(CHUNK_SIZE);
|
|
|
|
setFrontTile(tile, id);
|
|
}
|
|
|
|
public void setFrontTile(TileState tile, int id)
|
|
{
|
|
// Set the front tile
|
|
this.tiles_front[id] = tile.tile;
|
|
this.tiles_front_meta[id] = tile.meta;
|
|
}
|
|
|
|
public TileState getBackTile(Vec2i pos)
|
|
{
|
|
// Get the id
|
|
Vec2i cpos = new Vec2i(0, 0);
|
|
cpos.x = MathHelpers.mod(pos.x, CHUNK_SIZE.mx);
|
|
cpos.y = MathHelpers.mod(pos.y, CHUNK_SIZE.my);
|
|
int id = cpos.getId(CHUNK_SIZE);
|
|
|
|
return getBackTile(id);
|
|
}
|
|
|
|
public TileState getBackTile(int id)
|
|
{
|
|
// Send back the back tile
|
|
TileState ts = new TileState(this.tiles_back[id], this.tiles_back_meta[id]);
|
|
ts.light.x = this.tiles_lighting_r[id];
|
|
ts.light.y = this.tiles_lighting_g[id];
|
|
ts.light.z = this.tiles_lighting_b[id];
|
|
return ts;
|
|
}
|
|
|
|
public TileState getFrontTile(Vec2i pos)
|
|
{
|
|
// Get the id
|
|
Vec2i cpos = new Vec2i(0, 0);
|
|
cpos.x = MathHelpers.mod(pos.x, CHUNK_SIZE.mx);
|
|
cpos.y = MathHelpers.mod(pos.y, CHUNK_SIZE.my);
|
|
int id = cpos.getId(CHUNK_SIZE);
|
|
|
|
return getFrontTile(id);
|
|
}
|
|
|
|
public TileState getFrontTile(int id)
|
|
{
|
|
// Send back the front tile
|
|
TileState ts = new TileState(this.tiles_front[id], this.tiles_front_meta[id]);
|
|
ts.light.x = this.tiles_lighting_r[id];
|
|
ts.light.y = this.tiles_lighting_g[id];
|
|
ts.light.z = this.tiles_lighting_b[id];
|
|
return ts;
|
|
}
|
|
|
|
public void breakBackTile(Vec2i pos)
|
|
{
|
|
TileState ts = getBackTile(pos);
|
|
|
|
if(!ts.tile.unbreakable) {
|
|
setBackTile(layer.layergen.getTileDestroyed(), pos);
|
|
for(int i=0;i<20;i++) {
|
|
spawnEntity(new ParticleBreak(new Vec2d(pos.x+0.5, pos.y+0.5), ts));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void breakFrontTile(Vec2i pos)
|
|
{
|
|
TileState ts = getFrontTile(pos);
|
|
|
|
if(!ts.tile.unbreakable) {
|
|
setFrontTile(Tiles.VOID.getDefaultState(), pos);
|
|
for(int i=0;i<20;i++) {
|
|
spawnEntity(new ParticleBreak(new Vec2d(pos.x+0.5, pos.y+0.5), ts));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void killEntity(Entity e) {
|
|
entities.remove(e);
|
|
}
|
|
|
|
public ArrayList<Entity> getNearbyEntities(Vec2d pos, double distance)
|
|
{
|
|
// Get the list of entities to send back
|
|
ArrayList<Entity> nearby_entities = new ArrayList<Entity>();
|
|
|
|
// Loop over the entities
|
|
for(Entity e : entities)
|
|
{
|
|
if(
|
|
e.pos.x + distance > pos.x &&
|
|
e.pos.x - distance < pos.x &&
|
|
e.pos.y + distance > pos.y &&
|
|
e.pos.y - distance < pos.y
|
|
) {
|
|
if(MathHelpers.distance2d(e.pos.x, e.pos.y, pos.x, pos.y) < distance) {
|
|
nearby_entities.add(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Send back the entities
|
|
return nearby_entities;
|
|
}
|
|
|
|
}
|