Implemented player explosion intensity calculation / Fixed fire spread

This commit is contained in:
Anuken
2018-04-15 22:41:27 -04:00
parent cb569be3b3
commit 871b6548ab
11 changed files with 95 additions and 77 deletions

View File

@@ -1,5 +1,5 @@
#Autogenerated file. Do not modify. #Autogenerated file. Do not modify.
#Sun Apr 15 19:58:39 EDT 2018 #Sun Apr 15 22:39:16 EDT 2018
version=release version=release
androidBuildCode=927 androidBuildCode=927
name=Mindustry name=Mindustry

View File

@@ -75,7 +75,7 @@ public class Bullet extends BulletEntity<BulletType>{
if(other instanceof Unit){ if(other instanceof Unit){
Unit unit = (Unit)other; Unit unit = (Unit)other;
unit.velocity.add(vector.set(other.x, other.y).sub(x, y).setLength(type.knockback / unit.getMass())); unit.velocity.add(vector.set(other.x, other.y).sub(x, y).setLength(type.knockback / unit.getMass()));
unit.status.handleApply(unit, type.status, type.statusIntensity); unit.applyEffect(type.status, type.statusIntensity);
} }
} }

View File

@@ -6,7 +6,9 @@ import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.Weapons; import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.content.fx.ExplosionFx; import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.effect.DamageArea;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.ItemStack;
@@ -103,18 +105,19 @@ public class Player extends Unit{
@Override @Override
public void onDeath(){ public void onDeath(){
super.onDeath();
dead = true; dead = true;
if(Net.active()){ if(Net.active()){
NetEvents.handleUnitDeath(this); NetEvents.handleUnitDeath(this);
} }
Effects.effect(ExplosionFx.explosion, this); float explosiveness = 2f + (inventory.hasItem() ? inventory.getItem().item.explosiveness * inventory.getItem().amount : 0f);
Effects.shake(4f, 5f, this); float flammability = (inventory.hasItem() ? inventory.getItem().item.flammability * inventory.getItem().amount : 0f);
DamageArea.dynamicExplosion(x, y, flammability, explosiveness, 0f, getSize()/2f, Palette.darkFlame);
Effects.sound("die", this); Effects.sound("die", this);
control.setRespawnTime(respawnduration); control.setRespawnTime(respawnduration);
ui.hudfrag.fadeRespawn(true); ui.hudfrag.fadeRespawn(true);
super.onDeath();
} }
@Override @Override

View File

@@ -1,7 +1,6 @@
package io.anuke.mindustry.entities; package io.anuke.mindustry.entities;
import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
@@ -30,8 +29,6 @@ public class TileEntity extends Entity{
public boolean dead = false; public boolean dead = false;
public boolean added; public boolean added;
public Fire fire;
public PowerModule power; public PowerModule power;
public InventoryModule inventory; public InventoryModule inventory;
public LiquidModule liquid; public LiquidModule liquid;
@@ -54,14 +51,6 @@ public class TileEntity extends Entity{
return this; return this;
} }
public boolean hasFire(){
return fire != null;
}
public void setFire(){
this.fire = new Fire(tile).add();
}
public void write(DataOutputStream stream) throws IOException{ public void write(DataOutputStream stream) throws IOException{
} }

View File

@@ -37,6 +37,7 @@ public abstract class Unit extends SyncEntity {
@Override @Override
public void onDeath() { public void onDeath() {
inventory.clear();
drownTime = 0f; drownTime = 0f;
status.clear(); status.clear();
} }
@@ -99,6 +100,7 @@ public abstract class Unit extends SyncEntity {
} }
public void applyEffect(StatusEffect effect, float intensity){ public void applyEffect(StatusEffect effect, float intensity){
if(dead) return;
status.handleApply(this, effect, intensity); status.handleApply(this, effect, intensity);
} }

View File

@@ -1,13 +1,18 @@
package io.anuke.mindustry.entities.effect; package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -20,6 +25,47 @@ public class DamageArea{
private static Rectangle rect = new Rectangle(); private static Rectangle rect = new Rectangle();
private static Translator tr = new Translator(); private static Translator tr = new Translator();
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i ++){
int branches = 5 + Mathf.clamp((int)(power/30), 1, 20);
Timers.run(i*2f + Mathf.random(4f), () -> {
Lightning l = new Lightning(Team.none, Fx.none, 3, x, y, Mathf.random(360f), branches + Mathf.range(2));
l.color = Colors.get("power");
l.add();
});
}
for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i ++){
Timers.run(i/2, () -> {
Fireball f = new Fireball(x, y, color, Mathf.random(360f));
f.add();
});
}
float e = explosiveness;
int waves = Mathf.clamp((int)(explosiveness / 4), 0, 30);
for(int i = 0; i < waves; i ++){
int f = i;
Timers.run(i*2f, () -> {
DamageArea.damage(x, y, Mathf.clamp(radius + e, 0, 50f) * ((f + 1f)/waves), e/2f);
Effects.effect(ExplosionFx.blockExplosionSmoke, x + Mathf.range(radius), y + Mathf.range(radius));
});
}
if(explosiveness > 15f){
Effects.effect(ExplosionFx.shockwave, x, y);
}
if(explosiveness > 30f){
Effects.effect(ExplosionFx.bigShockwave, x, y);
}
float shake = Math.min(explosiveness/4f + 3f, 9f);
Effects.shake(shake, shake, x, y);
Effects.effect(ExplosionFx.blockExplosion, x, y);
}
/**Damages entities in a line. /**Damages entities in a line.
* Only enemies of the specified team are damaged.*/ * Only enemies of the specified team are damaged.*/
public static void collideLine(SolidEntity hitter, Team team, Effect effect, float x, float y, float angle, float length){ public static void collideLine(SolidEntity hitter, Team team, Effect effect, float x, float y, float angle, float length){

View File

@@ -9,17 +9,24 @@ import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.TimedEntity; import io.anuke.ucore.entities.TimedEntity;
import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.GridMap;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.effectGroup; import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class Fire extends TimedEntity { public class Fire extends TimedEntity {
private static GridMap<Fire> map = new GridMap<>();
private Tile tile; private Tile tile;
private float flammability = -1; private float flammability = -1;
public Fire(Tile tile){ public static void create(Tile tile){
if(!map.containsKey(tile.x, tile.y)){
new Fire(tile).add();
}
}
private Fire(Tile tile){
this.tile = tile; this.tile = tile;
lifetime = 1000f; lifetime = 1000f;
} }
@@ -31,21 +38,22 @@ public class Fire extends TimedEntity {
TileEntity entity = tile.target().entity; TileEntity entity = tile.target().entity;
boolean damage = entity != null; boolean damage = entity != null;
if(!damage){ if(!damage && flammability <= 0){
time += Timers.delta()*8; time += Timers.delta()*8;
}else if (flammability < 0){ }
if (flammability < 0){
flammability = tile.block().getFlammability(tile); flammability = tile.block().getFlammability(tile);
} }
if(damage) { if(damage) {
lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Timers.delta(); lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Timers.delta();
}
if (flammability > 1f && Mathf.chance(0.03 * Timers.delta() * Mathf.clamp(flammability/5f, 0.3f, 2f))) { if (flammability > 1f && Mathf.chance(0.03 * Timers.delta() * Mathf.clamp(flammability/5f, 0.3f, 2f))) {
GridPoint2 p = Mathf.select(Geometry.d4); GridPoint2 p = Mathf.select(Geometry.d4);
Tile other = world.tile(tile.x + p.x, tile.y + p.y); Tile other = world.tile(tile.x + p.x, tile.y + p.y);
new Fire(other).add(); create(other);
}
} }
if(Mathf.chance(0.1 * Timers.delta())){ if(Mathf.chance(0.1 * Timers.delta())){
@@ -66,4 +74,14 @@ public class Fire extends TimedEntity {
public Fire add(){ public Fire add(){
return add(effectGroup); return add(effectGroup);
} }
@Override
public void added() {
map.put(tile.x, tile.y, this);
}
@Override
public void removed() {
map.remove(tile.x, tile.y);
}
} }

View File

@@ -39,7 +39,7 @@ public class Fireball extends TimedEntity {
if(Mathf.chance(0.04 * Timers.delta())){ if(Mathf.chance(0.04 * Timers.delta())){
Tile tile = world.tileWorld(x, y); Tile tile = world.tileWorld(x, y);
if(tile != null){ if(tile != null){
new Fire(tile).add(); Fire.create(tile);
} }
} }

View File

@@ -64,6 +64,8 @@ public class DebugFragment implements Fragment {
row(); row();
new button("wave", () -> state.wavetime = 0f); new button("wave", () -> state.wavetime = 0f);
row(); row();
new button("death", () -> player.damage(99999, false));
row();
new button("spawn", () -> new BaseUnit(UnitTypes.scout, Team.red).set(player.x, player.y).add()); new button("spawn", () -> new BaseUnit(UnitTypes.scout, Team.red).set(player.x, player.y).add());
row(); row();
}}.end(); }}.end();

View File

@@ -158,7 +158,7 @@ public class HudFragment implements Fragment{
new label(()->"[orange]"+Bundles.get("text.respawn")+" " + (int)(control.getRespawnTime()/60)).scale(0.75f).pad(10); new label(()->"[orange]"+Bundles.get("text.respawn")+" " + (int)(control.getRespawnTime()/60)).scale(0.75f).pad(10);
visible(()->control.getRespawnTime() > 0 && !state.is(State.menu)); visible(()->false);
}}.end(); }}.end();
}}.end(); }}.end();
@@ -223,6 +223,6 @@ public class HudFragment implements Fragment{
} }
public void fadeRespawn(boolean in){ public void fadeRespawn(boolean in){
respawntable.addAction(Actions.color(in ? new Color(0, 0, 0, 0.3f) : Color.CLEAR, 0.3f)); //respawntable.addAction(Actions.color(in ? new Color(0, 0, 0, 0.3f) : Color.CLEAR, 0.3f));
} }
} }

