swb_base/ui/SniperScope.cs
using Sandbox.UI;
using Sandbox.UI.Construct;
using SWB.Shared;
using System;
namespace SWB.Base.UI;
public class SniperScope : Panel
{
IPlayerBase player => weapon.Owner;
Weapon weapon;
Panel lensWrapper;
Panel scope;
float verticalMov;
float horizontalMov;
float lensBob;
float lensRotation;
bool wasInAir;
public SniperScope( Weapon weapon, string lensTexture, string scopeTexture )
{
this.weapon = weapon;
StyleSheet.Load( "/swb_base/ui/SniperScope.cs.scss" );
AddClass( "hide" );
if ( scopeTexture is not null )
Add.Panel( "leftBar" );
lensWrapper = Add.Panel( "lensWrapper" );
lensWrapper.Add.Image( lensTexture, "lens" );
if ( scopeTexture is not null )
{
scope = lensWrapper.Add.Image( scopeTexture, "scope" );
Add.Panel( "rightBar" );
Add.Panel( "topBar" );
Add.Panel( "bottomBar" );
Add.Panel( "leftBarOffscreen" );
Add.Panel( "rightBarOffscreen" );
}
}
public override void Tick()
{
var show = weapon.IsValid() && weapon.IsScoping;
// Show when zooming
SetClass( "hide", !show );
if ( !show ) return;
// Scope size
var scopeSize = Screen.Height * ScaleFromScreen;
lensWrapper.Style.Width = Length.Pixels( scopeSize );
// Check if ADS & firing
if ( weapon.IsAiming && weapon.TimeSincePrimaryShoot < 0.1f )
return;
// Movement impact
var velocityJump = player.Velocity.z * 0.02f;
var velocityMove = (Math.Abs( player.Velocity.y ) + Math.Abs( player.Velocity.x )) * 0.005f;
var targetBob = 0f;
if ( velocityJump != 0 )
targetBob += velocityJump * 2;
else if ( velocityMove != 0 )
targetBob += MathF.Sin( RealTime.Now * 17f ) * velocityMove * 2;
if ( wasInAir && player.IsOnGround )
lensBob = 40;
lensBob = MathUtil.FILerp( lensBob, targetBob, 10 );
var fovModifier = (Preferences.FieldOfView - weapon.ScopeInfo.FOV) / 10;
var deltaYaw = (Input.AnalogLook.yaw / Time.Delta) / 100;
var deltaPitch = (-Input.AnalogLook.pitch / Time.Delta) / 50;
horizontalMov = MathUtil.FILerp( horizontalMov, deltaYaw * fovModifier, 10 );
verticalMov = MathUtil.FILerp( verticalMov, deltaPitch * fovModifier, 10 );
var marginTopPercent = lensBob + verticalMov;
var marginLeftPercent = horizontalMov;
Style.MarginTop = Length.Percent( marginTopPercent );
Style.MarginLeft = Length.Percent( marginLeftPercent );
weapon.SetScopeLensCenter( new( 0.5f + marginLeftPercent / 100f, 0.5f + marginTopPercent / 100f ) );
wasInAir = !player.IsOnGround;
if ( scope is null ) return;
// Rotation impact
var rightVector = player.EyeAngles.ToRotation().Right * player.Velocity;
var targetRotation = (rightVector.y + rightVector.x) * 0.015f;
var rotateTransform = new PanelTransform();
lensRotation = MathUtil.FILerp( lensRotation, targetRotation, 20 );
rotateTransform.AddRotation( 0, 0, lensRotation );
scope.Style.Transform = rotateTransform;
// Movement blur (deactivated due to lag)
// scope.Style.FilterBlur = Math.Abs( lensRotation * 2 + velocityJump + lensBob + (horizontalMov + verticalMov) * 3 );
}
[PanelEvent( "shoot" )]
public void ShootEvent( float fireDelay )
{
var rndHorizontal = Game.Random.Float( -1.25f, 1.25f );
var rndVertical = Game.Random.Float( -2.5f, -5 );
horizontalMov += rndHorizontal * weapon.Primary.Recoil * 2f;
verticalMov += rndVertical * weapon.Primary.Recoil * 2f;
}
}