namespace Sandbox; /// /// Deals damage to objects inside /// [Category( "Game" ), Icon( "medical_services" ), EditorHandle( Icon = "🤕" )] public sealed class TriggerHurt : Component { /// /// If not empty, the target must have one of these tags /// [Property, Group( "Damage" )] public TagSet DamageTags { get; set; } = new(); /// /// How much damage to apply /// [Property, Group( "Damage" )] public float Damage { get; set; } = 10.0f; /// /// The delay between applying the damage /// [Property, Group( "Damage" )] public float Rate { get; set; } = 1.0f; /// /// If not empty, the target must have one of these tags /// [Property, Group( "Target" )] public TagSet Include { get; set; } = new(); /// /// If not empty, the target must not have one of these tags /// [Property, Group( "Target" )] public TagSet Exclude { get; set; } = new(); TimeSince timeSinceDamage = 0.0f; Collider Collider => GetComponent(); protected override void OnFixedUpdate() { if ( !Networking.IsHost ) return; if ( timeSinceDamage < Rate ) return; if ( !Collider.IsValid() ) return; timeSinceDamage = 0; foreach ( var touching in Collider.Touching.SelectMany( x => x.GetComponentsInParent().Distinct() ) ) { if ( touching is not Component target ) continue; if ( !Exclude.IsEmpty && target.GameObject.Tags.HasAny( Exclude ) ) continue; if ( !Include.IsEmpty && !target.GameObject.Tags.HasAny( Include ) ) continue; var damage = new DamageInfo(); damage.Tags.Add( DamageTags ); damage.Attacker = GameObject; damage.Origin = WorldPosition; damage.Position = WorldPosition; damage.Damage = Damage; touching.OnDamage( damage ); } } }