From f2f37b020e135fcbbce9601e83cd01a591f40e36 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Sat, 24 Feb 2018 17:28:52 +0200 Subject: [PATCH] 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 --- .../Items/Components/Holdable/RepairTool.cs | 64 ++++++++++--------- .../BarotraumaShared/Source/Map/FireSource.cs | 44 ++++++++----- 2 files changed, 64 insertions(+), 44 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs index df3b9504b..75ce9a7e6 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs @@ -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 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 fireSourcesInRange = new List(); + //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; diff --git a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs index 4f0a684ce..e329521ca 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs @@ -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);