diff --git a/Barotrauma/BarotraumaClient/Source/Map/Gap.cs b/Barotrauma/BarotraumaClient/Source/Map/Gap.cs index 51fb5b309..c4b879fca 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Gap.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Gap.cs @@ -6,6 +6,8 @@ namespace Barotrauma { partial class Gap : MapEntity { + private float particleTimer; + public override void Draw(SpriteBatch sb, bool editing, bool back = true) { if (GameMain.DebugDraw) @@ -57,5 +59,106 @@ namespace Barotrauma (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); } } + + partial void EmitParticles(float deltaTime) + { + if (flowTargetHull == null || flowTargetHull.WaterVolume >= flowTargetHull.Volume) return; + + particleTimer += deltaTime; + + Vector2 pos = Position; + if (IsHorizontal) + { + pos.X += Math.Sign(flowForce.X); + pos.Y = MathHelper.Clamp((higherSurface + lowerSurface) / 2.0f, rect.Y - rect.Height, rect.Y) + 10; + } + else + { + pos.Y += Math.Sign(flowForce.Y) * rect.Height / 2.0f; + } + + //light dripping + if (open < 0.2f) + { + float particlesPerSec = open * 1000.0f; + float emitInterval = 1.0f / particlesPerSec; + while (particleTimer > emitInterval) + { + Vector2 velocity = flowForce; + if (!IsHorizontal) + { + velocity.X = Rand.Range(-500.0f, 500.0f) * open; + } + else + { + velocity.X *= Rand.Range(1.0f, 3.0f); + } + + var particle = GameMain.ParticleManager.CreateParticle( + Rand.Range(0.0f, open) < 0.05f ? "waterdrop" : "watersplash", + (Submarine == null ? pos : pos + Submarine.Position), + velocity, 0, flowTargetHull); + + particleTimer = 0.0f; + particleTimer -= emitInterval; + } + } + //heavy flow -> strong waterfall type of particles + else if (LerpedFlowForce.LengthSquared() > 20000.0f) + { + if (IsHorizontal) + { + Vector2 velocity = new Vector2( + MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f), + flowForce.Y * Rand.Range(0.5f, 0.7f)); + + var particle = GameMain.ParticleManager.CreateParticle( + "watersplash", + (Submarine == null ? pos : pos + Submarine.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f), + velocity, 0, flowTargetHull); + + if (particle != null) + { + particle.Size = particle.Size * Math.Min(Math.Abs(flowForce.X / 1000.0f), 5.0f); + } + + if (Math.Abs(flowForce.X) > 300.0f) + { + pos.X += Math.Sign(flowForce.X) * 10.0f; + pos.Y = Rand.Range(lowerSurface, rect.Y - rect.Height); + + GameMain.ParticleManager.CreateParticle( + "bubbles", + Submarine == null ? pos : pos + Submarine.Position, + flowForce / 10.0f, 0, flowTargetHull); + } + } + else + { + if (Math.Sign(flowTargetHull.Rect.Y - rect.Y) != Math.Sign(lerpedFlowForce.Y)) return; + + for (int i = 0; i < rect.Width; i += Rand.Range(80, 100)) + { + pos.X = Rand.Range(rect.X, rect.X + rect.Width); + + Vector2 velocity = new Vector2( + lerpedFlowForce.X * Rand.Range(0.5f, 0.7f), + Math.Max(lerpedFlowForce.Y, -100.0f) * Rand.Range(0.5f, 0.7f)); + + var splash = GameMain.ParticleManager.CreateParticle( + "watersplash", + Submarine == null ? pos : pos + Submarine.Position, + -velocity, 0, FlowTargetHull); + + if (splash != null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f); + + GameMain.ParticleManager.CreateParticle( + "bubbles", + Submarine == null ? pos : pos + Submarine.Position, + flowForce / 2.0f, 0, FlowTargetHull); + } + } + } + } } } diff --git a/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml b/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml index 2fd6522a8..42c6a8792 100644 --- a/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml +++ b/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml @@ -30,6 +30,44 @@ + + + + + + + + + + + 20000.0f && flowTargetHull != null && flowTargetHull.WaterVolume < flowTargetHull.Volume) - { - Vector2 pos = Position; - if (IsHorizontal) - { - pos.X += Math.Sign(flowForce.X); - pos.Y = MathHelper.Clamp((higherSurface + lowerSurface) / 2.0f, rect.Y - rect.Height, rect.Y) + 10; - - - Vector2 velocity = new Vector2( - MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f), - flowForce.Y * Rand.Range(0.5f, 0.7f)); - - var particle = GameMain.ParticleManager.CreateParticle( - "watersplash", - (Submarine == null ? pos : pos + Submarine.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f), - velocity, 0, flowTargetHull); - - if (particle != null) - { - particle.Size = particle.Size * Math.Min(Math.Abs(flowForce.X / 1000.0f), 5.0f); - } - - if (Math.Abs(flowForce.X) > 300.0f) - { - pos.X += Math.Sign(flowForce.X) * 10.0f; - pos.Y = Rand.Range(lowerSurface, rect.Y - rect.Height); - - GameMain.ParticleManager.CreateParticle( - "bubbles", - Submarine == null ? pos : pos + Submarine.Position, - flowForce / 10.0f, 0, flowTargetHull); - } - } - else - { - if (Math.Sign(flowTargetHull.Rect.Y - rect.Y) != Math.Sign(lerpedFlowForce.Y)) return; - - pos.Y += Math.Sign(flowForce.Y) * rect.Height / 2.0f; - for (int i = 0; i < rect.Width; i += (int)Rand.Range(80, 100)) - { - pos.X = Rand.Range(rect.X, rect.X + rect.Width); - - Vector2 velocity = new Vector2( - lerpedFlowForce.X * Rand.Range(0.5f, 0.7f), - Math.Max(lerpedFlowForce.Y, -100.0f) * Rand.Range(0.5f, 0.7f)); - - var splash = GameMain.ParticleManager.CreateParticle( - "watersplash", - Submarine == null ? pos : pos + Submarine.Position, - -velocity, 0, FlowTargetHull); - - if (splash != null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f); - - GameMain.ParticleManager.CreateParticle( - "bubbles", - Submarine == null ? pos : pos + Submarine.Position, - flowForce / 2.0f, 0, FlowTargetHull); - } - } - } -#endif + EmitParticles(deltaTime); if (flowTargetHull != null && lerpedFlowForce != Vector2.Zero) { @@ -312,6 +249,8 @@ namespace Barotrauma } } + partial void EmitParticles(float deltaTime); + void UpdateRoomToRoom(float deltaTime) { if (linkedTo.Count < 2) return; @@ -347,7 +286,6 @@ namespace Barotrauma //water level is above the lower boundary of the gap if (Math.Max(hull1.Surface + hull1.WaveY[hull1.WaveY.Length - 1], hull2.Surface + subOffset.Y + hull2.WaveY[0]) > rect.Y - size) { - int dir = (hull1.Pressure > hull2.Pressure + subOffset.Y) ? 1 : -1; //water flowing from the righthand room to the lefthand room diff --git a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs index a0865ede5..3f4c24d93 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs @@ -45,6 +45,8 @@ namespace Barotrauma public const int WallSectionSize = 96; public static List WallList = new List(); + const float LeakThreshold = 0.1f; + private StructurePrefab prefab; //farseer physics bodies, separated by gaps @@ -546,7 +548,7 @@ namespace Barotrauma { if (sectionIndex < 0 || sectionIndex >= sections.Length) return false; - return (sections[sectionIndex].damage>=prefab.Health); + return (sections[sectionIndex].damage >= prefab.Health); } /// @@ -556,7 +558,7 @@ namespace Barotrauma { if (sectionIndex < 0 || sectionIndex >= sections.Length) return false; - return (sections[sectionIndex].damage >= prefab.Health*0.5f); + return (sections[sectionIndex].damage >= prefab.Health * LeakThreshold); } public int SectionLength(int sectionIndex) @@ -694,14 +696,12 @@ namespace Barotrauma if (!MathUtils.IsValid(damage)) return; - - if (GameMain.Server != null && damage != sections[sectionIndex].damage) { GameMain.Server.CreateEntityEvent(this); } - if (damage < prefab.Health*0.5f) + if (damage < prefab.Health * LeakThreshold) { if (sections[sectionIndex].gap != null) { @@ -709,7 +709,7 @@ namespace Barotrauma sections[sectionIndex].gap.Remove(); sections[sectionIndex].gap = null; #if CLIENT - if(CastShadow) GenerateConvexHull(); + if (CastShadow) GenerateConvexHull(); #endif } } @@ -726,11 +726,12 @@ namespace Barotrauma sections[sectionIndex].gap.ConnectedWall = this; //AdjustKarma(attacker, 300); #if CLIENT - if(CastShadow) GenerateConvexHull(); + if (CastShadow) GenerateConvexHull(); #endif } - - sections[sectionIndex].gap.Open = (damage / prefab.Health - 0.5f) * 2.0f; + + float gapOpen = (damage / prefab.Health - LeakThreshold) * (1.0f / (1.0f - LeakThreshold)); + sections[sectionIndex].gap.Open = gapOpen; } float damageDiff = damage - sections[sectionIndex].damage;