v1.4.4.1 (Blood in the Water Update)

This commit is contained in:
Regalis11
2024-04-24 18:09:05 +03:00
parent 89b91d1c3e
commit ff1b8951a7
397 changed files with 15250 additions and 6479 deletions
@@ -24,6 +24,8 @@ namespace Barotrauma
public float damage;
public Gap gap;
public bool NoPhysicsBody;
public Structure Wall { get; }
public Vector2 Position => Wall.SectionPosition(Wall.Sections.IndexOf(this));
public Vector2 WorldPosition => Wall.SectionPosition(Wall.Sections.IndexOf(this), world: true);
@@ -49,21 +51,18 @@ namespace Barotrauma
public static List<Structure> WallList = new List<Structure>();
const float LeakThreshold = 0.1f;
const float BigGapThreshold = 0.7f;
#if CLIENT
public SpriteEffects SpriteEffects = SpriteEffects.None;
#endif
//dimensions of the wall sections' physics bodies (only used for debug rendering)
private readonly List<Vector2> bodyDebugDimensions = new List<Vector2>();
private readonly Dictionary<Body, Vector2> bodyDimensions = new Dictionary<Body, Vector2>();
private static Explosion explosionOnBroken;
#if DEBUG
[Serialize(false, IsPropertySaveable.Yes), ConditionallyEditable(ConditionallyEditable.ConditionType.HasBody)]
#else
[Serialize(false, IsPropertySaveable.Yes)]
#endif
public bool Indestructible
{
get;
@@ -596,7 +595,7 @@ namespace Barotrauma
private void CreateStairBodies()
{
Bodies = new List<Body>();
bodyDebugDimensions.Clear();
bodyDimensions.Clear();
float stairAngle = MathHelper.ToRadians(Math.Min(Prefab.StairAngle, 75.0f));
@@ -621,7 +620,7 @@ namespace Barotrauma
newBody.Position = ConvertUnits.ToSimUnits(stairPos) + BodyOffset * Scale;
bodyDebugDimensions.Add(new Vector2(bodyWidth, bodyHeight));
bodyDimensions.Add(newBody, new Vector2(bodyWidth, bodyHeight));
Bodies.Add(newBody);
}
@@ -962,18 +961,22 @@ namespace Barotrauma
return true;
}
public void AddDamage(int sectionIndex, float damage, Character attacker = null, bool emitParticles = true)
public void AddDamage(int sectionIndex, float damage, Character attacker = null, bool emitParticles = true, bool createWallDamageProjectiles = false)
{
if (!Prefab.Body || Prefab.Platform || Indestructible) { return; }
if (sectionIndex < 0 || sectionIndex > Sections.Length - 1) { return; }
var section = Sections[sectionIndex];
float prevDamage = section.damage;
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
{
SetDamage(sectionIndex, section.damage + damage, attacker);
}
#if CLIENT
if (damage > 0 && emitParticles)
{
float dmg = Math.Min(MaxHealth - section.damage, damage);
float dmg = Math.Min(section.damage - prevDamage, damage);
float particleAmount = MathHelper.Lerp(0, 25, MathUtils.InverseLerp(0, 100, dmg * Rand.Range(0.75f, 1.25f)));
// Special case for very low but frequent dmg like plasma cutter: 10% chance for emitting a particle
if (particleAmount < 1 && Rand.Value() < 0.10f)
@@ -996,13 +999,13 @@ namespace Barotrauma
var particle = GameMain.ParticleManager.CreateParticle(Prefab.DamageParticle,
position: particlePosFinal,
velocity: Rand.Vector(Rand.Range(1.0f, 50.0f)), collisionIgnoreTimer: 1f);
if (particle == null) break;
if (particle == null) { break; }
}
}
#endif
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
{
SetDamage(sectionIndex, section.damage + damage, attacker);
SetDamage(sectionIndex, section.damage + damage, attacker, createWallDamageProjectiles: createWallDamageProjectiles);
}
}
@@ -1132,7 +1135,7 @@ namespace Barotrauma
if (MathUtils.CircleIntersectsRectangle(transformedPos, attack.DamageRange, sectionRect))
{
damageAmount = attack.GetStructureDamage(deltaTime);
AddDamage(i, damageAmount, attacker);
AddDamage(i, damageAmount, attacker, createWallDamageProjectiles: attack.CreateWallDamageProjectiles);
#if CLIENT
if (attack.EmitStructureDamageParticles)
{
@@ -1165,7 +1168,11 @@ namespace Barotrauma
return new AttackResult(damageAmount, null);
}
public void SetDamage(int sectionIndex, float damage, Character attacker = null, bool createNetworkEvent = true, bool isNetworkEvent = true, bool createExplosionEffect = true)
public void SetDamage(int sectionIndex, float damage, Character attacker = null,
bool createNetworkEvent = true,
bool isNetworkEvent = true,
bool createExplosionEffect = true,
bool createWallDamageProjectiles = false)
{
if (Submarine != null && Submarine.GodMode || (Indestructible && !isNetworkEvent)) { return; }
if (!Prefab.Body) { return; }
@@ -1173,6 +1180,8 @@ namespace Barotrauma
damage = MathHelper.Clamp(damage, 0.0f, MaxHealth - Prefab.MinHealth);
if (Sections[sectionIndex].NoPhysicsBody) { return; }
#if SERVER
if (GameMain.Server != null && createNetworkEvent && damage != Sections[sectionIndex].damage)
{
@@ -1301,13 +1310,22 @@ namespace Barotrauma
}
var gap = Sections[sectionIndex].gap;
float gapOpen = MaxHealth <= 0.0f ? 0.0f : (damage / MaxHealth - LeakThreshold) * (1.0f / (1.0f - LeakThreshold));
float damageRatio = MaxHealth <= 0.0f ? 0 : damage / MaxHealth;
float gapOpen = 0;
if (damageRatio > BigGapThreshold)
{
gapOpen = MathHelper.Lerp(0.35f, 0.75f, MathUtils.InverseLerp(BigGapThreshold, 1.0f, damageRatio));
}
else if (damageRatio > LeakThreshold)
{
gapOpen = MathHelper.Lerp(0f, 0.35f, MathUtils.InverseLerp(LeakThreshold, BigGapThreshold, damageRatio));
}
gap.Open = gapOpen;
//gap appeared or became much larger -> explosion effect
if (gapOpen - prevGapOpenState > 0.25f && createExplosionEffect && !gap.IsRoomToRoom)
{
CreateWallDamageExplosion(gap, attacker);
CreateWallDamageExplosion(gap, attacker, createWallDamageProjectiles);
}
}
@@ -1337,7 +1355,7 @@ namespace Barotrauma
UpdateSections();
}
private static void CreateWallDamageExplosion(Gap gap, Character attacker)
private static void CreateWallDamageExplosion(Gap gap, Character attacker, bool createProjectiles)
{
const float explosionRange = 500.0f;
float explosionStrength = gap.Open;
@@ -1367,31 +1385,52 @@ namespace Barotrauma
{
explosionOnBroken.Attack.Afflictions.Add(AfflictionPrefab.InternalDamage.Instantiate(5.0f), null);
}
explosionOnBroken.CameraShake = 5.0f;
explosionOnBroken.IgnoreCover = false;
explosionOnBroken.OnlyInside = true;
explosionOnBroken.DistanceFalloff = false;
explosionOnBroken.PlayDamageSounds = true;
explosionOnBroken.DisableParticles();
}
explosionOnBroken.CameraShake = 25.0f;
explosionOnBroken.IgnoredCover = gap.ConnectedWall?.ToEnumerable();
explosionOnBroken.Attack.Range = explosionRange * gap.Open;
explosionOnBroken.Attack.Range = explosionOnBroken.CameraShakeRange = explosionRange * gap.Open;
explosionOnBroken.Attack.DamageMultiplier = explosionStrength;
explosionOnBroken.Attack.Stun = MathHelper.Clamp(explosionStrength, 0.5f, 1.0f);
explosionOnBroken.IgnoredCharacters.Clear();
if (attacker?.AIController is EnemyAIController) { explosionOnBroken.IgnoredCharacters.Add(attacker); }
explosionOnBroken?.Explode(gap.WorldPosition, damageSource: null, attacker: attacker);
if (createProjectiles)
{
if (ItemPrefab.Prefabs.TryGet("walldamageprojectile", out var projectilePrefab) && linkedHull != null)
{
float angle = gap.IsHorizontal ?
(linkedHull.WorldPosition.X < gap.WorldPosition.X ? MathHelper.Pi : 0) :
(linkedHull.WorldPosition.Y < gap.WorldPosition.Y ? -MathHelper.PiOver2 : MathHelper.PiOver2);
Spawner.AddItemToSpawnQueue(projectilePrefab, gap.WorldPosition, onSpawned: (item) =>
{
item.body.SetTransformIgnoreContacts(item.body.SimPosition, angle);
var projectile = item.GetComponent<Items.Components.Projectile>();
projectile?.Use();
});
}
}
#if CLIENT
SoundPlayer.PlaySound("Ricochet", gap.WorldPosition);
if (linkedHull != null)
{
for (int i = 0; i <= 50; i++)
{
Vector2 particlePos = new Vector2(Rand.Range(gap.WorldRect.X, gap.WorldRect.Right), Rand.Range(gap.WorldRect.Y - gap.WorldRect.Height, gap.WorldRect.Y));
var velocity = gap.IsHorizontal ?
var emitDirection = gap.IsHorizontal ?
gap.linkedTo[0].WorldPosition.X < gap.WorldPosition.X ? -Vector2.UnitX : Vector2.UnitX :
gap.linkedTo[0].WorldPosition.Y < gap.WorldPosition.Y ? -Vector2.UnitY : Vector2.UnitY;
velocity = new Vector2(velocity.X + Rand.Range(-0.2f, 0.2f), velocity.Y + Rand.Range(-0.2f, 0.2f));
var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, velocity * Rand.Range(100.0f, 3000.0f), collisionIgnoreTimer: 0.1f);
if (particle == null) { break; }
Vector2 particlePos = new Vector2(Rand.Range(gap.WorldRect.X, gap.WorldRect.Right), Rand.Range(gap.WorldRect.Y - gap.WorldRect.Height, gap.WorldRect.Y));
emitDirection = new Vector2(emitDirection.X + Rand.Range(-0.2f, 0.2f), emitDirection.Y + Rand.Range(-0.2f, 0.2f));
var shrapnelParticle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, emitDirection * Rand.Range(100.0f, 3000.0f), hullGuess: linkedHull, collisionIgnoreTimer: 0.1f);
var sparkParticle = GameMain.ParticleManager.CreateParticle("whitespark", particlePos, emitDirection * Rand.Range(1000.0f, 3000.0f), hullGuess: linkedHull, collisionIgnoreTimer: 0.05f);
if (shrapnelParticle == null || sparkParticle == null) { break; }
}
}
#endif
@@ -1416,7 +1455,7 @@ namespace Barotrauma
GameMain.World.Remove(b);
}
Bodies.Clear();
bodyDebugDimensions.Clear();
bodyDimensions.Clear();
#if CLIENT
convexHulls?.ForEach(ch => ch.Remove());
convexHulls?.Clear();
@@ -1454,8 +1493,27 @@ namespace Barotrauma
if (hasHoles || !Bodies.Any())
{
Body sensorBody = CreateRectBody(rect, createConvexHull: false);
sensorBody.CollisionCategories = Physics.CollisionRepair;
sensorBody.SetIsSensor(true);
sensorBody.CollisionCategories = Physics.CollisionRepairableWall;
}
foreach (var section in Sections)
{
bool intersectsWithBody = false;
foreach (var body in Bodies)
{
var bodyRect = new Rectangle(
ConvertUnits.ToDisplayUnits(body.Position - bodyDimensions[body] / 2).ToPoint(),
ConvertUnits.ToDisplayUnits(bodyDimensions[body]).ToPoint());
Rectangle sectionRect = section.rect;
sectionRect.Y -= section.rect.Height;
if (bodyRect.Intersects(sectionRect))
{
intersectsWithBody = true;
break;
}
}
section.NoPhysicsBody = !intersectsWithBody;
}
}
@@ -1511,7 +1569,7 @@ namespace Barotrauma
}
Bodies.Add(newBody);
bodyDebugDimensions.Add(new Vector2(ConvertUnits.ToSimUnits(rect.Width), ConvertUnits.ToSimUnits(rect.Height)));
bodyDimensions.Add(newBody, new Vector2(ConvertUnits.ToSimUnits(rect.Width), ConvertUnits.ToSimUnits(rect.Height)));
return newBody;
}
@@ -1534,7 +1592,7 @@ namespace Barotrauma
StairDirection = StairDirection == Direction.Left ? Direction.Right : Direction.Left;
Bodies.ForEach(b => GameMain.World.Remove(b));
Bodies.Clear();
bodyDebugDimensions.Clear();
bodyDimensions.Clear();
CreateStairBodies();
}
@@ -1562,7 +1620,7 @@ namespace Barotrauma
StairDirection = StairDirection == Direction.Left ? Direction.Right : Direction.Left;
Bodies.ForEach(b => GameMain.World.Remove(b));
Bodies.Clear();
bodyDebugDimensions.Clear();
bodyDimensions.Clear();
CreateStairBodies();
}