{"TotalCount":100,"Files":[{"Ident":"virtus.vr_shooter","Path":"SbTween/Examples/SbeTLS.cs","FileName":"SbeTLS.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\nusing SbTween;\r\n\r\nnamespace SbTween.Examples;\r\n\r\npublic sealed class SbeTLS : Component\r\n{\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tthis.TweenShakeLocation( 0.6f, 10 ).SetLoops( -1, LoopType.YoYo );\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"SbTween/Examples/TextRenderer/Sbe_TextTweenProperty.cs","FileName":"Sbe_TextTweenProperty.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\n\r\nnamespace SbTween.Examples;\r\n\r\npublic sealed class Sbe_TextTweenProperty : Component\r\n{\r\n\t[Property] public TextRenderer TR;\r\n\t[Property] public Color GlowText;\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tTR.TweenFontSize( 52f, 2 ).SetLoops( -1, LoopType.YoYo ).Play();\r\n\t\tTR.TweenOutlineColor(GlowText, 0.8f).SetLoops(-1, LoopType.YoYo ).Play();\r\n\t\tTR.TweenFontWeight(600, 0.4f).SetLoops(-1, LoopType.YoYo ).Play();\r\n\t}\r\n\r\n\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"SbTween/Examples/TextRenderer/Sbe_TextTypewriter.cs","FileName":"Sbe_TextTypewriter.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\n\r\nnamespace SbTween.Examples;\r\n\r\npublic sealed class Sbe_TextTypewriter : Component\r\n{\r\n\t[Property] public TextRenderer TR;\r\n\t[Property] public string Say;\r\n\t[Property] public bool useCursor;\r\n\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tif ( useCursor )\r\n\t\t{\r\n\r\n\t\t\tTR.TypewriterWithCursor( Say, 3, \u0022|\u0022 ).SetLoops( -1, LoopType.YoYo ).Play();\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tTR.Typewriter( Say, 1 ).SetLoops( -1, LoopType.YoYo ).Play();\r\n\t\t}\r\n\t}\r\n\r\n\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"SbTween/Extensions/MiscExtensions.cs","FileName":"MiscExtensions.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\n\r\nnamespace SbTween;\r\n\r\npublic static class MiscExtensions\r\n{\r\n\t// DECALS\r\n\tpublic static BaseTween TweenLifeTime( this Decal self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.LifeTime.ConstantValue; \r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.LifeTime = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenSize( this Decal self, Vector2 target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       Vector2 start = self.Size;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Size = Vector2.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenScale( this Decal self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.Scale.ConstantValue;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Scale = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenRotation( this Decal self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.Rotation.ConstantValue;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Rotation = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenDepth( this Decal self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.Depth;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Depth = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenParallax( this Decal self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.Parallax.ConstantValue;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Parallax = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenColorTint( this Decal self, Color target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       Color start = self.ColorTint.ConstantValue;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.ColorTint = Color.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenColorMix( this Decal self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.ColorMix.ConstantValue;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.ColorMix = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n    \r\n    // CUBEMAP FOG \r\n\r\n    public static BaseTween TweenBlur( this CubemapFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.Blur;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Blur = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenStartDistance( this CubemapFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.StartDistance;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.StartDistance = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenEndDistance( this CubemapFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.EndDistance;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.EndDistance = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenFalloffExponent( this CubemapFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.FalloffExponent;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.FalloffExponent = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenHeightWidth( this CubemapFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.HeightWidth;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.HeightWidth = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenHeightStart( this CubemapFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.HeightStart;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.HeightStart = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenHeightExponent( this CubemapFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.HeightExponent;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.HeightExponent = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenTint( this CubemapFog self, Color target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       Color start = self.Tint;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Tint = Color.Lerp( start, target, p ) ) );\r\n    }\r\n    \r\n    // GRADIENT FOG\r\n\r\n    public static BaseTween TweenStartDistance( this GradientFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.StartDistance;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.StartDistance = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenEndDistance( this GradientFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.EndDistance;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.EndDistance = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenFalloffExponent( this GradientFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.FalloffExponent;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.FalloffExponent = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenColor( this GradientFog self, Color target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       Color start = self.Color;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Color = Color.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenHeight( this GradientFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.Height;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.Height = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenVerticalFalloffExponent( this GradientFog self, float target, float duration )\r\n    {\r\n       if ( !self.IsValid() ) return null;\r\n       float start = self.VerticalFalloffExponent;\r\n       return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n          .OnUpdate( p =\u003E self.VerticalFalloffExponent = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n    \r\n    // VOLUMETRIC FOG\r\n\r\n    public static BaseTween TweenStrength( this VolumetricFogVolume self, float target, float duration )\r\n    {\r\n\t    if ( !self.IsValid() ) return null;\r\n\t    float start = self.Strength;\r\n\t    return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t    .OnUpdate( p =\u003E self.Strength = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenFalloffExponent( this VolumetricFogVolume self, float target, float duration )\r\n    {\r\n\t    if ( !self.IsValid() ) return null;\r\n\t    float start = self.FalloffExponent;\r\n\t    return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t    .OnUpdate( p =\u003E self.FalloffExponent = MathX.Lerp( start, target, p ) ) );\r\n    }\r\n\r\n    public static BaseTween TweenColor( this VolumetricFogVolume self, Color target, float duration )\r\n    {\r\n\t    if ( !self.IsValid() ) return null;\r\n\t    Color start = self.Color;\r\n\t    return TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t    .OnUpdate( p =\u003E self.Color = Color.Lerp( start, target, p ) ) );\r\n    }\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"SbTween/Extensions/PostProcessingExtensions.cs","FileName":"PostProcessingExtensions.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\nusing System;\r\n\r\nnamespace SbTween;\r\n\r\npublic static class PostProcessingExtensions\r\n{\r\n\t// FilmGrain\r\n\r\n\tpublic static BaseTween TweenIntensity( this FilmGrain pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Intensity;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Intensity )\r\n\t\t\t.OnUpdate( p =\u003E pp.Intensity = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenResponse( this FilmGrain pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Response;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Response )\r\n\t\t\t.OnUpdate( p =\u003E pp.Response = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t// Bloom\r\n\r\n\tpublic static BaseTween TweenStrength( this Bloom pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Strength;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Strength )\r\n\t\t\t.OnUpdate( p =\u003E pp.Strength = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenThreshold( this Bloom pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Threshold;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Threshold )\r\n\t\t\t.OnUpdate( p =\u003E pp.Threshold = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenGamma( this Bloom pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Gamma;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Gamma )\r\n\t\t\t.OnUpdate( p =\u003E pp.Gamma = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenTint( this Bloom pp, Color target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tColor start = pp.Tint;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Tint )\r\n\t\t\t.OnUpdate( p =\u003E pp.Tint = Color.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t// Blur\r\n\r\n\tpublic static BaseTween TweenSize( this Blur pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Size;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Size )\r\n\t\t\t.OnUpdate( p =\u003E pp.Size = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t// ChromaticAberration \r\n\r\n\tpublic static BaseTween TweenScale( this ChromaticAberration pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Scale;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Scale )\r\n\t\t\t.OnUpdate( p =\u003E pp.Scale = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenOffset( this ChromaticAberration pp, Vector3 target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tVector3 start = pp.Offset;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Offset )\r\n\t\t\t.OnUpdate( p =\u003E pp.Offset = Vector3.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t// ColorAdjustments\r\n\r\n\tpublic static BaseTween TweenBlend( this ColorAdjustments pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Blend;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Blend )\r\n\t\t\t.OnUpdate( p =\u003E pp.Blend = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenSaturation( this ColorAdjustments pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Saturation;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Saturation )\r\n\t\t\t.OnUpdate( p =\u003E pp.Saturation = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenHueRotate( this ColorAdjustments pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.HueRotate;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.HueRotate )\r\n\t\t\t.OnUpdate( p =\u003E pp.HueRotate = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenBrightness( this ColorAdjustments pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Brightness;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Brightness )\r\n\t\t\t.OnUpdate( p =\u003E pp.Brightness = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenContrast( this ColorAdjustments pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Contrast;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Contrast )\r\n\t\t\t.OnUpdate( p =\u003E pp.Contrast = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t// Vignette\r\n\r\n\tpublic static BaseTween TweenIntensity( this Vignette pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Intensity;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Intensity )\r\n\t\t\t.OnUpdate( p =\u003E pp.Intensity = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenSmoothness( this Vignette pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Smoothness;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Smoothness )\r\n\t\t\t.OnUpdate( p =\u003E pp.Smoothness = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenRoundness( this Vignette pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Roundness;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Roundness )\r\n\t\t\t.OnUpdate( p =\u003E pp.Roundness = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenColor( this Vignette pp, Color target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tColor start = pp.Color;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Color )\r\n\t\t\t.OnUpdate( p =\u003E pp.Color = Color.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenCenter( this Vignette pp, Vector2 target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tVector2 start = pp.Center;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Center )\r\n\t\t\t.OnUpdate( p =\u003E pp.Center = Vector2.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t// DepthOfField\r\n\r\n\tpublic static BaseTween TweenBlurSize( this DepthOfField pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.BlurSize;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.BlurSize )\r\n\t\t\t.OnUpdate( p =\u003E pp.BlurSize = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenFocalDistance( this DepthOfField pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.FocalDistance;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.FocalDistance )\r\n\t\t\t.OnUpdate( p =\u003E pp.FocalDistance = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenFocusRange( this DepthOfField pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.FocusRange;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.FocusRange )\r\n\t\t\t.OnUpdate( p =\u003E pp.FocusRange = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t// Sharpen \r\n\r\n\tpublic static BaseTween TweenSharpen( this Sharpen pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Scale;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Scale )\r\n\t\t\t.OnUpdate( p =\u003E pp.Scale = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\tpublic static BaseTween TweenTexelSize( this Sharpen pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.TexelSize;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.TexelSize )\r\n\t\t\t.OnUpdate( p =\u003E pp.TexelSize = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t// Pixelate\r\n\r\n\tpublic static BaseTween TweenScale( this Pixelate pp, float target, float duration )\r\n\t{\r\n\t\tif ( !pp.IsValid() ) return null;\r\n\t\tfloat start = pp.Scale;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = pp.Scale )\r\n\t\t\t.OnUpdate( p =\u003E pp.Scale = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"Assembly.cs","FileName":"Assembly.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"global using Sandbox;\r\nglobal using System.Collections.Generic;\r\nglobal using System.Linq;\r\n"},{"Ident":"virtus.vr_shooter","Path":"DesktopGrab.cs","FileName":"DesktopGrab.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\nusing Sandbox.Citizen;\r\nusing Sandbox.Mapping;\r\nusing System.Linq;\r\n\r\npublic sealed class DesktopGrab : Component\r\n{\r\n\t[RequireComponent] private PlayerViewModel PlayerViewModel { get; set; }\r\n\t[Property] private CameraComponent Camera { get; set; }\r\n\t[Property] public float InteractionDistance { get; set; } = 150f;\r\n\r\n\tprivate Player Player { get; set; }\r\n\tprivate PlayerInventory Inventory { get; set; }\r\n\tprivate PlayerAnimationBroadcast AnimBroadcaster { get; set; }\r\n\r\n\tprivate GrabPoint _activeGrabPoint;\r\n\tprivate GrabPoint _secondaryGrabPoint;\r\n\r\n\tprivate bool _throwWindupActive;\r\n\tprivate bool _throwRequested;\r\n\tprivate float _throwReadyAt;\r\n\r\n\tprivate bool _throwAnimActive;\r\n\tprivate float _throwReleaseAt;\r\n\r\n\tprivate static readonly string[] SlotActions = [\u0022slot1\u0022, \u0022slot2\u0022, \u0022slot3\u0022, \u0022slot4\u0022, \u0022slot5\u0022];\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tPlayer = GetComponentInParent\u003CPlayer\u003E();\r\n\t\tInventory = Player?.Inventory;\r\n\t\tAnimBroadcaster = Player?.Avatar?.GetComponent\u003CPlayerAnimationBroadcast\u003E();\r\n\r\n\t\tvar initialInventorySlot = Inventory?.Slots.FirstOrDefault( slot =\u003E slot.StoredItem.IsValid() );\r\n\t\tif ( initialInventorySlot.IsValid() )\r\n\t\t{\r\n\t\t\tEquipFromSlot( initialInventorySlot );\r\n\t\t}\r\n\t}\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tif ( IsProxy ) return;\r\n\r\n\t\t// The held item may have been destroyed out from under us (e.g. a grenade\r\n\t\t// exploding in hand) \u2014 clean up the stale state before doing anything else.\r\n\t\tif ( _activeGrabPoint is not null \u0026\u0026 !_activeGrabPoint.IsValid() )\r\n\t\t\tClearHeldState();\r\n\r\n\t\tif ( _throwAnimActive \u0026\u0026 Time.Now \u003E= _throwReleaseAt )\r\n\t\t{\r\n\t\t\tReleaseToWorld( GetThrowVelocity() );\r\n\t\t\tClearThrowAnimState();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tHandleSlotInput();\r\n\r\n\t\tif ( Input.Pressed( \u0022use\u0022 ) )\r\n\t\t\tHandleUseInput();\r\n\r\n\t\tif ( Input.Pressed( \u0022drop\u0022 ) )\r\n\t\t\tForceDropHeld();\r\n\r\n\t\tif ( _activeGrabPoint is not null \u0026\u0026 !_throwAnimActive )\r\n\t\t{\r\n\t\t\tvar throwable = _activeGrabPoint.ItemRoot.GetComponent\u003CThrowable\u003E();\r\n\t\t\tvar isThrowable = throwable is not null;\r\n\r\n\t\t\tif ( Input.Pressed( \u0022attack1\u0022 ) \u0026\u0026 isThrowable )\r\n\t\t\t{\r\n\t\t\t\tPlayerViewModel.Instance.PlayCharge();\r\n\t\t\t\tStartThrowWindup( throwable.ThrowDelay );\r\n\t\t\t}\r\n\r\n\t\t\tif ( Input.Released( \u0022attack1\u0022 ) \u0026\u0026 _throwWindupActive )\r\n\t\t\t\t_throwRequested = true;\r\n\r\n\t\t\tif ( _throwWindupActive \u0026\u0026 _throwRequested \u0026\u0026 Time.Now \u003E= _throwReadyAt )\r\n\t\t\t\tBeginThrowAnimation( throwable );\r\n\r\n\t\t\t_activeGrabPoint.SetTriggerState( Input.Down( \u0022attack1\u0022 ) );\r\n\r\n\t\t\tif ( Input.Pressed( \u0022reload\u0022 ) )\r\n\t\t\t\t_activeGrabPoint.Reload();\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void HandleUseInput()\r\n\t{\r\n\t\tvar gameObject = GetLookTrace();\r\n\r\n\t\tif ( !gameObject.IsValid() )\r\n\t\t\treturn;\r\n\r\n\t\tvar door = gameObject.GetComponent\u003CDoor\u003E();\r\n\t\tif ( door.IsValid() )\r\n\t\t\tdoor.Toggle( gameObject );\r\n\t\telse\r\n\t\t\tTryGrabObject( gameObject );\r\n\t}\r\n\r\n\tprivate void HandleSlotInput()\r\n\t{\r\n\t\tfor ( int i = 0; i \u003C SlotActions.Length; i\u002B\u002B )\r\n\t\t{\r\n\t\t\tif ( !Input.Pressed( SlotActions[i] ) )\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tHandleSlotKey( (InventorySlotIndex)i );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( Game.IsRunningInVR || Input.MouseCursorVisible )\n\t\t\treturn;\n\n\t\tif ( Input.Pressed( \u0022SlotPrev\u0022 ) )\n\t\t\tCycleInventory( -1 );\n\t\telse if ( Input.Pressed( \u0022SlotNext\u0022 ) )\n\t\t\tCycleInventory( 1 );\n\t}\n\n\tprivate void CycleInventory( int direction )\n\t{\n\t\tvar slots = Inventory?.Slots;\n\t\tif ( slots is not { Count: \u003E 0 } )\n\t\t\treturn;\n\n\t\tvar currentItem = _activeGrabPoint?.Components.GetInAncestorsOrSelf\u003CInventoryItem\u003E();\n\t\t// With empty hands, start at the first slot when moving forward, or the last going back.\n\t\tint currentIndex = direction \u003E 0 ? -1 : 0;\n\t\tfor ( int i = 0; i \u003C slots.Count; i\u002B\u002B )\n\t\t{\n\t\t\tif ( currentItem is not null \u0026\u0026 currentItem.SlotObject == slots[i].GameObject )\n\t\t\t{\n\t\t\t\tcurrentIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tfor ( int offset = 1; offset \u003C= slots.Count; offset\u002B\u002B )\n\t\t{\n\t\t\tvar index = (currentIndex \u002B direction * offset \u002B slots.Count) % slots.Count;\n\t\t\tvar slot = slots[index];\n\t\t\tvar item = slot.StoredItem;\n\t\t\tif ( !item.IsValid() || item == currentItem || !CanEquip( item ) )\n\t\t\t\tcontinue;\n\n\t\t\tif ( HolsterCurrentItem() )\n\t\t\t\tEquipFromSlot( slot );\n\n\t\t\treturn;\n\t\t}\n\t}\n\r\n\tprivate void HandleSlotKey( InventorySlotIndex slotIndex )\r\n\t{\r\n\t\tif ( Inventory is null )\r\n\t\t\treturn;\r\n\r\n\t\tvar slot = Inventory.GetSlot( slotIndex );\r\n\t\tif ( slot is null )\r\n\t\t\treturn;\r\n\r\n\t\tvar slotItem = slot.StoredItem;\r\n\t\tif ( slotItem is null )\r\n\t\t\treturn;\r\n\r\n\t\tvar currentItem = _activeGrabPoint?.Components.GetInAncestorsOrSelf\u003CInventoryItem\u003E();\r\n\t\tbool pressedHeldItemsSlot = currentItem is not null \u0026\u0026 currentItem.SlotObject == slot.GameObject;\r\n\r\n\t\tif ( !HolsterCurrentItem() )\r\n\t\t\treturn;\r\n\r\n\t\t// Tapping the held item\u0027s own slot key just holsters it\r\n\t\tif ( pressedHeldItemsSlot )\r\n\t\t\treturn;\r\n\r\n\t\tEquipFromSlot( slot );\r\n\t}\r\n\r\n\tprivate GameObject GetLookTrace()\r\n\t{\r\n\t\tvar ray = Camera.ScreenNormalToRay( new Vector2( 0.5f, 0.5f ) );\r\n\r\n\t\tvar trace = Scene.Trace.Ray( ray, InteractionDistance )\r\n\t\t\t.UsePhysicsWorld()\r\n\t\t\t.Run();\r\n\r\n\t\tif ( !trace.Hit || trace.GameObject is null )\r\n\t\t\treturn null;\r\n\r\n\t\treturn trace.GameObject;\r\n\t}\r\n\r\n\tprivate void TryGrabObject( GameObject gameObject )\r\n\t{\r\n\t\tvar itemRoot = gameObject.Root;\r\n\t\tvar inventoryItem = itemRoot.Components.Get\u003CInventoryItem\u003E();\r\n\t\tif ( inventoryItem is null || Inventory is null || inventoryItem.IsStowed )\r\n\t\t\treturn;\r\n\r\n\t\tvar freeSlot = Inventory.TryGetFreeSlot( inventoryItem.Type );\r\n\t\tif ( freeSlot is null )\r\n\t\t\treturn;\r\n\r\n\t\tif ( !CanEquip( inventoryItem ) || !HolsterCurrentItem() )\r\n\t\t\treturn;\r\n\r\n\t\t// Equip first: Grab() takes network ownership of the item, and only the\r\n\t\t// owner may write the item\u0027s [Sync] slot properties in Reserve().\r\n\t\tif ( EquipToHand( inventoryItem ) )\n\t\t\tfreeSlot.Reserve( inventoryItem );\n\t}\r\n\r\n\tprivate void EquipFromSlot( InventorySlot slot )\r\n\t{\r\n\t\tvar inventoryItem = slot.StoredItem;\r\n\t\tif ( inventoryItem is null || !CanEquip( inventoryItem ) )\r\n\t\t\treturn;\r\n\r\n\t\tEquipToHand( inventoryItem );\r\n\t}\r\n\r\n\t/// \u003Csummary\u003ETrue when the item has a primary grip that no one is holding yet.\u003C/summary\u003E\r\n\tprivate static bool CanEquip( InventoryItem item )\r\n\t{\r\n\t\tvar primaryGrip = FindGrip( item, secondary: false );\r\n\r\n\t\treturn primaryGrip is not null \u0026\u0026 !primaryGrip.IsGrabbed;\r\n\t}\r\n\r\n\tprivate static GrabPoint FindGrip( InventoryItem item, bool secondary )\r\n\t{\r\n\t\treturn item.GameObject.Components\r\n\t\t\t.GetAll\u003CGrabPoint\u003E( FindMode.InDescendants )\r\n\t\t\t.FirstOrDefault( g =\u003E g.IsSecondaryGrip == secondary );\r\n\t}\r\n\r\n\tprivate bool EquipToHand( InventoryItem item )\n\t{\n\t\tif ( !Inventory.TryEquipToHand( item, out var grip ) )\n\t\t\treturn false;\n\n\t\t_activeGrabPoint = grip;\n\t\t_secondaryGrabPoint = FindGrip( item, secondary: true );\n\r\n\t\tvar viewModel = _activeGrabPoint.GetComponentInParent\u003CViewModel\u003E();\r\n\t\tif ( viewModel is not null )\n\t\t\tPlayerViewModel.Show( viewModel );\n\t\treturn true;\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Puts the held item back in its inventory slot, keeping it on the body.\r\n\t/// Returns true if the hand ended up empty.\r\n\t/// \u003C/summary\u003E\r\n\tprivate bool HolsterCurrentItem()\r\n\t{\r\n\t\tif ( _activeGrabPoint is null )\r\n\t\t\treturn true;\r\n\r\n\t\tvar inventoryItem = _activeGrabPoint.Components.GetInAncestorsOrSelf\u003CInventoryItem\u003E();\r\n\t\tif ( inventoryItem is null || Inventory is null || !Inventory.TryStow( inventoryItem ) )\r\n\t\t\treturn false;\r\n\r\n\t\t_activeGrabPoint.Drop();\r\n\t\tClearHeldState();\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n\t/// \u003Csummary\u003EDrops the held item into the world, ignoring its inventory slot.\u003C/summary\u003E\r\n\tpublic void ForceDropHeld()\r\n\t{\r\n\t\tReleaseToWorld( null );\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Throws the held item along the camera direction using its Throwable settings.\r\n\t/// \u003C/summary\u003E\r\n\tpublic void ThrowObject()\r\n\t{\r\n\t\tif ( _activeGrabPoint is null )\r\n\t\t\treturn;\r\n\r\n\t\tvar throwable = _activeGrabPoint.ItemRoot.GetComponent\u003CThrowable\u003E();\r\n\t\tif ( throwable is null )\r\n\t\t\treturn;\r\n\r\n\t\tBeginThrowAnimation( throwable );\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Plays the throw viewmodel animation, then releases the item after ThrowAnimDuration.\r\n\t/// \u003C/summary\u003E\r\n\tprivate void BeginThrowAnimation( Throwable throwable )\r\n\t{\r\n\t\tif ( _activeGrabPoint is null )\r\n\t\t\treturn;\r\n\r\n\t\tClearThrowWindup();\r\n\r\n\t\tPlayerViewModel.Instance?.PlayAttack();\r\n\r\n\t\t_throwAnimActive = true;\r\n\t\t_throwReleaseAt = Time.Now \u002B throwable.ThrowAnimDuration;\r\n\t}\r\n\r\n\tprivate Vector3? GetThrowVelocity()\r\n\t{\r\n\t\tif ( _activeGrabPoint is null )\r\n\t\t\treturn null;\r\n\r\n\t\tvar throwable = _activeGrabPoint.ItemRoot.GetComponent\u003CThrowable\u003E();\r\n\t\tif ( throwable is null )\r\n\t\t\treturn null;\r\n\r\n\t\tvar ray = Camera.ScreenNormalToRay( new Vector2( 0.5f, 0.5f ) );\r\n\t\tvar direction = (ray.Forward \u002B Vector3.Up * throwable.UpwardBoost).Normal;\r\n\r\n\t\treturn direction * throwable.ThrowForce;\r\n\t}\r\n\r\n\tprivate void ReleaseToWorld( Vector3? throwVelocity )\r\n\t{\r\n\t\tif ( _activeGrabPoint is null )\r\n\t\t\treturn;\r\n\r\n\t\t_activeGrabPoint.ItemRoot.Components.Get\u003CInventoryItem\u003E()?.DropToWorld();\r\n\t\t_activeGrabPoint.Drop( throwVelocity );\r\n\r\n\t\tClearHeldState();\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Forgets the currently held item and resets viewmodel/animation state.\r\n\t/// Safe to call when the item has already been destroyed.\r\n\t/// \u003C/summary\u003E\r\n\tprivate void ClearHeldState()\r\n\t{\r\n\t\tPlayerViewModel.Hide();\r\n\r\n\t\t_activeGrabPoint = null;\r\n\t\t_secondaryGrabPoint = null;\r\n\r\n\t\tClearThrowWindup();\r\n\t\tClearThrowAnimState();\r\n\r\n\t\tAnimBroadcaster.HoldType = CitizenAnimationHelper.HoldTypes.None;\r\n\t\tAnimBroadcaster.SecondaryGrip = null;\r\n\t}\r\n\r\n\tprivate void StartThrowWindup( float delay )\r\n\t{\r\n\t\t_throwWindupActive = true;\r\n\t\t_throwRequested = false;\r\n\t\t_throwReadyAt = Time.Now \u002B delay;\r\n\t}\r\n\r\n\tprivate void ClearThrowWindup()\r\n\t{\r\n\t\t_throwWindupActive = false;\r\n\t\t_throwRequested = false;\r\n\t\t_throwReadyAt = 0f;\r\n\t}\r\n\r\n\tprivate void ClearThrowAnimState()\r\n\t{\r\n\t\t_throwAnimActive = false;\r\n\t\t_throwReleaseAt = 0f;\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"HookGun.cs","FileName":"HookGun.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\n\r\n/// \u003Csummary\u003EHeld utility that launches a latching hook and pulls the player to the hit point.\u003C/summary\u003E\r\npublic sealed class HookGun : Component\r\n{\r\n\tprivate enum HookState\r\n\t{\r\n\t\tIdle,\r\n\t\tFlying,\r\n\t\tPulling,\r\n\t}\r\n\r\n\t/// \u003Csummary\u003ETransform at the barrel; the hook spawns here in VR.\u003C/summary\u003E\r\n\t[Property] public GameObject MuzzleTransform { get; set; }\r\n\r\n\t/// \u003Csummary\u003EPrefab cloned when the hook is fired.\u003C/summary\u003E\r\n\t[Property] public GameObject HookPrefab { get; set; }\r\n\r\n\t/// \u003Csummary\u003EHook travel speed in world units per second.\u003C/summary\u003E\r\n\t[Property] public float HookSpeed { get; set; } = 2500f;\r\n\r\n\t/// \u003Csummary\u003EMax distance the hook can travel before it retracts.\u003C/summary\u003E\r\n\t[Property] public float MaxRange { get; set; } = 2500f;\r\n\r\n\t/// \u003Csummary\u003EPlayer pull speed toward the latch point in world units per second.\u003C/summary\u003E\r\n\t[Property, Group( \u0022Grapple\u0022 )]\r\n\tpublic float PullSpeed { get; set; } = 700f;\r\n\r\n\t/// \u003Csummary\u003EDistance from the latch point at which the pull stops yanking.\u003C/summary\u003E\r\n\t[Property, Group( \u0022Grapple\u0022 )]\r\n\tpublic float StopDistance { get; set; } = 48f;\r\n\r\n\t/// \u003Csummary\u003ELine drawn from the muzzle to the hook tip / latch point.\u003C/summary\u003E\r\n\t[Property] public LineRenderer Rope { get; set; }\r\n\r\n\t[Sync] private bool RopeActive { get; set; }\r\n\t[Sync] private Vector3 RopeEnd { get; set; }\r\n\r\n\tprivate HookState _state = HookState.Idle;\r\n\tprivate HookProjectile _activeHook;\r\n\tprivate Vector3 _attachPoint;\r\n\tprivate bool _ownedGrapple;\r\n\r\n\tprivate bool IsHeld =\u003E\r\n\t\tGameObject.Components.GetAll\u003CGrabPoint\u003E( FindMode.InDescendants ).Any( g =\u003E g.IsGrabbed );\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tif ( !IsProxy )\r\n\t\t{\r\n\t\t\tif ( _state != HookState.Idle \u0026\u0026 !IsHeld )\r\n\t\t\t\tRetract();\r\n\t\t\telse if ( _ownedGrapple \u0026\u0026 !IsPlayerStillGrappling() )\r\n\t\t\t\tRetract();\r\n\t\t}\r\n\r\n\t\tUpdateRopeEnd();\r\n\t\tUpdateRopeVisual();\r\n\t}\r\n\r\n\tprotected override void OnDestroy()\r\n\t{\r\n\t\tif ( !IsProxy )\r\n\t\t\tRetract();\r\n\t}\r\n\r\n\t/// \u003Csummary\u003ELaunch the hook when idle, or retract it while flying / pulling.\u003C/summary\u003E\r\n\tpublic void Fire()\r\n\t{\r\n\t\tif ( IsProxy )\r\n\t\t\treturn;\r\n\r\n\t\tif ( _state == HookState.Idle )\r\n\t\t\tLaunch();\r\n\t\telse\r\n\t\t\tRetract();\r\n\t}\r\n\r\n\tpublic void OnAttached( Vector3 hitPosition )\r\n\t{\r\n\t\tif ( IsProxy || _state != HookState.Flying )\r\n\t\t\treturn;\r\n\r\n\t\t_attachPoint = hitPosition;\r\n\t\t_state = HookState.Pulling;\r\n\t\tRopeActive = true;\r\n\t\tRopeEnd = hitPosition;\r\n\r\n\t\tvar playerController = ResolvePlayerController();\r\n\t\tif ( playerController.IsValid() )\r\n\t\t{\r\n\t\t\tplayerController.BeginGrapple( hitPosition, PullSpeed, StopDistance );\r\n\t\t\t_ownedGrapple = true;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void OnHookMissed()\r\n\t{\r\n\t\tif ( IsProxy )\r\n\t\t\treturn;\r\n\r\n\t\tif ( _state != HookState.Flying )\r\n\t\t\treturn;\r\n\r\n\t\t_activeHook = null;\r\n\t\t_state = HookState.Idle;\r\n\t\tRopeActive = false;\r\n\t}\r\n\r\n\tprivate void Launch()\r\n\t{\r\n\t\tif ( HookPrefab is null || MuzzleTransform is null )\r\n\t\t\treturn;\r\n\r\n\t\tVector3 spawnPosition;\r\n\t\tVector3 shootDirection;\r\n\r\n\t\tif ( Game.IsRunningInVR )\r\n\t\t{\r\n\t\t\tspawnPosition = MuzzleTransform.WorldPosition;\r\n\t\t\tshootDirection = MuzzleTransform.WorldRotation.Forward;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tif ( PlayerViewModel.Instance?.Camera is null )\r\n\t\t\t\treturn;\r\n\r\n\t\t\tvar ray = PlayerViewModel.Instance.GetAimRay( Vector2.Zero );\r\n\t\t\tspawnPosition = ray.Position;\r\n\t\t\tshootDirection = ray.Forward;\r\n\t\t}\r\n\r\n\t\tvar hookObject = HookPrefab.Clone( spawnPosition, Rotation.LookAt( shootDirection ) );\r\n\t\tvar projectile = hookObject.Components.Get\u003CHookProjectile\u003E();\r\n\t\tif ( projectile is null )\r\n\t\t{\r\n\t\t\thookObject.Destroy();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tprojectile.Velocity = shootDirection.Normal * HookSpeed;\r\n\t\tprojectile.WeaponObject = GameObject;\r\n\t\tprojectile.OwnerGun = this;\r\n\t\tprojectile.SpawnOrigin = spawnPosition;\r\n\t\tprojectile.MaxRange = MaxRange;\r\n\r\n\t\t_activeHook = projectile;\r\n\t\t_state = HookState.Flying;\r\n\t\tRopeActive = true;\r\n\t\tRopeEnd = spawnPosition;\r\n\t}\r\n\r\n\tprivate void Retract()\r\n\t{\r\n\t\tif ( _activeHook.IsValid() )\r\n\t\t{\r\n\t\t\tvar hook = _activeHook;\r\n\t\t\t_activeHook = null;\r\n\t\t\thook.OwnerGun = null;\r\n\t\t\thook.GameObject.Destroy();\r\n\t\t}\r\n\r\n\t\t_activeHook = null;\r\n\t\tEndOwnedGrapple();\r\n\t\t_state = HookState.Idle;\r\n\t\tRopeActive = false;\r\n\t}\r\n\r\n\tprivate void EndOwnedGrapple()\r\n\t{\r\n\t\tif ( !_ownedGrapple )\r\n\t\t\treturn;\r\n\r\n\t\tvar playerController = ResolvePlayerController();\r\n\t\tif ( playerController.IsValid() )\r\n\t\t\tplayerController.EndGrapple();\r\n\r\n\t\t_ownedGrapple = false;\r\n\t}\r\n\r\n\tprivate bool IsPlayerStillGrappling()\r\n\t{\r\n\t\tvar playerController = ResolvePlayerController();\r\n\t\treturn playerController.IsValid() \u0026\u0026 playerController.IsGrappling;\r\n\t}\r\n\r\n\tprivate void UpdateRopeEnd()\r\n\t{\r\n\t\tif ( IsProxy || !RopeActive )\r\n\t\t\treturn;\r\n\r\n\t\tif ( _state == HookState.Pulling )\r\n\t\t{\r\n\t\t\tRopeEnd = _attachPoint;\r\n\r\n\t\t\tvar playerController = ResolvePlayerController();\r\n\t\t\tif ( playerController.IsValid() \u0026\u0026 _ownedGrapple )\r\n\t\t\t\tplayerController.GrappleTarget = _attachPoint;\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif ( _activeHook.IsValid() )\r\n\t\t\tRopeEnd = _activeHook.WorldPosition;\r\n\t}\r\n\r\n\tprivate void UpdateRopeVisual()\r\n\t{\r\n\t\tif ( Rope is null )\r\n\t\t\treturn;\r\n\r\n\t\tvar ropeStart = ResolveRopeStart();\r\n\t\tif ( ropeStart is null )\r\n\t\t\treturn;\r\n\r\n\t\tRope.Enabled = RopeActive;\r\n\t\tif ( !RopeActive )\r\n\t\t\treturn;\r\n\r\n\t\tRope.UseVectorPoints = true;\r\n\t\tRope.VectorPoints = new List\u003CVector3\u003E\r\n\t\t{\r\n\t\t\tropeStart.WorldPosition,\r\n\t\t\tRopeEnd,\r\n\t\t};\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Local desktop owner: viewmodel muzzle. Everyone else (including other players on your client): world weapon muzzle.\r\n\t/// \u003C/summary\u003E\r\n\tprivate GameObject ResolveRopeStart()\r\n\t{\r\n\t\tif ( !IsProxy \u0026\u0026 !Game.IsRunningInVR )\r\n\t\t{\r\n\t\t\tvar viewMuzzle = PlayerViewModel.Instance?.Muzzle;\r\n\t\t\tif ( viewMuzzle.IsValid() )\r\n\t\t\t\treturn viewMuzzle;\r\n\t\t}\r\n\r\n\t\treturn MuzzleTransform;\r\n\t}\r\n\r\n\tprivate PlayerCharacterController ResolvePlayerController()\r\n\t{\r\n\t\tvar fromHierarchy = GetComponentInParent\u003CPlayerCharacterController\u003E();\r\n\t\tif ( fromHierarchy.IsValid() )\r\n\t\t\treturn fromHierarchy;\r\n\r\n\t\tif ( Player.CurrentPlayer.IsValid() )\r\n\t\t\treturn Player.CurrentPlayer.Components.Get\u003CPlayerCharacterController\u003E();\r\n\r\n\t\treturn null;\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"ui/inventoryitempanel.razor.scss","FileName":"inventoryitempanel.razor.scss","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"InventoryItemPanel {\r\n\tfont-weight: bold;\r\n\theight: 8vh;\r\n\twidth: 8vh;\r\n\r\n\t.container {\r\n\t\tborder: 5px gray solid;\r\n\t\tbackground: rgba(30, 30, 30, 0.7);\r\n\t\tborder-radius: 20px;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t\twidth: 100%;\r\n\t\theight: 100%;\r\n\t}\r\n\r\n\t.title {\r\n\t\tfont-size: 12px;\r\n\t\tfont-family: Poppins;\r\n\t\tcolor: #fff;\r\n\t}\r\n\r\n\t.selected {\r\n\t\tborder-color: green;\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"RagdollImpulseApplier.cs","FileName":"RagdollImpulseApplier.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\nusing System.Linq;\r\n\r\n/// \u003Csummary\u003E\r\n/// Waits for a newly created ragdoll\u0027s physics bodies, distributes an impulse\r\n/// across them once, then removes itself.\r\n/// \u003C/summary\u003E\r\npublic sealed class RagdollImpulseApplier : Component\r\n{\r\n\tpublic Vector3 Impulse { get; set; }\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\t// Only the network owner simulates and pushes the ragdoll. Proxies receive\r\n\t\t// the resulting ModelPhysics transforms from that authoritative instance.\r\n\t\tif ( IsProxy )\r\n\t\t\treturn;\r\n\r\n\t\tif ( Impulse.LengthSquared \u003C= 0f )\r\n\t\t{\r\n\t\t\tDestroy();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar modelPhysics = GetComponent\u003CModelPhysics\u003E();\r\n\t\tif ( modelPhysics is null || modelPhysics.Bodies is null )\r\n\t\t\treturn;\r\n\r\n\t\t// ModelPhysics keeps ragdoll rigidbodies in its Bodies collection rather\r\n\t\t// than exposing them as normal components in the GameObject hierarchy.\r\n\t\tvar bodies = modelPhysics.Bodies\r\n\t\t\t.Where( body =\u003E body.Component.IsValid() \u0026\u0026 body.Component.PhysicsBody.IsValid() )\r\n\t\t\t.ToArray();\r\n\r\n\t\tif ( bodies.Length == 0 )\r\n\t\t\treturn;\r\n\r\n\t\t// Divide the total impulse across all bones so models with more physics\r\n\t\t// bodies do not receive a proportionally stronger launch.\r\n\t\tvar impulsePerBody = Impulse / bodies.Length;\r\n\t\tforeach ( var body in bodies )\r\n\t\t\tbody.Component.PhysicsBody.ApplyImpulse( impulsePerBody );\r\n\r\n\t\tDestroy();\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"SbTween/Examples/SbecubeTS.cs","FileName":"SbecubeTS.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\nusing SbTween;\r\n\r\nnamespace SbTween.Examples;\r\n\r\npublic sealed class SbecubeTS : Component\r\n{\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tthis.TweenScale( new Vector3( 0.5f, 1f, 0.5f ),0.5f ).SetLoops(-1,LoopType.YoYo).SetEase(EaseType.InBounce).Play();\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"SbTween/Extensions/LightExtensions.cs","FileName":"LightExtensions.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\nusing Sandbox.UI;\r\nusing System;\r\n\r\nnamespace SbTween;\r\n\r\npublic static class LightExtensions\r\n{\r\n\r\n\tpublic static BaseTween TweenLightColor( this Light Light, Color target, float duration )\r\n\t{\r\n\t\tColor start = Light.LightColor;\r\n\t\tvar tween = new BaseTween( duration );\r\n\t\ttween.Target = Light.GameObject;\r\n\t\treturn TweenManager.Instance.AddTween( tween\r\n\t\t\t.OnStart( () =\u003E start = Light.LightColor )\r\n\t\t\t.OnUpdate( p =\u003E Light.LightColor = Color.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenRadius( this SpotLight light, float target, float duration )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat start = light.Radius;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = light.Radius )\r\n\t\t\t.OnUpdate( p =\u003E light.Radius = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenConeOuter( this SpotLight light, float target, float duration )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat start = light.ConeOuter;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = light.ConeOuter )\r\n\t\t\t.OnUpdate( p =\u003E light.ConeOuter = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenInnerCone( this SpotLight light, float target, float duration )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat start = light.ConeInner;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = light.ConeInner )\r\n\t\t\t.OnUpdate( p =\u003E light.ConeInner = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenAttenuation( this PointLight light, float target, float duration )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat start = light.Attenuation;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = light.Attenuation )\r\n\t\t\t.OnUpdate( p =\u003E light.Attenuation = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenRadius( this PointLight light, float target, float duration )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat start = light.Radius;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = light.Radius )\r\n\t\t\t.OnUpdate( p =\u003E light.Radius = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenAttenuation( this SpotLight light, float target, float duration )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat start = light.Attenuation;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnStart( () =\u003E start = light.Attenuation )\r\n\t\t\t.OnUpdate( p =\u003E light.Attenuation = MathX.Lerp( start, target, p ) ) );\r\n\t}\r\n\r\n\t//FLICKERING LIGHT\r\n\tpublic static BaseTween TweenFlickerLight( this PointLight light, float minBrightness, float maxBrightness, float duration, float speed = 10f )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat time = 0f;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnUpdate( _ =\u003E\r\n\t\t\t{\r\n\t\t\t\ttime \u002B= Time.Delta * speed;\r\n\t\t\t\tfloat noise = MathF.Sin( time * 1.3f ) * MathF.Sin( time * 2.7f ) * MathF.Sin( time * 0.9f );\r\n\t\t\t\tfloat t = (noise \u002B 1f) * 0.5f;\r\n\t\t\t\tlight.Attenuation = MathX.Lerp( minBrightness, maxBrightness, t );\r\n\t\t\t} ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenFlickerLight( this SpotLight light, float minBrightness, float maxBrightness, float duration, float speed = 10f )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat time = 0f;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnUpdate( _ =\u003E\r\n\t\t\t{\r\n\t\t\t\ttime \u002B= Time.Delta * speed;\r\n\t\t\t\tfloat noise = MathF.Sin( time * 1.3f ) * MathF.Sin( time * 2.7f ) * MathF.Sin( time * 0.9f );\r\n\t\t\t\tfloat t = (noise \u002B 1f) * 0.5f;\r\n\t\t\t\tlight.Attenuation = MathX.Lerp( minBrightness, maxBrightness, t );\r\n\t\t\t} ) );\r\n\t}\r\n\r\n\t//FLICKERING Color\r\n\r\n\tpublic static BaseTween TweenFlickerColor( this PointLight light, Color colorA, Color colorB, float duration, float speed = 10f )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat time = 0f;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnUpdate( _ =\u003E\r\n\t\t\t{\r\n\t\t\t\ttime \u002B= Time.Delta * speed;\r\n\t\t\t\tfloat noise = MathF.Sin( time * 1.3f ) * MathF.Sin( time * 2.7f ) * MathF.Sin( time * 0.9f );\r\n\t\t\t\tfloat t = (noise \u002B 1f) * 0.5f;\r\n\t\t\t\tlight.LightColor = Color.Lerp( colorA, colorB, t );\r\n\t\t\t} ) );\r\n\t}\r\n\r\n\tpublic static BaseTween TweenFlickerColor( this SpotLight light, Color colorA, Color colorB, float duration, float speed = 10f )\r\n\t{\r\n\t\tif ( !light.IsValid() ) return null;\r\n\r\n\t\tfloat time = 0f;\r\n\t\treturn TweenManager.Instance.AddTween( new BaseTween( duration )\r\n\t\t\t.OnUpdate( _ =\u003E\r\n\t\t\t{\r\n\t\t\t\ttime \u002B= Time.Delta * speed;\r\n\t\t\t\tfloat noise = MathF.Sin( time * 1.3f ) * MathF.Sin( time * 2.7f ) * MathF.Sin( time * 0.9f );\r\n\t\t\t\tfloat t = (noise \u002B 1f) * 0.5f;\r\n\t\t\t\tlight.LightColor = Color.Lerp( colorA, colorB, t );\r\n\t\t\t} ) );\r\n\t}\r\n\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"Inventory.cs","FileName":"Inventory.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\n\r\npublic sealed class Inventory : Component\r\n{\r\n\t[Property] public InventoryPanel InventoryPanel;\r\n\r\n\t// The inventory is a snapshot child, so its changing local transform needs explicit sync.\r\n\t[Sync( SyncFlags.Interpolate )] private Transform SlotTransform { get; set; } = global::Transform.Zero;\r\n\t[Sync( SyncFlags.Interpolate )] private float SlotHeightScale { get; set; } = 1f;\r\n\r\n\tprivate float _appliedSlotHeightScale = 1f;\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tInventoryPanel.GameObject.Enabled = !IsProxy \u0026\u0026 !Game.IsRunningInVR;\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Runs after this frame\u0027s locomotion and desktop mouse look. VR reads Input.VR.Head directly\r\n\t/// so it does not depend on the camera\u0027s VRTrackedObject update order.\r\n\t/// \u003C/summary\u003E\r\n\tprotected override void OnPreRender()\r\n\t{\r\n\t\tif ( IsProxy )\r\n\t\t{\r\n\t\t\tLocalTransform = SlotTransform;\r\n\t\t\tApplyCalibratedSlotHeights( SlotHeightScale );\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar player = GetComponentInParent\u003CPlayerCharacterController\u003E();\r\n\t\tif ( !player.IsValid() )\r\n\t\t\treturn;\r\n\r\n\t\t// Bots already turn their player root and have no local camera or headset.\r\n\t\tif ( player.GetComponent\u003CPlayer\u003E() is { IsBot: true } )\r\n\t\t\treturn;\r\n\r\n\t\tif ( !Game.IsRunningInVR )\r\n\t\t{\r\n\t\t\tif ( player.Camera.IsValid() )\r\n\t\t\t{\r\n\t\t\t\tWorldRotation = Rotation.FromYaw( player.Camera.WorldRotation.Angles().yaw );\r\n\t\t\t\tUpdateDesktopStowedItems( player.Camera.WorldRotation );\r\n\t\t\t}\r\n\r\n\t\t\tSlotTransform = LocalTransform;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar head = Input.VR.Head;\r\n\r\n\t\t// Yaw only so hip/chest slots stay at body height while still tracking look heading.\r\n\t\tWorldRotation = Rotation.FromYaw( head.Rotation.Angles().yaw );\r\n\r\n\t\tApplyCalibratedSlotHeights( player.HeightScale );\r\n\r\n\t\t// Keep authored slot offsets relative to the head: standing matches the scaled prefab,\r\n\t\t// crouch/sit drops the holsters by the same amount the headset dropped.\r\n\t\tvar standingEyeHeight = player.HeightScale * PlayerCharacterController.ReferenceStandingEyeHeight;\r\n\t\tvar headHeight = head.Position.z - player.WorldPosition.z;\r\n\t\tLocalPosition = Vector3.Up * (headHeight - standingEyeHeight);\r\n\t\tSlotHeightScale = player.HeightScale;\r\n\t\tSlotTransform = LocalTransform;\r\n\t}\r\n\r\n\tprivate void UpdateDesktopStowedItems( Rotation lookRotation )\r\n\t{\r\n\t\tforeach ( var slot in GetComponentsInChildren\u003CInventorySlot\u003E() )\r\n\t\t{\r\n\t\t\tvar item = slot.StoredItem;\r\n\t\t\tif ( !item.IsValid() || item.IsProxy || !item.IsStowed || item.GameObject.Parent != slot.GameObject )\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\t// Desktop holsters keep the slot position, but face the view so active tools\r\n\t\t\t// (such as a flashlight) shine ahead instead of along the authored VR holster angle.\r\n\t\t\titem.WorldRotation = lookRotation;\r\n\t\t}\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Prefab slots are authored for the 64\u0022 reference citizen. Scale their local height\r\n\t/// so holsters sit on the avatar after VR standing-eye-height calibration.\r\n\t/// \u003C/summary\u003E\r\n\tprivate void ApplyCalibratedSlotHeights( float heightScale )\r\n\t{\r\n\t\tif ( heightScale \u003C= 0f || heightScale.AlmostEqual( _appliedSlotHeightScale ) )\r\n\t\t\treturn;\r\n\r\n\t\tvar factor = heightScale / _appliedSlotHeightScale;\r\n\t\tforeach ( var slot in GetComponentsInChildren\u003CInventorySlot\u003E() )\r\n\t\t{\r\n\t\t\tvar pos = slot.LocalPosition;\r\n\t\t\tslot.LocalPosition = pos.WithZ( pos.z * factor );\r\n\t\t}\r\n\r\n\t\t_appliedSlotHeightScale = heightScale;\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"Inventory/InventoryItem.cs","FileName":"InventoryItem.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\nusing Sandbox.Citizen;\r\nusing System.Linq;\r\n\r\npublic enum ItemType\r\n{\r\n\tPrimary,\r\n\tSecondary,\r\n\tUtility\r\n}\r\n\r\npublic sealed class InventoryItem : Component\r\n{\r\n\tprivate const float DroppedLifetime = 15f;\r\n\t[Sync] private float DespawnAt { get; set; }\r\n\r\n\t/// \u003Csummary\u003EWhich inventory slot category this item can be placed in.\u003C/summary\u003E\r\n\t[Property] public ItemType Type { get; set; }\r\n\r\n\t/// \u003Csummary\u003EIcon material shown for this item in the inventory HUD.\u003C/summary\u003E\r\n\t[Property] public string ItemIconPath { get; set; } = \u0022/materials/default.webp\u0022;\r\n\r\n\t/// \u003Csummary\u003ECitizen hold pose used while this item is in hand (desktop bodies and proxies).\u003C/summary\u003E\r\n\t[Property] public CitizenAnimationHelper.HoldTypes HoldType { get; private set; }\r\n\r\n\t/// \u003Csummary\u003EWhich hand the citizen holds this item in.\u003C/summary\u003E\r\n\t[Property] public CitizenAnimationHelper.Hand Handedness { get; private set; }\r\n\t[Property] public Vector3 RightHandPosition { get; private set; }\r\n\t[Property] public Rotation RightHandRotation { get; private set; } = Rotation.Identity;\r\n\r\n\t/// \u003Csummary\u003ELocal offset from the holster slot. Zero sits on the slot origin.\u003C/summary\u003E\r\n\t[Property, Group( \u0022Stow\u0022 )] public Vector3 StowedPosition { get; private set; }\r\n\r\n\t/// \u003Csummary\u003ELocal rotation applied when this item is holstered. Rotate this so a flashlight beam points forward while stowed.\u003C/summary\u003E\r\n\t[Property, Group( \u0022Stow\u0022 )] public Rotation StowedRotation { get; private set; } = Rotation.Identity;\r\n\r\n\t[Sync]\r\n\tpublic GameObject SlotObject { get; private set; }\r\n\r\n\t[Sync, Change( nameof( OnIsStowedChanged ) )]\r\n\tpublic bool IsStowed { get; set; }\r\n\r\n\t[Sync, Change( nameof( OnIsPhysicsEnabledChanged ) )]\r\n\tpublic bool IsPhysicsEnabled { get; set; } = true;\r\n\r\n\tpublic InventorySlot Slot =\u003E SlotObject?.Components.Get\u003CInventorySlot\u003E();\r\n\tprivate Player Carrier =\u003E Slot?.Components.GetInAncestorsOrSelf\u003CPlayer\u003E()\r\n\t\t?? Components.GetInAncestorsOrSelf\u003CPlayer\u003E();\r\n\r\n\t/// \u003Csummary\u003ETrue while any grip on this item is still held by a hand.\u003C/summary\u003E\r\n\tpublic bool IsHeld =\u003E GameObject.Components.GetAll\u003CGrabPoint\u003E( FindMode.InDescendants ).Any( g =\u003E g.IsGrabbed );\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tOnIsPhysicsEnabledChanged( IsPhysicsEnabled, IsPhysicsEnabled );\r\n\r\n\t\t// An item can spawn in already stowed (initial loadout, or a proxy of someone\r\n\t\t// else\u0027s carried item), so apply that state once instead of waiting for a change.\r\n\t\tif ( IsStowed )\r\n\t\t\tOnIsStowedChanged( false, true );\r\n\t}\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tif ( IsProxy || DespawnAt \u003C= 0f )\r\n\t\t\treturn;\r\n\r\n\t\tif ( IsStowed || IsHeld )\r\n\t\t{\r\n\t\t\tCancelDespawnTimer();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif ( Time.Now \u003E= DespawnAt )\r\n\t\t\tGameObject.Destroy();\r\n\t}\r\n\r\n\t/// \u003Csummary\u003EStarts a fresh cleanup timer after the last hand releases the item into the world.\u003C/summary\u003E\r\n\tpublic void StartDespawnTimer()\r\n\t{\r\n\t\tif ( IsProxy || IsStowed || IsHeld )\r\n\t\t\treturn;\r\n\r\n\t\tDespawnAt = Time.Now \u002B DroppedLifetime;\r\n\t}\r\n\r\n\t/// \u003Csummary\u003EPicking up or holstering an item cancels its pending cleanup.\u003C/summary\u003E\r\n\tpublic void CancelDespawnTimer()\r\n\t{\r\n\t\tif ( !IsProxy )\r\n\t\t\tDespawnAt = 0f;\r\n\t}\r\n\r\n\tpublic void AssignSlot( GameObject slotObject )\r\n\t{\r\n\t\tSlotObject = slotObject;\r\n\t}\r\n\r\n\tpublic void ClearSlot()\r\n\t{\r\n\t\tvar slot = Slot;\r\n\t\tif ( slot is not null \u0026\u0026 slot.StoredItemObject == GameObject )\r\n\t\t\tslot.ClearStoredItem();\r\n\r\n\t\tSlotObject = null;\r\n\t\tIsStowed = false;\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Detaches this item from the player and restores its world model. Physics is only\r\n\t/// re-enabled once nothing holds it; \u003Csee cref=\u0022GrabPoint.Drop\u0022/\u003E does that for the\r\n\t/// last hand to let go, so a two-handed grip keeps driving the item.\r\n\t/// \u003C/summary\u003E\r\n\tpublic void DropToWorld()\r\n\t{\r\n\t\tClearSlot();\r\n\r\n\t\tGameObject.SetParent( null, true );\r\n\t\tSetWorldModelVisible( true );\r\n\r\n\t\tif ( !IsHeld )\r\n\t\t{\r\n\t\t\tIsPhysicsEnabled = true;\r\n\t\t\tStartDespawnTimer();\r\n\t\t}\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Shows or hides the item\u0027s world model for the local client only; rendering isn\u0027t\r\n\t/// networked, so each machine decides what its own player gets to see.\r\n\t/// \u003C/summary\u003E\r\n\tpublic void SetWorldModelVisible( bool visible )\r\n\t{\r\n\t\tvar modelRenderer = GetComponent\u003CModelRenderer\u003E();\r\n\t\tif ( modelRenderer?.SceneObject is not null )\r\n\t\t\tmodelRenderer.SceneObject.RenderingEnabled = visible;\r\n\t}\r\n\r\n\tprivate void OnIsStowedChanged( bool wasStowed, bool isStowed )\r\n\t{\r\n\t\tif ( isStowed )\r\n\t\t{\r\n\t\t\t// A stowed item is only drawn for the VR player carrying it: desktop owners see a\r\n\t\t\t// viewmodel instead, and nobody else should see items pinned to another body.\r\n\t\t\tSetWorldModelVisible( !IsProxy \u0026\u0026 Game.IsRunningInVR \u0026\u0026 Carrier == Player.CurrentPlayer );\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Out of the slot: other players see it in the carrier\u0027s hands again, while a local\r\n\t\t// desktop player stays on their viewmodel until the item is dropped into the world.\r\n\t\tSetWorldModelVisible( IsProxy || Game.IsRunningInVR || Carrier is { IsBot: true } );\r\n\t}\r\n\r\n\tpublic Rotation GetStowedRotation()\r\n\t{\r\n\t\t// Older items (including hot-reloaded instances) can still contain a zero quaternion.\r\n\t\treturn StowedRotation == default( Rotation ) ? Rotation.Identity : StowedRotation;\r\n\t}\r\n\r\n\tpublic void Stow()\r\n\t{\r\n\t\tCancelDespawnTimer();\r\n\t\tIsStowed = true;\r\n\t}\r\n\r\n\tpublic void Unstow()\r\n\t{\r\n\t\tIsStowed = false;\r\n\t}\r\n\r\n\tprivate void OnIsPhysicsEnabledChanged( bool oldValue, bool newValue )\r\n\t{\r\n\t\tvar modelCollider = GetComponent\u003CModelCollider\u003E( includeDisabled: true );\r\n\t\tmodelCollider?.Enabled = newValue;\r\n\r\n\t\tvar rigidBody = GetComponent\u003CRigidbody\u003E( includeDisabled: true );\r\n\t\trigidBody?.Enabled = newValue;\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"Inventory/InventorySlot.cs","FileName":"InventorySlot.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"using Sandbox;\r\n\r\npublic enum InventorySlotIndex\r\n{\r\n\tSlot1,\r\n\tSlot2,\r\n\tSlot3,\r\n\tSlot4,\r\n\tSlot5\r\n}\r\n\r\npublic sealed class InventorySlot : Component\r\n{\r\n\t/// \u003Csummary\u003EHotbar index for this slot; maps to slot1\u2013slot5 input actions.\u003C/summary\u003E\r\n\t[Property] public InventorySlotIndex SlotIndex { get; set; }\r\n\r\n\t/// \u003Csummary\u003EOnly items of this type can be placed in this slot.\u003C/summary\u003E\r\n\t[Property] public ItemType SlotType { get; set; }\r\n\r\n\t/// \u003Csummary\u003EWorld-units radius for VR drop detection and slot highlight.\u003C/summary\u003E\r\n\t[Property] public float Radius { get; set; } = 8f;\r\n\r\n\t[Sync] public GameObject StoredItemObject { get; private set; }\r\n\r\n\tpublic InventoryItem StoredItem =\u003E StoredItemObject?.Components.Get\u003CInventoryItem\u003E();\r\n\r\n\tpublic bool IsEmpty =\u003E StoredItemObject is null;\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// True if this slot can take the item. An item that already reserved this slot counts,\r\n\t/// so a desktop player holstering what they picked up lands back in their own slot.\r\n\t/// \u003C/summary\u003E\r\n\tpublic bool CanAccept( InventoryItem item )\r\n\t{\r\n\t\tif ( item is null || item.Type != SlotType )\r\n\t\t\treturn false;\r\n\r\n\t\treturn IsEmpty || StoredItemObject == item.GameObject;\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Puts the item away on the body: parents it to the slot and freezes its physics.\r\n\t/// Single stow path for VR, desktop and loadout. Stowing also hides the item\u0027s world\r\n\t/// model for everyone but a VR carrier, which \u003Csee cref=\u0022InventoryItem.IsStowed\u0022/\u003E drives.\r\n\t/// \u003C/summary\u003E\r\n\tpublic bool TryStow( InventoryItem item )\r\n\t{\r\n\t\tif ( !CanAccept( item ) )\r\n\t\t\treturn false;\r\n\r\n\t\tStoredItemObject = item.GameObject;\r\n\t\titem.AssignSlot( GameObject );\r\n\t\titem.IsPhysicsEnabled = false;\r\n\t\titem.Stow();\r\n\r\n\t\tAttachToSlot( item );\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// Claims this slot for an item that stays in hand, so the hotbar key keeps working\r\n\t/// until the item is holstered with \u003Csee cref=\u0022TryStow\u0022/\u003E.\r\n\t/// \u003C/summary\u003E\r\n\tpublic void Reserve( InventoryItem item )\r\n\t{\r\n\t\tif ( !CanAccept( item ) )\r\n\t\t\treturn;\r\n\r\n\t\tStoredItemObject = item.GameObject;\r\n\t\titem.AssignSlot( GameObject );\r\n\t}\r\n\r\n\tpublic void ClearStoredItem()\r\n\t{\r\n\t\tStoredItemObject = null;\r\n\t}\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tif ( IsProxy )\r\n\t\t\treturn;\r\n\r\n\t\tUpdateStowedTransform();\r\n\t\tUpdateVrHighlight();\r\n\t}\r\n\r\n\tprivate void UpdateStowedTransform()\r\n\t{\r\n\t\tvar item = StoredItem;\r\n\t\tif ( item is null || !item.IsStowed )\r\n\t\t\treturn;\r\n\r\n\t\tif ( item.GameObject.Parent != GameObject )\r\n\t\t\tAttachToSlot( item );\r\n\t}\r\n\r\n\tprivate void AttachToSlot( InventoryItem item )\r\n\t{\r\n\t\titem.GameObject.SetParent( GameObject, false );\r\n\t\titem.GameObject.LocalPosition = item.StowedPosition;\r\n\t\titem.GameObject.LocalRotation = item.GetStowedRotation();\r\n\t}\r\n\r\n\tprivate void UpdateVrHighlight()\r\n\t{\r\n\t\tif ( !Game.IsRunningInVR || Components.GetInAncestorsOrSelf\u003CPlayer\u003E() != Player.CurrentPlayer )\r\n\t\t\treturn;\r\n\r\n\t\tvar heldItem = GetHeldItemOfSlotType();\r\n\t\tif ( heldItem is null || !IsEmpty )\r\n\t\t\treturn;\r\n\r\n\t\tvar color = ShouldHighlight( heldItem ) ? Color.Green : Color.Red;\r\n\t\tGizmo.Draw.Color = color.WithAlpha( 0.45f );\r\n\t\tGizmo.Draw.LineSphere( WorldPosition, Radius );\r\n\t}\r\n\r\n\tprivate InventoryItem GetHeldItemOfSlotType()\r\n\t{\r\n\t\tif ( Player.CurrentPlayer is null )\r\n\t\t\treturn null;\r\n\r\n\t\treturn Player.CurrentPlayer.Inventory.GetHeldItemOfType( SlotType );\r\n\t}\r\n\r\n\tprivate bool ShouldHighlight( InventoryItem heldItem )\r\n\t{\r\n\t\treturn WorldPosition.Distance( GetVrStowPosition( heldItem ) ) \u003C= Radius;\r\n\t}\r\n\r\n\t// Holster proximity uses the grabbing hand, not the item root \u2014 a long gun\u0027s\r\n\t// origin can sit well outside the slot while the grip is inside it.\r\n\tprivate Vector3 GetVrStowPosition( InventoryItem item )\r\n\t{\r\n\t\tVector3? closestHand = null;\r\n\t\tvar closestDistance = float.MaxValue;\r\n\r\n\t\tforeach ( var grabPoint in item.GameObject.Components.GetAll\u003CGrabPoint\u003E( FindMode.InDescendants ) )\r\n\t\t{\r\n\t\t\tif ( !grabPoint.IsGrabbed )\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tvar handPosition = grabPoint.HandTransform.Position;\r\n\t\t\tvar distance = WorldPosition.Distance( handPosition );\r\n\t\t\tif ( distance \u003E= closestDistance )\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tclosestDistance = distance;\r\n\t\t\tclosestHand = handPosition;\r\n\t\t}\r\n\r\n\t\treturn closestHand ?? item.GameObject.WorldPosition;\r\n\t}\r\n\r\n\tprotected override void DrawGizmos()\r\n\t{\r\n\t\tGizmo.Draw.Color = Color.Cyan.WithAlpha( 0.35f );\r\n\t\tGizmo.Draw.LineSphere( Vector3.Zero, Radius );\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"UI/KillFeed.razor","FileName":"KillFeed.razor","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"@using System;\r\n@using System.Collections.Generic;\r\n@using System.Globalization;\r\n@using System.Linq;\r\n@using Sandbox;\r\n@using Sandbox.UI;\r\n@inherits PanelComponent\r\n@namespace Sandbox\r\n\r\n\u003Croot class=\u0022@(IsWorldPanel ? \u0022full\u0022 : \u0022\u0022)\u0022\u003E\r\n\t\u003Cdiv class=\u0022feed\u0022\u003E\r\n\t\t@foreach ( var entry in VisibleEntries )\r\n\t\t{\r\n\t\t\tvar opacity = EntryOpacity( entry ).ToString( \u00220.###\u0022, CultureInfo.InvariantCulture );\r\n\t\t\t\u003Cdiv class=\u0022entry\u0022 style=\u0022opacity: @opacity;\u0022\u003E\r\n\t\t\t\t@if ( !entry.IsSuicide )\r\n\t\t\t\t{\r\n\t\t\t\t\t\u003Clabel class=\u0022name @(IsLocal( entry.KillerId ) ? \u0022local\u0022 : \u0022\u0022)\u0022\u003E@entry.KillerName\u003C/label\u003E\r\n\t\t\t\t\t@if ( !string.IsNullOrEmpty( entry.WeaponIconPath ) )\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\u003Cimg class=\u0022weapon\u0022 src=\u0022@entry.WeaponIconPath\u0022 /\u003E\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\u003Clabel class=\u0022separator\u0022\u003E\u00BB\u003C/label\u003E\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse\r\n\t\t\t\t{\r\n\t\t\t\t\t\u003Clabel class=\u0022separator suicide\u0022\u003E\u2620\u003C/label\u003E\r\n\t\t\t\t}\r\n\t\t\t\t\u003Clabel class=\u0022name @(IsLocal( entry.VictimId ) ? \u0022local\u0022 : \u0022\u0022)\u0022\u003E@entry.VictimName\u003C/label\u003E\r\n\t\t\t\t@if ( entry.Headshot )\r\n\t\t\t\t{\r\n\t\t\t\t\t\u003Clabel class=\u0022headshot\u0022\u003EHS\u003C/label\u003E\r\n\t\t\t\t}\r\n\t\t\t\u003C/div\u003E\r\n\t\t}\r\n\t\u003C/div\u003E\r\n\u003C/root\u003E\r\n\r\n@code\r\n{\r\n\tprivate const float FadeStart = 4f;\r\n\r\n\tprivate static KillFeedHistory History =\u003E DeathmatchGame.Instance?.KillFeedHistory;\r\n\r\n\t/// \u003Csummary\u003EWhen true, layout fills a WorldPanel (VR); when false, uses ScreenPanel HUD offsets.\u003C/summary\u003E\r\n\t[Property] bool IsWorldPanel { get; set; }\r\n\r\n\tprivate IEnumerable\u003CKillFeedHistory.Entry\u003E VisibleEntries =\u003E\r\n\t\t(History?.Entries ?? Array.Empty\u003CKillFeedHistory.Entry\u003E())\r\n\t\t\t.Where( e =\u003E Time.Now - e.CreatedAt \u003C KillFeedHistory.EntryLifetime );\r\n\r\n\tpublic static void Add( Guid attackerId, Guid victimId, bool headshot, bool isSuicide, string weaponIconPath )\r\n\t{\r\n\t\tvar attacker = NetworkManager.Instance?.GetPlayerSession( attackerId );\r\n\t\tvar victim = NetworkManager.Instance?.GetPlayerSession( victimId );\r\n\r\n\t\tPushEntry(\r\n\t\t\tattackerId,\r\n\t\t\tvictimId,\r\n\t\t\tattacker?.DisplayName ?? \u0022Unknown\u0022,\r\n\t\t\tvictim?.DisplayName ?? \u0022Unknown\u0022,\r\n\t\t\theadshot,\r\n\t\t\tisSuicide,\r\n\t\t\tweaponIconPath\r\n\t\t);\r\n\t}\r\n\r\n\tpublic void AddEntry( Guid attackerId, Guid victimId, bool headshot, bool isSuicide, string weaponIconPath ) =\u003E\r\n\t\tAdd( attackerId, victimId, headshot, isSuicide, weaponIconPath );\r\n\r\n\t/// \u003Csummary\u003EInserts a sample killfeed row (cycles kill / headshot / suicide).\u003C/summary\u003E\r\n\t[Button( \u0022Add Test Entry\u0022 )]\r\n\tpublic void AddTestEntry()\r\n\t{\r\n\t\tvar localId = Connection.Local?.Id ?? Guid.Empty;\r\n\t\tvar variant = (History?.Version ?? 0) % 3;\r\n\r\n\t\tswitch ( variant )\r\n\t\t{\r\n\t\t\tcase 0:\r\n\t\t\t\tPushEntry( localId, Guid.NewGuid(), \u0022TestKiller\u0022, \u0022TestVictim\u0022, false, false, \u0022/materials/m4a1.png\u0022 );\r\n\t\t\t\tbreak;\r\n\t\t\tcase 1:\r\n\t\t\t\tPushEntry( localId, Guid.NewGuid(), \u0022TestKiller\u0022, \u0022TestVictim\u0022, true, false, \u0022/materials/usp.webp\u0022 );\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tPushEntry( localId, localId, \u0022TestVictim\u0022, \u0022TestVictim\u0022, false, true, \u0022\u0022 );\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate static void PushEntry( Guid killerId, Guid victimId, string killerName, string victimName, bool headshot, bool isSuicide, string weaponIconPath ) =\u003E\r\n\t\tHistory?.Add( killerId, victimId, killerName, victimName, headshot, isSuicide, weaponIconPath );\r\n\r\n\tprivate static bool IsLocal( Guid connectionId ) =\u003E\n\t\tConnection.Local is not null \u0026\u0026 Connection.Local.Id == connectionId;\r\n\r\n\tprivate static float EntryOpacity( KillFeedHistory.Entry entry )\r\n\t{\r\n\t\tvar age = Time.Now - entry.CreatedAt;\r\n\t\tif ( age \u003C FadeStart )\r\n\t\t\treturn 1f;\r\n\r\n\t\treturn Math.Clamp( 1f - (age - FadeStart) / (KillFeedHistory.EntryLifetime - FadeStart), 0f, 1f );\r\n\t}\r\n\r\n\tprotected override int BuildHash()\r\n\t{\r\n\t\tvar fadeTick = (int)(Time.Now * 10f);\r\n\t\treturn HashCode.Combine( History?.Version ?? 0, fadeTick, History?.Entries.Count ?? 0, IsWorldPanel );\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"UI/ScoreboardRow.razor","FileName":"ScoreboardRow.razor","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"@using Sandbox;\r\n@using Sandbox.UI;\r\n@inherits Panel\r\n@namespace Sandbox\r\n\r\n\u003Croot\u003E\r\n\t\u003Cdiv class=\u0022player-info\u0022\u003E\r\n\t\t@if (!Player.IsBot)\r\n\t\t{\r\n\t\t\t\u003Cimg src=\u0022@Player.AvatarUrl\u0022 alt=\u0022@Player.DisplayName avatar\u0022 class=\u0022avatar\u0022 /\u003E\r\n\t\t}\r\n\t\t\u003Cspan class=\u0022name\u0022\u003E@Player.DisplayName\u003C/span\u003E\r\n\t\t@if (Player.IsBot)\r\n\t\t{\r\n\t\t\t\u003Cspan class=\u0022bot-tag\u0022\u003EBOT\u003C/span\u003E\r\n\t\t}\r\n\t\telse if (Player.IsVR)\r\n\t\t{\r\n\t\t\t\u003Cspan class=\u0022vr-tag\u0022\u003EVR\u003C/span\u003E\r\n\t\t}\r\n\t\u003C/div\u003E\r\n\t\u003Cdiv class=\u0022stats\u0022\u003E\r\n\t\t\u003Cspan class=\u0022stat\u0022\u003EK: @Player.Kills\u003C/span\u003E\r\n\t\t\u003Cspan class=\u0022stat\u0022\u003ED: @Player.Deaths\u003C/span\u003E\r\n\t\t\u003Cspan class=\u0022stat\u0022\u003EPing: @GetPing(Player)\u003C/span\u003E\r\n\t\u003C/div\u003E\r\n\u003C/root\u003E\r\n\r\n@code\r\n{\r\n\r\n\t[Property] public PlayerSession Player { get; set; }\r\n\r\n\tprivate int GetPing(PlayerSession Player)\r\n\t{\r\n\t\tif (Player.IsBot)\r\n\t\t\treturn 0;\r\n\t\tvar connection = Connection.All.FirstOrDefault(c =\u003E c.Id == Player.Network.OwnerId);\r\n\t\treturn connection?.Ping.CeilToInt() ?? -1;\r\n\t}\r\n\r\n\t/// \u003Csummary\u003E\r\n\t/// the hash determines if the system should be rebuilt. If it changes, it will be rebuilt\r\n\t/// \u003C/summary\u003E\r\n\tprotected override int BuildHash() =\u003E System.HashCode.Combine( Player.AvatarUrl, Player.DisplayName, Player.Kills, Player.Deaths, Player.IsVR, Player.IsBot );\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"ui/maploadingscreen.razor.scss","FileName":"maploadingscreen.razor.scss","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"MapLoadingScreen {\r\n\twidth: 100%;\r\n\theight: 100%;\r\n\tposition: absolute;\r\n\toverflow: hidden;\r\n\r\n\t.backdrop {\r\n\t\tposition: absolute;\r\n\t\twidth: 100%;\r\n\t\theight: 100%;\r\n\t\tbackground-color: #0a0a0e;\r\n\t\tbackground-size: cover;\r\n\t\tbackground-position: center;\r\n\t\tbackground-repeat: no-repeat;\r\n\t}\r\n\r\n\t.scrim {\r\n\t\tposition: absolute;\r\n\t\twidth: 100%;\r\n\t\theight: 100%;\r\n\t\tbackground: linear-gradient( to top, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.35) );\r\n\t}\r\n\r\n\t.content {\r\n\t\tposition: absolute;\r\n\t\twidth: 100%;\r\n\t\theight: 100%;\r\n\t\tflex-direction: column;\r\n\t\tjustify-content: flex-end;\r\n\t\talign-items: center;\r\n\t\tpadding: 80px;\r\n\t\tgap: 12px;\r\n\t}\r\n\r\n\t.title {\r\n\t\tfont-size: 48px;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: white;\r\n\t\ttext-transform: uppercase;\r\n\t\ttext-shadow: 0 2px 12px rgba(0, 0, 0, 0.8);\r\n\t}\r\n\r\n\t.spinner {\r\n\t\twidth: 40px;\r\n\t\theight: 40px;\r\n\t\tmargin: 8px 0;\r\n\t\tborder: 4px solid rgba(255, 255, 255, 0.2);\r\n\t\tborder-top-color: #ffd54a;\r\n\t\tborder-radius: 50%;\r\n\t\tanimation-name: map-load-spin;\r\n\t\tanimation-duration: 0.8s;\r\n\t\tanimation-timing-function: linear;\r\n\t\tanimation-iteration-count: infinite;\r\n\t}\r\n\r\n\t.status {\r\n\t\tfont-size: 22px;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #ffd54a;\r\n\t\ttext-transform: uppercase;\r\n\t\ttext-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);\r\n\t}\r\n}\r\n\r\n@keyframes map-load-spin {\r\n\tfrom {\r\n\t\ttransform: rotate( 0deg );\r\n\t}\r\n\r\n\tto {\r\n\t\ttransform: rotate( 360deg );\r\n\t}\r\n}\r\n"},{"Ident":"virtus.vr_shooter","Path":"ui/healthbar.razor.scss","FileName":"healthbar.razor.scss","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"HealthBar {\n\tposition: absolute;\n\tbottom: 160px;\n\tleft: 100px;\n\twidth: 300px;\n\theight: 50px;\n\tbackground: rgba(0, 0, 0, 0.7);\n\tborder: 2px solid white;\n\tborder-radius: 6px;\n\n\t\u0026.full {\n\t\tposition: relative;\n\t\t// Clear the desktop HUD offsets when filling the VR hand panel.\n\t\tbottom: 0;\n\t\tleft: 0;\n\t\twidth: 100%;\n\t\theight: 100%;\n\n\t\t.protection-label {\n\t\t\tfont-size: 4px;\n\t\t\tline-height: 4px;\n\t\t\twhite-space: nowrap;\n\t\t}\n\t}\n\n\t\u0026.protected {\n\t\tborder-color: #5ee7ff;\n\t\tbox-shadow: 0px 0px 12px rgba(94, 231, 255, 0.5);\n\t}\n\n\t.protection-label {\n\t\tposition: absolute;\n\t\tinset: 0;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tfont-family: Poppins;\n\t\tfont-size: 18px;\n\t\tfont-weight: bold;\n\t\tcolor: white;\n\t}\n\n\t.fill {\n\t\theight: 100%;\n\t}\n\n\t.ease-transition {\n\t\ttransition: width 0.15s ease;\n\t}\n}\n"},{"Ident":"virtus.vr_shooter","Path":"ui/scoreboard.razor.scss","FileName":"scoreboard.razor.scss","PackageType":"game","CodeKind":"Game","AssetVersionId":379922,"Code":"Scoreboard {\r\n    width: 100%;\r\n    height: 100%;\r\n    justify-content: center;\r\n    align-items: stretch;\r\n    padding: 50px;\r\n\r\n    \u0026.full {\r\n        padding: 0;\r\n        align-items: end;\r\n    }\r\n\r\n    .container {\r\n        position: absolute;\r\n        width: 600px;\r\n        display: flex;\r\n        flex-direction: column;\r\n        background: rgba(20, 20, 25, 0.92);\r\n        border: 2px solid rgba(255,255,255,0.08);\r\n        border-radius: 10px;\r\n        overflow: hidden;\r\n\r\n        \u0026.full {\r\n            width: 400px;\r\n        }\r\n    }\r\n\r\n    \u0026.desktop {\n        align-items: flex-start;\n    }\n\n    \u0026.desktop,\n    \u0026.full {\n        .container {\n            position: relative;\r\n            max-width: 100%;\r\n            max-height: 100%;\r\n        }\r\n\r\n        // Keep the timer and voting visible while the player list uses the remaining space.\r\n        .header,\r\n        .map-vote {\r\n            flex-shrink: 0;\r\n        }\r\n\r\n        .players {\r\n            min-height: 0;\r\n            flex-shrink: 1;\r\n            overflow-x: hidden;\r\n            overflow-y: scroll;\r\n            pointer-events: all;\r\n\r\n            ScoreboardRow {\r\n                flex-shrink: 0;\r\n            }\r\n        }\r\n    }\r\n\r\n    .header {\r\n        flex-direction: column;\r\n        background-color: rgba(255,255,255,.04);\r\n    }\r\n\r\n    .match-info {\r\n        height: 52px;\r\n        padding: 0 18px;\r\n        align-items: center;\r\n        justify-content: space-between;\r\n    }\r\n\r\n    .state {\r\n        font-size: 24px;\r\n        font-weight: bold;\r\n        color: white;\r\n        text-transform: uppercase;\r\n    }\r\n\r\n    .timer {\r\n        font-size: 30px;\r\n        font-weight: bold;\r\n        color: #ffd54a;\r\n    }\r\n\r\n    .columns {\r\n        height: 32px;\r\n        padding: 0 18px;\r\n        align-items: center;\r\n        border-top: 1px solid rgba(255,255,255,.08);\r\n        color: rgba(255,255,255,.5);\r\n        font-size: 14px;\r\n        text-transform: uppercase;\r\n    }\r\n\r\n    .name {\r\n        flex-grow: 1;\r\n    }\r\n\r\n    .score {\r\n        width: 70px;\r\n        text-align: center;\r\n    }\r\n\r\n    .ping {\r\n        width: 60px;\r\n        text-align: right;\r\n    }\r\n\r\n    .players {\r\n        display: flex;\r\n        flex-direction: column;\r\n        gap: 6px;\r\n        padding: 10px;\r\n    }\r\n\r\n    .map-vote {\r\n        flex-direction: column;\r\n        gap: 8px;\r\n        padding: 10px 12px 14px;\r\n        border-top: 1px solid rgba(255,255,255,.08);\r\n    }\r\n\r\n    .map-vote-title {\r\n        font-size: 14px;\r\n        font-weight: bold;\r\n        color: rgba(255,255,255,.7);\r\n        text-transform: uppercase;\r\n    }\r\n\r\n    .map-vote-options {\r\n        flex-direction: row;\r\n        gap: 8px;\r\n    }\r\n\r\n    .map-card {\n        // Divide the available width equally, regardless of title or thumbnail size.\n        flex-basis: 0;\n        flex-grow: 1;\n        flex-shrink: 1;\n        min-width: 0;\n        flex-direction: column;\n        gap: 4px;\r\n        padding: 6px;\r\n        background: rgba(255,255,255,.04);\r\n        border: 2px solid rgba(255,255,255,.08);\r\n        border-radius: 8px;\r\n        cursor: pointer;\r\n        pointer-events: all;\r\n\r\n        \u0026:hover {\r\n            border-color: rgba(255,255,255,.25);\r\n            background: rgba(255,255,255,.08);\r\n        }\r\n\r\n        \u0026.selected {\r\n            border-color: #ffd54a;\r\n            background: rgba(255, 213, 74, .12);\r\n        }\r\n    }\r\n\r\n    .map-thumb {\r\n        width: 100%;\r\n        height: 72px;\r\n        background-size: cover;\r\n        background-position: center;\r\n        border-radius: 4px;\r\n        pointer-events: none;\r\n\r\n        \u0026.placeholder {\r\n            background: rgba(255,255,255,.06);\r\n        }\r\n    }\r\n\r\n    .map-name {\r\n        font-size: 13px;\r\n        font-weight: bold;\r\n        color: white;\r\n        text-overflow: ellipsis;\r\n        white-space: nowrap;\r\n        overflow: hidden;\r\n        pointer-events: none;\r\n    }\r\n\r\n    .map-votes {\r\n        font-size: 16px;\r\n        font-weight: bold;\r\n        color: #ffd54a;\r\n        pointer-events: none;\r\n    }\r\n}\r\n"}]}