Weapons/TripminePlaced.cs
public sealed class TripminePlaced : Component, Component.ITriggerListener, Component.IDamageable, IKillIcon, IInstigator
{
[RequireComponent] CapsuleCollider Collider { get; set; }
[Property] float TimeToActive { get; set; } = 5f;
[Property] public float MaxDamage { get; set; } = 125;
[Property] public float Radius { get; set; } = 256;
[Property] GameObject HitObject { get; set; }
public PlayerData Instigator { get; set; }
[Property] public Curve DamageFalloff { get; set; } = new Curve( new Curve.Frame( 1.0f, 1.0f ), new Curve.Frame( 0.0f, 0.0f ) );
[Property] Texture IKillIcon.DisplayIcon { get; set; }
TimeUntil timeUntilActive { get; set; }
bool IsActive { get; set; }
protected override void OnStart()
{
base.OnStart();
timeUntilActive = TimeToActive;
Collider.Enabled = false;
}
protected override void OnFixedUpdate()
{
base.OnFixedUpdate();
if ( !IsActive )
{
ActivateLaser();
}
}
void ActivateLaser()
{
if ( timeUntilActive > 0 ) return;
IsActive = true;
Sound.Play( "notify_beep", WorldPosition );
var tr = Scene.Trace.Ray( WorldPosition, WorldPosition + WorldRotation.Forward * 10000 )
.IgnoreGameObjectHierarchy( GameObject.Root )
.WithoutTags( "player" )
.Run();
Collider.End = Vector3.Forward * tr.Distance;
Collider.Radius = 0.2f;
Collider.Enabled = true;
HitObject.WorldPosition = tr.EndPosition;
timeUntilActive = 0.33f;
}
public void Explode( PlayerData instigator = default, GameObject weapon = default )
{
var actualInstigator = instigator ?? Instigator;
Damage.Radius( WorldPosition, Radius, MaxDamage, [DamageTags.Explosion], GameObject, weapon.IsValid() ? weapon : GameObject, DamageFalloff, actualInstigator );
CreateEffects();
GameObject.Destroy();
}
[Rpc.Broadcast( NetFlags.HostOnly )]
private void CreateEffects()
{
if ( Application.IsDedicatedServer ) return;
Effects.SpawnScorch( WorldPosition, WorldRotation.Forward, GameObject );
Effects.SpawnExplosion( WorldPosition );
}
void ITriggerListener.OnTriggerEnter( GameObject other )
{
if ( !Networking.IsHost ) return;
if ( GameObject.IsDestroyed ) return;
if ( other.Tags.Has( "tripmine" ) ) return;
if ( timeUntilActive > 0 ) return;
Explode();
}
void IDamageable.OnDamage( in DamageInfo damage )
{
if ( damage.Weapon == GameObject ) return;
if ( damage is not DamageInfo dmg )
return;
if ( dmg.Tags.Has( DamageTags.Explosion ) )
{
DelayedExplode();
return;
}
// Get the instigator from the damage info
var damageInstigator = dmg.Attacker?.GetComponent<Player>()?.PlayerData;
Explode( damageInstigator, dmg.Weapon );
}
async void DelayedExplode()
{
await Task.Delay( 400 );
if ( GameObject.IsDestroyed ) return;
Explode();
GameObject.Destroy();
}
}