From e9b066b866323bf1638badf696374f0f59ed564e Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 9 Feb 2020 23:43:08 -0500 Subject: [PATCH] Fires, puddles, feature reimplementations --- .../annotations/impl/EntityProcess.java | 8 +- .../src/main/resources/classids.properties | 10 +- core/src/mindustry/content/Bullets.java | 9 +- core/src/mindustry/entities/AllDefs.java | 32 +++++ core/src/mindustry/entities/AllEntities.java | 56 --------- core/src/mindustry/entities/Damage.java | 3 +- core/src/mindustry/entities/Effects.java | 2 +- core/src/mindustry/entities/Fires.java | 65 ++++++++++ core/src/mindustry/entities/Puddles.java | 105 ++++++++++++++++ core/src/mindustry/entities/Units.java | 10 +- .../entities/bullet/LiquidBulletType.java | 19 ++- .../mindustry/entities/def/BulletComp.java | 1 + .../src/mindustry/entities/def/DecalComp.java | 1 + core/src/mindustry/entities/def/FireComp.java | 61 +-------- .../entities/def/GroundEffectComp.java | 1 + .../mindustry/entities/def/PlayerComp.java | 1 + .../mindustry/entities/def/PuddleComp.java | 119 ++++++++++++++++++ .../entities/def/StandardEffectComp.java | 1 + core/src/mindustry/entities/def/TileComp.java | 1 + core/src/mindustry/world/Block.java | 3 +- core/src/mindustry/world/BlockStorage.java | 4 +- .../blocks/defense/turrets/LiquidTurret.java | 20 +-- .../world/blocks/defense/turrets/Turret.java | 2 +- 23 files changed, 375 insertions(+), 159 deletions(-) create mode 100644 core/src/mindustry/entities/AllDefs.java delete mode 100644 core/src/mindustry/entities/AllEntities.java create mode 100644 core/src/mindustry/entities/Fires.java create mode 100644 core/src/mindustry/entities/Puddles.java create mode 100644 core/src/mindustry/entities/def/PuddleComp.java diff --git a/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java b/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java index 9ab779e575..4b6a5cabc3 100644 --- a/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java +++ b/annotations/src/main/java/mindustry/annotations/impl/EntityProcess.java @@ -192,11 +192,13 @@ public class EntityProcess extends BaseProcessor{ for(Selement type : allDefs){ EntityDef ann = type.annotation(EntityDef.class); boolean isFinal = ann.isFinal(); - if(type.isType() && !type.name().endsWith("Def")){ - err("All entity def names must end with 'Def'", type.e); + + if(type.isType() && (!type.name().endsWith("Def") && !type.name().endsWith("Comp"))){ + err("All entity def names must end with 'Def'/'Comp'", type.e); } + String name = type.isType() ? - type.name().replace("Def", "Entity") : + type.name().replace("Def", "Entity").replace("Comp", "Entity") : createName(type); //skip double classes diff --git a/annotations/src/main/resources/classids.properties b/annotations/src/main/resources/classids.properties index 42de63b71b..3f4db7471a 100644 --- a/annotations/src/main/resources/classids.properties +++ b/annotations/src/main/resources/classids.properties @@ -1,5 +1,7 @@ #Maps entity names to IDs. Autogenerated. +mindustry.entities.def.PuddleComp=12 +mindustry.entities.def.BulletComp=13 dagger=7 mindustry.entities.AllEntities.GenericBuilderDef=6 mindustry.entities.AllEntities.BulletDef=0 @@ -10,5 +12,11 @@ mindustry.entities.AllEntities.EffectDef=2 mindustry.entities.AllEntities.GenericUnitDef=5 mindustry.entities.AllEntities.TileDef=3 vanguard=10 +mindustry.entities.def.PlayerComp=17 dagger2=8 -mindustry.entities.AllEntities.DecalDef=1 \ No newline at end of file +mindustry.entities.def.DecalComp=14 +mindustry.entities.AllEntities.DecalDef=1 +mindustry.entities.def.StandardEffectComp=18 +mindustry.entities.def.TileComp=19 +mindustry.entities.def.FireComp=15 +mindustry.entities.def.GroundEffectComp=16 \ No newline at end of file diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java index a3c4925e19..c37f60f946 100644 --- a/core/src/mindustry/content/Bullets.java +++ b/core/src/mindustry/content/Bullets.java @@ -425,8 +425,7 @@ public class Bullets implements ContentList{ if(Mathf.chance(0.04 * Time.delta())){ Tile tile = world.tileWorld(b.x(), b.y()); if(tile != null){ - //TODO implement - //Fire.create(tile); + Fires.create(tile); } } @@ -521,8 +520,7 @@ public class Bullets implements ContentList{ public void hit(Bulletc b, float hitx, float hity){ hitEffect.at(hitx, hity, colors[2]); if(Mathf.chance(0.4)){ - //TODO implement - // Fire.create(world.tileWorld(hitx + Mathf.range(5f), hity + Mathf.range(5f))); + Fires.create(world.tileWorld(hitx + Mathf.range(5f), hity + Mathf.range(5f))); } } @@ -641,8 +639,7 @@ public class Bullets implements ContentList{ for(int i = 0; i < 3; i++){ Tile tile = world.tileWorld(x + Mathf.range(8f), y + Mathf.range(8f)); - //TODO implement - //Puddle.deposit(tile, Liquids.oil, 5f); + Puddles.deposit(tile, Liquids.oil, 5f); } } }; diff --git a/core/src/mindustry/entities/AllDefs.java b/core/src/mindustry/entities/AllDefs.java new file mode 100644 index 0000000000..67f41bfd5d --- /dev/null +++ b/core/src/mindustry/entities/AllDefs.java @@ -0,0 +1,32 @@ +package mindustry.entities; + +import mindustry.annotations.Annotations.*; +import mindustry.gen.*; + +class AllDefs{ + + @GroupDef(Entityc.class) + void all(){ + + } + + @GroupDef(Playerc.class) + void player(){ + + } + + @GroupDef(value = Unitc.class, spatial = true) + void unit(){ + + } + + @GroupDef(Tilec.class) + void tile(){ + + } + + @GroupDef(Syncc.class) + void sync(){ + + } +} diff --git a/core/src/mindustry/entities/AllEntities.java b/core/src/mindustry/entities/AllEntities.java deleted file mode 100644 index e7b4e159ca..0000000000 --- a/core/src/mindustry/entities/AllEntities.java +++ /dev/null @@ -1,56 +0,0 @@ -package mindustry.entities; - -import mindustry.annotations.Annotations.*; -import mindustry.gen.*; - -class AllEntities{ - - @EntityDef(value = {Bulletc.class, Velc.class, Timedc.class}, pooled = true) - class BulletDef{} - - @EntityDef(value = {Tilec.class}, isFinal = false) - class TileDef{} - - @EntityDef(value = {StandardEffectc.class, Childc.class}, pooled = true) - class EffectDef{} - - @EntityDef(value = {GroundEffectc.class, Childc.class}, pooled = true) - class GroundEffectDef{} - - @EntityDef(value = {Decalc.class}, pooled = true) - class DecalDef{} - - @EntityDef({Playerc.class}) - class PlayerDef{} - - @EntityDef({Unitc.class}) - class GenericUnitDef{} - - @EntityDef(value = {Firec.class}, pooled = true) - class FireDef{} - - @GroupDef(Entityc.class) - void all(){ - - } - - @GroupDef(Playerc.class) - void player(){ - - } - - @GroupDef(value = Unitc.class, spatial = true) - void unit(){ - - } - - @GroupDef(Tilec.class) - void tile(){ - - } - - @GroupDef(Syncc.class) - void sync(){ - - } -} diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index b1a70219c1..931cbd762d 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -66,8 +66,7 @@ public class Damage{ float cy = y + Mathf.range(range); Tile tile = world.tileWorld(cx, cy); if(tile != null){ - //TODO uncomment - //Fire.create(tile); + Fires.create(tile); } } } diff --git a/core/src/mindustry/entities/Effects.java b/core/src/mindustry/entities/Effects.java index 911cbadb83..bec60a7dea 100644 --- a/core/src/mindustry/entities/Effects.java +++ b/core/src/mindustry/entities/Effects.java @@ -41,7 +41,7 @@ public class Effects{ Rect pos = Tmp.r2.setSize(effect.size).setCenter(x, y); if(view.overlaps(pos)){ - Effectc entity = effect.ground ? GroundEffectEntity.create() : EffectEntity.create(); + Effectc entity = effect.ground ? GroundEffectEntity.create() : StandardEffectEntity.create(); entity.effect(effect); entity.rotation(rotation); entity.data(data); diff --git a/core/src/mindustry/entities/Fires.java b/core/src/mindustry/entities/Fires.java new file mode 100644 index 0000000000..6cdb2ba6b1 --- /dev/null +++ b/core/src/mindustry/entities/Fires.java @@ -0,0 +1,65 @@ +package mindustry.entities; + +import arc.*; +import arc.struct.*; +import arc.util.*; +import mindustry.content.*; +import mindustry.game.EventType.*; +import mindustry.gen.*; +import mindustry.world.*; + +import static mindustry.Vars.*; + +public class Fires{ + private static final float baseLifetime = 1000f; + private static final IntMap map = new IntMap<>(); + + /** 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 Firec get(int x, int y){ + return map.get(Pos.get(x, y)); + } + + 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()); + Fx.steam.at(fire); + if(fire.time() >= fire.lifetime()){ + Events.fire(Trigger.fireExtinguish); + } + } + } + + public static void remove(Tile tile){ + map.remove(tile.pos()); + } +} diff --git a/core/src/mindustry/entities/Puddles.java b/core/src/mindustry/entities/Puddles.java new file mode 100644 index 0000000000..29cf7aa1b8 --- /dev/null +++ b/core/src/mindustry/entities/Puddles.java @@ -0,0 +1,105 @@ +package mindustry.entities; + +import arc.math.*; +import arc.struct.*; +import arc.util.*; +import mindustry.content.*; +import mindustry.game.*; +import mindustry.gen.*; +import mindustry.type.*; +import mindustry.world.*; + +public class Puddles{ + private static final IntMap map = new IntMap<>(); + + public static final float maxLiquid = 70f; + + /** Deposists a Puddlec between tile and source. */ + public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){ + deposit(tile, source, liquid, amount, 0); + } + + /** Deposists a Puddlec at a tile. */ + public static void deposit(Tile tile, Liquid liquid, float amount){ + deposit(tile, tile, liquid, amount, 0); + } + + /** Returns the Puddlec on the specified tile. May return null. */ + public static Puddlec get(Tile tile){ + return map.get(tile.pos()); + } + + public static void deposit(Tile tile, Tile source, Liquid liquid, float amount, int generation){ + if(tile == null) return; + + if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){ + reactPuddle(tile.floor().liquidDrop, liquid, amount, tile, + (tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f); + + Puddlec p = map.get(tile.pos()); + + if(generation == 0 && p != null && p.lastRipple() <= Time.time() - 40f){ + Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, tile.floor().liquidDrop.color); + p.lastRipple(Time.time()); + } + return; + } + + Puddlec p = map.get(tile.pos()); + if(p == null){ + Puddlec puddle = PuddleEntity.create(); + puddle.tile(tile); + puddle.liquid(liquid); + puddle.amount(amount); + puddle.generation(generation); + puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f); + puddle.add(); + map.put(tile.pos(), puddle); + }else if(p.liquid() == liquid){ + p.accepting(Math.max(amount, p.accepting())); + + if(generation == 0 && p.lastRipple() <= Time.time() - 40f && p.amount() >= maxLiquid / 2f){ + Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, p.liquid().color); + p.lastRipple(Time.time()); + } + }else{ + p.amount(p.amount() + reactPuddle(p.liquid(), liquid, amount, p.tile(), p.x(), p.y())); + } + } + + public static void remove(Tile tile){ + if(tile == null) return; + + map.remove(tile.pos()); + } + + /** Reacts two liquids together at a location. */ + private static float reactPuddle(Liquid dest, Liquid liquid, float amount, Tile tile, float x, float y){ + if((dest.flammability > 0.3f && liquid.temperature > 0.7f) || + (liquid.flammability > 0.3f && dest.temperature > 0.7f)){ //flammable liquid + hot liquid + Fires.create(tile); + if(Mathf.chance(0.006 * amount)){ + Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), -1f, 1f, 1f); + } + }else if(dest.temperature > 0.7f && liquid.temperature < 0.55f){ //cold liquid poured onto hot Puddlec + if(Mathf.chance(0.5f * amount)){ + Fx.steam.at(x, y); + } + return -0.1f * amount; + }else if(liquid.temperature > 0.7f && dest.temperature < 0.55f){ //hot liquid poured onto cold Puddlec + if(Mathf.chance(0.8f * amount)){ + Fx.steam.at(x, y); + } + return -0.4f * amount; + } + return 0f; + } + + /** + * Returns whether the first liquid can 'stay' on the second one. + * Currently, the only place where this can happen is oil on water. + */ + private static boolean canStayOn(Liquid liquid, Liquid other){ + return liquid == Liquids.oil && other == Liquids.water; + } +} diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index 9c8bc16f20..7070ed6b6a 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -29,16 +29,16 @@ public class Units{ * @param range The maximum distance from the target X/Y the targeter can be for it to be valid * @return whether the target is invalid */ - public static boolean invalidateTarget(Teamc target, Team team, float x, float y, float range){ - return target == null || (range != Float.MAX_VALUE && !target.withinDst(x, y, range)) || target.team() == team || (target instanceof Healthc && !((Healthc)target).isValid()); + public static boolean invalidateTarget(Posc target, Team team, float x, float y, float range){ + return target == null || !target.isAdded() || (range != Float.MAX_VALUE && !target.withinDst(x, y, range)) || (target instanceof Teamc && ((Teamc)target).team() == team) || (target instanceof Healthc && !((Healthc)target).isValid()); } - /** See {@link #invalidateTarget(Teamc, Team, float, float, float)} */ - public static boolean invalidateTarget(Teamc target, Team team, float x, float y){ + /** See {@link #invalidateTarget(Posc, Team, float, float, float)} */ + public static boolean invalidateTarget(Posc target, Team team, float x, float y){ return invalidateTarget(target, team, x, y, Float.MAX_VALUE); } - /** See {@link #invalidateTarget(Teamc, Team, float, float, float)} */ + /** See {@link #invalidateTarget(Posc, Team, float, float, float)} */ public static boolean invalidateTarget(Teamc target, Unitc targeter, float range){ return invalidateTarget(target, targeter.team(), targeter.x(), targeter.y(), range); } diff --git a/core/src/mindustry/entities/bullet/LiquidBulletType.java b/core/src/mindustry/entities/bullet/LiquidBulletType.java index e6be46263d..4a7ddf1718 100644 --- a/core/src/mindustry/entities/bullet/LiquidBulletType.java +++ b/core/src/mindustry/entities/bullet/LiquidBulletType.java @@ -5,6 +5,7 @@ import arc.graphics.g2d.*; import arc.math.geom.*; import arc.util.ArcAnnotate.*; import mindustry.content.*; +import mindustry.entities.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.world.*; @@ -47,13 +48,12 @@ public class LiquidBulletType extends BulletType{ super.update(b); if(liquid.canExtinguish()){ - //TODO implement Tile tile = world.tileWorld(b.x(), b.y()); - //if(tile != null && Fire.has(tile.x, tile.y)){ - //Fire.extinguish(tile, 100f); - // b.remove(); - // hit(b); - //} + if(tile != null && Fires.has(tile.x, tile.y)){ + Fires.extinguish(tile, 100f); + b.remove(); + hit(b); + } } } @@ -67,14 +67,13 @@ public class LiquidBulletType extends BulletType{ @Override public void hit(Bulletc b, float hitx, float hity){ hitEffect.at(hitx, hity, liquid.color); - //TODO implement - // Puddle.deposit(world.tileWorld(hitx, hity), liquid, puddleSize); + Puddles.deposit(world.tileWorld(hitx, hity), liquid, puddleSize); if(liquid.temperature <= 0.5f && liquid.flammability < 0.3f){ float intensity = 400f; - //Fire.extinguish(world.tileWorld(hitx, hity), intensity); + Fires.extinguish(world.tileWorld(hitx, hity), intensity); for(Point2 p : Geometry.d4){ - // Fire.extinguish(world.tileWorld(hitx + p.x * tilesize, hity + p.y * tilesize), intensity); + Fires.extinguish(world.tileWorld(hitx + p.x * tilesize, hity + p.y * tilesize), intensity); } } } diff --git a/core/src/mindustry/entities/def/BulletComp.java b/core/src/mindustry/entities/def/BulletComp.java index a22a83281e..94be34b6fa 100644 --- a/core/src/mindustry/entities/def/BulletComp.java +++ b/core/src/mindustry/entities/def/BulletComp.java @@ -10,6 +10,7 @@ import mindustry.world.*; import static mindustry.Vars.*; +@EntityDef(value = {Bulletc.class}, pooled = true) @Component abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Drawc, Shielderc, Ownerc, Velc, Bulletc, Timerc, DrawLayerBulletsc{ Object data; diff --git a/core/src/mindustry/entities/def/DecalComp.java b/core/src/mindustry/entities/def/DecalComp.java index d6f8ea012b..2afd58ced4 100644 --- a/core/src/mindustry/entities/def/DecalComp.java +++ b/core/src/mindustry/entities/def/DecalComp.java @@ -6,6 +6,7 @@ import arc.math.*; import mindustry.annotations.Annotations.*; import mindustry.gen.*; +@EntityDef(value = {Decalc.class}, pooled = true) @Component abstract class DecalComp implements Drawc, Timedc, Rotc, Posc, DrawLayerFloorc{ transient float x, y, rotation; diff --git a/core/src/mindustry/entities/def/FireComp.java b/core/src/mindustry/entities/def/FireComp.java index 4f6f8b7f32..482fc19d2c 100644 --- a/core/src/mindustry/entities/def/FireComp.java +++ b/core/src/mindustry/entities/def/FireComp.java @@ -1,25 +1,22 @@ 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.*; +@EntityDef(value = {Firec.class}, pooled = true) @Component 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; + private static final float spreadChance = 0.05f, fireballChance = 0.07f; transient float time, lifetime, x, y; @@ -27,46 +24,6 @@ abstract class FireComp implements Timedc, Posc, Firec{ private Block block; private float baseFlammability = -1, puddleFlammability; - /** 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())){ @@ -82,7 +39,6 @@ abstract class FireComp implements Timedc, Posc, Firec{ } time = Mathf.clamp(time + Time.delta(), 0, lifetime()); - map.put(tile.pos(), this); if(Vars.net.client()){ return; @@ -114,7 +70,7 @@ abstract class FireComp implements Timedc, Posc, Firec{ 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); + Fires.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); @@ -122,13 +78,8 @@ abstract class FireComp implements Timedc, Posc, Firec{ } if(Mathf.chance(0.1 * Time.delta())){ - //TODO implement - //Puddle p = Puddle.getPuddle(tile); - //if(p != null){ - // puddleFlammability = p.getFlammability() / 3f; - //}else{ - puddleFlammability = 0; - //} + Puddlec p = Puddles.get(tile); + puddleFlammability = p != null ? p.getFlammability() / 3f : 0; if(damage){ entity.damage(0.4f); @@ -141,7 +92,7 @@ abstract class FireComp implements Timedc, Posc, Firec{ @Override public void remove(){ - map.remove(tile.pos()); + Fires.remove(tile); } } diff --git a/core/src/mindustry/entities/def/GroundEffectComp.java b/core/src/mindustry/entities/def/GroundEffectComp.java index c1a10fc11d..a080ad3aac 100644 --- a/core/src/mindustry/entities/def/GroundEffectComp.java +++ b/core/src/mindustry/entities/def/GroundEffectComp.java @@ -3,6 +3,7 @@ package mindustry.entities.def; import mindustry.annotations.Annotations.*; import mindustry.gen.*; +@EntityDef(value = {GroundEffectc.class, Childc.class}, pooled = true) @Component abstract class GroundEffectComp implements Effectc, DrawLayerFloorOverc{ diff --git a/core/src/mindustry/entities/def/PlayerComp.java b/core/src/mindustry/entities/def/PlayerComp.java index 1825ccf667..d953175505 100644 --- a/core/src/mindustry/entities/def/PlayerComp.java +++ b/core/src/mindustry/entities/def/PlayerComp.java @@ -20,6 +20,7 @@ import mindustry.ui.*; import static mindustry.Vars.*; +@EntityDef({Playerc.class}) @Component abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc{ @NonNull diff --git a/core/src/mindustry/entities/def/PuddleComp.java b/core/src/mindustry/entities/def/PuddleComp.java new file mode 100644 index 0000000000..381ab1a01f --- /dev/null +++ b/core/src/mindustry/entities/def/PuddleComp.java @@ -0,0 +1,119 @@ +package mindustry.entities.def; + +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.math.geom.*; +import arc.util.*; +import mindustry.*; +import mindustry.annotations.Annotations.*; +import mindustry.content.*; +import mindustry.entities.*; +import mindustry.gen.*; +import mindustry.type.*; +import mindustry.world.*; + +import static mindustry.Vars.world; +import static mindustry.entities.Puddles.maxLiquid; + +@EntityDef(value = {Puddlec.class}, pooled = true) +@Component +abstract class PuddleComp implements Posc, DrawLayerFloorOverc{ + private static final int maxGeneration = 2; + private static final Color tmp = new Color(); + private static final Rect rect = new Rect(); + private static final Rect rect2 = new Rect(); + private static int seeds; + + transient float x, y; + + float amount, lastRipple, accepting, updateTime; + int generation; + Tile tile; + Liquid liquid; + + public float getFlammability(){ + return liquid.flammability * amount; + } + + @Override + public void update(){ + //update code + float addSpeed = accepting > 0 ? 3f : 0f; + + amount -= Time.delta() * (1f - liquid.viscosity) / (5f + addSpeed); + + amount += accepting; + accepting = 0f; + + if(amount >= maxLiquid / 1.5f && generation < maxGeneration){ + float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Time.delta(); + for(Point2 point : Geometry.d4){ + Tile other = world.tile(tile.x + point.x, tile.y + point.y); + if(other != null && other.block() == Blocks.air){ + Puddles.deposit(other, tile, liquid, deposited, generation + 1); + amount -= deposited / 2f; //tweak to speed up/slow down Puddlec propagation + } + } + } + + amount = Mathf.clamp(amount, 0, maxLiquid); + + if(amount <= 0f){ + remove(); + } + + //effects-only code + if(amount >= maxLiquid / 2f && updateTime <= 0f){ + Units.nearby(rect.setSize(Mathf.clamp(amount / (maxLiquid / 1.5f)) * 10f).setCenter(x, y), unit -> { + if(unit.isGrounded()){ + unit.hitbox(rect2); + if(rect.overlaps(rect2)){ + unit.apply(liquid.effect, 60 * 2); + + if(unit.vel().len() > 0.1){ + Fx.ripple.at(unit.x(), unit.y(), liquid.color); + } + } + } + }); + + if(liquid.temperature > 0.7f && (tile.link().entity != null) && Mathf.chance(0.3 * Time.delta())){ + Fires.create(tile); + } + + updateTime = 20f; + } + + updateTime -= Time.delta(); + } + + @Override + public void drawFloorOver(){ + seeds = id(); + boolean onLiquid = tile.floor().isLiquid; + float f = Mathf.clamp(amount / (maxLiquid / 1.5f)); + float smag = onLiquid ? 0.8f : 0f; + float sscl = 20f; + + Draw.color(tmp.set(liquid.color).shiftValue(-0.05f)); + Fill.circle(x + Mathf.sin(Time.time() + seeds * 532, sscl, smag), y + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 8f); + Angles.randLenVectors(id(), 3, f * 6f, (ex, ey) -> { + Fill.circle(x + ex + Mathf.sin(Time.time() + seeds * 532, sscl, smag), + y + ey + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 5f); + seeds++; + }); + Draw.color(); + + if(liquid.lightColor.a > 0.001f && f > 0){ + Color color = liquid.lightColor; + float opacity = color.a * f; + Vars.renderer.lights.add(tile.drawx(), tile.drawy(), 30f * f, color, opacity * 0.8f); + } + } + + @Override + public void remove(){ + Puddles.remove(tile); + } +} diff --git a/core/src/mindustry/entities/def/StandardEffectComp.java b/core/src/mindustry/entities/def/StandardEffectComp.java index 4de2986f3d..5622a589e4 100644 --- a/core/src/mindustry/entities/def/StandardEffectComp.java +++ b/core/src/mindustry/entities/def/StandardEffectComp.java @@ -3,6 +3,7 @@ package mindustry.entities.def; import mindustry.annotations.Annotations.*; import mindustry.gen.*; +@EntityDef(value = {StandardEffectc.class, Childc.class}, pooled = true) @Component abstract class StandardEffectComp implements Effectc, DrawLayerEffectsc{ diff --git a/core/src/mindustry/entities/def/TileComp.java b/core/src/mindustry/entities/def/TileComp.java index 697d7d44c7..c5cdb014c8 100644 --- a/core/src/mindustry/entities/def/TileComp.java +++ b/core/src/mindustry/entities/def/TileComp.java @@ -15,6 +15,7 @@ import mindustry.world.modules.*; import static mindustry.Vars.*; +@EntityDef(value = {Tilec.class}, isFinal = false) @Component abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{ static final float timeToSleep = 60f * 1; diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index e8f679cfa4..ff24204783 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -630,8 +630,7 @@ public class Block extends BlockStorage{ Time.run(i / 2f, () -> { Tile other = world.tile(tile.x + Mathf.range(size / 2), tile.y + Mathf.range(size / 2)); if(other != null){ - //TODO puddle - //Puddle.deposit(other, liquid, splash); + Puddles.deposit(other, liquid, splash); } }); } diff --git a/core/src/mindustry/world/BlockStorage.java b/core/src/mindustry/world/BlockStorage.java index 9807952b88..0315fa4d8f 100644 --- a/core/src/mindustry/world/BlockStorage.java +++ b/core/src/mindustry/world/BlockStorage.java @@ -7,6 +7,7 @@ import arc.util.*; import mindustry.*; import mindustry.content.*; import mindustry.ctype.*; +import mindustry.entities.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.world.consumers.*; @@ -176,8 +177,7 @@ public abstract class BlockStorage extends UnlockableContent{ } }else if(leakResistance != 100f && !next.block().solid && !next.block().hasLiquids){ float leakAmount = tile.entity.liquids().get(liquid) / leakResistance; - //TODO deposit puddle - //Puddle.deposit(next, tile, liquid, leakAmount); + Puddles.deposit(next, tile, liquid, leakAmount); tile.entity.liquids().remove(liquid, leakAmount); } return 0; diff --git a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java index 6515512697..ec0920387c 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java @@ -67,16 +67,6 @@ public class LiquidTurret extends Turret{ return entity.target != null && hasAmmo(tile); } - @Override - protected boolean validateTarget(Tile tile){ - TurretEntity entity = tile.ent(); - if(entity.liquids().current().canExtinguish() && entity.target instanceof Tile){ - //TODO fix - //return Fire.has(((Tile)entity.target).x, ((Tile)entity.target).y); - } - return super.validateTarget(tile); - } - @Override protected void findTarget(Tile tile){ TurretEntity entity = tile.ent(); @@ -84,10 +74,10 @@ public class LiquidTurret extends Turret{ int tr = (int)(range / tilesize); for(int x = -tr; x <= tr; x++){ for(int y = -tr; y <= tr; y++){ - //if(Fire.has(x + tile.x, y + tile.y)){ - // entity.target = world.tile(x + tile.x, y + tile.y); - // return; - //} + if(Fires.has(x + tile.x, y + tile.y)){ + entity.target = Fires.get(x + tile.x, y + tile.y); + return; + } } } } @@ -103,7 +93,7 @@ public class LiquidTurret extends Turret{ type.shootEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation, entity.liquids().current().color); type.smokeEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation, entity.liquids().current().color); - //shootSound.at(tile); + shootSound.at(tile); if(shootShake > 0){ Effects.shake(shootShake, shootShake, tile.entity); diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 53a2e4c06f..c7fc031f96 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -317,7 +317,7 @@ public abstract class Turret extends Block{ public float recoil = 0f; public float heat; public int shots; - public Teamc target; + public Posc target; @Override public void write(DataOutput stream) throws IOException{