ProjectZombie/src/shootergame/entity/EntityExplosion.java

115 lines
3.2 KiB
Java

package shootergame.entity;
import shootergame.Main;
import shootergame.entity.particle.ParticleBlood;
import shootergame.entity.particle.ParticleBreak;
import shootergame.entity.particle.ParticleSmoke;
import shootergame.init.Sounds;
import shootergame.init.Tiles;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.TileState;
import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec2i;
import shootergame.util.math.vec.Vec3d;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class EntityExplosion extends Entity
{
private double damage;
private int radius;
public EntityExplosion(Vec2d pos, int radius, double damage) {
super(pos);
this.damage = damage;
this.radius = radius;
}
@Override
public void tick(Chunk chunk, Layer layer) {
super.tick(chunk, layer);
boolean killed_entities = false;
// Kill all the nearby entities
for(Entity e : layer.getNearbyEntities(pos, radius))
{
// Is this entity alive
if(e instanceof EntityAlive)
{
EntityAlive ea = (EntityAlive)e;
// Remove some health from the entity based on were the entity is
killed_entities = true;
double distance = e.pos.distance(pos);
if(distance == 0) {
ea.removeHealth(damage);
}
else {
ea.removeHealth(damage / distance);
}
}
}
// Loop over the tiles around the tnt
for(int ex=-radius;ex<radius;ex++) {
for(int ey=-radius;ey<radius;ey++)
{
// Calculate the distance from the explosion centre
double distance = Math.sqrt(ex*ex + ey*ey);
// Is the point within the distance from the explosion centre
if(distance < radius)
{
// Get the actual tile position
double px = ex + pos.x;
double py = ey + pos.y;
// Get the layer
Layer l = Main.world.getLayer();
// Calculate the blackened gradient
byte blackened_gradient = (byte)( Byte.MAX_VALUE - distance / radius * Byte.MAX_VALUE );
// Get the front and back tile
Vec2i tpos = new Vec2i(MathHelpers.floor(px), MathHelpers.floor(py));
TileState bts = l.getBackTile(tpos);
TileState fts = l.getFrontTile(tpos);
// Is this tile the same as the "empty" tile
TileState ets = l.layergen.getTileDestroyed();
if(bts.tile == ets.tile) {
if(bts.meta > blackened_gradient) blackened_gradient = bts.meta;
}
// Set the tiles
if(!bts.tile.unbreakable) {
l.setBackTile(new TileState(ets.tile, blackened_gradient), tpos);
l.spawnEntity(new ParticleBreak(new Vec2d(tpos.x+rand.nextDouble(), tpos.y+rand.nextDouble()), bts));
}
if(!fts.tile.unbreakable) {
l.setFrontTile(Tiles.VOID.getDefaultState(), tpos);
l.spawnEntity(new ParticleBreak(new Vec2d(tpos.x+rand.nextDouble(), tpos.y+rand.nextDouble()), fts));
}
// Spawn some blood if entities were killed
if(killed_entities)
l.spawnEntity(new ParticleBlood(rand, new Vec2d(px, py), py));
// Spawn some smoke
l.spawnEntity(new ParticleSmoke(new Vec2d(px, py)));
}
}
}
// Play the explosion sound
Sounds.EXPLOSION.play(new Vec3d(pos.x, pos.y, 0), 1);
// Kill the explosion entity
kill();
}
}