diff --git a/Subsurface/Content/Particles/ParticlePrefabs.xml b/Subsurface/Content/Particles/ParticlePrefabs.xml
index da68c848f..f258b789b 100644
--- a/Subsurface/Content/Particles/ParticlePrefabs.xml
+++ b/Subsurface/Content/Particles/ParticlePrefabs.xml
@@ -9,6 +9,8 @@
lifetime="2"
growtime ="0.2"
collideswithwalls="true"
+ friction="0.01"
+ restitution="0.2"
collisionradius="30.0"
velocitychange="0.0, -9.8">
@@ -153,7 +155,8 @@
collisionradius="80.0"
velocitychange="0.0, 2.5"
animduration="4"
- restitution="0.98"
+ friction="0.01"
+ restitution="0.01"
loopanim="false">
@@ -222,6 +225,7 @@
growtime ="0.3"
lifetime="3"
collisionradius="30.0"
+ friction="0.01"
restitution="0.1"
velocitychange="0.0, -0.5">
@@ -250,7 +254,7 @@
lifetime="10.0"
drawtarget="both"
collideswithwalls="true"
- collisionradius="10.0"
+ collisionradius="10.0"
restitution="0.2"
waterdrag="0.1"
growtime ="0.0"
diff --git a/Subsurface/Source/Map/FireSource.cs b/Subsurface/Source/Map/FireSource.cs
index f9a016115..2401d8493 100644
--- a/Subsurface/Source/Map/FireSource.cs
+++ b/Subsurface/Source/Map/FireSource.cs
@@ -195,7 +195,7 @@ namespace Barotrauma
if (Rand.Int(5) == 1)
{
var smokeParticle = GameMain.ParticleManager.CreateParticle("smoke",
- particlePos, particleVel * 0.1f, 0.0f, hull);
+ particlePos, new Vector2(particleVel.X, particleVel.Y * 0.1f), 0.0f, hull);
if (smokeParticle != null)
{
@@ -236,9 +236,10 @@ namespace Barotrauma
{
if (particleHull == hull || particleHull==null) return;
- if (particleHull.FireSources.Find(fs => pos.X > fs.position.X-100.0f && pos.X < fs.position.X+fs.size.X+100.0f)!=null) return;
+ //hull already has a firesource roughly at the particles position -> don't create a new one
+ if (particleHull.FireSources.Find(fs => pos.X > fs.position.X - 100.0f && pos.X < fs.position.X + fs.size.X + 100.0f) != null) return;
- new FireSource(new Vector2(pos.X, particleHull.WorldRect.Y-particleHull.Rect.Height + 5.0f));
+ new FireSource(new Vector2(pos.X, particleHull.WorldRect.Y - particleHull.Rect.Height + 5.0f));
}
private void DamageCharacters(float deltaTime)
@@ -293,7 +294,7 @@ namespace Barotrauma
{
Vector2 spawnPos = new Vector2(
WorldPosition.X + Rand.Range(0.0f, size.X),
- Rand.Range(position.Y - size.Y, WorldPosition.Y) + 10.0f);
+ WorldPosition.Y + 10.0f);
Vector2 speed = new Vector2((spawnPos.X - (WorldPosition.X + size.X / 2.0f)), (float)Math.Sqrt(size.X) * Rand.Range(20.0f, 25.0f));
diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs
index e2aa312f2..0724fae4e 100644
--- a/Subsurface/Source/Map/Gap.cs
+++ b/Subsurface/Source/Map/Gap.cs
@@ -266,7 +266,7 @@ namespace Barotrauma
lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, deltaTime);
- if (LerpedFlowForce.LengthSquared() > 10000.0f && flowTargetHull != null && flowTargetHull.Volume < flowTargetHull.FullVolume)
+ if (LerpedFlowForce.LengthSquared() > 20000.0f && flowTargetHull != null && flowTargetHull.Volume < flowTargetHull.FullVolume)
{
//UpdateFlowForce();
@@ -274,7 +274,7 @@ namespace Barotrauma
if (isHorizontal)
{
pos.X += Math.Sign(flowForce.X);
- pos.Y = MathHelper.Clamp((higherSurface + lowerSurface) / 2.0f, rect.Y - rect.Height, rect.Y);
+ 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),
@@ -283,7 +283,7 @@ namespace Barotrauma
var particle = GameMain.ParticleManager.CreateParticle(
"watersplash",
(Submarine == null ? pos : pos + Submarine.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f),
- velocity);
+ velocity, 0, flowTargetHull);
if (particle != null)
{
@@ -298,7 +298,7 @@ namespace Barotrauma
GameMain.ParticleManager.CreateParticle(
"bubbles",
Submarine == null ? pos : pos + Submarine.Position,
- flowForce / 10.0f);
+ flowForce / 10.0f, 0, flowTargetHull);
}
}
else
diff --git a/Subsurface/Source/Particles/Particle.cs b/Subsurface/Source/Particles/Particle.cs
index 1b8ffbd52..4102288cf 100644
--- a/Subsurface/Source/Particles/Particle.cs
+++ b/Subsurface/Source/Particles/Particle.cs
@@ -182,7 +182,7 @@ namespace Barotrauma.Particles
if (prefab.DeleteOnCollision || prefab.CollidesWithWalls)
{
- Vector2 edgePos = position + prefab.CollisionRadius * Vector2.Normalize(velocity) * size.X;
+ //Vector2 edgePos = position + prefab.CollisionRadius * Vector2.Normalize(velocity) * size.X;
if (currentHull == null)
{
@@ -194,38 +194,68 @@ namespace Barotrauma.Particles
}
}
- else if (!Submarine.RectContains(currentHull.WorldRect, edgePos))
+ else
{
- if (prefab.DeleteOnCollision) return false;
-
- bool gapFound = false;
- foreach (Gap gap in hullGaps)
+ Vector2 collisionNormal = Vector2.Zero;
+ if (velocity.Y < 0.0f && position.Y - prefab.CollisionRadius * size.Y < currentHull.WorldRect.Y - currentHull.WorldRect.Height)
{
- if (!gap.isHorizontal)
+ if (prefab.DeleteOnCollision) return false;
+ collisionNormal = new Vector2(0.0f, 1.0f);
+ }
+ else if (velocity.Y > 0.0f && position.Y + prefab.CollisionRadius * size.Y > currentHull.WorldRect.Y)
+ {
+ if (prefab.DeleteOnCollision) return false;
+ collisionNormal = new Vector2(0.0f, -1.0f);
+ }
+ else if (velocity.X < 0.0f && position.X - prefab.CollisionRadius * size.X < currentHull.WorldRect.X)
+ {
+ if (prefab.DeleteOnCollision) return false;
+ collisionNormal = new Vector2(1.0f, 0.0f);
+ }
+ else if (velocity.X > 0.0f && position.X + prefab.CollisionRadius * size.X > currentHull.WorldRect.Right)
+ {
+ if (prefab.DeleteOnCollision) return false;
+ collisionNormal = new Vector2(-1.0f, 0.0f);
+ }
+
+ if (collisionNormal != Vector2.Zero)
+ {
+ bool gapFound = false;
+ foreach (Gap gap in hullGaps)
{
- if (gap.WorldRect.X > position.X || gap.WorldRect.Right < position.X) continue;
- if (Math.Sign(velocity.Y) != Math.Sign(gap.WorldRect.Y - (currentHull.WorldRect.Y - currentHull.WorldRect.Height))) continue;
+ if (gap.isHorizontal != (collisionNormal.X != 0.0f)) continue;
+
+ if (gap.isHorizontal)
+ {
+ if (gap.WorldRect.Y < position.Y || gap.WorldRect.Y - gap.WorldRect.Height > position.Y) continue;
+ int gapDir = Math.Sign(gap.WorldRect.Center.X - currentHull.WorldRect.Center.X);
+ if (Math.Sign(velocity.X) != gapDir || Math.Sign(position.X - currentHull.WorldRect.Center.X) != gapDir) continue;
+ }
+ else
+ {
+ if (gap.WorldRect.X > position.X || gap.WorldRect.Right < position.X) continue;
+ float hullCenterY = currentHull.WorldRect.Y - currentHull.WorldRect.Height / 2;
+ int gapDir = Math.Sign(gap.WorldRect.Y - hullCenterY);
+ if (Math.Sign(velocity.Y) != gapDir || Math.Sign(position.Y - hullCenterY) != gapDir) continue;
+ }
+
+ gapFound = true;
+ break;
+ }
+
+ if (!gapFound)
+ {
+ OnWallCollisionInside(currentHull, collisionNormal);
}
else
{
- if (gap.WorldRect.Y < position.Y || gap.WorldRect.Y - gap.WorldRect.Height > position.Y) continue;
- if (Math.Sign(velocity.X) != Math.Sign(gap.WorldRect.Center.X - currentHull.WorldRect.Center.X)) continue;
+ Hull newHull = Hull.FindHull(position);
+ if (newHull != currentHull)
+ {
+ hullGaps = currentHull == null ? new List() : currentHull.ConnectedGaps;
+ OnChangeHull?.Invoke(position, currentHull);
+ }
}
-
- gapFound = true;
- break;
- }
-
- if (!gapFound)
- {
- OnWallCollisionInside(currentHull, edgePos);
- }
- else
- {
- currentHull = Hull.FindHull(position);
- hullGaps = currentHull == null ? new List() : currentHull.ConnectedGaps;
-
- if (OnChangeHull != null) OnChangeHull(edgePos, currentHull);
}
}
}
@@ -242,41 +272,43 @@ namespace Barotrauma.Particles
if (Math.Abs(velocity.X) < 0.0001f && Math.Abs(velocity.Y) < 0.0001f) return;
float speed = velocity.Length();
- velocity -= (velocity / speed) * Math.Min(speed * speed * prefab.WaterDrag * deltaTime, 1.0f);
+ velocity -= (velocity / speed) * Math.Min(speed * speed * dragCoefficient * deltaTime, 1.0f);
}
- private void OnWallCollisionInside(Hull prevHull, Vector2 edgePos)
+ private void OnWallCollisionInside(Hull prevHull, Vector2 collisionNormal)
{
Rectangle prevHullRect = prevHull.WorldRect;
Vector2 subVel = ConvertUnits.ToDisplayUnits(prevHull.Submarine.Velocity);
-
velocity -= subVel;
- if (edgePos.Y < prevHullRect.Y - prevHullRect.Height)
+ if (Math.Abs(collisionNormal.X) > Math.Abs(collisionNormal.Y))
{
- position.Y = prevHullRect.Y - prevHullRect.Height + prefab.CollisionRadius;
- velocity.Y = -velocity.Y;
+ if (collisionNormal.X > 0.0f)
+ {
+ position.X = Math.Max(position.X, prevHullRect.X + prefab.CollisionRadius * size.X);
+ }
+ else
+ {
+ position.X = Math.Min(position.X, prevHullRect.Right - prefab.CollisionRadius * size.X);
+ }
+ velocity.X = Math.Sign(collisionNormal.X) * Math.Abs(velocity.X) * prefab.Restitution;
+ velocity.Y *= (1.0f - prefab.Friction);
}
- else if (edgePos.Y > prevHullRect.Y)
+ else
{
- position.Y = prevHullRect.Y - prefab.CollisionRadius;
- velocity.X = Math.Abs(velocity.Y) * Math.Sign(velocity.X);
- velocity.Y = -velocity.Y * 0.1f;
- }
+ if (collisionNormal.Y > 0.0f)
+ {
+ position.Y = Math.Max(position.Y, prevHullRect.Y - prevHullRect.Height + prefab.CollisionRadius * size.Y);
+ }
+ else
+ {
+ position.Y = Math.Min(position.Y, prevHullRect.Y - prefab.CollisionRadius * size.Y);
- if (edgePos.X < prevHullRect.X)
- {
- position.X = prevHullRect.X + prefab.CollisionRadius;
- velocity.X = -velocity.X;
+ }
+ velocity.X *= (1.0f - prefab.Friction);
+ velocity.Y = Math.Sign(collisionNormal.Y) * Math.Abs(velocity.Y) * prefab.Restitution;
}
- else if (edgePos.X > prevHullRect.X + prevHullRect.Width)
- {
- position.X = prevHullRect.X + prevHullRect.Width - prefab.CollisionRadius;
- velocity.X = -velocity.X;
- }
-
- velocity *= prefab.Restitution;
velocity += subVel;
}
@@ -347,8 +379,6 @@ namespace Barotrauma.Particles
prefab.Sprites[spriteIndex].Origin, drawRotation,
drawSize, SpriteEffects.None, prefab.Sprites[spriteIndex].Depth);
}
-
-
}
}
}
diff --git a/Subsurface/Source/Particles/ParticlePrefab.cs b/Subsurface/Source/Particles/ParticlePrefab.cs
index 47c9d29c5..0308c1fa1 100644
--- a/Subsurface/Source/Particles/ParticlePrefab.cs
+++ b/Subsurface/Source/Particles/ParticlePrefab.cs
@@ -38,6 +38,7 @@ namespace Barotrauma.Particles
public readonly bool DeleteOnCollision;
public readonly bool CollidesWithWalls;
+ public readonly float Friction;
public readonly float Restitution;
public readonly Vector2 VelocityChange;
@@ -107,6 +108,7 @@ namespace Barotrauma.Particles
Drag = ToolBox.GetAttributeFloat(element, "drag", 0.0f);
WaterDrag = ToolBox.GetAttributeFloat(element, "waterdrag", 0.0f);
+ Friction = ToolBox.GetAttributeFloat(element, "friction", 0.5f);
Restitution = ToolBox.GetAttributeFloat(element, "restitution", 0.5f);
switch (ToolBox.GetAttributeString(element, "blendstate", "alphablend"))