From 1ee9684d9606b5c19b03bb4353218f4ad6b30e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=93=D0=BE=D0=BB=D0=BE=D0=BC=D1=88=D1=82=D0=BE=D0=BA?= Date: Sat, 12 Sep 2026 17:37:17 +0300 Subject: [PATCH] Leave sinking wreckage when units die over liquids (#12633) --- core/src/mindustry/content/Fx.java | 16 ++++++++++++++++ core/src/mindustry/entities/comp/UnitComp.java | 11 ++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index b49e251c32..8908703f21 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -118,6 +118,22 @@ public class Fx{ Draw.scl = p; }), + //water equivalent of wreck decals - Effect.decal() doesn't render on liquids + unitDrown = new Effect(3600f, e -> { + if(!(e.data instanceof TextureRegion reg)) return; + + Draw.z(Layer.scorch); + mixcol(e.color, 1f); + alpha(0.85f * (1f - Mathf.curve(e.fin(), 0.98f))); + rect(reg, e.x, e.y, e.rotation); + reset(); + + //small ripples drifting over the debris, so the water still reads as moving on top of it + if(Mathf.chanceDelta(0.02f)){ + Fx.ripple.at(e.x + Mathf.range(reg.width / 3f), e.y + Mathf.range(reg.height / 3f), 0.6f, e.color); + } + }), + unitSpirit = new Effect(17f, e -> { if(!(e.data instanceof Position to)) return; diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index b666c2d946..45905e2602 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -929,11 +929,20 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I } if(!headless && type.createScorch){ + Tile deathTile = world.tileWorld(x, y); + //decals don't render on liquids, so wreckage sinks instead of leaving a mark on top + boolean sinks = deathTile != null && !deathTile.floor().hasSurface(); + Color sinkColor = sinks ? deathTile.floor().mapColor : null; + for(int i = 0; i < type.wreckRegions.length; i++){ if(type.wreckRegions[i].found()){ float range = type.hitSize /4f; Tmp.v1.rnd(range); - Effect.decal(type.wreckRegions[i], x + Tmp.v1.x, y + Tmp.v1.y, rotation - 90); + if(sinks){ + Fx.unitDrown.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation - 90, sinkColor, type.wreckRegions[i]); + }else{ + Effect.decal(type.wreckRegions[i], x + Tmp.v1.x, y + Tmp.v1.y, rotation - 90); + } } } }