View File

@@ -1,21 +1,15 @@
package io.anuke.mindustry.world; package io.anuke.mindustry.world;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.reflect.ClassReflection; import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.effect.DamageArea; import io.anuke.mindustry.entities.effect.DamageArea;
import io.anuke.mindustry.entities.effect.Fireball;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.DrawLayer; import io.anuke.mindustry.graphics.DrawLayer;
import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
@@ -24,8 +18,6 @@ import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Liquid; import io.anuke.mindustry.resource.Liquid;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.graphics.Lines;
@@ -248,48 +240,14 @@ public class Block extends BaseBlock {
tempColor.mul(1f/units); tempColor.mul(1f/units);
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i ++){ DamageArea.dynamicExplosion(x, y, flammability, explosiveness, power, tilesize * size/2f, tempColor);
int branches = 5 + Mathf.clamp((int)(power/30), 1, 20);
Timers.run(i*2f + Mathf.random(4f), () -> {
Lightning l = new Lightning(Team.none, Fx.none, 3, x, y, Mathf.random(360f), branches + Mathf.range(2));
l.color = Colors.get("power");
l.add();
});
}
for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i ++){
Timers.run(i/2, () -> {
Fireball f = new Fireball(x, y, tempColor, Mathf.random(360f));
f.add();
});
}
float e = explosiveness;
int waves = Mathf.clamp((int)(explosiveness / 4), 0, 30);
for(int i = 0; i < waves; i ++){
int f = i;
Timers.run(i*2f, () -> {
DamageArea.damage(x, y, Mathf.clamp(size * tilesize + e, 0, 50f) * ((f + 1f)/waves), e/2f);
Effects.effect(ExplosionFx.blockExplosionSmoke, x + Mathf.range(size * tilesize/2f), y + Mathf.range(size * tilesize/2f));
});
}
if(explosiveness > 15f){
Effects.effect(ExplosionFx.shockwave, x, y);
}
if(explosiveness > 30f){
Effects.effect(ExplosionFx.bigShockwave, x, y);
}
float shake = Math.min(explosiveness/4f + 3f, 9f);
Effects.shake(shake, shake, x, y);
Effects.effect(ExplosionFx.blockExplosion, x, y);
} }
public float getFlammability(Tile tile){ public float getFlammability(Tile tile){
if(!hasInventory || tile.entity == null){ if(!hasInventory || tile.entity == null){
if(tile.floor().liquid && !solid){
return tile.floor().liquidDrop.flammability;
}
return 0; return 0;
}else{ }else{
float result = 0f; float result = 0f;