diff --git a/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java b/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java index 1d80e46c61..618b05b08b 100644 --- a/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java +++ b/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java @@ -105,7 +105,7 @@ public class EntityProcess extends BaseProcessor{ //add utility methods to interface for(Smethod method : component.methods()){ //skip private methods, those are for internal use. - if(method.is(Modifier.PRIVATE)) continue; + if(method.isAny(Modifier.PRIVATE, Modifier.STATIC)) continue; //keep track of signatures used to prevent dupes signatures.add(method.e.toString()); @@ -353,6 +353,8 @@ public class EntityProcess extends BaseProcessor{ MethodSpec.Builder resetBuilder = MethodSpec.methodBuilder("reset").addModifiers(Modifier.PUBLIC); for(FieldSpec spec : builder.fieldSpecs){ Svar variable = specVariables.get(spec); + if(variable.isAny(Modifier.STATIC, Modifier.FINAL)) continue; + if(spec.type.isPrimitive()){ //set to primitive default resetBuilder.addStatement("$L = $L", spec.name, varInitializers.containsKey(variable) ? varInitializers.get(variable) : getDefault(spec.type.toString())); diff --git a/annotations/src/main/java/mindustry/annotations/util/Svar.java b/annotations/src/main/java/mindustry/annotations/util/Svar.java index cf58d7a6f5..6f307e8bc9 100644 --- a/annotations/src/main/java/mindustry/annotations/util/Svar.java +++ b/annotations/src/main/java/mindustry/annotations/util/Svar.java @@ -11,6 +11,13 @@ public class Svar extends Selement{ super(e); } + public boolean isAny(Modifier... mods){ + for(Modifier m : mods){ + if(is(m)) return true; + } + return false; + } + public boolean is(Modifier mod){ return e.getModifiers().contains(mod); } diff --git a/core/assets/sprites/sprites2.png b/core/assets/sprites/sprites2.png index 8ec34230fb..fd61a547db 100644 Binary files a/core/assets/sprites/sprites2.png and b/core/assets/sprites/sprites2.png differ diff --git a/core/src/mindustry/entities/def/FireComp.java b/core/src/mindustry/entities/def/FireComp.java index ed33341af5..9e2a5d7e70 100644 --- a/core/src/mindustry/entities/def/FireComp.java +++ b/core/src/mindustry/entities/def/FireComp.java @@ -1,8 +1,142 @@ package mindustry.entities.def; +import arc.*; +import arc.math.*; +import arc.math.geom.*; +import arc.struct.*; +import arc.util.*; +import mindustry.*; import mindustry.annotations.Annotations.*; +import mindustry.content.*; +import mindustry.entities.*; +import mindustry.game.EventType.*; +import mindustry.game.*; import mindustry.gen.*; +import mindustry.world.*; + +import static mindustry.Vars.*; @Component -abstract class FireComp implements Timedc{ +abstract class FireComp implements Timedc, Posc, Firec{ + private static final IntMap map = new IntMap<>(); + private static final float baseLifetime = 1000f, spreadChance = 0.05f, fireballChance = 0.07f; + + transient float time, lifetime, x, y; + + Tile tile; + private Block block; + private float baseFlammability = -1, puddleFlammability; + + //TODO move these somewhere else. + /** Start a fire on the tile. If there already is a file there, refreshes its lifetime. */ + public static void create(Tile tile){ + if(net.client() || tile == null) return; //not clientside. + + Firec fire = map.get(tile.pos()); + + if(fire == null){ + fire = FireEntity.create(); + fire.tile(tile); + fire.lifetime(baseLifetime); + fire.set(tile.worldx(), tile.worldy()); + fire.add(); + map.put(tile.pos(), fire); + }else{ + fire.lifetime(baseLifetime); + fire.time(0f); + } + } + + public static boolean has(int x, int y){ + if(!Structs.inBounds(x, y, world.width(), world.height()) || !map.containsKey(Pos.get(x, y))){ + return false; + } + Firec fire = map.get(Pos.get(x, y)); + return fire.isAdded() && fire.fin() < 1f && fire.tile() != null && fire.tile().x == x && fire.tile().y == y; + } + + /** + * Attempts to extinguish a fire by shortening its life. If there is no fire here, does nothing. + */ + public static void extinguish(Tile tile, float intensity){ + if(tile != null && map.containsKey(tile.pos())){ + Firec fire = map.get(tile.pos()); + fire.time(fire.time() + intensity * Time.delta()); + if(fire.time() >= fire.lifetime()){ + Events.fire(Trigger.fireExtinguish); + } + } + } + + @Override + public void update(){ + if(Mathf.chance(0.1 * Time.delta())){ + Fx.fire.at(x + Mathf.range(4f), y + Mathf.range(4f)); + } + + if(Mathf.chance(0.05 * Time.delta())){ + Fx.fireSmoke.at(x + Mathf.range(4f), y + Mathf.range(4f)); + } + + if(Mathf.chance(0.001 * Time.delta())){ + Sounds.fire.at(this); + } + + time = Mathf.clamp(time + Time.delta(), 0, lifetime()); + map.put(tile.pos(), this); + + if(Vars.net.client()){ + return; + } + + if(time >= lifetime() || tile == null){ + remove(); + return; + } + + Tilec entity = tile.link().entity; + boolean damage = entity != null; + + float flammability = baseFlammability + puddleFlammability; + + if(!damage && flammability <= 0){ + time += Time.delta() * 8; + } + + if(baseFlammability < 0 || block != tile.block()){ + baseFlammability = tile.block().getFlammability(tile); + block = tile.block(); + } + + if(damage){ + lifetime += Mathf.clamp(flammability / 8f, 0f, 0.6f) * Time.delta(); + } + + if(flammability > 1f && Mathf.chance(spreadChance * Time.delta() * Mathf.clamp(flammability / 5f, 0.3f, 2f))){ + Point2 p = Geometry.d4[Mathf.random(3)]; + Tile other = world.tile(tile.x + p.x, tile.y + p.y); + create(other); + + if(Mathf.chance(fireballChance * Time.delta() * Mathf.clamp(flammability / 10f))){ + Bullets.fireball.createNet(Team.derelict, x, y, Mathf.random(360f), -1f, 1, 1); + } + } + + if(Mathf.chance(0.1 * Time.delta())){ + //TODO implement + //Puddle p = Puddle.getPuddle(tile); + //if(p != null){ + // puddleFlammability = p.getFlammability() / 3f; + //}else{ + puddleFlammability = 0; + //} + + if(damage){ + entity.damage(0.4f); + } + Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f, + unit -> !unit.isFlying() && !unit.isImmune(StatusEffects.burning), + unit -> unit.apply(StatusEffects.burning, 60 * 5)); + } + } } diff --git a/core/src/mindustry/graphics/ScorchGenerator.java b/core/src/mindustry/graphics/ScorchGenerator.java index 162a9dc788..b7dfd15439 100644 --- a/core/src/mindustry/graphics/ScorchGenerator.java +++ b/core/src/mindustry/graphics/ScorchGenerator.java @@ -2,7 +2,6 @@ package mindustry.graphics; import arc.graphics.*; import arc.math.*; -import arc.util.*; import arc.util.noise.*; /** Generates a scorch pixmap based on parameters. Thread safe, unless multiple scorch generators are running in parallel. */ @@ -20,9 +19,7 @@ public class ScorchGenerator{ double dst = Mathf.dst(x, y, size/2, size/2) / (size / 2f); double scaled = Math.abs(dst - 0.5f) * 5f + add; scaled -= noise(Angles.angle(x, y, size/2, size/2))*nscl; - boolean present = scaled < 1.5f; - - pix.draw(x, y, Tmp.c1.set(Color.white).a(Mathf.clamp(1f + 1.5f - (float)scaled))); + if(scaled < 1.5f) pix.draw(x, y, color); }); return pix;