Explosion propagation
This commit is contained in:
@@ -97,7 +97,7 @@ public class WaveSpawner{
|
|||||||
}
|
}
|
||||||
Time.run(20f, () -> Effects.effect(Fx.spawnShockwave, spawn.x * tilesize, spawn.y * tilesize));
|
Time.run(20f, () -> Effects.effect(Fx.spawnShockwave, spawn.x * tilesize, spawn.y * tilesize));
|
||||||
//would be interesting to see player structures survive this without hacks
|
//would be interesting to see player structures survive this without hacks
|
||||||
Time.run(40f, () -> Damage.damage(waveTeam, spawn.x * tilesize, spawn.y * tilesize, shockwaveBase + Mathf.random(shockwaveRand), 99999999f));
|
Time.run(40f, () -> Damage.damage(waveTeam, spawn.x * tilesize, spawn.y * tilesize, shockwaveBase + Mathf.random(shockwaveRand), 99999999f, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,8 +331,10 @@ public class Renderer implements ApplicationListener{
|
|||||||
|
|
||||||
int w = world.width()*tilesize, h = world.height()*tilesize;
|
int w = world.width()*tilesize, h = world.height()*tilesize;
|
||||||
|
|
||||||
boolean isWater = settings.getBool("animatedwater");
|
boolean hadShields = Core.settings.getBool("animatedshields");
|
||||||
settings.put("animatedwater", false);
|
boolean hadWater = Core.settings.getBool("animatedwater");
|
||||||
|
Core.settings.put("animatedwater", false);
|
||||||
|
Core.settings.put("animatedshields", false);
|
||||||
|
|
||||||
FrameBuffer buffer = new FrameBuffer(w, h);
|
FrameBuffer buffer = new FrameBuffer(w, h);
|
||||||
|
|
||||||
@@ -366,7 +368,8 @@ public class Renderer implements ApplicationListener{
|
|||||||
|
|
||||||
buffer.dispose();
|
buffer.dispose();
|
||||||
|
|
||||||
settings.put("animatedwater", isWater);
|
Core.settings.put("animatedwater", hadWater);
|
||||||
|
Core.settings.put("animatedshields", hadShields);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
package io.anuke.mindustry.entities;
|
package io.anuke.mindustry.entities;
|
||||||
|
|
||||||
import io.anuke.mindustry.entities.Effects.Effect;
|
import io.anuke.annotations.Annotations.Struct;
|
||||||
|
import io.anuke.arc.collection.GridBits;
|
||||||
|
import io.anuke.arc.collection.IntQueue;
|
||||||
import io.anuke.arc.function.Consumer;
|
import io.anuke.arc.function.Consumer;
|
||||||
import io.anuke.arc.function.Predicate;
|
import io.anuke.arc.function.Predicate;
|
||||||
import io.anuke.arc.graphics.Color;
|
import io.anuke.arc.graphics.Color;
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.Mathf;
|
||||||
import io.anuke.arc.math.geom.Geometry;
|
import io.anuke.arc.math.geom.Geometry;
|
||||||
|
import io.anuke.arc.math.geom.Point2;
|
||||||
import io.anuke.arc.math.geom.Rectangle;
|
import io.anuke.arc.math.geom.Rectangle;
|
||||||
import io.anuke.arc.math.geom.Vector2;
|
import io.anuke.arc.math.geom.Vector2;
|
||||||
import io.anuke.arc.util.Time;
|
import io.anuke.arc.util.Time;
|
||||||
import io.anuke.mindustry.content.Bullets;
|
import io.anuke.mindustry.content.Bullets;
|
||||||
import io.anuke.mindustry.content.Fx;
|
import io.anuke.mindustry.content.Fx;
|
||||||
|
import io.anuke.mindustry.entities.Effects.Effect;
|
||||||
import io.anuke.mindustry.entities.bullet.Bullet;
|
import io.anuke.mindustry.entities.bullet.Bullet;
|
||||||
import io.anuke.mindustry.entities.effect.Fire;
|
import io.anuke.mindustry.entities.effect.Fire;
|
||||||
import io.anuke.mindustry.entities.effect.Lightning;
|
import io.anuke.mindustry.entities.effect.Lightning;
|
||||||
import io.anuke.mindustry.entities.type.Unit;
|
import io.anuke.mindustry.entities.type.Unit;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.gen.Call;
|
import io.anuke.mindustry.gen.Call;
|
||||||
|
import io.anuke.mindustry.gen.PropCell;
|
||||||
import io.anuke.mindustry.graphics.Pal;
|
import io.anuke.mindustry.graphics.Pal;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
@@ -27,6 +32,8 @@ public class Damage{
|
|||||||
private static Rectangle rect = new Rectangle();
|
private static Rectangle rect = new Rectangle();
|
||||||
private static Rectangle hitrect = new Rectangle();
|
private static Rectangle hitrect = new Rectangle();
|
||||||
private static Vector2 tr = new Vector2();
|
private static Vector2 tr = new Vector2();
|
||||||
|
private static GridBits bits = new GridBits(30, 30);
|
||||||
|
private static IntQueue propagation = new IntQueue();
|
||||||
|
|
||||||
/**Creates a dynamic explosion based on specified parameters.*/
|
/**Creates a dynamic explosion based on specified parameters.*/
|
||||||
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){
|
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){
|
||||||
@@ -152,11 +159,16 @@ public class Damage{
|
|||||||
|
|
||||||
/**Damages everything in a radius.*/
|
/**Damages everything in a radius.*/
|
||||||
public static void damage(float x, float y, float radius, float damage){
|
public static void damage(float x, float y, float radius, float damage){
|
||||||
damage(null, x, y, radius, damage);
|
damage(null, x, y, radius, damage, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Damages all entities and blocks in a radius that are enemies of the team.*/
|
/**Damages all entities and blocks in a radius that are enemies of the team.*/
|
||||||
public static void damage(Team team, float x, float y, float radius, float damage){
|
public static void damage(Team team, float x, float y, float radius, float damage){
|
||||||
|
damage(team, x, y, radius, damage, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Damages all entities and blocks in a radius that are enemies of the team.*/
|
||||||
|
public static void damage(Team team, float x, float y, float radius, float damage, boolean complete){
|
||||||
Consumer<Unit> cons = entity -> {
|
Consumer<Unit> cons = entity -> {
|
||||||
if(entity.getTeam() == team || entity.dst(x, y) > radius){
|
if(entity.getTeam() == team || entity.dst(x, y) > radius){
|
||||||
return;
|
return;
|
||||||
@@ -175,25 +187,68 @@ public class Damage{
|
|||||||
Units.getNearby(rect, cons);
|
Units.getNearby(rect, cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
int trad = (int) (radius / tilesize);
|
if(!complete){
|
||||||
Tile tile = world.tileWorld(x, y);
|
int trad = (int)(radius / tilesize);
|
||||||
if(tile != null){
|
Tile tile = world.tileWorld(x, y);
|
||||||
tileDamage(tile.x, tile.y, trad);
|
if(tile != null){
|
||||||
|
tileDamage(team, tile.x, tile.y, trad, damage);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
completeDamage(team, x, y, radius, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void tileDamage(int x, int y, int radius){
|
public static void tileDamage(Team team, int startx, int starty, int radius, float baseDamage){
|
||||||
/*
|
bits.clear();
|
||||||
|
propagation.clear();
|
||||||
|
int bitOffset = bits.width()/2;
|
||||||
|
|
||||||
|
propagation.addFirst(PropCell.get((byte)0, (byte)0, (short)baseDamage));
|
||||||
|
//clamp radius to fit bits
|
||||||
|
radius = Math.min(radius, bits.width()/2);
|
||||||
|
|
||||||
|
while(!propagation.isEmpty()){
|
||||||
|
int prop = propagation.removeLast();
|
||||||
|
int x = PropCell.x(prop);
|
||||||
|
int y = PropCell.y(prop);
|
||||||
|
int damage = PropCell.damage(prop);
|
||||||
|
//manhattan distance used for calculating falloff, results in a diamond pattern
|
||||||
|
int dst = Math.abs(x) + Math.abs(y);
|
||||||
|
|
||||||
|
int scaledDamage = (int)(damage * (1f - (float)dst / radius));
|
||||||
|
|
||||||
|
bits.set(bitOffset + x, bitOffset + y);
|
||||||
|
Tile tile = world.tile(startx + x, starty + y);
|
||||||
|
|
||||||
|
if(scaledDamage <= 0 || tile == null) continue;
|
||||||
|
|
||||||
|
//apply damage to entity if needed
|
||||||
|
if(tile.entity != null && tile.getTeam() != team){
|
||||||
|
int health = (int)tile.entity.health;
|
||||||
|
tile.entity.damage(scaledDamage);
|
||||||
|
scaledDamage -= health;
|
||||||
|
|
||||||
|
if(scaledDamage <= 0) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Point2 p : Geometry.d4){
|
||||||
|
if(!bits.get(bitOffset + x + p.x, bitOffset + y + p.y)){
|
||||||
|
propagation.addFirst(PropCell.get((byte)(x + p.x), (byte)(y + p.y), (short)scaledDamage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void completeDamage(Team team, float x, float y, float radius, float damage){
|
||||||
|
int trad = (int) (radius / tilesize);
|
||||||
for(int dx = -trad; dx <= trad; dx++){
|
for(int dx = -trad; dx <= trad; dx++){
|
||||||
for(int dy = -trad; dy <= trad; dy++){
|
for(int dy = -trad; dy <= trad; dy++){
|
||||||
Tile tile = world.tile(Math.round(x / tilesize) + dx, Math.round(y / tilesize) + dy);
|
Tile tile = world.tile(Math.round(x / tilesize) + dx, Math.round(y / tilesize) + dy);
|
||||||
if(tile != null && tile.entity != null && (team == null || state.teams.areEnemies(team, tile.getTeam())) && Mathf.dst(dx, dy, 0, 0) <= trad){
|
if(tile != null && tile.entity != null && (team == null || state.teams.areEnemies(team, tile.getTeam())) && Mathf.dst(dx, dy) <= trad){
|
||||||
float amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage);
|
tile.entity.damage(damage);
|
||||||
tile.entity.damage(amount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float calculateDamage(float x, float y, float tx, float ty, float radius, float damage){
|
private static float calculateDamage(float x, float y, float tx, float ty, float radius, float damage){
|
||||||
@@ -202,4 +257,11 @@ public class Damage{
|
|||||||
float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff);
|
float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff);
|
||||||
return damage * scaled;
|
return damage * scaled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Struct
|
||||||
|
class PropCellStruct{
|
||||||
|
byte x;
|
||||||
|
byte y;
|
||||||
|
short damage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user