From 934f6fb7e2caece89a967b1888d24631b3f19d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?= <6766154+Zumorica@users.noreply.github.com> Date: Thu, 13 Feb 2020 15:57:40 +0100 Subject: [PATCH] Add OnDamaged method to IOnDamageBehavior (#685) * Add OnDamaged method to IOnDamageBehavior * Adds Source, SourceMob to OnDamage. --- .../Components/Damage/DamageThreshold.cs | 35 +++++++++++++++++++ .../Components/Damage/DamageableComponent.cs | 14 ++++++-- .../Mining/AsteroidRockComponent.cs | 2 +- .../Components/Mobs/SpeciesComponent.cs | 4 +-- .../Components/Power/PoweredLightComponent.cs | 2 +- .../Projectiles/ProjectileComponent.cs | 7 ++-- .../Projectiles/ThrownItemComponent.cs | 2 +- .../Temperature/TemperatureComponent.cs | 2 +- .../Weapon/Melee/MeleeWeaponComponent.cs | 2 +- .../Ranged/Hitscan/HitscanWeaponComponent.cs | 6 ++-- .../Components/Damage/IDamageableComponent.cs | 12 ++++--- .../GameObjects/IOnDamageBehavior.cs | 14 ++++++-- 12 files changed, 80 insertions(+), 22 deletions(-) diff --git a/Content.Server/GameObjects/Components/Damage/DamageThreshold.cs b/Content.Server/GameObjects/Components/Damage/DamageThreshold.cs index cf9596eef9..8cf06a9103 100644 --- a/Content.Server/GameObjects/Components/Damage/DamageThreshold.cs +++ b/Content.Server/GameObjects/Components/Damage/DamageThreshold.cs @@ -1,5 +1,7 @@ using System; using Content.Shared.GameObjects; +using JetBrains.Annotations; +using Robust.Shared.Interfaces.GameObjects; namespace Content.Server.GameObjects { @@ -60,5 +62,38 @@ namespace Content.Server.GameObjects ExcessDamage = excess; } } + + public class DamageEventArgs : EventArgs + { + /// + /// Type of damage. + /// + public DamageType Type { get; } + + /// + /// Change in damage. + /// + public int Damage { get; } + + /// + /// The entity that damaged this one. + /// Could be null. + /// + public IEntity Source { get; } + + /// + /// The mob entity that damaged this one. + /// Could be null. + /// + public IEntity SourceMob { get; } + + public DamageEventArgs(DamageType type, int damage, IEntity source, IEntity sourceMob) + { + Type = type; + Damage = damage; + Source = source; + SourceMob = sourceMob; + } + } } diff --git a/Content.Server/GameObjects/Components/Damage/DamageableComponent.cs b/Content.Server/GameObjects/Components/Damage/DamageableComponent.cs index a933884708..76d34a39af 100644 --- a/Content.Server/GameObjects/Components/Damage/DamageableComponent.cs +++ b/Content.Server/GameObjects/Components/Damage/DamageableComponent.cs @@ -5,6 +5,7 @@ using Content.Server.Interfaces; using Content.Server.Interfaces.GameObjects; using Content.Shared.GameObjects; using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -36,6 +37,7 @@ namespace Content.Server.GameObjects Dictionary> Thresholds = new Dictionary>(); public event EventHandler DamageThresholdPassed; + public event EventHandler Damaged; public override ComponentState GetComponentState() { @@ -62,13 +64,14 @@ namespace Content.Server.GameObjects foreach (var damagebehavior in Owner.GetAllComponents()) { AddThresholdsFrom(damagebehavior); + Damaged += damagebehavior.OnDamaged; } RecalculateComponentThresholds(); } /// - public void TakeDamage(DamageType damageType, int amount) + public void TakeDamage(DamageType damageType, int amount, IEntity source = null, IEntity sourceMob = null) { if (damageType == DamageType.Total) { @@ -88,6 +91,8 @@ namespace Content.Server.GameObjects _currentDamage[damageType] = Math.Max(0, _currentDamage[damageType] + amount); UpdateForDamageType(damageType, oldValue); + Damaged?.Invoke(this, new DamageEventArgs(damageType, amount, source, sourceMob)); + if (Resistances.AppliesToTotal(damageType)) { oldTotalValue = _currentDamage[DamageType.Total]; @@ -97,13 +102,13 @@ namespace Content.Server.GameObjects } /// - public void TakeHealing(DamageType damageType, int amount) + public void TakeHealing(DamageType damageType, int amount, IEntity source = null, IEntity sourceMob = null) { if (damageType == DamageType.Total) { throw new ArgumentException("Cannot heal for DamageType.Total"); } - TakeDamage(damageType, -amount); + TakeDamage(damageType, -amount, source, sourceMob); } public void HealAllDamage() @@ -163,6 +168,9 @@ namespace Content.Server.GameObjects List thresholds = onDamageBehavior.GetAllDamageThresholds(); + if (thresholds == null) + return; + foreach (DamageThreshold threshold in thresholds) { if (!Thresholds[threshold.DamageType].Contains(threshold)) diff --git a/Content.Server/GameObjects/Components/Mining/AsteroidRockComponent.cs b/Content.Server/GameObjects/Components/Mining/AsteroidRockComponent.cs index ae0ff93a36..bc11b88107 100644 --- a/Content.Server/GameObjects/Components/Mining/AsteroidRockComponent.cs +++ b/Content.Server/GameObjects/Components/Mining/AsteroidRockComponent.cs @@ -33,7 +33,7 @@ namespace Content.Server.GameObjects.Components.Mining var item = eventArgs.AttackWith; if (!item.TryGetComponent(out MeleeWeaponComponent meleeWeaponComponent)) return false; - Owner.GetComponent().TakeDamage(DamageType.Brute, meleeWeaponComponent.Damage); + Owner.GetComponent().TakeDamage(DamageType.Brute, meleeWeaponComponent.Damage, item, eventArgs.User); if (!item.TryGetComponent(out PickaxeComponent pickaxeComponent)) return true; if (!string.IsNullOrWhiteSpace(pickaxeComponent.MiningSound) && diff --git a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs index 94f860ab9e..6d68d59881 100644 --- a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs @@ -184,8 +184,8 @@ namespace Content.Server.GameObjects bruteDamage += 30; break; } - Owner.GetComponent().TakeDamage(DamageType.Brute, bruteDamage); - Owner.GetComponent().TakeDamage(DamageType.Heat, burnDamage); + Owner.GetComponent().TakeDamage(DamageType.Brute, bruteDamage, eventArgs.Source); + Owner.GetComponent().TakeDamage(DamageType.Heat, burnDamage, eventArgs.Source); } } diff --git a/Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs b/Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs index 7b5bd39733..fc66958ece 100644 --- a/Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs +++ b/Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs @@ -73,7 +73,7 @@ namespace Content.Server.GameObjects.Components.Power void Burn() { - damageableComponent.TakeDamage(DamageType.Heat, 20); + damageableComponent.TakeDamage(DamageType.Heat, 20, Owner); } void Eject() diff --git a/Content.Server/GameObjects/Components/Projectiles/ProjectileComponent.cs b/Content.Server/GameObjects/Components/Projectiles/ProjectileComponent.cs index 519e0f8892..b2b3ca923e 100644 --- a/Content.Server/GameObjects/Components/Projectiles/ProjectileComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/ProjectileComponent.cs @@ -71,9 +71,12 @@ namespace Content.Server.GameObjects.Components.Projectiles { if (entity.TryGetComponent(out DamageableComponent damage)) { - foreach (var damageType in _damages) + Owner.EntityManager.TryGetEntity(Shooter, out var shooter); + + foreach (var (damageType, amount) in _damages) { - damage.TakeDamage(damageType.Key, damageType.Value); + + damage.TakeDamage(damageType, amount, Owner, shooter); } } diff --git a/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs b/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs index d07e91b9e9..cbc63c3231 100644 --- a/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs @@ -31,7 +31,7 @@ namespace Content.Server.GameObjects.Components { if (entity.TryGetComponent(out DamageableComponent damage)) { - damage.TakeDamage(DamageType.Brute, 10); + damage.TakeDamage(DamageType.Brute, 10, Owner, User); } } diff --git a/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs b/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs index 0a250f9d3c..dcea664899 100644 --- a/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs +++ b/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs @@ -43,7 +43,7 @@ namespace Content.Server.GameObjects _secondsSinceLastDamageUpdate += frameTime; - Owner.TryGetComponent(out DamageableComponent component); + Owner.TryGetComponent(out DamageableComponent component); while (_secondsSinceLastDamageUpdate >= 1) { diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index def7fc56dc..54249e39ba 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -96,7 +96,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee if (entity.TryGetComponent(out DamageableComponent damageComponent)) { - damageComponent.TakeDamage(DamageType.Brute, Damage); + damageComponent.TakeDamage(DamageType.Brute, Damage, Owner, eventArgs.User); hitEntities.Add(entity); } } diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Hitscan/HitscanWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Hitscan/HitscanWeaponComponent.cs index c38281fe28..3ae6d069cd 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Hitscan/HitscanWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Hitscan/HitscanWeaponComponent.cs @@ -92,15 +92,15 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan var ray = new CollisionRay(userPosition, angle.ToVec(), (int)(CollisionGroup.Impassable | CollisionGroup.MobImpassable)); var rayCastResults = IoCManager.Resolve().IntersectRay(user.Transform.MapID, ray, MaxLength, user); - Hit(rayCastResults, energyModifier); + Hit(rayCastResults, energyModifier, user); AfterEffects(user, rayCastResults, angle, energyModifier); } - protected virtual void Hit(RayCastResults ray, float damageModifier) + protected virtual void Hit(RayCastResults ray, float damageModifier, IEntity user = null) { if (ray.HitEntity != null && ray.HitEntity.TryGetComponent(out DamageableComponent damage)) { - damage.TakeDamage(DamageType.Heat, (int)Math.Round(_damage * damageModifier, MidpointRounding.AwayFromZero)); + damage.TakeDamage(DamageType.Heat, (int)Math.Round(_damage * damageModifier, MidpointRounding.AwayFromZero), Owner, user); //I used Math.Round over Convert.toInt32, as toInt32 always rounds to //even numbers if halfway between two numbers, rather than rounding to nearest } diff --git a/Content.Server/Interfaces/GameObjects/Components/Damage/IDamageableComponent.cs b/Content.Server/Interfaces/GameObjects/Components/Damage/IDamageableComponent.cs index 4e4116c92f..e45685a46b 100644 --- a/Content.Server/Interfaces/GameObjects/Components/Damage/IDamageableComponent.cs +++ b/Content.Server/Interfaces/GameObjects/Components/Damage/IDamageableComponent.cs @@ -17,15 +17,19 @@ namespace Content.Server.Interfaces.GameObjects /// /// Type of damage being received. /// Amount of damage being received. - void TakeDamage(DamageType damageType, int amount); + /// Entity that damaged this entity. + /// Mob that damaged this entity. + void TakeDamage(DamageType damageType, int amount, IEntity source, IEntity sourceMob); /// /// Handles receiving healing. /// Converts healing via the resistance set then applies it /// and informs components of thresholds passed as necessary. /// - /// Type of damage being received. - /// Amount of damage being received. - void TakeHealing(DamageType damageType, int amount); + /// Type of healing being received. + /// Amount of healing being received. + /// Entity that healed this entity. + /// Mob that healed this entity. + void TakeHealing(DamageType damageType, int amount, IEntity source, IEntity sourceMob); } } diff --git a/Content.Server/Interfaces/GameObjects/IOnDamageBehavior.cs b/Content.Server/Interfaces/GameObjects/IOnDamageBehavior.cs index c15da0d04c..fdd8b7bb93 100644 --- a/Content.Server/Interfaces/GameObjects/IOnDamageBehavior.cs +++ b/Content.Server/Interfaces/GameObjects/IOnDamageBehavior.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Content.Server.GameObjects; namespace Content.Server.Interfaces @@ -15,13 +16,20 @@ namespace Content.Server.Interfaces /// Gets a list of all DamageThresholds this component/entity are interested in. /// /// List of DamageThresholds to be added to DamageableComponent for watching. - List GetAllDamageThresholds(); + List GetAllDamageThresholds() => null; /// /// Damage threshold passed event hookup. /// /// Damageable component. /// Damage threshold and whether it's passed in one way or another. - void OnDamageThresholdPassed(object obj, DamageThresholdPassedEventArgs e); + void OnDamageThresholdPassed(object obj, DamageThresholdPassedEventArgs e) { } + + /// + /// Called when the entity is damaged. + /// + /// Damageable component. + /// DamageEventArgs + void OnDamaged(object obj, DamageEventArgs e) { } } }