115 lines
3.2 KiB
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();
|
|
}
|
|
}
|