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

@@ -75,7 +75,7 @@ public class Bullet extends BulletEntity<BulletType>{
if(other instanceof Unit){
Unit unit = (Unit)other;
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.fx.ExplosionFx;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.effect.DamageArea;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.ItemStack;
@@ -103,18 +105,19 @@ public class Player extends Unit{
@Override
public void onDeath(){
super.onDeath();
dead = true;
if(Net.active()){
NetEvents.handleUnitDeath(this);
}
Effects.effect(ExplosionFx.explosion, this);
Effects.shake(4f, 5f, this);
float explosiveness = 2f + (inventory.hasItem() ? inventory.getItem().item.explosiveness * inventory.getItem().amount : 0f);
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);
control.setRespawnTime(respawnduration);
ui.hudfrag.fadeRespawn(true);
super.onDeath();
}
@Override

View File

@@ -1,7 +1,6 @@
package io.anuke.mindustry.entities;
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.NetEvents;
import io.anuke.mindustry.world.Block;
@@ -30,8 +29,6 @@ public class TileEntity extends Entity{
public boolean dead = false;
public boolean added;
public Fire fire;
public PowerModule power;
public InventoryModule inventory;
public LiquidModule liquid;
@@ -53,14 +50,6 @@ public class TileEntity extends Entity{
return this;
}
public boolean hasFire(){
return fire != null;
}
public void setFire(){
this.fire = new Fire(tile).add();
}
public void write(DataOutputStream stream) throws IOException{

View File

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

View File

@@ -1,13 +1,18 @@
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.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.Units;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Mathf;
@@ -20,6 +25,47 @@ public class DamageArea{
private static Rectangle rect = new Rectangle();
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.
* 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){

View File

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

View File

@@ -64,6 +64,8 @@ public class DebugFragment implements Fragment {
row();
new button("wave", () -> state.wavetime = 0f);
row();
new button("death", () -> player.damage(99999, false));
row();
new button("spawn", () -> new BaseUnit(UnitTypes.scout, Team.red).set(player.x, player.y).add());
row();
}}.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);
visible(()->control.getRespawnTime() > 0 && !state.is(State.menu));
visible(()->false);
}}.end();
}}.end();
@@ -223,6 +223,6 @@ public class HudFragment implements Fragment{
}
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;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
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.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
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.Layer;
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.ItemStack;
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.Hue;
import io.anuke.ucore.graphics.Lines;
@@ -248,48 +240,14 @@ public class Block extends BaseBlock {
tempColor.mul(1f/units);
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, 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);
DamageArea.dynamicExplosion(x, y, flammability, explosiveness, power, tilesize * size/2f, tempColor);
}
public float getFlammability(Tile tile){
if(!hasInventory || tile.entity == null){
if(tile.floor().liquid && !solid){
return tile.floor().liquidDrop.flammability;
}
return 0;
}else{
float result = 0f;