diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index 03b92baa8..98c44895a 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -817,6 +817,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Subsurface/Content/Particles/ParticlePrefabs.xml b/Subsurface/Content/Particles/ParticlePrefabs.xml
index d2be342c8..7182505bc 100644
--- a/Subsurface/Content/Particles/ParticlePrefabs.xml
+++ b/Subsurface/Content/Particles/ParticlePrefabs.xml
@@ -234,4 +234,68 @@
velocitychange="0.0, 1.0">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Subsurface/Content/Particles/shrapnel.png b/Subsurface/Content/Particles/shrapnel.png
new file mode 100644
index 000000000..ad42c6eeb
Binary files /dev/null and b/Subsurface/Content/Particles/shrapnel.png differ
diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs
index b976b4ebd..1f25e71b5 100644
--- a/Subsurface/Source/Map/Gap.cs
+++ b/Subsurface/Source/Map/Gap.cs
@@ -163,6 +163,8 @@ namespace Barotrauma
hulls[1] = temp;
}
+ flowTargetHull = hulls[0];
+
for (int i = 0 ; i <2; i++)
{
if (hulls[i]==null) continue;
diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs
index a2fb24ee6..5eddba372 100644
--- a/Subsurface/Source/Map/Structure.cs
+++ b/Subsurface/Source/Map/Structure.cs
@@ -537,8 +537,22 @@ namespace Barotrauma
if (sectionIndex < 0 || sectionIndex > sections.Length - 1) return;
- if (GameMain.Client == null) SetDamage(sectionIndex, sections[sectionIndex].damage + damage);
+ var section = sections[sectionIndex];
+ int particleAmount = (int)(Math.Min(Health - section.damage, damage) * Rand.Range(0.1f, 1.0f));
+ for (int i = 0; i < particleAmount; i++)
+ {
+ Vector2 particlePos = new Vector2(
+ Rand.Range(section.rect.X, section.rect.Right),
+ Rand.Range(section.rect.Y - section.rect.Height, section.rect.Y));
+
+ if (Submarine != null) particlePos += Submarine.DrawPosition;
+
+ var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, Rand.Vector(Rand.Range(1.0f, 50.0f)));
+ if (particle == null) break;
+ }
+
+ if (GameMain.Client == null) SetDamage(sectionIndex, section.damage + damage);
}
public int FindSectionIndex(Vector2 displayPos)
diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs
index 2d633ee98..4742058f2 100644
--- a/Subsurface/Source/Map/SubmarineBody.cs
+++ b/Subsurface/Source/Map/SubmarineBody.cs
@@ -444,6 +444,18 @@ namespace Barotrauma
float wallImpact = Vector2.Dot(Velocity, -collisionNormal);
ApplyImpact(wallImpact, -collisionNormal, contact);
+
+ Vector2 n;
+ FixedArray2 particlePos;
+ contact.GetWorldManifold(out n, out particlePos);
+
+ int particleAmount = (int)(wallImpact*10.0f);
+ for (int i = 0; i < particleAmount; i++)
+ {
+ var particle = GameMain.ParticleManager.CreateParticle("iceshards",
+ ConvertUnits.ToDisplayUnits(particlePos[0]) + Rand.Vector(Rand.Range(1.0f, 50.0f)),
+ Rand.Vector(Rand.Range(50.0f,500.0f)) + Velocity);
+ }
return true;
}
diff --git a/Subsurface/Source/Particles/Particle.cs b/Subsurface/Source/Particles/Particle.cs
index df76d43c8..4d9f87429 100644
--- a/Subsurface/Source/Particles/Particle.cs
+++ b/Subsurface/Source/Particles/Particle.cs
@@ -37,6 +37,7 @@ namespace Barotrauma.Particles
private Vector2 velocityChange;
private Vector2 drawPosition;
+ private float drawRotation;
//private float checkCollisionTimer;
@@ -65,6 +66,12 @@ namespace Barotrauma.Particles
get { return velocityChange; }
set { velocityChange = value; }
}
+
+ public Vector2 Velocity
+ {
+ get { return velocity; }
+ set { velocity = value; }
+ }
public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null)
{
@@ -74,26 +81,19 @@ namespace Barotrauma.Particles
spriteIndex = Rand.Int(prefab.Sprites.Count);
currentHull = Hull.FindHull(position, hullGuess);
- //if (currentHull != null && currentHull.Submarine != null)
- //{
- // Vector2 subVel = ConvertUnits.ToDisplayUnits(currentHull.Submarine.Velocity);
- // //subVel.Y = -subVel.Y;
- // speed += subVel;
- //}
- //else
- //{
- // int a = 1;
- //}
- //if (currentHull == null) position = Submarine.Loaded == null ? position : position + Submarine.Loaded.Position;
this.position = position;
prevPosition = position;
-
+
drawPosition = position;
-
velocity = MathUtils.IsValid(speed) ? speed : Vector2.Zero;
+ if (currentHull != null && currentHull.Submarine != null)
+ {
+ velocity += ConvertUnits.ToDisplayUnits(currentHull.Submarine.Velocity);
+ }
+
this.rotation = rotation + Rand.Range(prefab.StartRotationMin, prefab.StartRotationMax);
prevRotation = rotation;
@@ -142,12 +142,12 @@ namespace Barotrauma.Particles
public bool Update(float deltaTime)
{
-
- Vector2 subVel = currentHull ==null || currentHull.Submarine==null ? Vector2.Zero : ConvertUnits.ToDisplayUnits(currentHull.Submarine.Velocity);
+ prevPosition = position;
+ prevRotation = rotation;
//over 3 times faster than position += velocity * deltatime
- position.X += (velocity.X+subVel.X) * deltaTime;
- position.Y += (velocity.Y+subVel.Y) * deltaTime;
+ position.X += velocity.X * deltaTime;
+ position.Y += velocity.Y * deltaTime;
if (prefab.RotateToDirection)
{
@@ -161,6 +161,16 @@ namespace Barotrauma.Particles
rotation += angularVelocity * deltaTime;
}
+ if (prefab.WaterDrag > 0.0f &&
+ (currentHull == null || (currentHull.Submarine != null && position.Y - currentHull.Submarine.DrawPosition.Y < currentHull.Surface)))
+ {
+ ApplyDrag(prefab.WaterDrag, deltaTime);
+ }
+ else if (prefab.Drag > 0.0f)
+ {
+ ApplyDrag(prefab.Drag, deltaTime);
+ }
+
velocity.X += velocityChange.X * deltaTime;
velocity.Y += velocityChange.Y * deltaTime;
@@ -174,11 +184,20 @@ namespace Barotrauma.Particles
color.G / 255.0f + prefab.ColorChange.Y * deltaTime,
color.B / 255.0f + prefab.ColorChange.Z * deltaTime);
- if ((prefab.DeleteOnCollision || prefab.CollidesWithWalls) && currentHull!=null)
+ if (prefab.DeleteOnCollision || prefab.CollidesWithWalls)
{
Vector2 edgePos = position + prefab.CollisionRadius * Vector2.Normalize(velocity) * size.X;
-
- if (!Submarine.RectContains(currentHull.WorldRect, edgePos))
+
+ if (currentHull == null)
+ {
+ var collidedHull = Hull.FindHullOld(edgePos);
+ if (collidedHull != null)
+ {
+ if (prefab.DeleteOnCollision) return false;
+ OnWallCollisionOutside(collidedHull);
+ }
+ }
+ else if (!Submarine.RectContains(currentHull.WorldRect, edgePos))
{
if (prefab.DeleteOnCollision) return false;
@@ -196,15 +215,13 @@ namespace Barotrauma.Particles
if (Math.Sign(velocity.X) != Math.Sign(gap.WorldRect.Center.X - currentHull.WorldRect.Center.X)) continue;
}
- //Rectangle enlargedRect = new Rectangle(gap.Rect.X - 10, gap.Rect.Y + 10, gap.Rect.Width + 20, gap.Rect.Height + 20);
- //if (!Submarine.RectContains(enlargedRect, position)) continue;
gapFound = true;
}
if (!gapFound)
{
- OnWallCollision(currentHull, edgePos);
+ OnWallCollisionInside(currentHull, edgePos);
}
else
{
@@ -212,21 +229,9 @@ namespace Barotrauma.Particles
hullGaps = currentHull == null ? new List() : currentHull.ConnectedGaps;
if (OnChangeHull != null) OnChangeHull(edgePos, currentHull);
-
- }
-
- //Hull prevHull = Hull.FindHull(prevPosition, hullLimits, currentHull);
-
- //if (prevHull == null) return false;
-
+ }
}
-
- //if (position.Y < currentHull.Rect.Y-currentHull.Rect.Height)
- //{
- // position.Y = currentHull.Rect.Y - currentHull.Rect.Height;
- // velocity.Y *= -0.2f;
- //}
- //if (!Submarine.RectContains(currentHull.Rect, position)) return false;
+
}
lifeTime -= deltaTime;
@@ -236,10 +241,22 @@ namespace Barotrauma.Particles
return true;
}
- private void OnWallCollision(Hull prevHull, Vector2 position)
+ private void ApplyDrag(float dragCoefficient, float deltaTime)
+ {
+ if (velocity == Vector2.Zero) return;
+
+ float speed = velocity.Length();
+ velocity -= (velocity / speed) * Math.Min(speed * speed * prefab.WaterDrag * deltaTime, 1.0f);
+ }
+
+ private void OnWallCollisionInside(Hull prevHull, Vector2 position)
{
Rectangle prevHullRect = prevHull.WorldRect;
+ Vector2 subVel = ConvertUnits.ToDisplayUnits(prevHull.Submarine.Velocity);
+
+ velocity -= subVel;
+
if (position.Y < prevHullRect.Y - prevHullRect.Height)
{
position.Y = prevHullRect.Y - prevHullRect.Height + 1.0f;
@@ -264,30 +281,64 @@ namespace Barotrauma.Particles
}
velocity *= prefab.Restitution;
+
+ velocity += subVel;
}
-
- public void Draw(SpriteBatch spriteBatch)
+
+
+ private void OnWallCollisionOutside(Hull collisionHull)
{
- drawPosition = Physics.Interpolate(prevPosition, position);
- float drawRotation = Physics.Interpolate(prevRotation, rotation);
-
- //drawPosition = ConvertUnits.ToDisplayUnits(drawPosition);
-
- Vector2 drawSize = size;
-
- if (prefab.GrowTime>0.0f && totalLifeTime-lifeTime < prefab.GrowTime)
+ Rectangle hullRect = collisionHull.WorldRect;
+
+ if (position.Y < hullRect.Y - hullRect.Height)
{
- drawSize *= ((totalLifeTime - lifeTime) / prefab.GrowTime);
+ position.Y = hullRect.Y - hullRect.Height - 1.0f;
+ velocity.Y = -velocity.Y;
+ }
+ else if (position.Y > hullRect.Y)
+ {
+ position.Y = hullRect.Y + 1.0f;
+ velocity.X = Math.Abs(velocity.Y) * Math.Sign(velocity.X);
+ velocity.Y = -velocity.Y;
}
- prefab.Sprites[spriteIndex].Draw(spriteBatch,
- new Vector2(drawPosition.X, -drawPosition.Y),
- color * alpha,
- prefab.Sprites[spriteIndex].Origin, drawRotation,
- drawSize, SpriteEffects.None, prefab.Sprites[spriteIndex].Depth);
+ if (position.X < hullRect.X)
+ {
+ position.X = hullRect.X - 1.0f;
+ velocity.X = -velocity.X;
+ }
+ else if (position.X > hullRect.X + hullRect.Width)
+ {
+ position.X = hullRect.X + hullRect.Width + 1.0f;
+ velocity.X = -velocity.X;
+ }
+
+ velocity *= prefab.Restitution;
+ }
+
+ public void UpdateDrawPos()
+ {
+ drawPosition = Physics.Interpolate(prevPosition, position);
+ drawRotation = Physics.Interpolate(prevRotation, rotation);
prevPosition = position;
prevRotation = rotation;
}
+
+ public void Draw(SpriteBatch spriteBatch)
+ {
+ Vector2 drawSize = size;
+
+ if (prefab.GrowTime > 0.0f && totalLifeTime - lifeTime < prefab.GrowTime)
+ {
+ drawSize *= ((totalLifeTime - lifeTime) / prefab.GrowTime);
+ }
+
+ prefab.Sprites[spriteIndex].Draw(spriteBatch,
+ new Vector2(drawPosition.X, -drawPosition.Y),
+ color * alpha,
+ prefab.Sprites[spriteIndex].Origin, drawRotation,
+ drawSize, SpriteEffects.None, prefab.Sprites[spriteIndex].Depth);
+ }
}
}
diff --git a/Subsurface/Source/Particles/ParticleManager.cs b/Subsurface/Source/Particles/ParticleManager.cs
index 9759587c1..cf522d8d1 100644
--- a/Subsurface/Source/Particles/ParticleManager.cs
+++ b/Subsurface/Source/Particles/ParticleManager.cs
@@ -113,6 +113,14 @@ namespace Barotrauma.Particles
}
}
+ public void UpdateTransforms()
+ {
+ for (int i = 0; i < particleCount; i++)
+ {
+ particles[i].UpdateDrawPos();
+ }
+ }
+
public void Draw(SpriteBatch spriteBatch, bool inWater, ParticleBlendState blendState)
{
ParticlePrefab.DrawTargetType drawTarget = inWater ? ParticlePrefab.DrawTargetType.Water : ParticlePrefab.DrawTargetType.Air;
diff --git a/Subsurface/Source/Particles/ParticlePrefab.cs b/Subsurface/Source/Particles/ParticlePrefab.cs
index 54efa74fa..c0af6a518 100644
--- a/Subsurface/Source/Particles/ParticlePrefab.cs
+++ b/Subsurface/Source/Particles/ParticlePrefab.cs
@@ -20,6 +20,8 @@ namespace Barotrauma.Particles
public readonly Vector2 StartSizeMin, StartSizeMax;
public readonly Vector2 SizeChangeMin, SizeChangeMax;
+ public readonly float Drag, WaterDrag;
+
public readonly Color StartColor;
public readonly float StartAlpha;
@@ -89,6 +91,9 @@ namespace Barotrauma.Particles
SizeChangeMax = SizeChangeMin;
}
+ Drag = ToolBox.GetAttributeFloat(element, "drag", 0.0f);
+ WaterDrag = ToolBox.GetAttributeFloat(element, "waterdrag", 0.0f);
+
Restitution = ToolBox.GetAttributeFloat(element, "restitution", 0.5f);
switch (ToolBox.GetAttributeString(element, "blendstate", "alphablend"))
diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs
index bb95df021..6fae5ad43 100644
--- a/Subsurface/Source/Screens/GameScreen.cs
+++ b/Subsurface/Source/Screens/GameScreen.cs
@@ -109,23 +109,24 @@ namespace Barotrauma
}
#endif
- if (GameMain.GameSession!=null) GameMain.GameSession.Update((float)deltaTime);
- //EventManager.Update(gameTime);
-
- if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime);
-
- Character.UpdateAll(cam, (float)deltaTime);
-
- BackgroundCreatureManager.Update(cam, (float)deltaTime);
-
- GameMain.ParticleManager.Update((float)deltaTime);
-
- StatusEffect.UpdateAll((float)deltaTime);
-
Physics.accumulator = Math.Min(Physics.accumulator, Physics.step * 6);
//Physics.accumulator = Physics.step;
while (Physics.accumulator >= Physics.step)
{
+
+ if (GameMain.GameSession != null) GameMain.GameSession.Update((float)Physics.step);
+ //EventManager.Update(gameTime);
+
+ if (Level.Loaded != null) Level.Loaded.Update((float)Physics.step);
+
+ Character.UpdateAll(cam, (float)Physics.step);
+
+ BackgroundCreatureManager.Update(cam, (float)Physics.step);
+
+ GameMain.ParticleManager.Update((float)Physics.step);
+
+ StatusEffect.UpdateAll((float)Physics.step);
+
if (Character.Controlled != null && Lights.LightManager.ViewTarget != null)
{
cam.TargetPos = Lights.LightManager.ViewTarget.WorldPosition;
@@ -210,6 +211,8 @@ namespace Barotrauma
sub.UpdateTransform();
}
+ GameMain.ParticleManager.UpdateTransforms();
+
GameMain.LightManager.ObstructVision = Character.Controlled != null && Character.Controlled.ObstructVision;
GameMain.LightManager.UpdateLightMap(graphics, spriteBatch, cam);