From 43d6ee5e06f525ace67dfaa10b2386c918843fe8 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 12 Feb 2018 11:20:25 +0200 Subject: [PATCH] Spark & smoke particle effects when welding or cutting something. Closes #155. --- .../Source/Particles/ParticleEmitter.cs | 12 +- .../Content/Items/Tools/tools.xml | 19 ++- .../Content/Particles/ParticlePrefabs.xml | 158 +++++++++++++++++- .../Items/Components/Holdable/RepairTool.cs | 113 +++++++++++-- .../Source/Items/Components/ItemComponent.cs | 15 +- 5 files changed, 276 insertions(+), 41 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs b/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs index 9cde23a8e..9ae1fbd99 100644 --- a/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs +++ b/Barotrauma/BarotraumaClient/Source/Particles/ParticleEmitter.cs @@ -21,7 +21,7 @@ namespace Barotrauma.Particles Prefab = prefab; } - public void Emit(float deltaTime, Vector2 position, Hull hullGuess = null) + public void Emit(float deltaTime, Vector2 position, Hull hullGuess = null, float angle = 0.0f, float particleRotation = 0.0f) { emitTimer += deltaTime; @@ -30,23 +30,23 @@ namespace Barotrauma.Particles float emitInterval = 1.0f / Prefab.ParticlesPerSecond; while (emitTimer > emitInterval) { - Emit(position, hullGuess); + Emit(position, hullGuess, angle, particleRotation); emitTimer -= emitInterval; } } for (int i = 0; i < Prefab.ParticleAmount; i++) { - Emit(position, hullGuess); + Emit(position, hullGuess, particleRotation); } } - private void Emit(Vector2 position, Hull hullGuess = null) + private void Emit(Vector2 position, Hull hullGuess = null, float angle = 0.0f, float particleRotation = 0.0f) { - float angle = Rand.Range(Prefab.AngleMin, Prefab.AngleMax); + angle += Rand.Range(Prefab.AngleMin, Prefab.AngleMax); Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Rand.Range(Prefab.VelocityMin, Prefab.VelocityMax); - var particle = GameMain.ParticleManager.CreateParticle(Prefab.ParticlePrefab, position, velocity, 0.0f, hullGuess); + var particle = GameMain.ParticleManager.CreateParticle(Prefab.ParticlePrefab, position, velocity, particleRotation, hullGuess); if (particle != null) { diff --git a/Barotrauma/BarotraumaShared/Content/Items/Tools/tools.xml b/Barotrauma/BarotraumaShared/Content/Items/Tools/tools.xml index 028a53555..d0acf5051 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Tools/tools.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Tools/tools.xml @@ -28,6 +28,13 @@ + + + + + + + @@ -77,11 +84,18 @@ - + + + + + + + + @@ -144,7 +158,8 @@ - + + diff --git a/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml b/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml index 42c6a8792..e7ebdb9bd 100644 --- a/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml +++ b/Barotrauma/BarotraumaShared/Content/Particles/ParticlePrefabs.xml @@ -119,7 +119,7 @@ velocitychange="0.0, 0.0"> - + + + + + + + + + + + + + + + + + + + + + + diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs index 74ae7f130..df3b9504b 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs @@ -5,6 +5,10 @@ using System; using System.Collections.Generic; using System.Xml.Linq; +#if CLIENT +using Barotrauma.Particles; +#endif + namespace Barotrauma.Items.Components { class RepairTool : ItemComponent @@ -45,18 +49,19 @@ namespace Barotrauma.Items.Components get; set; } - [Serialize("", false)] - public string Particles +#if CLIENT + public ParticleEmitter ParticleEmitter { - get { return particles; } - set { particles = value; } + get; + private set; } - [Serialize(0.0f, false)] - public float ParticleSpeed - { - get; set; - } + private List ParticleEmitterHitStructure = new List(); + + private List ParticleEmitterHitItem = new List(); + + private List ParticleEmitterHitCharacter = new List(); +#endif [Serialize("0.0,0.0", false)] public Vector2 BarrelPos @@ -89,6 +94,20 @@ namespace Barotrauma.Items.Components case "fixable": fixableEntities.Add(subElement.Attribute("name").Value); break; +#if CLIENT + case "particleemitter": + ParticleEmitter = new ParticleEmitter(subElement); + break; + case "particleemitterhititem": + ParticleEmitterHitItem.Add(new ParticleEmitter(subElement)); + break; + case "particleemitterhitstructure": + ParticleEmitterHitStructure.Add(new ParticleEmitter(subElement)); + break; + case "particleemitterhitcharacter": + ParticleEmitterHitCharacter.Add(new ParticleEmitter(subElement)); + break; +#endif } } } @@ -144,8 +163,10 @@ namespace Barotrauma.Items.Components } #if CLIENT - GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition + TransformedBarrelPos, - -item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi), ParticleSpeed); + 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; @@ -191,10 +212,7 @@ 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, @@ -203,6 +221,14 @@ 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); @@ -223,14 +249,49 @@ namespace Barotrauma.Items.Components } else if ((targetLimb = (targetBody.UserData as Limb)) != null) { - targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, user); + targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, user); + +#if CLIENT + Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition); + 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); + emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi); + } +#endif } else if ((targetItem = (targetBody.UserData as Item)) != null) { targetItem.IsHighlighted = true; - ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime); - } + float prevCondition = targetItem.Condition; + + ApplyStatusEffectsOnTarget(deltaTime, ActionType.OnUse, targetItem.AllPropertyObjects); + +#if CLIENT + if (item.Condition != prevCondition) + { + Vector2 progressBarPos = targetItem.DrawPosition; + + var progressBar = user.UpdateHUDProgressBar( + targetItem, + progressBarPos, + targetItem.Condition / 100.0f, + Color.Red, Color.Green); + + if (progressBar != null) progressBar.Size = new Vector2(60.0f, 20.0f); + + Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition); + 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); + emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi); + } + } +#endif + } } public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) @@ -267,5 +328,21 @@ namespace Barotrauma.Items.Components return leak.Open <= 0.0f; } + + private void ApplyStatusEffectsOnTarget(float deltaTime, ActionType actionType, List targets) + { + if (statusEffectLists == null) return; + + List statusEffects; + if (!statusEffectLists.TryGetValue(actionType, out statusEffects)) return; + + foreach (StatusEffect effect in statusEffects) + { + if (effect.Targets.HasFlag(StatusEffect.TargetType.UseTarget)) + { + effect.Apply(actionType, deltaTime, item, targets); + } + } + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs index b28c2ba29..fc8bc3c02 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs @@ -534,20 +534,7 @@ namespace Barotrauma.Items.Components item.ApplyStatusEffect(effect, type, deltaTime, character); } } - - public void ApplyStatusEffects(ActionType type, List targets, float deltaTime) - { - if (statusEffectLists == null) return; - - List statusEffects; - if (!statusEffectLists.TryGetValue(type, out statusEffects)) return; - - foreach (StatusEffect effect in statusEffects) - { - effect.Apply(type, deltaTime, item, targets); - } - } - + public virtual void Load(XElement componentElement) { if (componentElement == null) return;