An OrbiterLens game entity that orbits a unit and visually pulses. It tints its model based on whether its orbited unit is alive, follows the unit at a distance based on the unit radius, bobs in Z, and when colliding with Bullet instances it applies a lens buff to the bullet and briefly scales up.
using System;
using Sandbox;
public class OrbiterLens : Orbiter
{
[Sync] public float DamagePercent { get; set; }
private TimeSince _timeSinceBuff;
private float _lastAlpha;
protected override void OnStart()
{
base.OnStart();
if ( IsProxy )
return;
CollideWithTags.Add( "bullet" );
OrbitDistance = 35f;
_lastAlpha = -1f;
}
protected override void OnUpdate()
{
base.OnUpdate();
float alpha = OrbitedUnit.IsValid() && !OrbitedUnit.IsDying
? 0.5f
: 0f;
if ( alpha != _lastAlpha )
{
Model.Tint = Model.Tint.WithAlpha( alpha );
_lastAlpha = alpha;
}
if ( IsProxy )
return;
if ( !OrbitedUnit.IsValid() || OrbitedUnit.IsDying )
return;
WorldRotation = Rotation.LookAt( Position2D - OrbitedUnit.Position2D );
OrbitDistance = OrbitedUnit.Radius + 35f;
if ( _timeSinceBuff < 0.3f )
{
WorldScale = new Vector3( Utils.Map( _timeSinceBuff, 0f, 0.275f, 1.3f, 1f, EasingType.SineOut ) );
}
}
protected override float GetZPos()
{
return OrbitedUnit.WorldPosition.z + 45f * (1f + Utils.FastSin( Time.Now * 6f ) * 0.185f);
}
public override void Colliding( Thing other, float percent, float dt )
{
base.Colliding( other, percent, dt );
if ( !OrbitedUnit.IsValid() || OrbitedUnit.IsDying )
return;
if ( other is Bullet bullet && !bullet.IsLensBuffed )
{
bullet.LensBuff( 1f + DamagePercent );
WorldScale = new Vector3( 1.3f );
_timeSinceBuff = 0f;
}
}
}