diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 6295b8e928..1a3b4b1dde 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -637,7 +637,6 @@ stat.buildspeed = Build Speed stat.minespeed = Mine Speed stat.minetier = Mine Tier - bar.drilltierreq = Better Drill Required bar.noresources = Missing Resources bar.corereq = Core Base Required diff --git a/core/src/mindustry/ai/BaseAI.java b/core/src/mindustry/ai/BaseAI.java index 51c5be43b3..2c1fb11617 100644 --- a/core/src/mindustry/ai/BaseAI.java +++ b/core/src/mindustry/ai/BaseAI.java @@ -72,6 +72,11 @@ public class BaseAI{ int wx = (int)(World.toTile(pos.getX()) + Tmp.v1.x), wy = (int)(World.toTile(pos.getY()) + Tmp.v1.y); Tile tile = world.tiles.getc(wx, wy); + //try not to block the spawn point + if(spawner.getSpawns().contains(t -> t.within(tile, tilesize * 40f))){ + continue; + } + Seq parts = null; //pick a completely random base part, and place it a random location diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index ca5bf9a0d0..5d0c45348d 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -1293,6 +1293,14 @@ public class Fx{ }); }), + coreBurn = new Effect(23, e -> { + randLenVectors(e.id, 5, e.fin() * 9f, (x, y) -> { + float len = e.fout() * 4f; + color(Pal.accent, Color.gray, e.fin()); + Fill.circle(e.x + x, e.y + y, len/2f); + }); + }), + plasticburn = new Effect(40, e -> { randLenVectors(e.id, 5, 3f + e.fin() * 5f, (x, y) -> { color(Color.valueOf("e9ead3"), Color.gray, e.fin()); diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 2b3ec1df0c..f7ba45b156 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1654,7 +1654,7 @@ public class UnitTypes implements ContentList{ mineTier = 1; buildSpeed = 0.5f; drag = 0.05f; - speed = 2.8f; + speed = 3f; rotateSpeed = 15f; accel = 0.1f; itemCapacity = 30; @@ -1675,7 +1675,7 @@ public class UnitTypes implements ContentList{ lifetime = 60f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - tileDamageMultiplier = 0.09f; + tileDamageMultiplier = 0.03f; }}; }}); }}; @@ -1689,7 +1689,7 @@ public class UnitTypes implements ContentList{ mineTier = 1; buildSpeed = 0.75f; drag = 0.05f; - speed = 3f; + speed = 3.3f; rotateSpeed = 17f; accel = 0.1f; itemCapacity = 50; @@ -1716,7 +1716,7 @@ public class UnitTypes implements ContentList{ lifetime = 60f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - tileDamageMultiplier = 0.1f; + tileDamageMultiplier = 0.03f; }}; }}); }}; @@ -1730,7 +1730,7 @@ public class UnitTypes implements ContentList{ mineTier = 2; buildSpeed = 1f; drag = 0.05f; - speed = 3.5f; + speed = 3.55f; rotateSpeed = 19f; accel = 0.11f; itemCapacity = 70; @@ -1755,7 +1755,7 @@ public class UnitTypes implements ContentList{ lifetime = 70f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - tileDamageMultiplier = 0.1f; + tileDamageMultiplier = 0.03f; homingPower = 0.04f; }}; }}); diff --git a/core/src/mindustry/content/Weathers.java b/core/src/mindustry/content/Weathers.java index 273fdb5899..d3758eebfb 100644 --- a/core/src/mindustry/content/Weathers.java +++ b/core/src/mindustry/content/Weathers.java @@ -1,19 +1,11 @@ package mindustry.content; -import arc.*; import arc.graphics.*; -import arc.graphics.Texture.*; -import arc.graphics.g2d.*; -import arc.math.*; -import arc.util.*; import mindustry.ctype.*; -import mindustry.gen.*; import mindustry.type.*; -import mindustry.world.*; +import mindustry.type.weather.*; import mindustry.world.meta.*; -import static mindustry.Vars.*; - public class Weathers implements ContentList{ public static Weather rain, @@ -23,317 +15,52 @@ public class Weathers implements ContentList{ @Override public void load(){ - snow = new Weather("snow"){ - TextureRegion region; - float yspeed = 2f, xspeed = 0.25f, padding = 16f, size = 12f, density = 1200f; + snow = new ParticleWeather("snow"){{ + sizeMax = 13f; + sizeMin = 2.6f; + density = 1200f; + attrs.set(Attribute.light, -0.15f); + }}; - { - attrs.set(Attribute.light, -0.15f); - } + rain = new RainWeather("rain"){{ + attrs.set(Attribute.light, -0.2f); + attrs.set(Attribute.water, 0.2f); + status = StatusEffects.wet; + }}; - @Override - public void load(){ - super.load(); + sandstorm = new ParticleWeather("sandstorm"){{ + color = stormColor = Color.valueOf("f7cba4"); + drawStorm = true; + useWindVector = true; + sizeMax = 140f; + sizeMin = 70f; + minAlpha = 0f; + maxAlpha = 0.2f; + density = 1500f; + baseSpeed = 6.1f; + attrs.set(Attribute.light, -0.1f); + attrs.set(Attribute.water, -0.1f); + opacityMultiplier = 0.8f; + force = 0.1f; + }}; - region = Core.atlas.find("circle-shadow"); - } - - @Override - public void drawOver(WeatherState state){ - rand.setSeed(0); - Tmp.r1.setCentered(Core.camera.position.x, Core.camera.position.y, Core.graphics.getWidth() / renderer.minScale(), Core.graphics.getHeight() / renderer.minScale()); - Tmp.r1.grow(padding); - Core.camera.bounds(Tmp.r2); - int total = (int)(Tmp.r1.area() / density * state.intensity()); - - for(int i = 0; i < total; i++){ - float scl = rand.random(0.5f, 1f); - float scl2 = rand.random(0.5f, 1f); - float sscl = rand.random(0.2f, 1f); - float x = (rand.random(0f, world.unitWidth()) + Time.time() * xspeed * scl2); - float y = (rand.random(0f, world.unitHeight()) - Time.time() * yspeed * scl); - - x += Mathf.sin(y, rand.random(30f, 80f), rand.random(1f, 7f)); - - x -= Tmp.r1.x; - y -= Tmp.r1.y; - x = Mathf.mod(x, Tmp.r1.width); - y = Mathf.mod(y, Tmp.r1.height); - x += Tmp.r1.x; - y += Tmp.r1.y; - - if(Tmp.r3.setCentered(x, y, size * sscl).overlaps(Tmp.r2)){ - Draw.rect(region, x, y, size * sscl, size * sscl); - } - } - } - }; - - rain = new Weather("rain"){ - float yspeed = 5f, xspeed = 1.5f, padding = 16f, size = 40f, density = 1200f; - TextureRegion[] splashes = new TextureRegion[12]; - - { - attrs.set(Attribute.light, -0.2f); - attrs.set(Attribute.water, 0.2f); - status = StatusEffects.wet; - } - - @Override - public void load(){ - super.load(); - - for(int i = 0; i < splashes.length; i++){ - splashes[i] = Core.atlas.find("splash-" + i); - } - } - - @Override - public void drawOver(WeatherState state){ - Tmp.r1.setCentered(Core.camera.position.x, Core.camera.position.y, Core.graphics.getWidth() / renderer.minScale(), Core.graphics.getHeight() / renderer.minScale()); - Tmp.r1.grow(padding); - Core.camera.bounds(Tmp.r2); - int total = (int)(Tmp.r1.area() / density * state.intensity()); - Lines.stroke(0.75f); - float alpha = Draw.getColor().a; - Draw.color(Color.royal, Color.white, 0.3f); - - for(int i = 0; i < total; i++){ - float scl = rand.random(0.5f, 1f); - float scl2 = rand.random(0.5f, 1f); - float sscl = rand.random(0.2f, 1f); - float x = (rand.random(0f, world.unitWidth()) + Time.time() * xspeed * scl2); - float y = (rand.random(0f, world.unitHeight()) - Time.time() * yspeed * scl); - float tint = rand.random(1f) * alpha; - - x -= Tmp.r1.x; - y -= Tmp.r1.y; - x = Mathf.mod(x, Tmp.r1.width); - y = Mathf.mod(y, Tmp.r1.height); - x += Tmp.r1.x; - y += Tmp.r1.y; - - if(Tmp.r3.setCentered(x, y, size * sscl).overlaps(Tmp.r2)){ - Draw.alpha(tint); - Lines.lineAngle(x, y, Angles.angle(xspeed * scl2, - yspeed * scl), size*sscl/2f); - } - } - } - - @Override - public void drawUnder(WeatherState state){ - Tmp.r1.setCentered(Core.camera.position.x, Core.camera.position.y, Core.graphics.getWidth() / renderer.minScale(), Core.graphics.getHeight() / renderer.minScale()); - Tmp.r1.grow(padding); - Core.camera.bounds(Tmp.r2); - int total = (int)(Tmp.r1.area() / density * state.intensity()) / 2; - Lines.stroke(0.75f); - - float t = Time.time() / 22f; - - for(int i = 0; i < total; i++){ - float offset = rand.random(0f, 1f); - float time = t + offset; - - int pos = (int)((time)); - float life = time % 1f; - float x = (rand.random(0f, world.unitWidth()) + pos*953); - float y = (rand.random(0f, world.unitHeight()) - pos*453); - - x -= Tmp.r1.x; - y -= Tmp.r1.y; - x = Mathf.mod(x, Tmp.r1.width); - y = Mathf.mod(y, Tmp.r1.height); - x += Tmp.r1.x; - y += Tmp.r1.y; - - if(Tmp.r3.setCentered(x, y, life * 4f).overlaps(Tmp.r2)){ - Tile tile = world.tileWorld(x, y); - - if(tile != null && tile.floor().liquidDrop == Liquids.water){ - Draw.color(Tmp.c1.set(tile.floor().mapColor).mul(1.5f).a(state.opacity())); - Draw.rect(splashes[(int)(life * (splashes.length - 1))], x, y); - }else if(tile != null && tile.floor().liquidDrop == null && !tile.floor().solid){ - Draw.color(Color.royal, Color.white, 0.3f); - Draw.alpha(Mathf.slope(life) * state.opacity()); - - float space = 45f; - for(int j : new int[]{-1, 1}){ - Tmp.v1.trns(90f + j*space, 1f + 5f * life); - Lines.lineAngle(x + Tmp.v1.x, y + Tmp.v1.y, 90f + j*space, 3f * (1f - life)); - } - } - } - } - } - }; - - sandstorm = new Weather("sandstorm"){ - TextureRegion region; - float size = 140f, padding = size, invDensity = 1500f, baseSpeed = 6.1f; - float force = 0.4f * 0; - Color color = Color.valueOf("f7cba4"); - Texture noise; - - { - attrs.set(Attribute.light, -0.1f); - opacityMultiplier = 0.8f; - } - - @Override - public void load(){ - region = Core.atlas.find("circle-shadow"); - noise = new Texture("sprites/noiseAlpha.png"); - noise.setWrap(TextureWrap.repeat); - noise.setFilter(TextureFilter.linear); - } - - @Override - public void dispose(){ - noise.dispose(); - } - - @Override - public void update(WeatherState state){ - float speed = force * state.intensity; - float windx = state.windVector.x * speed, windy = state.windVector.y * speed; - - for(Unit unit : Groups.unit){ - unit.impulse(windx, windy); - } - } - - @Override - public void drawOver(WeatherState state){ - Draw.tint(color); - float speed = baseSpeed * state.intensity; - float windx = state.windVector.x * speed, windy = state.windVector.y * speed; - - float scale = 1f / 2000f; - float scroll = Time.time() * scale; - Tmp.tr1.texture = noise; - Core.camera.bounds(Tmp.r1); - Tmp.tr1.set(Tmp.r1.x*scale, Tmp.r1.y*scale, (Tmp.r1.x + Tmp.r1.width)*scale, (Tmp.r1.y + Tmp.r1.height)*scale); - Tmp.tr1.scroll(-windx * scroll, windy * scroll); - Draw.rect(Tmp.tr1, Core.camera.position.x, Core.camera.position.y, Core.camera.width, -Core.camera.height); - - rand.setSeed(0); - Tmp.r1.setCentered(Core.camera.position.x, Core.camera.position.y, Core.graphics.getWidth() / renderer.minScale(), Core.graphics.getHeight() / renderer.minScale()); - Tmp.r1.grow(padding); - Core.camera.bounds(Tmp.r2); - int total = (int)(Tmp.r1.area() / invDensity * state.intensity()); - Draw.tint(color); - float baseAlpha = Draw.getColor().a; - - for(int i = 0; i < total; i++){ - float scl = rand.random(0.5f, 1f); - float scl2 = rand.random(0.5f, 1f); - float sscl = rand.random(0.5f, 1f); - float x = (rand.random(0f, world.unitWidth()) + Time.time() * windx * scl2); - float y = (rand.random(0f, world.unitHeight()) + Time.time() * windy * scl); - float alpha = rand.random(0.2f); - - x += Mathf.sin(y, rand.random(30f, 80f), rand.random(1f, 7f)); - - x -= Tmp.r1.x; - y -= Tmp.r1.y; - x = Mathf.mod(x, Tmp.r1.width); - y = Mathf.mod(y, Tmp.r1.height); - x += Tmp.r1.x; - y += Tmp.r1.y; - - if(Tmp.r3.setCentered(x, y, size * sscl).overlaps(Tmp.r2)){ - Draw.alpha(alpha * baseAlpha); - Draw.rect(region, x, y, size * sscl, size * sscl); - } - } - } - }; - - sporestorm = new Weather("sporestorm"){ - TextureRegion region; - float size = 5f, padding = size, invDensity = 2000f, baseSpeed = 4.3f, force = 0.28f * 0; - Color color = Color.valueOf("7457ce"); - Texture noise; - - { - attrs.set(Attribute.spores, 1f); - attrs.set(Attribute.light, -0.15f); - status = StatusEffects.sporeSlowed; - statusGround = false; - opacityMultiplier = 0.85f; - } - - @Override - public void load(){ - region = Core.atlas.find("circle-shadow"); - noise = new Texture("sprites/noiseAlpha.png"); - noise.setWrap(TextureWrap.repeat); - noise.setFilter(TextureFilter.linear); - } - - @Override - public void update(WeatherState state){ - float speed = force * state.intensity; - float windx = state.windVector.x * speed, windy = state.windVector.y * speed; - - for(Unit unit : Groups.unit){ - unit.impulse(windx, windy); - } - } - - @Override - public void dispose(){ - noise.dispose(); - } - - @Override - public void drawOver(WeatherState state){ - Draw.alpha(state.opacity * 0.8f); - Draw.tint(color); - - float speed = baseSpeed * state.intensity; - float windx = state.windVector.x * speed, windy = state.windVector.y * speed; - - float scale = 1f / 2000f; - float scroll = Time.time() * scale; - Tmp.tr1.texture = noise; - Core.camera.bounds(Tmp.r1); - Tmp.tr1.set(Tmp.r1.x*scale, Tmp.r1.y*scale, (Tmp.r1.x + Tmp.r1.width)*scale, (Tmp.r1.y + Tmp.r1.height)*scale); - Tmp.tr1.scroll(-windx * scroll, windy * scroll); - Draw.rect(Tmp.tr1, Core.camera.position.x, Core.camera.position.y, Core.camera.width, -Core.camera.height); - - rand.setSeed(0); - Tmp.r1.setCentered(Core.camera.position.x, Core.camera.position.y, Core.graphics.getWidth() / renderer.minScale(), Core.graphics.getHeight() / renderer.minScale()); - Tmp.r1.grow(padding); - Core.camera.bounds(Tmp.r2); - int total = (int)(Tmp.r1.area() / invDensity * state.intensity()); - Draw.tint(color); - float baseAlpha = state.opacity; - Draw.alpha(baseAlpha); - - for(int i = 0; i < total; i++){ - float scl = rand.random(0.5f, 1f); - float scl2 = rand.random(0.5f, 1f); - float sscl = rand.random(0.5f, 1f); - float x = (rand.random(0f, world.unitWidth()) + Time.time() * windx * scl2); - float y = (rand.random(0f, world.unitHeight()) + Time.time() * windy * scl); - float alpha = rand.random(0.1f, 0.8f); - - x += Mathf.sin(y, rand.random(30f, 80f), rand.random(1f, 7f)); - - x -= Tmp.r1.x; - y -= Tmp.r1.y; - x = Mathf.mod(x, Tmp.r1.width); - y = Mathf.mod(y, Tmp.r1.height); - x += Tmp.r1.x; - y += Tmp.r1.y; - - if(Tmp.r3.setCentered(x, y, size * sscl).overlaps(Tmp.r2)){ - Draw.alpha(alpha * baseAlpha); - Fill.circle(x, y, size * sscl / 2f); - } - } - } - }; + sporestorm = new ParticleWeather("sporestorm"){{ + color = stormColor = Color.valueOf("7457ce"); + particleRegion = "circle"; + drawStorm = true; + statusGround = false; + useWindVector = true; + sizeMax = 5f; + sizeMin = 2.5f; + minAlpha = 0.1f; + maxAlpha = 0.8f; + density = 2000f; + baseSpeed = 4.3f; + attrs.set(Attribute.spores, 1f); + attrs.set(Attribute.light, -0.15f); + status = StatusEffects.sporeSlowed; + opacityMultiplier = 0.85f; + force = 0.1f; + }}; } } diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index 727fad8bed..d3f21845ad 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -50,9 +50,7 @@ public abstract class UnlockableContent extends MappableContent{ } /** Intializes stats on demand. Should only be called once. Only called before something is displayed. */ - @CallSuper public void setStats(){ - stats.intialized = true; } /** Generate any special icons for this content. Called asynchronously.*/ diff --git a/core/src/mindustry/game/Universe.java b/core/src/mindustry/game/Universe.java index 30f0100b2d..2140f08271 100644 --- a/core/src/mindustry/game/Universe.java +++ b/core/src/mindustry/game/Universe.java @@ -187,7 +187,7 @@ public class Universe{ } //add production, making sure that it's capped - sector.info.production.each((item, stat) -> sector.info.items.add(item, Math.min((int)(stat.mean * seconds * scl), sector.info.storageCapacity - sector.info.items.get(item)))); + sector.info.production.each((item, stat) -> sector.info.items.add(item, Math.min((int)(stat.mean * newSecondsPassed * scl), sector.info.storageCapacity - sector.info.items.get(item)))); sector.saveInfo(); } diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 9a1118c22d..0d88d01034 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -303,6 +303,20 @@ public class ContentParser{ return unit; }, + ContentType.weather, (TypeParser)(mod, name, value) -> { + Weather item; + if(locate(ContentType.weather, name) != null){ + item = locate(ContentType.weather, name); + readBundle(ContentType.weather, name, value); + }else{ + readBundle(ContentType.weather, name, value); + Class type = resolve(getType(value), "mindustry.type.weather"); + item = make(type); + } + currentContent = item; + read(() -> readFields(item, value)); + return item; + }, ContentType.item, parser(ContentType.item, Item::new), ContentType.liquid, parser(ContentType.liquid, Liquid::new) //ContentType.sector, parser(ContentType.sector, SectorPreset::new) diff --git a/core/src/mindustry/type/Weather.java b/core/src/mindustry/type/Weather.java index 86e44c0174..675e378541 100644 --- a/core/src/mindustry/type/Weather.java +++ b/core/src/mindustry/type/Weather.java @@ -1,6 +1,8 @@ package mindustry.type; +import arc.*; import arc.func.*; +import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; @@ -10,6 +12,7 @@ import mindustry.content.*; import mindustry.ctype.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.world.*; import mindustry.world.blocks.*; import static mindustry.Vars.*; @@ -90,6 +93,138 @@ public abstract class Weather extends UnlockableContent{ } + public void drawParticles(TextureRegion region, Color color, + float sizeMin, float sizeMax, + float density, float intensity, float opacity, + float windx, float windy, + float minAlpha, float maxAlpha, + float sinSclMin, float sinSclMax, float sinMagMin, float sinMagMax){ + rand.setSeed(0); + Tmp.r1.setCentered(Core.camera.position.x, Core.camera.position.y, Core.graphics.getWidth() / renderer.minScale(), Core.graphics.getHeight() / renderer.minScale()); + Tmp.r1.grow(sizeMax * 1.5f); + Core.camera.bounds(Tmp.r2); + int total = (int)(Tmp.r1.area() / density * intensity); + Draw.color(color, opacity); + + for(int i = 0; i < total; i++){ + float scl = rand.random(0.5f, 1f); + float scl2 = rand.random(0.5f, 1f); + float size = rand.random(sizeMin, sizeMax); + float x = (rand.random(0f, world.unitWidth()) + Time.time() * windx * scl2); + float y = (rand.random(0f, world.unitHeight()) + Time.time() * windy * scl); + float alpha = rand.random(minAlpha, maxAlpha); + + x += Mathf.sin(y, rand.random(sinSclMin, sinSclMax), rand.random(sinMagMin, sinMagMax)); + + x -= Tmp.r1.x; + y -= Tmp.r1.y; + x = Mathf.mod(x, Tmp.r1.width); + y = Mathf.mod(y, Tmp.r1.height); + x += Tmp.r1.x; + y += Tmp.r1.y; + + if(Tmp.r3.setCentered(x, y, size).overlaps(Tmp.r2)){ + Draw.alpha(alpha * opacity); + Draw.rect(region, x, y, size, size); + } + } + } + + public void drawRain(float sizeMin, float sizeMax, float xspeed, float yspeed, float density, float intensity, float stroke, Color color){ + float padding = sizeMax*0.9f; + + Tmp.r1.setCentered(Core.camera.position.x, Core.camera.position.y, Core.graphics.getWidth() / renderer.minScale(), Core.graphics.getHeight() / renderer.minScale()); + Tmp.r1.grow(padding); + Core.camera.bounds(Tmp.r2); + int total = (int)(Tmp.r1.area() / density * intensity); + Lines.stroke(stroke); + float alpha = Draw.getColor().a; + Draw.color(color); + + for(int i = 0; i < total; i++){ + float scl = rand.random(0.5f, 1f); + float scl2 = rand.random(0.5f, 1f); + float size = rand.random(sizeMin, sizeMax); + float x = (rand.random(0f, world.unitWidth()) + Time.time() * xspeed * scl2); + float y = (rand.random(0f, world.unitHeight()) - Time.time() * yspeed * scl); + float tint = rand.random(1f) * alpha; + + x -= Tmp.r1.x; + y -= Tmp.r1.y; + x = Mathf.mod(x, Tmp.r1.width); + y = Mathf.mod(y, Tmp.r1.height); + x += Tmp.r1.x; + y += Tmp.r1.y; + + if(Tmp.r3.setCentered(x, y, size).overlaps(Tmp.r2)){ + Draw.alpha(tint); + Lines.lineAngle(x, y, Angles.angle(xspeed * scl2, - yspeed * scl), size/2f); + } + } + } + + public void drawSplashes(TextureRegion[] splashes, float padding, float density, float intensity, float opacity, float timeScale, float stroke, Color color, Liquid splasher){ + Tmp.r1.setCentered(Core.camera.position.x, Core.camera.position.y, Core.graphics.getWidth() / renderer.minScale(), Core.graphics.getHeight() / renderer.minScale()); + Tmp.r1.grow(padding); + Core.camera.bounds(Tmp.r2); + int total = (int)(Tmp.r1.area() / density * intensity) / 2; + Lines.stroke(stroke); + + float t = Time.time() / timeScale; + + for(int i = 0; i < total; i++){ + float offset = rand.random(0f, 1f); + float time = t + offset; + + int pos = (int)((time)); + float life = time % 1f; + float x = (rand.random(0f, world.unitWidth()) + pos*953); + float y = (rand.random(0f, world.unitHeight()) - pos*453); + + x -= Tmp.r1.x; + y -= Tmp.r1.y; + x = Mathf.mod(x, Tmp.r1.width); + y = Mathf.mod(y, Tmp.r1.height); + x += Tmp.r1.x; + y += Tmp.r1.y; + + if(Tmp.r3.setCentered(x, y, life * 4f).overlaps(Tmp.r2)){ + Tile tile = world.tileWorld(x, y); + + //only create splashes on specific liquid. + if(tile != null && tile.floor().liquidDrop == splasher){ + Draw.color(Tmp.c1.set(tile.floor().mapColor).mul(1.5f).a(opacity)); + Draw.rect(splashes[(int)(life * (splashes.length - 1))], x, y); + }else if(tile != null && tile.floor().liquidDrop == null && !tile.floor().solid){ + Draw.color(color); + Draw.alpha(Mathf.slope(life) * opacity); + + float space = 45f; + for(int j : new int[]{-1, 1}){ + Tmp.v1.trns(90f + j*space, 1f + 5f * life); + Lines.lineAngle(x + Tmp.v1.x, y + Tmp.v1.y, 90f + j*space, 3f * (1f - life)); + } + } + } + } + } + + public void drawNoise(Texture noise, Color color, float noisescl, float opacity, float baseSpeed, float intensity, Vec2 windVector){ + Draw.alpha(opacity); + Draw.tint(color); + + float speed = baseSpeed * intensity; + float windx = windVector.x * speed, windy = windVector.y * speed; + + float scale = 1f / noisescl; + float scroll = Time.time() * scale; + Tmp.tr1.texture = noise; + Core.camera.bounds(Tmp.r1); + Tmp.tr1.set(Tmp.r1.x*scale, Tmp.r1.y*scale, (Tmp.r1.x + Tmp.r1.width)*scale, (Tmp.r1.y + Tmp.r1.height)*scale); + Tmp.tr1.scroll(-windx * scroll, -windy * scroll); + Draw.rect(Tmp.tr1, Core.camera.position.x, Core.camera.position.y, Core.camera.width, -Core.camera.height); + } + @Override public boolean isHidden(){ return true; diff --git a/core/src/mindustry/type/weather/ParticleWeather.java b/core/src/mindustry/type/weather/ParticleWeather.java new file mode 100644 index 0000000000..facb4d7297 --- /dev/null +++ b/core/src/mindustry/type/weather/ParticleWeather.java @@ -0,0 +1,79 @@ +package mindustry.type.weather; + +import arc.*; +import arc.graphics.*; +import arc.graphics.Texture.*; +import arc.graphics.g2d.*; +import arc.util.*; +import mindustry.gen.*; +import mindustry.type.*; + +public class ParticleWeather extends Weather{ + public String particleRegion = "circle-shadow"; + public Color color = Color.white.cpy(); + public TextureRegion region; + public float yspeed = -2f, xspeed = 0.25f, padding = 16f, sizeMin = 2.4f, sizeMax = 12f, density = 1200f, minAlpha = 1f, maxAlpha = 1f, force = 0, noiseScale = 2000f, baseSpeed = 6.1f; + public float sinSclMin = 30f, sinSclMax = 80f, sinMagMin = 1f, sinMagMax = 7f; + + public Color stormColor = color; + public boolean drawStorm = false, drawParticles = true, useWindVector = false; + public String noisePath = "noiseAlpha"; + public @Nullable Texture noise; + + public ParticleWeather(String name){ + super(name); + } + + @Override + public void load(){ + super.load(); + + region = Core.atlas.find(particleRegion); + + //load noise texture + //TODO mod support + if(drawStorm){ + Core.assets.load("sprites/" + noisePath + ".png", Texture.class); + } + } + + @Override + public void update(WeatherState state){ + float speed = force * state.intensity; + if(speed > 0.001f){ + float windx = state.windVector.x * speed, windy = state.windVector.y * speed; + + for(Unit unit : Groups.unit){ + unit.impulse(windx, windy); + } + } + } + + @Override + public void drawOver(WeatherState state){ + + if(drawStorm){ + if(noise == null){ + noise = Core.assets.get("sprites/" + noisePath + ".png", Texture.class); + noise.setWrap(TextureWrap.repeat); + noise.setFilter(TextureFilter.linear); + } + + drawNoise(noise, stormColor, noiseScale, state.opacity, baseSpeed, state.intensity, state.windVector); + } + + if(drawParticles){ + float windx, windy; + if(useWindVector){ + float speed = baseSpeed * state.intensity; + windx = state.windVector.x * speed; + windy = state.windVector.y * speed; + }else{ + windx = this.xspeed; + windy = this.yspeed; + } + + drawParticles(region, color, sizeMin, sizeMax, density, state.intensity, state.opacity, windx, windy, minAlpha, maxAlpha, sinSclMin, sinSclMax, sinMagMin, sinMagMax); + } + } +} diff --git a/core/src/mindustry/type/weather/RainWeather.java b/core/src/mindustry/type/weather/RainWeather.java new file mode 100644 index 0000000000..78fd096062 --- /dev/null +++ b/core/src/mindustry/type/weather/RainWeather.java @@ -0,0 +1,38 @@ +package mindustry.type.weather; + +import arc.*; +import arc.graphics.*; +import arc.graphics.g2d.*; +import mindustry.content.*; +import mindustry.gen.*; +import mindustry.type.*; + +public class RainWeather extends Weather{ + public float yspeed = 5f, xspeed = 1.5f, padding = 16f, density = 1200f, stroke = 0.75f, sizeMin = 8f, sizeMax = 40f, splashTimeScale = 22f; + public Liquid liquid = Liquids.water; + public TextureRegion[] splashes = new TextureRegion[12]; + public Color color = Color.valueOf("7a95eaff"); + + public RainWeather(String name){ + super(name); + } + + @Override + public void load(){ + super.load(); + + for(int i = 0; i < splashes.length; i++){ + splashes[i] = Core.atlas.find("splash-" + i); + } + } + + @Override + public void drawOver(WeatherState state){ + drawRain(sizeMin, sizeMax, xspeed, yspeed, density, state.intensity, stroke, color); + } + + @Override + public void drawUnder(WeatherState state){ + drawSplashes(splashes, sizeMax, density, state.intensity, state.opacity, splashTimeScale, stroke, color, liquid); + } +} diff --git a/core/src/mindustry/world/blocks/storage/StorageBlock.java b/core/src/mindustry/world/blocks/storage/StorageBlock.java index 71045e166b..32b3713350 100644 --- a/core/src/mindustry/world/blocks/storage/StorageBlock.java +++ b/core/src/mindustry/world/blocks/storage/StorageBlock.java @@ -30,7 +30,7 @@ public class StorageBlock extends Block{ Tile edge = Edges.getFacingEdge(source, self); Tile edge2 = Edges.getFacingEdge(self, source); if(edge != null && edge2 != null){ - Fx.fuelburn.at((edge.worldx() + edge2.worldx())/2f, (edge.worldy() + edge2.worldy())/2f); + Fx.coreBurn.at((edge.worldx() + edge2.worldx())/2f, (edge.worldy() + edge2.worldy())/2f); } } }