Tweaked structure gap logic to make smaller leaks more common. Walls now start leaking after taking >10% damage, and initially only emit smaller "drip particles".
This commit is contained in:
@@ -6,6 +6,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class Gap : MapEntity
|
partial class Gap : MapEntity
|
||||||
{
|
{
|
||||||
|
private float particleTimer;
|
||||||
|
|
||||||
public override void Draw(SpriteBatch sb, bool editing, bool back = true)
|
public override void Draw(SpriteBatch sb, bool editing, bool back = true)
|
||||||
{
|
{
|
||||||
if (GameMain.DebugDraw)
|
if (GameMain.DebugDraw)
|
||||||
@@ -57,5 +59,106 @@ namespace Barotrauma
|
|||||||
(int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f));
|
(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,44 @@
|
|||||||
<sprite texture="Content/Particles/spatter.png" sourcerect="128,128,128,128"/>
|
<sprite texture="Content/Particles/spatter.png" sourcerect="128,128,128,128"/>
|
||||||
</mist>
|
</mist>
|
||||||
|
|
||||||
|
<waterdrop
|
||||||
|
lifetime="5"
|
||||||
|
angularvelocitymin="0"
|
||||||
|
angularvelocitymax="0"
|
||||||
|
startrotationmin="0"
|
||||||
|
startrotationmax="0"
|
||||||
|
rotatetodirection="True"
|
||||||
|
drag="0"
|
||||||
|
waterdrag="0.3"
|
||||||
|
velocitychange="0,-9.8"
|
||||||
|
velocitychangewater="0,-5"
|
||||||
|
collisionradius="10"
|
||||||
|
collideswithwalls="True"
|
||||||
|
deleteoncollision="True"
|
||||||
|
friction="0.5"
|
||||||
|
restitution="0.2"
|
||||||
|
startsizemin="0.4,0.2"
|
||||||
|
startsizemax="0.4,0.2"
|
||||||
|
sizechangemin="-0.02,-0.02"
|
||||||
|
sizechangemax="-0.02,-0.02"
|
||||||
|
growtime="0.1"
|
||||||
|
startcolor="1,1,1,1"
|
||||||
|
startalpha="0.5"
|
||||||
|
colorchange="0,0,0,-0.3"
|
||||||
|
drawtarget="Air"
|
||||||
|
blendstate="AlphaBlend"
|
||||||
|
animduration="1"
|
||||||
|
loopanim="True">
|
||||||
|
<sprite texture="Content/Particles/shrapnel.png" sourcerect="0,96,32,32"/>
|
||||||
|
<sprite texture="Content/Particles/shrapnel.png" sourcerect="32,96,32,32"/>
|
||||||
|
<sprite texture="Content/Particles/shrapnel.png" sourcerect="64,96,32,32"/>
|
||||||
|
<sprite texture="Content/Particles/shrapnel.png" sourcerect="96,96,32,32"/>
|
||||||
|
<sprite texture="Content/Particles/shrapnel.png" sourcerect="128,96,32,32"/>
|
||||||
|
<sprite texture="Content/Particles/shrapnel.png" sourcerect="160,96,32,32"/>
|
||||||
|
<sprite texture="Content/Particles/shrapnel.png" sourcerect="192,96,32,32"/>
|
||||||
|
<sprite texture="Content/Particles/shrapnel.png" sourcerect="224,96,32,32"/>
|
||||||
|
</waterdrop>
|
||||||
|
|
||||||
<dustcloud
|
<dustcloud
|
||||||
startsizemin="0.8,0.8" startsizemax="1.0,1.0"
|
startsizemin="0.8,0.8" startsizemax="1.0,1.0"
|
||||||
sizechange="0.0,0.0"
|
sizechange="0.0,0.0"
|
||||||
|
|||||||
@@ -20,9 +20,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//the force of the water flow which is exerted on physics bodies
|
//the force of the water flow which is exerted on physics bodies
|
||||||
private Vector2 flowForce;
|
private Vector2 flowForce;
|
||||||
|
|
||||||
private Hull flowTargetHull;
|
private Hull flowTargetHull;
|
||||||
|
|
||||||
private float higherSurface;
|
private float higherSurface;
|
||||||
private float lowerSurface;
|
private float lowerSurface;
|
||||||
|
|
||||||
@@ -213,69 +212,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, deltaTime * 5.0f);
|
lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, deltaTime * 5.0f);
|
||||||
|
|
||||||
#if CLIENT
|
EmitParticles(deltaTime);
|
||||||
if (LerpedFlowForce.LengthSquared() > 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
|
|
||||||
|
|
||||||
if (flowTargetHull != null && lerpedFlowForce != Vector2.Zero)
|
if (flowTargetHull != null && lerpedFlowForce != Vector2.Zero)
|
||||||
{
|
{
|
||||||
@@ -312,6 +249,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void EmitParticles(float deltaTime);
|
||||||
|
|
||||||
void UpdateRoomToRoom(float deltaTime)
|
void UpdateRoomToRoom(float deltaTime)
|
||||||
{
|
{
|
||||||
if (linkedTo.Count < 2) return;
|
if (linkedTo.Count < 2) return;
|
||||||
@@ -347,7 +286,6 @@ namespace Barotrauma
|
|||||||
//water level is above the lower boundary of the gap
|
//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)
|
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;
|
int dir = (hull1.Pressure > hull2.Pressure + subOffset.Y) ? 1 : -1;
|
||||||
|
|
||||||
//water flowing from the righthand room to the lefthand room
|
//water flowing from the righthand room to the lefthand room
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ namespace Barotrauma
|
|||||||
public const int WallSectionSize = 96;
|
public const int WallSectionSize = 96;
|
||||||
public static List<Structure> WallList = new List<Structure>();
|
public static List<Structure> WallList = new List<Structure>();
|
||||||
|
|
||||||
|
const float LeakThreshold = 0.1f;
|
||||||
|
|
||||||
private StructurePrefab prefab;
|
private StructurePrefab prefab;
|
||||||
|
|
||||||
//farseer physics bodies, separated by gaps
|
//farseer physics bodies, separated by gaps
|
||||||
@@ -546,7 +548,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (sectionIndex < 0 || sectionIndex >= sections.Length) return false;
|
if (sectionIndex < 0 || sectionIndex >= sections.Length) return false;
|
||||||
|
|
||||||
return (sections[sectionIndex].damage>=prefab.Health);
|
return (sections[sectionIndex].damage >= prefab.Health);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -556,7 +558,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (sectionIndex < 0 || sectionIndex >= sections.Length) return false;
|
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)
|
public int SectionLength(int sectionIndex)
|
||||||
@@ -694,14 +696,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!MathUtils.IsValid(damage)) return;
|
if (!MathUtils.IsValid(damage)) return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (GameMain.Server != null && damage != sections[sectionIndex].damage)
|
if (GameMain.Server != null && damage != sections[sectionIndex].damage)
|
||||||
{
|
{
|
||||||
GameMain.Server.CreateEntityEvent(this);
|
GameMain.Server.CreateEntityEvent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damage < prefab.Health*0.5f)
|
if (damage < prefab.Health * LeakThreshold)
|
||||||
{
|
{
|
||||||
if (sections[sectionIndex].gap != null)
|
if (sections[sectionIndex].gap != null)
|
||||||
{
|
{
|
||||||
@@ -709,7 +709,7 @@ namespace Barotrauma
|
|||||||
sections[sectionIndex].gap.Remove();
|
sections[sectionIndex].gap.Remove();
|
||||||
sections[sectionIndex].gap = null;
|
sections[sectionIndex].gap = null;
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if(CastShadow) GenerateConvexHull();
|
if (CastShadow) GenerateConvexHull();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -726,11 +726,12 @@ namespace Barotrauma
|
|||||||
sections[sectionIndex].gap.ConnectedWall = this;
|
sections[sectionIndex].gap.ConnectedWall = this;
|
||||||
//AdjustKarma(attacker, 300);
|
//AdjustKarma(attacker, 300);
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if(CastShadow) GenerateConvexHull();
|
if (CastShadow) GenerateConvexHull();
|
||||||
#endif
|
#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;
|
float damageDiff = damage - sections[sectionIndex].damage;
|
||||||
|
|||||||
Reference in New Issue
Block a user