Applied fire extinguisher changes from the command-improvement branch: the repair tool steps through the ray that's used to find firesources in range and collects all firesources along the way instead of just checking the start and end positions of the ray (-> fires are much easier to extinguish now). Closes #274

This commit is contained in:
Joonas Rikkonen
2018-02-24 17:28:52 +02:00
parent 7044631901
commit f2f37b020e
2 changed files with 64 additions and 44 deletions
@@ -163,10 +163,13 @@ namespace Barotrauma.Items.Components
} }
#if CLIENT #if CLIENT
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi); if (ParticleEmitter != null)
ParticleEmitter.Emit( {
deltaTime, item.WorldPosition + TransformedBarrelPos, float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
item.CurrentHull, particleAngle, -particleAngle); ParticleEmitter.Emit(
deltaTime, item.WorldPosition + TransformedBarrelPos,
item.CurrentHull, particleAngle, -particleAngle);
}
#endif #endif
return true; return true;
@@ -174,27 +177,35 @@ namespace Barotrauma.Items.Components
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies) private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
{ {
Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies,
Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair, false);
if (ExtinquishAmount > 0.0f && item.CurrentHull != null) if (ExtinquishAmount > 0.0f && item.CurrentHull != null)
{ {
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f); List<FireSource> fireSourcesInRange = new List<FireSource>();
//step along the ray in 10% intervals, collecting all fire sources in the range
displayPos += item.CurrentHull.Submarine.Position; for (float x = 0.0f; x <= Submarine.LastPickedFraction; x += 0.1f)
Hull hull = Hull.FindHull(displayPos, item.CurrentHull);
if (hull != null)
{ {
hull.Extinguish(deltaTime, ExtinquishAmount, displayPos); Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * x);
if (hull != item.CurrentHull) displayPos += item.CurrentHull.Submarine.Position;
Hull hull = Hull.FindHull(displayPos, item.CurrentHull);
if (hull == null) continue;
foreach (FireSource fs in hull.FireSources)
{ {
item.CurrentHull.Extinguish(deltaTime, ExtinquishAmount, displayPos); if (fs.IsInDamageRange(displayPos, 100.0f) && !fireSourcesInRange.Contains(fs))
{
fireSourcesInRange.Add(fs);
}
} }
} }
foreach (FireSource fs in fireSourcesInRange)
{
fs.Extinguish(deltaTime, ExtinquishAmount);
}
} }
Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies,
Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair, false);
if (targetBody == null || targetBody.UserData == null) return; if (targetBody == null || targetBody.UserData == null) return;
pickedPosition = Submarine.LastPickedPosition; pickedPosition = Submarine.LastPickedPosition;
@@ -212,7 +223,10 @@ namespace Barotrauma.Items.Components
#if CLIENT #if CLIENT
Vector2 progressBarPos = targetStructure.SectionPosition(sectionIndex); Vector2 progressBarPos = targetStructure.SectionPosition(sectionIndex);
if (targetStructure.Submarine != null) progressBarPos += targetStructure.Submarine.DrawPosition; if (targetStructure.Submarine != null)
{
progressBarPos += targetStructure.Submarine.DrawPosition;
}
var progressBar = user.UpdateHUDProgressBar( var progressBar = user.UpdateHUDProgressBar(
targetStructure, targetStructure,
@@ -221,17 +235,9 @@ namespace Barotrauma.Items.Components
Color.Red, Color.Green); Color.Red, Color.Green);
if (progressBar != null) progressBar.Size = new Vector2(60.0f, 20.0f); if (progressBar != null) progressBar.Size = new Vector2(60.0f, 20.0f);
Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
if (targetStructure.Submarine != null) particlePos += targetStructure.Submarine.DrawPosition;
foreach (var emitter in ParticleEmitterHitStructure)
{
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
}
#endif #endif
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess,user); targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess, user);
//if the next section is small enough, apply the effect to it as well //if the next section is small enough, apply the effect to it as well
//(to make it easier to fix a small "left-over" section) //(to make it easier to fix a small "left-over" section)
@@ -60,7 +60,7 @@ namespace Barotrauma
public float DamageRange public float DamageRange
{ {
get { return (float)Math.Sqrt(size.X) * 20.0f; } get { return (float)Math.Sqrt(size.X) * 20.0f; }
} }
public Hull Hull public Hull Hull
@@ -181,7 +181,7 @@ namespace Barotrauma
private void OnChangeHull(Vector2 pos, Hull particleHull) private void OnChangeHull(Vector2 pos, Hull particleHull)
{ {
if (particleHull == hull || particleHull==null) return; if (particleHull == hull || particleHull == null) return;
//hull already has a firesource roughly at the particles position -> don't create a new one //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; if (particleHull.FireSources.Find(fs => pos.X > fs.position.X - 100.0f && pos.X < fs.position.X + fs.size.X + 100.0f) != null) return;
@@ -198,9 +198,7 @@ namespace Barotrauma
Character c = Character.CharacterList[i]; Character c = Character.CharacterList[i];
if (c.AnimController.CurrentHull == null || c.IsDead) continue; if (c.AnimController.CurrentHull == null || c.IsDead) continue;
float range = DamageRange; if (!IsInDamageRange(c, DamageRange)) continue;
if (c.Position.X < position.X - range || c.Position.X > position.X + size.X + range) continue;
if (c.Position.Y < position.Y - size.Y || c.Position.Y > hull.Rect.Y) continue;
float dmg = (float)Math.Sqrt(size.X) * deltaTime / c.AnimController.Limbs.Length; float dmg = (float)Math.Sqrt(size.X) * deltaTime / c.AnimController.Limbs.Length;
foreach (Limb limb in c.AnimController.Limbs) foreach (Limb limb in c.AnimController.Limbs)
@@ -210,6 +208,22 @@ namespace Barotrauma
} }
} }
public bool IsInDamageRange(Character c, float damageRange)
{
if (c.Position.X < position.X - damageRange || c.Position.X > position.X + size.X + damageRange) return false;
if (c.Position.Y < position.Y - size.Y || c.Position.Y > hull.Rect.Y) return false;
return true;
}
public bool IsInDamageRange(Vector2 worldPosition, float damageRange)
{
if (worldPosition.X < WorldPosition.X - damageRange || worldPosition.X > WorldPosition.X + size.X + damageRange) return false;
if (worldPosition.Y < WorldPosition.Y - size.Y || worldPosition.Y > hull.WorldRect.Y) return false;
return true;
}
private void DamageItems(float deltaTime) private void DamageItems(float deltaTime)
{ {
if (size.X <= 0.0f || GameMain.Client != null) return; if (size.X <= 0.0f || GameMain.Client != null) return;
@@ -276,20 +290,15 @@ namespace Barotrauma
if (size.X < 1.0f) Remove(); if (size.X < 1.0f) Remove();
} }
public void Extinguish(float deltaTime, float amount, Vector2 pos) public void Extinguish(float deltaTime, float amount)
{ {
float range = 100.0f;
if (pos.X < WorldPosition.X - range || pos.X > WorldPosition.X + size.X + range) return;
if (pos.Y < WorldPosition.Y - range || pos.Y > WorldPosition.Y + 500.0f) return;
float extinquishAmount = amount * deltaTime; float extinquishAmount = amount * deltaTime;
#if CLIENT #if CLIENT
float steamCount = Rand.Range(-5.0f, (float)Math.Sqrt(amount)); float steamCount = Rand.Range(-5.0f, (float)Math.Sqrt(amount));
for (int i = 0; i < steamCount; i++) for (int i = 0; i < steamCount; i++)
{ {
Vector2 spawnPos = new Vector2(pos.X + Rand.Range(-5.0f, 5.0f), Rand.Range(position.Y - size.Y, position.Y) + 10.0f); Vector2 spawnPos = new Vector2(Rand.Range(position.X, position.X + size.X), Rand.Range(position.Y - size.Y, position.Y) + 10.0f);
Vector2 speed = new Vector2((spawnPos.X - (position.X + size.X / 2.0f)), (float)Math.Sqrt(size.X) * Rand.Range(20.0f, 25.0f)); Vector2 speed = new Vector2((spawnPos.X - (position.X + size.X / 2.0f)), (float)Math.Sqrt(size.X) * Rand.Range(20.0f, 25.0f));
@@ -312,6 +321,11 @@ namespace Barotrauma
if (size.X < 1.0f) Remove(); if (size.X < 1.0f) Remove();
} }
public void Extinguish(float deltaTime, float amount, Vector2 worldPosition)
{
if (IsInDamageRange(worldPosition, 100.0f)) Extinguish(deltaTime, amount);
}
public void Remove() public void Remove()
{ {
#if CLIENT #if CLIENT