717 lines
17 KiB
Java
Executable File
717 lines
17 KiB
Java
Executable File
package projectzombie.world.chunk;
|
|
|
|
import java.nio.FloatBuffer;
|
|
import java.util.ArrayList;
|
|
import java.util.Random;
|
|
|
|
import bdf.classes.IBdfClassManager;
|
|
import bdf.types.BdfArray;
|
|
import bdf.types.BdfNamedList;
|
|
import bdf.types.BdfObject;
|
|
import gl_engine.MathHelpers;
|
|
import gl_engine.matrix.Matrix4;
|
|
import gl_engine.range.Range2i;
|
|
import gl_engine.texture.TextureRef3D;
|
|
import gl_engine.vec.Vec2d;
|
|
import gl_engine.vec.Vec2i;
|
|
import gl_engine.vec.Vec3d;
|
|
import projectzombie.Main;
|
|
import projectzombie.display.Camera;
|
|
import projectzombie.entity.Entity;
|
|
import projectzombie.entity.EntityAlive;
|
|
import projectzombie.entity.EntityHoldsEntities;
|
|
import projectzombie.entity.EntityKillWithParticles;
|
|
import projectzombie.entity.EntityParticle;
|
|
import projectzombie.entity.EntityParticlePart;
|
|
import projectzombie.entity.particle.ParticleBreak;
|
|
import projectzombie.entity.tileentity.TileEntity;
|
|
import projectzombie.init.Tiles;
|
|
import projectzombie.model.IModel;
|
|
import projectzombie.model.Model;
|
|
import projectzombie.model.ModelChunk;
|
|
import projectzombie.tiles.Tile;
|
|
import projectzombie.util.math.TileState;
|
|
import projectzombie.util.math.random.RandomHelpers;
|
|
import projectzombie.world.layer.Layer;
|
|
|
|
public class Chunk implements IBdfClassManager
|
|
{
|
|
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 Random rand = new Random();
|
|
|
|
public static int SIMULATION_DISTANCE = 10;
|
|
public static int RENDER_DISTANCE = 2;
|
|
|
|
public static boolean SHOW_CHUNKS = false;
|
|
|
|
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[] = new byte[CHUNK_INDEX];
|
|
public ArrayList<Entity> entities = new ArrayList<Entity>();
|
|
private Layer layer;
|
|
public Vec2i c_pos;
|
|
private boolean dirty;
|
|
private boolean light_dirty;
|
|
private boolean render_dirty;
|
|
|
|
private ModelChunk model;
|
|
|
|
public boolean isDirty()
|
|
{
|
|
if(entities.size() > 0) {
|
|
return true;
|
|
}
|
|
|
|
return dirty;
|
|
}
|
|
|
|
public void clearDirty() {
|
|
dirty = false;
|
|
}
|
|
|
|
private void setDirty() {
|
|
this.light_dirty = true;
|
|
this.render_dirty = true;
|
|
this.dirty = true;
|
|
}
|
|
|
|
public boolean isLightDirty() {
|
|
return light_dirty;
|
|
}
|
|
|
|
public void resetLightDirty() {
|
|
this.light_dirty = false;
|
|
}
|
|
|
|
@Override
|
|
public void BdfClassLoad(BdfObject bdf)
|
|
{
|
|
BdfNamedList nl = bdf.getNamedList();
|
|
|
|
// Load all the tiles and meta
|
|
short[] tb = nl.get("tilesBack").getShortArray();
|
|
short[] tf = nl.get("tilesFront").getShortArray();
|
|
byte[] mb = nl.get("metaBack").getByteArray();
|
|
byte[] mf = nl.get("metaFront").getByteArray();
|
|
|
|
for(int i=0;i<CHUNK_INDEX;i++)
|
|
{
|
|
tiles_back[i] = Tiles.tiles.get(tb[i]);
|
|
tiles_front[i] = Tiles.tiles.get(tf[i]);
|
|
tiles_back_meta[i] = mb[i];
|
|
tiles_front_meta[i] = mf[i];
|
|
tiles_lighting[i] = 0;
|
|
}
|
|
|
|
// Load all the entities
|
|
entities.clear();
|
|
BdfArray bdf_entities = nl.get("entities").getArray();
|
|
|
|
for(BdfObject bdf_entity : bdf_entities) {
|
|
Entity entity = Entity.loadEntity(bdf_entity);
|
|
if(entity != null) {
|
|
entity.chunk = this;
|
|
entities.add(entity);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void BdfClassSave(BdfObject bdf)
|
|
{
|
|
BdfNamedList nl = bdf.getNamedList();
|
|
|
|
short[] tb = new short[CHUNK_INDEX];
|
|
short[] tf = new short[CHUNK_INDEX];
|
|
|
|
// Save all the tiles and tile meta
|
|
for(int i=0;i<CHUNK_INDEX;i++) {
|
|
tb[i] = tiles_back[i].id;
|
|
tf[i] = tiles_front[i].id;
|
|
}
|
|
|
|
nl.set("tilesBack", bdf.newObject().setShortArray(tb));
|
|
nl.set("tilesFront", bdf.newObject().setShortArray(tf));
|
|
nl.set("metaBack", bdf.newObject().setByteArray(tiles_back_meta));
|
|
nl.set("metaFront", bdf.newObject().setByteArray(tiles_front_meta));
|
|
|
|
// Save all the saveable entity data
|
|
BdfArray bdf_entities = bdf.newArray();
|
|
nl.set("entities", bdf.newObject().setArray(bdf_entities));
|
|
for(Entity e : entities) {
|
|
if(e.getID() == -1)
|
|
continue;
|
|
BdfObject bdf_e = bdf.newObject();
|
|
e.BdfClassSave(bdf_e);
|
|
bdf_entities.add(bdf_e);
|
|
}
|
|
}
|
|
|
|
public Chunk(Layer layer, Vec2i c_pos, BdfObject bdf)
|
|
{
|
|
this.layer = layer;
|
|
this.c_pos = c_pos;
|
|
|
|
setDirty();
|
|
BdfClassLoad(bdf);
|
|
}
|
|
|
|
public Chunk(Layer layer, Vec2i c_pos, Random rand)
|
|
{
|
|
// Set some specified values
|
|
this.layer = layer;
|
|
this.c_pos = c_pos;
|
|
this.dirty = false;
|
|
this.light_dirty = true;
|
|
|
|
// 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;
|
|
|
|
// Set the light level to 0
|
|
tiles_lighting[i] = 0;
|
|
}
|
|
}
|
|
|
|
public int getParticlePoolSize() {
|
|
return getParticlePoolSize(entities.toArray());
|
|
}
|
|
|
|
public int getParticlePoolSize(Object[] entities)
|
|
{
|
|
int particle_pool_size = 0;
|
|
|
|
for(Object o : entities)
|
|
{
|
|
Entity e = (Entity)o;
|
|
|
|
if(e == null || e.isDead()) {
|
|
continue;
|
|
}
|
|
|
|
if(e instanceof EntityHoldsEntities) {
|
|
particle_pool_size += getParticlePoolSize(((EntityHoldsEntities) e).getEntities());
|
|
}
|
|
|
|
if(e instanceof EntityParticle)
|
|
{
|
|
EntityParticle ep = (EntityParticle) e;
|
|
|
|
for(int i=0;i<ep.getParticleCount();i++)
|
|
{
|
|
EntityParticlePart p = ep.getParticleAt(i);
|
|
|
|
if(p == null) {
|
|
continue;
|
|
}
|
|
|
|
Vec3d pos = Matrix4.multiply(
|
|
Camera.camera.projection,
|
|
p.pos.subtract(new Vec3d(0.5 + Camera.camera.x, 0, 0.5 + Camera.camera.y)));
|
|
|
|
if(Math.abs(pos.x) <= 1.125 && Math.abs(pos.y) <= 1.125 && Math.abs(pos.z) <= 1.125) {
|
|
particle_pool_size += 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return particle_pool_size;
|
|
}
|
|
|
|
private int renderEntities(Object[] entities, FloatBuffer particle_pool, int upto)
|
|
{
|
|
// Render each entity
|
|
for(Object o : entities)
|
|
{
|
|
Entity e = (Entity)o;
|
|
|
|
if(e == null || e.isDead()) {
|
|
continue;
|
|
}
|
|
|
|
if(e instanceof EntityHoldsEntities) {
|
|
upto = renderEntities(((EntityHoldsEntities) e).getEntities(), particle_pool, upto);
|
|
}
|
|
|
|
if(e instanceof EntityParticle && Main.world.isPoolDirty())
|
|
{
|
|
EntityParticle ep = (EntityParticle)e;
|
|
|
|
for(int i=0;i<ep.getParticleCount();i++)
|
|
{
|
|
EntityParticlePart p = ep.getParticleAt(i);
|
|
|
|
if(p == null) {
|
|
continue;
|
|
}
|
|
|
|
Vec3d pos = Matrix4.multiply(
|
|
Camera.camera.projection,
|
|
p.pos.subtract(new Vec3d(0.5 + Camera.camera.x, 0, 0.5 + Camera.camera.y)));
|
|
|
|
if(Math.abs(pos.x) > 1.125 || Math.abs(pos.y) > 1.125 || Math.abs(pos.z) > 1.125) {
|
|
continue;
|
|
}
|
|
|
|
float px = (float)(p.pos.x - 0.5f - Camera.camera.x);
|
|
float py = (float)(p.pos.y);
|
|
float pz = (float)(p.pos.z - 0.5f - Camera.camera.y);
|
|
|
|
float k = Model.OFFSET;
|
|
float tsx = p.tex.sx+k;
|
|
float tex = p.tex.ex-k;
|
|
float tsy = p.tex.sy+k;
|
|
float tey = p.tex.ey-k;
|
|
float tz = p.tex.z;
|
|
|
|
float g = (float)p.getFade();
|
|
float s = (float)p.size / 2;
|
|
float f = p.flags;
|
|
|
|
float a_si = p.animationSize;
|
|
float a_sp = p.animationSpeed;
|
|
|
|
float a = -s, b = s, c = 0, d = 0;
|
|
|
|
if(p.isFlat()) {
|
|
c = a;
|
|
d = b;
|
|
a = 0;
|
|
b = 0;
|
|
}
|
|
|
|
/*
|
|
layout (location = 0) in vec3 aPos;
|
|
layout (location = 1) in vec3 aTex;
|
|
layout (location = 2) in vec2 aTexY;
|
|
layout (location = 3) in vec3 aOffset;
|
|
layout (location = 4) in vec2 aAnimate;
|
|
layout (location = 5) in vec3 aFlags;
|
|
*/
|
|
|
|
float[] verticies = {
|
|
-s, a, c, tex, tsy, tz, tsy, tey, px, py, pz, a_si, a_sp, g, 0, f,
|
|
-s, b, d, tex, tey, tz, tsy, tey, px, py, pz, a_si, a_sp, g, 0, f,
|
|
+s, b, d, tsx, tey, tz, tsy, tey, px, py, pz, a_si, a_sp, g, 0, f,
|
|
+s, a, c, tsx, tsy, tz, tsy, tey, px, py, pz, a_si, a_sp, g, 0, f,
|
|
};
|
|
|
|
for(int j=0;j<verticies.length;j++) {
|
|
particle_pool.put(upto+j, verticies[j]);
|
|
}
|
|
|
|
upto += verticies.length;
|
|
}
|
|
}
|
|
|
|
IModel model = e.getModel();
|
|
|
|
if(model == null) {
|
|
continue;
|
|
}
|
|
|
|
Vec3d pos = e.getPos();
|
|
|
|
// Don't try to render anything if the model is empty
|
|
if(model.getSize() == 0) {
|
|
continue;
|
|
}
|
|
|
|
// Render the model
|
|
model.setModel(Matrix4.translate(
|
|
pos.x - Camera.camera.x - 0.5, pos.y,
|
|
pos.z - Camera.camera.y - 0.5));
|
|
model.render();
|
|
}
|
|
|
|
return upto;
|
|
}
|
|
|
|
public int render(Camera camera, FloatBuffer particle_pool, int upto)
|
|
{
|
|
if(model == null || this.render_dirty)
|
|
{
|
|
this.render_dirty = false;
|
|
int verticies_size = 0;
|
|
int indicies_size = 0;
|
|
int index_offset = 0;
|
|
|
|
for(int i=0;i<CHUNK_INDEX;i++) {
|
|
TileState bt = getBackTile(i);
|
|
TileState ft = getFrontTile(i);
|
|
verticies_size += bt.tile.getModel(bt.meta).getSize();
|
|
verticies_size += ft.tile.getModel(ft.meta).getSize();
|
|
indicies_size += bt.tile.getModel(bt.meta).getIndexSize();
|
|
indicies_size += ft.tile.getModel(ft.meta).getIndexSize();
|
|
}
|
|
|
|
int[] indicies = new int[indicies_size];
|
|
float[] verticies = new float[verticies_size * Model.SIZE];
|
|
TextureRef3D[] textures = new TextureRef3D[verticies_size];
|
|
int upto_v = 0;
|
|
int upto_i = 0;
|
|
|
|
for(int i=0;i<CHUNK_INDEX;i++)
|
|
{
|
|
Vec2i pos = Vec2i.fromId(CHUNK_SIZE, i);
|
|
|
|
for(TileState state : new TileState[] {getFrontTile(pos), getBackTile(pos)})
|
|
{
|
|
Model model = state.tile.getModel(state.meta);
|
|
|
|
TextureRef3D[] textures2 = model.getTextures();
|
|
float[] verticies2 = model.getVerticies();
|
|
int[] indicies2 = model.getIndicies();
|
|
|
|
for(int j=0;j<model.getSize();j++)
|
|
{
|
|
textures[upto_v] = textures2[j];
|
|
|
|
for(int k=0;k<Model.SIZE;k++)
|
|
{
|
|
switch(k)
|
|
{
|
|
case 8:
|
|
verticies[upto_v * Model.SIZE + k ] = pos.x;
|
|
continue;
|
|
|
|
case 10:
|
|
verticies[upto_v * Model.SIZE + k ] = pos.y;
|
|
continue;
|
|
|
|
default:
|
|
verticies[upto_v * Model.SIZE + k ] = verticies2[j * Model.SIZE + k ];
|
|
continue;
|
|
}
|
|
}
|
|
|
|
upto_v += 1;
|
|
}
|
|
|
|
for(int j=0;j<indicies2.length;j++) {
|
|
indicies[j + upto_i] = indicies2[j] + index_offset;
|
|
}
|
|
|
|
upto_i += indicies2.length;
|
|
index_offset += model.getSize();
|
|
}
|
|
}
|
|
|
|
if(model != null) {
|
|
model.free();
|
|
}
|
|
|
|
model = new ModelChunk(verticies, indicies, textures, verticies_size);
|
|
}
|
|
|
|
// Render all the tiles in the chunk as a block
|
|
model.setModel(Matrix4.translate(c_pos.x * 16 - Camera.camera.x, 0, c_pos.y * 16 - Camera.camera.y));
|
|
model.render();
|
|
|
|
return renderEntities(entities.toArray(), particle_pool, upto);
|
|
}
|
|
|
|
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) {
|
|
ea.onDeath(layer);
|
|
killEntity(e);
|
|
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.getPos().x;
|
|
double py = e.getPos().z;
|
|
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 createTileEntity(Vec2i pos, TileEntity te)
|
|
{
|
|
TileEntity te_old = getTileEntity(pos);
|
|
|
|
// Kill the old tile entity if it exists
|
|
if(te_old != null) {
|
|
te_old.kill();
|
|
}
|
|
|
|
te.setPos(new Vec3d(pos.x, 0, pos.y));
|
|
spawnEntity(te);
|
|
}
|
|
|
|
public void destroyTileEntity(Vec2i pos)
|
|
{
|
|
TileEntity te = getTileEntity(pos);
|
|
|
|
if(te != null) {
|
|
te.kill();
|
|
}
|
|
}
|
|
|
|
public TileEntity getTileEntity(Vec2i pos)
|
|
{
|
|
for(Entity e : entities)
|
|
{
|
|
if(e instanceof TileEntity && e.getPos().xz().toInt().equal(pos)) {
|
|
return (TileEntity)e;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
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)
|
|
{
|
|
Vec2i pos = Vec2i.fromId(CHUNK_SIZE, id).add(c_pos.multiply(16));
|
|
tiles_back[id].onDestroy(layer, this, new TileState(tiles_back[id], tiles_back_meta[id]), tile, pos);
|
|
|
|
// Set the back tile
|
|
tiles_back[id] = tile.tile;
|
|
tiles_back_meta[id] = tile.meta;
|
|
|
|
setDirty();
|
|
|
|
tile.tile.onGenerate(layer, this, tile, pos);
|
|
}
|
|
|
|
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)
|
|
{
|
|
Vec2i pos = Vec2i.fromId(CHUNK_SIZE, id).add(c_pos.multiply(16));
|
|
tiles_front[id].onDestroy(layer, this, new TileState(tiles_front[id], tiles_front_meta[id]), tile, pos);
|
|
|
|
// Set the front tile
|
|
this.tiles_front[id] = tile.tile;
|
|
this.tiles_front_meta[id] = tile.meta;
|
|
|
|
setDirty();
|
|
|
|
tile.tile.onGenerate(layer, this, tile, pos);
|
|
}
|
|
|
|
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 = getLightLevel(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 = getLightLevel(id);
|
|
return ts;
|
|
}
|
|
|
|
public void breakBackTile(Vec2i pos)
|
|
{
|
|
TileState ts = getBackTile(pos);
|
|
setDirty();
|
|
|
|
if(!ts.tile.unbreakable) {
|
|
setBackTile(layer.layergen.getTileDestroyed(layer, pos), pos);
|
|
spawnEntity(new ParticleBreak(new Vec3d(pos.x + 0.5, 0, pos.y + 0.5), new Vec3d(0, 0, 0), ts.tile.getModel(ts.meta)));
|
|
}
|
|
}
|
|
|
|
public void breakFrontTile(Vec2i pos)
|
|
{
|
|
TileState ts = getFrontTile(pos);
|
|
setDirty();
|
|
|
|
if(!ts.tile.unbreakable) {
|
|
setFrontTile(Tiles.VOID.getDefaultState(), pos);
|
|
spawnEntity(new ParticleBreak(new Vec3d(pos.x + 0.5, 0, pos.y + 0.5),
|
|
new Vec3d(0, 0, 0), ts.tile.getModel(ts.meta)));
|
|
}
|
|
}
|
|
|
|
public double getLightLevel(int id) {
|
|
return tiles_lighting[id] / (double)Byte.MAX_VALUE;
|
|
}
|
|
|
|
public double getLightLevel(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 getLightLevel(id);
|
|
}
|
|
|
|
public void setLightLevel(double light, int id) {
|
|
this.tiles_lighting[id] = (byte)(light * Byte.MAX_VALUE);
|
|
}
|
|
|
|
public void setLightLevel(double light, 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);
|
|
|
|
setLightLevel(light, id);
|
|
}
|
|
|
|
public void killEntity(Entity e)
|
|
{
|
|
if(e instanceof EntityKillWithParticles) {
|
|
((EntityKillWithParticles)e).killWithParticles();
|
|
}
|
|
|
|
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)
|
|
{
|
|
Vec2d epos = e.getPos().xz();
|
|
|
|
if(
|
|
epos.x + distance > pos.x &&
|
|
epos.x - distance < pos.x &&
|
|
epos.y + distance > pos.y &&
|
|
epos.y - distance < pos.y
|
|
) {
|
|
if(pos.squareDistance(epos) < distance) {
|
|
nearby_entities.add(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Send back the entities
|
|
return nearby_entities;
|
|
}
|
|
|
|
public void tickRandomly()
|
|
{
|
|
// Get a random tile
|
|
int id = RandomHelpers.randrange(rand, CHUNK_INDEX);
|
|
Vec2i pos = Vec2i.fromId(CHUNK_SIZE, id);
|
|
pos.x += c_pos.x * 16;
|
|
pos.y += c_pos.y * 16;
|
|
|
|
// Randomly select the front and back tiles
|
|
TileState ts;
|
|
if(rand.nextBoolean()) {
|
|
ts = getBackTile(id);
|
|
}
|
|
else {
|
|
ts = getFrontTile(id);
|
|
}
|
|
|
|
// Tick the tile
|
|
ts.tile.tickRandomly(layer, this, ts, pos);
|
|
}
|
|
|
|
public void free()
|
|
{
|
|
if(this.model != null) {
|
|
this.model.free();
|
|
this.model = null;
|
|
}
|
|
}
|
|
|
|
}
|