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

View File

@@ -163,10 +163,13 @@ namespace Barotrauma.Items.Components
}
#if CLIENT
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
ParticleEmitter.Emit(
deltaTime, item.WorldPosition + TransformedBarrelPos,
item.CurrentHull, particleAngle, -particleAngle);
if (ParticleEmitter != null)
{
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
ParticleEmitter.Emit(
deltaTime, item.WorldPosition + TransformedBarrelPos,
item.CurrentHull, particleAngle, -particleAngle);
}
#endif
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)
{
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)
{
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f);
displayPos += item.CurrentHull.Submarine.Position;
Hull hull = Hull.FindHull(displayPos, item.CurrentHull);
if (hull != null)
List<FireSource> fireSourcesInRange = new List<FireSource>();
//step along the ray in 10% intervals, collecting all fire sources in the range
for (float x = 0.0f; x <= Submarine.LastPickedFraction; x += 0.1f)
{
hull.Extinguish(deltaTime, ExtinquishAmount, displayPos);
if (hull != item.CurrentHull)
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * x);
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;
pickedPosition = Submarine.LastPickedPosition;
@@ -212,7 +223,10 @@ namespace Barotrauma.Items.Components
#if CLIENT
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(
targetStructure,
@@ -221,17 +235,9 @@ namespace Barotrauma.Items.Components
Color.Red, Color.Green);
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
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
//(to make it easier to fix a small "left-over" section)
@@ -253,7 +259,7 @@ namespace Barotrauma.Items.Components
#if CLIENT
Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
if (targetLimb.character.Submarine != null) particlePos += targetLimb.character.Submarine.DrawPosition;
if (targetLimb.character.Submarine != null) particlePos += targetLimb.character.Submarine.DrawPosition;
foreach (var emitter in ParticleEmitterHitCharacter)
{
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
@@ -283,7 +289,7 @@ namespace Barotrauma.Items.Components
if (progressBar != null) progressBar.Size = new Vector2(60.0f, 20.0f);
Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
if (targetItem.Submarine != null) particlePos += targetItem.Submarine.DrawPosition;
if (targetItem.Submarine != null) particlePos += targetItem.Submarine.DrawPosition;
foreach (var emitter in ParticleEmitterHitItem)
{
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
@@ -293,7 +299,7 @@ namespace Barotrauma.Items.Components
#endif
}
}
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
{
Gap leak = objective.OperateTarget as Gap;

View File

@@ -60,7 +60,7 @@ namespace Barotrauma
public float DamageRange
{
get { return (float)Math.Sqrt(size.X) * 20.0f; }
get { return (float)Math.Sqrt(size.X) * 20.0f; }
}
public Hull Hull
@@ -181,7 +181,7 @@ namespace Barotrauma
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
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];
if (c.AnimController.CurrentHull == null || c.IsDead) continue;
float range = DamageRange;
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;
if (!IsInDamageRange(c, DamageRange)) continue;
float dmg = (float)Math.Sqrt(size.X) * deltaTime / c.AnimController.Limbs.Length;
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)
{
if (size.X <= 0.0f || GameMain.Client != null) return;
@@ -251,7 +265,7 @@ namespace Barotrauma
for (int i = 0; i < steamCount; i++)
{
Vector2 spawnPos = new Vector2(
WorldPosition.X + Rand.Range(0.0f, size.X),
WorldPosition.X + Rand.Range(0.0f, size.X),
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));
@@ -270,26 +284,21 @@ namespace Barotrauma
//evaporate some of the water
hull.WaterVolume -= extinquishAmount;
if (GameMain.Client != null) return;
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;
#if CLIENT
float steamCount = Rand.Range(-5.0f, (float)Math.Sqrt(amount));
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));
@@ -312,6 +321,11 @@ namespace Barotrauma
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()
{
#if CLIENT
@@ -331,7 +345,7 @@ namespace Barotrauma
foreach (Decal d in burnDecals)
{
d.StopFadeIn();
}
}
#endif
hull.RemoveFire(this);