{"TotalCount":27,"Files":[{"Ident":"seilordstudio.one_more_push","Path":"MapEventManager.cs","FileName":"MapEventManager.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System;\r\nusing System.Linq;\r\n\r\npublic enum WeatherType\r\n{\r\n    None,\r\n    LowGravity,\r\n    SlipperyIce,\r\n    StrongWind\r\n}\r\n\r\npublic sealed class MapEventManager : Component\r\n{\r\n    public static MapEventManager Instance { get; private set; }\r\n\r\n    [Property] public float EventDuration { get; set; } = 12f;\r\n    [Property] public float EventInterval { get; set; } = 25f;\r\n    [Property] public float LowGravityForce { get; set; } = 450f;\r\n    [Property] public float WindForce { get; set; } = 400f;\r\n\r\n    public WeatherType CurrentEvent { get; private set; } = WeatherType.None;\r\n    public Vector3 CurrentWindDirection { get; private set; } = Vector3.Right;\r\n    public float TimeRemaining { get; private set; }\r\n\r\n    private TimeUntil _nextEventTime;\r\n    private TimeUntil _eventEndTime;\r\n\r\n    protected override void OnAwake()\r\n    {\r\n        Instance = this;\r\n        _nextEventTime = EventInterval;\r\n    }\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( IsProxy ) return;\r\n\r\n        if ( CurrentEvent == WeatherType.None \u0026\u0026 _nextEventTime )\r\n        {\r\n            StartRandomEvent();\r\n        }\r\n        else if ( CurrentEvent != WeatherType.None )\r\n        {\r\n            TimeRemaining = _eventEndTime;\r\n            if ( _eventEndTime )\r\n            {\r\n                EndEvent();\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override void OnFixedUpdate()\r\n    {\r\n        if ( CurrentEvent == WeatherType.None ) return;\r\n\r\n        var players = Scene.GetAllComponents\u003CCharacterController\u003E();\r\n        var rigidbodies = Scene.GetAllComponents\u003CRigidbody\u003E();\r\n\r\n        if ( CurrentEvent == WeatherType.LowGravity )\r\n        {\r\n            foreach ( var cc in players )\r\n            {\r\n                if ( cc.IsValid() )\r\n                {\r\n                    cc.Velocity \u002B= Vector3.Up * LowGravityForce * Time.Delta;\r\n                }\r\n            }\r\n            foreach ( var rb in rigidbodies )\r\n            {\r\n                if ( rb.IsValid() \u0026\u0026 !rb.IsProxy )\r\n                {\r\n                    rb.ApplyImpulse( Vector3.Up * (rb.PhysicsBody.Mass * LowGravityForce * Time.Delta) );\r\n                }\r\n            }\r\n        }\r\n        else if ( CurrentEvent == WeatherType.StrongWind )\r\n        {\r\n            foreach ( var cc in players )\r\n            {\r\n                if ( cc.IsValid() )\r\n                {\r\n                    cc.Velocity \u002B= CurrentWindDirection * WindForce * Time.Delta;\r\n                }\r\n            }\r\n            foreach ( var rb in rigidbodies )\r\n            {\r\n                if ( rb.IsValid() \u0026\u0026 !rb.IsProxy )\r\n                {\r\n                    rb.ApplyImpulse( CurrentWindDirection * WindForce * 15f * Time.Delta );\r\n                }\r\n            }\r\n        }\r\n        else if ( CurrentEvent == WeatherType.SlipperyIce )\r\n        {\r\n            foreach ( var cc in players )\r\n            {\r\n                if ( cc.IsValid() \u0026\u0026 cc.IsOnGround )\r\n                {\r\n                    var vel = cc.Velocity;\r\n                    vel.x *= 1.015f;\r\n                    vel.y *= 1.015f;\r\n                    cc.Velocity = vel;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private void StartRandomEvent()\r\n    {\r\n        var values = Enum.GetValues( typeof( WeatherType ) ).Cast\u003CWeatherType\u003E().Where( w =\u003E w != WeatherType.None ).ToArray();\r\n        CurrentEvent = values[Random.Shared.Next( values.Length )];\r\n        _eventEndTime = EventDuration;\r\n\r\n        if ( CurrentEvent == WeatherType.StrongWind )\r\n        {\r\n            float angle = Random.Shared.NextSingle() * MathF.PI * 2f;\r\n            CurrentWindDirection = new Vector3( MathF.Cos( angle ), MathF.Sin( angle ), 0f ).Normal;\r\n        }\r\n\r\n        Log.Info( $\u0022[MapEventManager] \u0417\u0430\u043F\u0443\u0449\u0435\u043D \u043F\u043E\u0433\u043E\u0434\u043D\u044B\u0439 \u0438\u0432\u0435\u043D\u0442: {CurrentEvent}\u0022 );\r\n    }\r\n\r\n    private void EndEvent()\r\n    {\r\n        Log.Info( $\u0022[MapEventManager] \u0417\u0430\u0432\u0435\u0440\u0448\u0451\u043D \u0438\u0432\u0435\u043D\u0442: {CurrentEvent}\u0022 );\r\n        CurrentEvent = WeatherType.None;\r\n        _nextEventTime = EventInterval;\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"ScoreManager.cs","FileName":"ScoreManager.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System; // \u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u043E \u0434\u043B\u044F \u0440\u0430\u0431\u043E\u0442\u044B Math.Max\r\n\r\npublic class ScoreManager : Component\r\n{\r\n    public static ScoreManager Instance { get; private set; }\r\n\r\n    public int Score { get; private set; } = 0;\r\n    public int Deaths { get; private set; } = 0; \r\n\r\n    protected override void OnStart()\r\n    {\r\n        Instance = this;\r\n        SaveManager.Load(); \r\n    }\r\n\r\n    public void AddScore( int amount = 1 )\r\n    {\r\n        Score \u002B= amount;\r\n        SaveManager.TryUpdateHighScore( Score ); \r\n    }\r\n\r\n    public void AddDeath( int amount = 1 )\r\n    {\r\n        Deaths \u002B= amount;\r\n\r\n       \r\n        Score = Math.Max( 0, Score - 20 );\r\n    }\r\n\r\n    public void ResetScore()\r\n    {\r\n        Score = 0;\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"StickyTarZone.cs","FileName":"StickyTarZone.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System.Collections.Generic;\r\n\r\npublic sealed class StickyTarZone : Component, Component.ITriggerListener\r\n{\r\n    [Property] public float SpeedMultiplier { get; set; } = 0.4f; \r\n    [Property] public float RigidbodyDrag { get; set; } = 0.85f;  \r\n    [Property] public Color TarTint { get; set; } = new Color( 0.1f, 0.1f, 0.1f, 1f ); \r\n\r\n    private readonly HashSet\u003CGameObject\u003E _insideObjects = new();\r\n    private readonly Dictionary\u003CModelRenderer, Color\u003E _originalColors = new();\r\n\r\n    public void OnTriggerEnter( Collider other )\r\n    {\r\n        if ( !other.GameObject.IsValid() ) return;\r\n\r\n        var rootObj = other.GameObject.Root;\r\n        _insideObjects.Add( rootObj );\r\n\r\n        \r\n        var renderers = rootObj.Components.GetAll\u003CModelRenderer\u003E();\r\n        foreach ( var mr in renderers )\r\n        {\r\n            if ( mr.IsValid() \u0026\u0026 !_originalColors.ContainsKey( mr ) )\r\n            {\r\n                _originalColors[mr] = mr.Tint;\r\n                mr.Tint = TarTint;\r\n            }\r\n        }\r\n    }\r\n\r\n    public void OnTriggerExit( Collider other )\r\n    {\r\n        if ( !other.GameObject.IsValid() ) return;\r\n\r\n        var rootObj = other.GameObject.Root;\r\n        _insideObjects.Remove( rootObj );\r\n\r\n        \r\n        var renderers = rootObj.Components.GetAll\u003CModelRenderer\u003E();\r\n        foreach ( var mr in renderers )\r\n        {\r\n            if ( mr.IsValid() \u0026\u0026 _originalColors.TryGetValue( mr, out var origColor ) )\r\n            {\r\n                mr.Tint = origColor;\r\n                _originalColors.Remove( mr );\r\n            }\r\n        }\r\n    }\r\n\r\n    protected override void OnFixedUpdate()\r\n    {\r\n        \r\n        _insideObjects.RemoveWhere( obj =\u003E !obj.IsValid() );\r\n\r\n        foreach ( var targetObj in _insideObjects )\r\n        {\r\n            \r\n            var rb = targetObj.Components.Get\u003CRigidbody\u003E();\r\n            if ( rb.IsValid() \u0026\u0026 rb.PhysicsBody.IsValid() )\r\n                {\r\n                    rb.PhysicsBody.Velocity *= 0.5f; // \u0417\u0430\u043C\u0435\u0434\u043B\u0435\u043D\u0438\u0435 \u0432 \u0441\u043C\u043E\u043B\u0435\r\n                }\r\n\r\n            \r\n            var cc = targetObj.Components.Get\u003CCharacterController\u003E();\r\n            if ( cc.IsValid() )\r\n            {\r\n                cc.Velocity *= SpeedMultiplier;\r\n            }\r\n        }\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"TimeFreezeAbility.cs","FileName":"TimeFreezeAbility.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\n\r\npublic sealed class TimeFreezeAbility : Component\r\n{\r\n    [Property] public float FreezeDuration { get; set; } = 4f;\r\n    [Property] public float Cooldown { get; set; } = 20f;\r\n    [Property] public float FreezeRadius { get; set; } = 500f;\r\n    [Property] public GameObject FreezeParticle { get; set; }\r\n    [Property] public SoundEvent FreezeSound { get; set; }\r\n\r\n    public bool IsFreezeActive { get; private set; } = false;\r\n\r\n    private TimeSince timeSinceActivated;\r\n    private TimeSince timeSinceCooldown;\r\n    private bool isCoolingDown = false;\r\n\r\n    private List\u003CRigidbody\u003E frozenRigidbodies = new();\r\n    private List\u003CCharacterController\u003E frozenControllers = new();\r\n    private Dictionary\u003CModelRenderer, Color\u003E originalRendererColors = new();\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( IsFreezeActive \u0026\u0026 timeSinceActivated \u003E= FreezeDuration )\r\n        {\r\n            UnfreezeTime();\r\n        }\r\n\r\n        if ( Input.Pressed( \u0022use\u0022 ) )\r\n        {\r\n            TryActivateFreeze();\r\n        }\r\n\r\n        if ( IsFreezeActive )\r\n        {\r\n            foreach ( var rb in frozenRigidbodies )\r\n            {\r\n                if ( rb.IsValid() )\r\n                {\r\n                    rb.Velocity = Vector3.Zero;\r\n                    rb.AngularVelocity = Vector3.Zero;\r\n                }\r\n            }\r\n\r\n            foreach ( var cc in frozenControllers )\r\n            {\r\n                if ( cc.IsValid() )\r\n                {\r\n                    cc.Velocity = Vector3.Zero;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public void TryActivateFreeze()\r\n    {\r\n        if ( IsFreezeActive ) return;\r\n        if ( isCoolingDown \u0026\u0026 timeSinceCooldown \u003C Cooldown ) return;\r\n\r\n        IsFreezeActive = true;\r\n        timeSinceActivated = 0;\r\n        frozenRigidbodies.Clear();\r\n        frozenControllers.Clear();\r\n        originalRendererColors.Clear();\r\n\r\n        if ( FreezeParticle.IsValid() )\r\n        {\r\n            FreezeParticle.Clone( WorldPosition );\r\n        }\r\n\r\n        if ( FreezeSound != null )\r\n        {\r\n            Sound.Play( FreezeSound, WorldPosition );\r\n        }\r\n\r\n        var startPos = WorldPosition;\r\n        var endPos = WorldPosition \u002B Vector3.Up * 1f;\r\n\r\n        var hits = Scene.Trace.Sphere( FreezeRadius, startPos, endPos )\r\n            .IgnoreGameObject( GameObject )\r\n            .RunAll();\r\n\r\n        foreach ( var hit in hits )\r\n        {\r\n            if ( !hit.GameObject.IsValid() ) continue;\r\n\r\n            var targetObj = hit.GameObject.Root;\r\n\r\n            var rb = targetObj.Components.Get\u003CRigidbody\u003E();\r\n            if ( rb.IsValid() \u0026\u0026 !frozenRigidbodies.Contains( rb ) )\r\n            {\r\n                frozenRigidbodies.Add( rb );\r\n            }\r\n\r\n            var cc = targetObj.Components.Get\u003CCharacterController\u003E();\r\n            if ( cc.IsValid() \u0026\u0026 !frozenControllers.Contains( cc ) )\r\n            {\r\n                frozenControllers.Add( cc );\r\n            }\r\n\r\n            var renderers = targetObj.Components.GetAll\u003CModelRenderer\u003E();\r\n            foreach ( var mr in renderers )\r\n            {\r\n                if ( mr.IsValid() \u0026\u0026 !originalRendererColors.ContainsKey( mr ) )\r\n                {\r\n                    originalRendererColors[mr] = mr.Tint;\r\n                    mr.Tint = new Color( 0.3f, 0.7f, 1.0f, 1.0f );\r\n                }\r\n            }\r\n        }\r\n\r\n        Log.Info( $\u0022[TimeFreeze] Frozen {frozenRigidbodies.Count} Rigidbodies and {frozenControllers.Count} Controllers!\u0022 );\r\n    }\r\n\r\n    private void UnfreezeTime()\r\n    {\r\n        IsFreezeActive = false;\r\n        isCoolingDown = true;\r\n        timeSinceCooldown = 0;\r\n\r\n        foreach ( var kvp in originalRendererColors )\r\n        {\r\n            if ( kvp.Key.IsValid() )\r\n            {\r\n                kvp.Key.Tint = kvp.Value;\r\n            }\r\n        }\r\n\r\n        frozenRigidbodies.Clear();\r\n        frozenControllers.Clear();\r\n        originalRendererColors.Clear();\r\n\r\n        Log.Info( \u0022[TimeFreeze] Time Freeze Expired!\u0022 );\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"CustomTopDownController.cs","FileName":"CustomTopDownController.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"public sealed class CustomTopDownController : Component\r\n{\r\n\t[RequireComponent] PlayerController Controller { get; set; }\r\n\r\n\tprotected override void OnFixedUpdate()\r\n\t{\r\n\t\t// Lets make the player move when we press WASD\r\n\t\tvar speed = Input.Down( \u0022Run\u0022 ) ? Controller.RunSpeed : Controller.WalkSpeed;\r\n\t\tController.WishVelocity = Input.AnalogMove * speed;\r\n\r\n\t\t// And rotate the player to face the direction of the movement\r\n\t\tif ( Controller.WishVelocity.LengthSquared \u003E 0 )\r\n\t\t{\r\n\t\t\tvar targetAngle = Controller.WishVelocity.EulerAngles;\r\n\t\t\tController.EyeAngles = Rotation.Slerp( Controller.EyeAngles, targetAngle, Time.Delta * 10f );\r\n\t\t}\r\n\t}\r\n\r\n\tprotected override void OnPreRender()\r\n\t{\r\n\t\t// This will update the camera\u0027s position so that it\u0027s up in the air and back a bit, looking down at an angle.\r\n\t\tScene.Camera.WorldPosition = Controller.WorldPosition \u002B Vector3.Up * 1024f \u002B Vector3.Backward * 256f;\r\n\t\tScene.Camera.WorldRotation = new Angles( 75, 0, 0 );\r\n\t}\r\n}\r\n\r\n\r\n\r\n"},{"Ident":"seilordstudio.one_more_push","Path":"RoundManager.cs","FileName":"RoundManager.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Threading.Tasks;\r\n\r\npublic sealed class RoundManager : Component\r\n{\r\n    public static RoundManager Instance { get; private set; }\r\n\r\n    [Property] public float RoundTime { get; set; } = 120f;\r\n    [Sync] public float TimeLeft { get; set; }\r\n    [Sync] public bool IsInRound { get; set; }\r\n    [Sync] public int CurrentRound { get; set; } = 1;\r\n\r\n    protected override void OnAwake()\r\n    {\r\n        Instance = this;\r\n    }\r\n\r\n    protected override void OnStart()\r\n    {\r\n        StartNewRound();\r\n    }\r\n\r\n    public void StartNewRound()\r\n    {\r\n        TimeLeft = RoundTime;\r\n        IsInRound = true;\r\n\r\n        ResetArena();\r\n        RespawnAllPlayers();\r\n\r\n        var shrinker = Scene.GetAllComponents\u003CArenaShrinker\u003E().FirstOrDefault();\r\n        if ( shrinker.IsValid() )\r\n        {\r\n            shrinker.StartRound();\r\n        }\r\n\r\n        Log.Info( $\u0022[RoundManager] \u0420\u0430\u0443\u043D\u0434 {CurrentRound} \u043D\u0430\u0447\u0430\u0442!\u0022 );\r\n    }\r\n\r\n    public void OnPlayerEliminated( GameObject player )\r\n    {\r\n        if ( !IsInRound ) return;\r\n\r\n        if ( player.IsValid() )\r\n        {\r\n            player.Enabled = false;\r\n        }\r\n\r\n        var activePlayers = Scene.GetAllComponents\u003CPushAbility\u003E()\r\n            .Where( p =\u003E p.GameObject.IsValid() \u0026\u0026 p.GameObject.Enabled );\r\n\r\n        if ( activePlayers.Count() \u003C= 1 )\r\n        {\r\n            _ = EndRound();\r\n        }\r\n    }\r\n\r\n    public async Task EndRound()\r\n    {\r\n        if ( !IsInRound ) return;\r\n\r\n        IsInRound = false;\r\n        CurrentRound\u002B\u002B;\r\n\r\n        Log.Info( $\u0022\u0420\u0430\u0443\u043D\u0434 {CurrentRound - 1} \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D! \u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A \u0447\u0435\u0440\u0435\u0437 3 \u0441\u0435\u043A\u0443\u043D\u0434\u044B...\u0022 );\r\n\r\n        await Task.DelaySeconds( 3f );\r\n\r\n        StartNewRound();\r\n    }\r\n\r\n    private void ResetArena()\r\n    {\r\n        var tiles = Scene.GetAllComponents\u003CArenaTile\u003E();\r\n        foreach ( var tile in tiles )\r\n        {\r\n            if ( tile.IsValid() )\r\n            {\r\n                tile.ResetTile();\r\n            }\r\n        }\r\n    }\r\n\r\n    private void RespawnAllPlayers()\r\n    {\r\n        var spawn = Scene.GetAllComponents\u003CSpawnPoint\u003E().FirstOrDefault();\r\n        Vector3 spawnPos = spawn.IsValid() ? spawn.WorldPosition : new Vector3( 0, 0, 250 );\r\n\r\n        var players = Scene.GetAllComponents\u003CPushAbility\u003E();\r\n        foreach ( var player in players )\r\n        {\r\n            if ( !player.IsValid() ) continue;\r\n\r\n            var root = player.GameObject.Root;\r\n            root.Enabled = true;\r\n            root.WorldPosition = spawnPos;\r\n\r\n            var cc = root.Components.Get\u003CCharacterController\u003E( true );\r\n            if ( cc.IsValid() )\r\n            {\r\n                cc.Velocity = Vector3.Zero;\r\n            }\r\n\r\n            var rb = root.Components.Get\u003CRigidbody\u003E( true );\r\n            if ( rb.IsValid() )\r\n            {\r\n                rb.Velocity = Vector3.Zero;\r\n                rb.AngularVelocity = Vector3.Zero;\r\n            }\r\n        }\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"pushhud.razor.scss","FileName":"pushhud.razor.scss","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"@font-face {\r\n    font-family: \u0027Russo One\u0027;\r\n    src: url( \u0027prefab/RussoOne-Regular.ttf\u0027 );\r\n}\r\n\r\nPushHud, root, .hud-root {\r\n    position: absolute;\r\n    left: 0px;\r\n    top: 0px;\r\n    width: 100%;\r\n    height: 100%;\r\n    background-color: transparent;\r\n    pointer-events: none;\r\n    font-family: \u0027Russo One\u0027, sans-serif;\r\n}\r\n\r\n/* --- \u0412\u0415\u0420\u0425\u041D\u042F\u042F \u041F\u0410\u041D\u0415\u041B\u042C \u0421\u0427\u0415\u0422\u0427\u0418\u041A\u041E\u0412 \u0418 \u0420\u0410\u0423\u041D\u0414\u0410 --- */\r\n.top-header-container {\r\n    position: absolute;\r\n    top: 20px;\r\n    left: 50%;\r\n    transform: translateX(-50%);\r\n    flex-direction: column;\r\n    align-items: center;\r\n    gap: 10px;\r\n}\r\n\r\n.score-box {\r\n    flex-direction: row;\r\n    align-items: center;\r\n    gap: 28px;\r\n    background-color: rgba(12, 14, 20, 0.95);\r\n    border: 2.5px solid #ffaa00;\r\n    border-radius: 12px;\r\n    padding: 10px 30px 12px 30px;\r\n    box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.85);\r\n\r\n    .score-card {\r\n        flex-direction: column;\r\n        align-items: center;\r\n        min-width: 75px;\r\n\r\n        .score-title {\r\n            font-size: 13px;\r\n            color: #9aa0a6;\r\n            letter-spacing: 1px;\r\n            text-shadow: 0px 1px 3px rgba(0, 0, 0, 0.9);\r\n        }\r\n\r\n        .score-value {\r\n            font-size: 32px;\r\n            color: #ffffff;\r\n            margin-top: -2px;\r\n            text-shadow: 0px 2px 5px rgba(0, 0, 0, 0.9);\r\n        }\r\n\r\n        \u0026.time {\r\n            .score-title { color: #ffb700; }\r\n            .score-value { color: #ffd000; }\r\n        }\r\n\r\n        \u0026.death .score-value {\r\n            color: #ff4757;\r\n        }\r\n\r\n        \u0026.highlight {\r\n            .score-title { color: #ffaa00; }\r\n            .score-value { color: #ffaa00; }\r\n        }\r\n    }\r\n}\r\n\r\n.round-badge {\r\n    padding: 6px 24px;\r\n    background-color: rgba(15, 18, 24, 0.95);\r\n    border: 2px solid #ff9900;\r\n    border-radius: 20px;\r\n    color: #ffaa00;\r\n    font-size: 13px;\r\n    font-weight: bold;\r\n    letter-spacing: 2px;\r\n    text-shadow: 0px 0px 10px rgba(255, 170, 0, 0.7);\r\n    box-shadow: 0px 4px 14px rgba(0, 0, 0, 0.7);\r\n}\r\n\r\n/* --- \u041F\u041E\u0413\u041E\u0414\u041D\u042B\u0415 \u0418\u0412\u0415\u041D\u0422\u042B / \u0410\u041D\u041E\u041C\u0410\u041B\u0418\u0418 --- */\r\n.weather-banner {\r\n    flex-direction: row;\r\n    align-items: center;\r\n    gap: 14px;\r\n    background-color: rgba(14, 16, 22, 0.95);\r\n    border: 2.5px solid rgba(255, 255, 255, 0.25);\r\n    border-radius: 10px;\r\n    padding: 8px 20px;\r\n    margin-top: 6px;\r\n    box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.85);\r\n\r\n    .weather-icon {\r\n        font-size: 24px;\r\n    }\r\n\r\n    .weather-info {\r\n        flex-direction: column;\r\n\r\n        .weather-title {\r\n            font-size: 16px;\r\n            color: #ffffff;\r\n            letter-spacing: 0.5px;\r\n            text-shadow: 0px 1px 3px rgba(0, 0, 0, 0.9);\r\n        }\r\n\r\n        .weather-sub {\r\n            font-size: 10px;\r\n            color: #8a929a;\r\n            letter-spacing: 1.5px;\r\n        }\r\n    }\r\n\r\n    .weather-timer-badge {\r\n        background-color: rgba(255, 255, 255, 0.12);\r\n        border: 1px solid rgba(255, 255, 255, 0.25);\r\n        border-radius: 6px;\r\n        padding: 6px 12px;\r\n\r\n        .timer-text {\r\n            font-size: 15px;\r\n            color: #ffffff;\r\n            text-shadow: 0px 1px 3px rgba(0, 0, 0, 0.9);\r\n        }\r\n    }\r\n\r\n    \u0026.wind {\r\n        border-color: #ff9900;\r\n        .weather-title, .timer-text { color: #ffaa00; }\r\n    }\r\n\r\n    \u0026.ice {\r\n        border-color: #00e5ff;\r\n        .weather-title, .timer-text { color: #00e5ff; }\r\n    }\r\n\r\n    \u0026.gravity {\r\n        border-color: #d670ff;\r\n        .weather-title, .timer-text { color: #d670ff; }\r\n    }\r\n}\r\n\r\n/* --- \u041A\u041D\u041E\u041F\u041A\u0410 \u041C\u0415\u041D\u042E [ESC] --- */\r\n.side-settings-btn {\r\n    position: absolute;\r\n    top: 25px;\r\n    right: 25px;\r\n    height: 48px;\r\n    padding: 0 18px;\r\n    background-color: rgba(12, 14, 20, 0.95);\r\n    border: 2px solid rgba(255, 255, 255, 0.3);\r\n    border-radius: 10px;\r\n    flex-direction: row;\r\n    align-items: center;\r\n    justify-content: center;\r\n    gap: 10px;\r\n    pointer-events: all;\r\n    cursor: pointer;\r\n\r\n    .key-hint {\r\n        font-size: 13px;\r\n        color: #9aa0a6;\r\n    }\r\n\r\n    .icon {\r\n        font-size: 22px;\r\n        color: #ffffff;\r\n    }\r\n\r\n    \u0026:hover {\r\n        background-color: rgba(255, 255, 255, 0.2);\r\n        border-color: #ffaa00;\r\n\r\n        .key-hint, .icon {\r\n            color: #ffaa00;\r\n        }\r\n    }\r\n}\r\n\r\n/* --- \u0422\u0410\u0411\u041B\u0418\u0426\u0410 \u0418\u0413\u0420\u041E\u041A\u041E\u0412 (\u0421\u041F\u0420\u0410\u0412\u0410 \u0412\u0412\u0415\u0420\u0425\u0423 \u041F\u041E\u0414 ESC) --- */\r\n.scoreboard-box {\r\n    position: absolute;\r\n    top: 85px; \r\n    right: 25px;\r\n    width: 250px;\r\n    flex-direction: column;\r\n    background-color: rgba(12, 14, 20, 0.95);\r\n    border: 1.5px solid rgba(255, 255, 255, 0.25);\r\n    border-radius: 12px;\r\n    padding: 12px 16px;\r\n    gap: 10px;\r\n    box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.8);\r\n\r\n    .scoreboard-header {\r\n        border-bottom: 1px solid rgba(255, 255, 255, 0.15);\r\n        padding-bottom: 6px;\r\n\r\n        .header-title {\r\n            font-size: 12px;\r\n            color: #7f8c8d;\r\n            letter-spacing: 1.5px;\r\n        }\r\n    }\r\n\r\n    .player-list {\r\n        flex-direction: column;\r\n        gap: 6px;\r\n\r\n        .player-row {\r\n            flex-direction: row;\r\n            justify-content: space-between;\r\n            align-items: center;\r\n            padding: 6px 10px;\r\n            border-radius: 6px;\r\n            background-color: rgba(255, 255, 255, 0.05);\r\n\r\n            .player-name {\r\n                font-size: 15px;\r\n                color: #ffffff;\r\n                text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.8);\r\n            }\r\n\r\n            .player-score {\r\n                font-size: 16px;\r\n                color: #ffaa00;\r\n                text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.8);\r\n            }\r\n\r\n            \u0026.local {\r\n                background-color: rgba(0, 255, 157, 0.18);\r\n                border: 1px solid rgba(0, 255, 157, 0.5);\r\n\r\n                .player-name, .player-score {\r\n                    color: #00ff9d;\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/* --- \u0427\u0410\u0422 \u0418 \u0423\u0412\u0415\u0414\u041E\u041C\u041B\u0415\u041D\u0418\u042F (\u0421\u041B\u0415\u0412\u0410 \u0412\u0412\u0415\u0420\u0425\u0423) --- */\r\n.top-left-box {\r\n    position: absolute;\r\n    top: 25px;\r\n    left: 25px;\r\n    flex-direction: column;\r\n    gap: 12px;\r\n    pointer-events: none;\r\n\r\n    .chat-box {\r\n        width: 380px;\r\n        flex-direction: column;\r\n        gap: 10px;\r\n\r\n        .chat-messages {\r\n            flex-direction: column;\r\n            gap: 6px;\r\n\r\n            .chat-row {\r\n                flex-direction: row;\r\n                gap: 10px;\r\n                background-color: rgba(10, 12, 18, 0.92);\r\n                padding: 6px 12px;\r\n                border-radius: 8px;\r\n                border-left: 4px solid #ffaa00;\r\n\r\n                .chat-author {\r\n                    font-size: 14px;\r\n                    color: #ffaa00;\r\n                }\r\n\r\n                .chat-text {\r\n                    font-size: 14px;\r\n                    color: #ffffff;\r\n                    text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.8);\r\n                }\r\n            }\r\n        }\r\n\r\n        .hints-row {\r\n            flex-direction: row;\r\n            gap: 10px;\r\n        }\r\n\r\n        .chat-hint {\r\n            pointer-events: all;\r\n            font-size: 13px;\r\n            color: #d1d5db;\r\n            background-color: rgba(14, 18, 24, 0.95);\r\n            border: 1.5px solid rgba(255, 255, 255, 0.25);\r\n            border-radius: 8px;\r\n            padding: 8px 14px;\r\n            cursor: pointer;\r\n            text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);\r\n\r\n            \u0026:hover {\r\n                color: #00ff9d;\r\n                border-color: #00ff9d;\r\n            }\r\n\r\n            \u0026.prop-hint {\r\n                color: #ffaa00;\r\n                border-color: rgba(255, 170, 0, 0.6);\r\n\r\n                \u0026:hover {\r\n                    color: #ffd000;\r\n                    border-color: #ffaa00;\r\n                }\r\n            }\r\n        }\r\n\r\n        .chat-input-row {\r\n            pointer-events: all;\r\n            \r\n            textentry {\r\n                width: 100%;\r\n                height: 40px;\r\n                background-color: rgba(10, 12, 18, 0.95);\r\n                border: 2px solid #ffaa00;\r\n                color: #ffffff;\r\n                padding: 0 12px;\r\n                font-size: 15px;\r\n                border-radius: 8px;\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/* --- \u0428\u041A\u0410\u041B\u0410 \u0417\u0410\u0420\u042F\u0414\u0410 \u0418 \u041F\u0415\u0420\u0415\u0417\u0410\u0420\u042F\u0414\u041A\u0410 --- */\r\n.cooldown-box {\r\n    position: absolute;\r\n    left: 25px;\r\n    bottom: 25px;\r\n    flex-direction: column;\r\n    align-items: flex-start;\r\n    gap: 6px;\r\n\r\n    .cooldown-title {\r\n        font-size: 13px;\r\n        color: #9aa0a6;\r\n        letter-spacing: 1px;\r\n        text-shadow: 0px 1px 3px rgba(0, 0, 0, 0.9);\r\n    }\r\n\r\n    .bar-background {\r\n        width: 300px;\r\n        height: 22px;\r\n        background-color: rgba(10, 12, 18, 0.95);\r\n        border: 2px solid #ffffff;\r\n        border-radius: 8px;\r\n        overflow: hidden;\r\n\r\n        .bar-fill {\r\n            height: 100%;\r\n            background-color: #ffaa00;\r\n        }\r\n    }\r\n}\r\n\r\n.charge-box {\r\n    position: absolute;\r\n    bottom: 150px;\r\n    left: 50%;\r\n    transform: translateX(-50%);\r\n    width: 380px;\r\n    flex-direction: column;\r\n\r\n    .charge-title {\r\n        color: #ff9900;\r\n        font-size: 15px;\r\n        font-weight: bold;\r\n        letter-spacing: 2px;\r\n        text-align: center;\r\n        margin-bottom: 8px;\r\n        text-shadow: 0px 2px 4px rgba(0, 0, 0, 0.9);\r\n    }\r\n\r\n    .bar-background {\r\n        width: 100%;\r\n        height: 18px;\r\n        background-color: rgba(10, 12, 18, 0.95);\r\n        border: 2px solid #ff9900;\r\n        border-radius: 8px;\r\n        overflow: hidden;\r\n\r\n        .bar-fill.charge {\r\n            height: 100%;\r\n            background: linear-gradient(to right, #ffaa00, #ff3300);\r\n            transition: width 0.05s ease-out;\r\n        }\r\n    }\r\n}\r\n\r\n/* --- \u0425\u041E\u0422\u0411\u0410\u0420 \u0421\u041F\u041E\u0421\u041E\u0411\u041D\u041E\u0421\u0422\u0415\u0419 (\u0421\u041D\u0418\u0417\u0423) --- */\r\n.hotbar-container {\r\n    position: absolute;\r\n    bottom: 25px;\r\n    left: 50%;\r\n    transform: translateX(-50%);\r\n    flex-direction: row;\r\n    gap: 16px;\r\n    pointer-events: all;\r\n\r\n    .slot-wrapper {\r\n        flex-direction: column;\r\n        align-items: center;\r\n        gap: 8px;\r\n\r\n        .hotbar-slot {\r\n            width: 80px;\r\n            height: 80px;\r\n            background-color: rgba(14, 16, 22, 0.95);\r\n            background-image: linear-gradient(to bottom, #2b2b2b, #121212);\r\n            border: 2px solid rgba(255, 255, 255, 0.25);\r\n            border-radius: 10px;\r\n            flex-direction: column;\r\n            justify-content: center;\r\n            align-items: center;\r\n            cursor: pointer;\r\n\r\n            \u0026.selected {\r\n                border-color: #ffaa00;\r\n                box-shadow: 0px 0px 16px rgba(255, 170, 0, 0.65);\r\n            }\r\n\r\n            \u0026.locked {\r\n                opacity: 0.5;\r\n                background-color: rgba(8, 8, 12, 0.95);\r\n            }\r\n\r\n            .slot-name {\r\n                font-size: 13px;\r\n                color: #ffffff;\r\n                text-align: center;\r\n                text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);\r\n            }\r\n\r\n            .slot-cost {\r\n                font-size: 13px;\r\n                color: #ffd000;\r\n                margin-top: 4px;\r\n                font-weight: bold;\r\n            }\r\n        }\r\n\r\n        .key-badge {\r\n            width: 36px;\r\n            height: 36px;\r\n            background-image: linear-gradient(to bottom, #ffaa00, #cc6600);\r\n            border: 1.5px solid #ffe082;\r\n            border-radius: 8px;\r\n            justify-content: center;\r\n            align-items: center;\r\n            font-size: 16px;\r\n            font-weight: bold;\r\n            color: #ffffff;\r\n            text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);\r\n            box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.6);\r\n\r\n            \u0026.selected {\r\n                background-image: linear-gradient(to bottom, #ffbb00, #e65100);\r\n                border-color: #ffffff;\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/* --- \u041E\u0412\u0415\u0420\u041B\u0415\u0419 \u0418 \u041C\u0415\u041D\u042E --- */\r\n.menu-overlay {\r\n    position: absolute;\r\n    left: 0px;\r\n    top: 0px;\r\n    width: 100%;\r\n    height: 100%;\r\n    background-color: rgba(8, 10, 14, 0.82);\r\n    justify-content: center;\r\n    align-items: center;\r\n    pointer-events: all;\r\n    z-index: 100;\r\n}\r\n\r\n.menu-card {\r\n    flex-direction: column;\r\n    align-items: center;\r\n    gap: 18px;\r\n    background-color: rgba(14, 16, 22, 0.98);\r\n    padding: 36px 60px;\r\n    border-radius: 16px;\r\n    border: 2px solid rgba(255, 255, 255, 0.25);\r\n    min-width: 380px;\r\n    box-shadow: 0px 12px 40px rgba(0, 0, 0, 0.9);\r\n\r\n    .menu-title {\r\n        color: #ffffff;\r\n        font-size: 30px;\r\n        font-weight: bold;\r\n        letter-spacing: 2px;\r\n        margin-bottom: 10px;\r\n        text-shadow: 0px 2px 6px rgba(0, 0, 0, 0.9);\r\n    }\r\n\r\n    .menu-btn {\r\n        width: 100%;\r\n        padding: 14px 28px;\r\n        background-color: rgba(255, 255, 255, 0.1);\r\n        border: 1.5px solid rgba(255, 255, 255, 0.25);\r\n        color: #ffffff;\r\n        font-size: 18px;\r\n        font-weight: bold;\r\n        border-radius: 10px;\r\n        align-items: center;\r\n        justify-content: center;\r\n        cursor: pointer;\r\n\r\n        \u0026:hover {\r\n            background-color: rgba(255, 170, 0, 0.25);\r\n            border-color: #ffaa00;\r\n            color: #ffaa00;\r\n        }\r\n\r\n        \u0026.play {\r\n            background-color: #00ff9d;\r\n            border-color: #00ff9d;\r\n            color: #000000;\r\n\r\n            \u0026:hover {\r\n                background-color: #00cc7d;\r\n                border-color: #00cc7d;\r\n                color: #000000;\r\n            }\r\n        }\r\n\r\n        \u0026.quit:hover {\r\n            background-color: rgba(255, 71, 87, 0.45);\r\n            border-color: #ff4757;\r\n            color: #ffffff;\r\n        }\r\n    }\r\n}\r\n\r\n/* --- \u041C\u0415\u041D\u042E \u0421\u041F\u0410\u0412\u041D\u0410 \u041F\u0420\u041E\u041F\u0421\u041E\u0412 --- */\r\n.prop-menu-card {\r\n    flex-direction: column;\r\n    align-items: center;\r\n    gap: 24px;\r\n    background-color: rgba(14, 16, 22, 0.98);\r\n    padding: 32px 48px;\r\n    border-radius: 16px;\r\n    border: 2.5px solid #ffaa00;\r\n    min-width: 460px;\r\n    box-shadow: 0px 14px 45px rgba(0, 0, 0, 0.95);\r\n\r\n    .menu-title {\r\n        color: #ffaa00;\r\n        font-size: 24px;\r\n        font-weight: bold;\r\n        letter-spacing: 2px;\r\n        text-shadow: 0px 2px 5px rgba(0, 0, 0, 0.9);\r\n    }\r\n\r\n    .prop-grid {\r\n        display: flex;\r\n        flex-direction: row;\r\n        flex-wrap: wrap;\r\n        justify-content: center;\r\n        gap: 16px;\r\n        width: 100%;\r\n\r\n        .prop-item {\r\n            width: 180px;\r\n            padding: 16px 14px;\r\n            background-color: rgba(255, 255, 255, 0.08);\r\n            border: 1.5px solid rgba(255, 170, 0, 0.35);\r\n            border-radius: 12px;\r\n            flex-direction: column;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 8px;\r\n            cursor: pointer;\r\n\r\n            .prop-name {\r\n                font-size: 16px;\r\n                color: #ffffff;\r\n                text-align: center;\r\n                text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);\r\n            }\r\n\r\n            .prop-cost {\r\n                font-size: 14px;\r\n                font-weight: bold;\r\n                color: #ffd000;\r\n            }\r\n\r\n            \u0026:hover {\r\n                background-color: rgba(255, 170, 0, 0.25);\r\n                border-color: #ffaa00;\r\n\r\n                .prop-name {\r\n                    color: #ffaa00;\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n/* --- \u041D\u0410\u0421\u0422\u0420\u041E\u0419\u041A\u0418 --- */\r\n.settings-card {\r\n    min-width: 440px;\r\n\r\n    .settings-content {\r\n        flex-direction: column;\r\n        gap: 16px;\r\n        width: 100%;\r\n        margin-bottom: 14px;\r\n\r\n        .setting-item {\r\n            color: #e0e0e0;\r\n            font-size: 16px;\r\n            font-weight: bold;\r\n            text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);\r\n        }\r\n\r\n        .lang-row {\r\n            justify-content: space-between;\r\n            align-items: center;\r\n            width: 100%;\r\n        }\r\n\r\n        .lang-selector {\r\n            gap: 10px;\r\n\r\n            .lang-btn {\r\n                padding: 8px 18px;\r\n                background-color: rgba(255, 255, 255, 0.12);\r\n                border: 1.5px solid rgba(255, 255, 255, 0.25);\r\n                border-radius: 8px;\r\n                color: #b0b0b0;\r\n                font-size: 14px;\r\n                font-weight: bold;\r\n                cursor: pointer;\r\n\r\n                \u0026:hover {\r\n                    background-color: rgba(255, 255, 255, 0.25);\r\n                    color: #ffffff;\r\n                }\r\n\r\n                \u0026.active {\r\n                    background-color: #00ff9d;\r\n                    border-color: #00ff9d;\r\n                    color: #000000;\r\n                }\r\n            }\r\n        }\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"ManeuverAbility.cs","FileName":"ManeuverAbility.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System;\r\n\r\npublic sealed class ManeuverAbility : Component\r\n{\r\n    [Property] public float DashForce { get; set; } = 900f;\r\n    [Property] public float DashCooldown { get; set; } = 1.2f;\r\n\r\n    [Property] public float ParryWindow { get; set; } = 0.4f;\r\n    [Property] public float ParryCooldown { get; set; } = 2.5f;\r\n\r\n    [Property] public SoundEvent DashSound { get; set; }\r\n    [Property] public SoundEvent ParrySound { get; set; }\r\n    [Property] public SoundEvent ReflectSound { get; set; }\r\n    [Property] public GameObject DashParticle { get; set; }\r\n    [Property] public GameObject ParryParticle { get; set; }\r\n\r\n    private TimeSince _lastDash;\r\n    private TimeSince _lastParry;\r\n    private TimeSince _parryTimer;\r\n\r\n    public bool IsParrying =\u003E _parryTimer \u003C ParryWindow;\r\n    public bool IsDashReady =\u003E _lastDash \u003E= DashCooldown;\r\n    public bool IsParryReady =\u003E _lastParry \u003E= ParryCooldown;\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( IsProxy ) return;\r\n\r\n        if ( Input.Pressed( \u0022run\u0022 ) \u0026\u0026 IsDashReady )\r\n        {\r\n            ExecuteDash();\r\n        }\r\n\r\n        if ( Input.Pressed( \u0022attack2\u0022 ) \u0026\u0026 IsParryReady )\r\n        {\r\n            ExecuteParry();\r\n        }\r\n    }\r\n\r\n    private void ExecuteDash()\r\n    {\r\n        var cc = Components.Get\u003CCharacterController\u003E();\r\n        if ( !cc.IsValid() ) return;\r\n\r\n        var moveInput = Input.AnalogMove;\r\n        var wishDir = (WorldTransform.Forward * moveInput.x \u002B WorldTransform.Left * moveInput.y).Normal;\r\n\r\n        if ( wishDir.IsNearlyZero() )\r\n        {\r\n            wishDir = WorldTransform.Forward;\r\n        }\r\n\r\n        PerformDash( wishDir );\r\n    }\r\n\r\n    private void ExecuteParry()\r\n    {\r\n        PerformParry();\r\n    }\r\n\r\n    // --- \u041C\u0415\u0422\u041E\u0414\u042B \u0414\u041B\u042F \u0411\u041E\u0422\u041E\u0412 \u0418 \u0412\u041D\u0415\u0428\u041D\u0418\u0425 \u0412\u042B\u0417\u041E\u0412\u041E\u0412 ---\r\n\r\n    public void TryExecuteBotDash( Vector3 direction )\r\n    {\r\n        if ( !IsDashReady ) return;\r\n        PerformDash( direction );\r\n    }\r\n\r\n    public void TryExecuteBotParry()\r\n    {\r\n        if ( !IsParryReady ) return;\r\n        PerformParry();\r\n    }\r\n\r\n    private void PerformDash( Vector3 direction )\r\n    {\r\n        _lastDash = 0;\r\n\r\n        var cc = Components.Get\u003CCharacterController\u003E();\r\n        if ( cc.IsValid() )\r\n        {\r\n            cc.Velocity \u002B= direction.Normal * DashForce;\r\n\r\n            if ( DashSound != null ) Sound.Play( DashSound, WorldPosition );\r\n            if ( DashParticle.IsValid() ) DashParticle.Clone( WorldPosition );\r\n        }\r\n    }\r\n\r\n    private void PerformParry()\r\n    {\r\n        _lastParry = 0;\r\n        _parryTimer = 0;\r\n\r\n        if ( ParrySound != null ) Sound.Play( ParrySound, WorldPosition );\r\n        if ( ParryParticle.IsValid() ) ParryParticle.Clone( WorldPosition );\r\n    }\r\n\r\n    public void OnSuccessfulReflect( Vector3 reflectOrigin )\r\n    {\r\n        if ( ReflectSound != null )\r\n        {\r\n            Sound.Play( ReflectSound, WorldPosition );\r\n        }\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"MusicManager.cs","FileName":"MusicManager.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\n\r\npublic class MusicManager : Component\r\n{\r\n    public static MusicManager Instance { get; private set; }\r\n\r\n    [Property] public SoundEvent MusicSound { get; set; }\r\n\r\n    private SoundHandle _musicHandle;\r\n\r\n    protected override void OnStart()\r\n    {\r\n        Instance = this;\r\n\r\n        if ( PushHud.EnableMusic )\r\n        {\r\n            PlayMusic();\r\n        }\r\n    }\r\n\r\n    public void ToggleMusic( bool enable )\r\n    {\r\n        if ( enable )\r\n        {\r\n            PlayMusic();\r\n        }\r\n        else\r\n        {\r\n            StopMusic();\r\n        }\r\n    }\r\n\r\n    public void PlayMusic()\r\n    {\r\n        if ( _musicHandle.IsValid() ) return;\r\n\r\n        if ( MusicSound != null )\r\n        {\r\n            _musicHandle = Sound.Play( MusicSound );\r\n        }\r\n    }\r\n\r\n    public void StopMusic()\r\n    {\r\n        if ( _musicHandle.IsValid() )\r\n        {\r\n            _musicHandle.Stop();\r\n        }\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"ShieldAbility.cs","FileName":"ShieldAbility.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\n\r\npublic sealed class ShieldAbility : Component\r\n{\r\n    [Property] public float ShieldDuration { get; set; } = 5f;\r\n    [Property] public float Cooldown { get; set; } = 15f;\r\n    [Property] public GameObject ShieldVisual { get; set; }\r\n\r\n    public bool IsShieldActive { get; private set; } = false;\r\n\r\n    private TimeSince timeSinceActivated;\r\n    private TimeSince timeSinceCooldown;\r\n    private bool isCoolingDown = false;\r\n\r\n    protected override void OnStart()\r\n    {\r\n        if ( ShieldVisual.IsValid() )\r\n        {\r\n            ShieldVisual.Enabled = false;\r\n        }\r\n    }\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( IsShieldActive \u0026\u0026 timeSinceActivated \u003E= ShieldDuration )\r\n        {\r\n            DeactivateShield();\r\n        }\r\n\r\n        if ( Input.Pressed( \u0022Flashlight\u0022 ) )\r\n        {\r\n            TryActivateShield();\r\n        }\r\n    }\r\n\r\n    public void TryActivateShield()\r\n    {\r\n        if ( IsShieldActive ) return;\r\n        if ( isCoolingDown \u0026\u0026 timeSinceCooldown \u003C Cooldown ) return;\r\n\r\n        IsShieldActive = true;\r\n        timeSinceActivated = 0;\r\n\r\n        if ( ShieldVisual.IsValid() )\r\n        {\r\n            ShieldVisual.Enabled = true;\r\n        }\r\n\r\n        Log.Info( \u0022[ShieldAbility] Shield Activated!\u0022 );\r\n    }\r\n\r\n    private void DeactivateShield()\r\n    {\r\n        IsShieldActive = false;\r\n        isCoolingDown = true;\r\n        timeSinceCooldown = 0;\r\n\r\n        if ( ShieldVisual.IsValid() )\r\n        {\r\n            ShieldVisual.Enabled = false;\r\n        }\r\n\r\n        Log.Info( \u0022[ShieldAbility] Shield Expired!\u0022 );\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"ArenaTile.cs","FileName":"ArenaTile.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\n\r\npublic sealed class ArenaTile : Component\r\n{\r\n    private Vector3 initialPosition;\r\n    public bool IsFalling { get; private set; } = false;\r\n\r\n    [Property] public float FallSpeed { get; set; } = 500f;\r\n\r\n    private ModelRenderer modelRenderer;\r\n    private Color originalColor = Color.White;\r\n\r\n    protected override void OnStart()\r\n    {\r\n        initialPosition = WorldPosition;\r\n        modelRenderer = Components.Get\u003CModelRenderer\u003E();\r\n\r\n        if ( modelRenderer.IsValid() )\r\n        {\r\n            originalColor = modelRenderer.Tint;\r\n        }\r\n    }\r\n\r\n    public void HighlightWarning( bool enable )\r\n    {\r\n        if ( !modelRenderer.IsValid() ) return;\r\n        modelRenderer.Tint = enable ? Color.Red : originalColor;\r\n    }\r\n\r\n    public void Drop()\r\n    {\r\n        IsFalling = true;\r\n    }\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( IsFalling )\r\n        {\r\n            WorldPosition \u002B= Vector3.Down * FallSpeed * Time.Delta;\r\n        }\r\n    }\r\n\r\n    public void ResetTile()\r\n    {\r\n        IsFalling = false;\r\n        WorldPosition = initialPosition;\r\n        HighlightWarning( false );\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"Assembly.cs","FileName":"Assembly.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"global using Sandbox;\r\nglobal using System.Collections.Generic;\r\nglobal using System.Linq;\r\n"},{"Ident":"seilordstudio.one_more_push","Path":"ExplosiveBarrel.cs","FileName":"ExplosiveBarrel.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System;\r\nusing System.Linq;\r\n\r\npublic sealed class ExplosiveBarrel : Component, Component.ICollisionListener\r\n{\r\n    [Property] public float ExplosionRadius { get; set; } = 450f;\r\n    [Property] public float ExplosionForce { get; set; } = 65000f;\r\n    [Property] public float ImpactThreshold { get; set; } = 250f;\r\n    [Property] public GameObject ExplosionParticle { get; set; }\r\n    [Property] public SoundEvent ExplosionSound { get; set; }\r\n\r\n    private bool _hasExploded = false;\r\n\r\n    public void Explode()\r\n    {\r\n        if ( _hasExploded || !GameObject.IsValid() ) return;\r\n        _hasExploded = true;\r\n\r\n        if ( ExplosionParticle.IsValid() )\r\n        {\r\n            ExplosionParticle.Clone( WorldPosition );\r\n        }\r\n\r\n        if ( ExplosionSound != null )\r\n        {\r\n            Sound.Play( ExplosionSound, WorldPosition );\r\n        }\r\n\r\n        var hits = Scene.Trace.Sphere( ExplosionRadius, WorldPosition, WorldPosition \u002B Vector3.Up * 2f )\r\n            .IgnoreGameObject( GameObject )\r\n            .RunAll();\r\n\r\n        foreach ( var hit in hits )\r\n        {\r\n            if ( !hit.GameObject.IsValid() ) continue;\r\n\r\n            var targetObj = hit.GameObject.Root;\r\n\r\n            var shield = targetObj.Components.Get\u003CShieldAbility\u003E( true );\r\n            if ( shield.IsValid() \u0026\u0026 shield.IsShieldActive ) continue;\r\n\r\n            var chainBarrel = targetObj.Components.Get\u003CExplosiveBarrel\u003E();\r\n            if ( chainBarrel.IsValid() \u0026\u0026 chainBarrel != this )\r\n            {\r\n                chainBarrel.Explode();\r\n                continue;\r\n            }\r\n\r\n            var rb = targetObj.Components.Get\u003CRigidbody\u003E();\r\n            if ( rb.IsValid() )\r\n            {\r\n                var dir = (hit.GameObject.WorldPosition - WorldPosition).Normal;\r\n                dir.z = MathF.Max( dir.z, 0.4f );\r\n                rb.ApplyImpulse( dir * ExplosionForce );\r\n            }\r\n        }\r\n\r\n        Log.Info( $\u0022[ExplosiveBarrel] Booom! Barrel exploded at {WorldPosition}\u0022 );\r\n        GameObject.Destroy();\r\n    }\r\n\r\n    public void OnCollisionStart( Collision collision )\r\n    {\r\n        if ( collision.Contact.Speed.Length \u003E ImpactThreshold )\r\n        {\r\n            Explode();\r\n        }\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"BotSpawner.cs","FileName":"BotSpawner.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System;\r\nusing System.Collections.Generic;\r\n\r\npublic sealed class BotSpawner : Component\r\n{\r\n    [Property] public GameObject BotPrefab { get; set; }\r\n    [Property] public float SpawnInterval { get; set; } = 4f;\r\n    [Property] public int MaxBots { get; set; } = 5;\r\n\r\n    public static bool EnableBots { get; set; } = true;\r\n\r\n    private List\u003CGameObject\u003E _activeBots = new();\r\n    private TimeSince _timeSinceLastSpawn = 0;\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( IsProxy ) return;\r\n\r\n        // \u0415\u0441\u043B\u0438 \u0431\u043E\u0442\u044B \u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u044B \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445 \u2014 \u0443\u0434\u0430\u043B\u044F\u0435\u043C \u0443\u0436\u0435 \u0437\u0430\u0441\u043F\u0430\u0432\u043D\u0435\u043D\u043D\u044B\u0445\r\n        if ( !EnableBots )\r\n        {\r\n            if ( _activeBots.Count \u003E 0 )\r\n            {\r\n                foreach ( var bot in _activeBots )\r\n                {\r\n                    if ( bot.IsValid() ) bot.Destroy();\r\n                }\r\n                _activeBots.Clear();\r\n            }\r\n            return;\r\n        }\r\n\r\n        if ( _timeSinceLastSpawn \u003E SpawnInterval )\r\n        {\r\n            _timeSinceLastSpawn = 0;\r\n            SpawnBot();\r\n        }\r\n    }\r\n\r\n    private void SpawnBot()\r\n    {\r\n        if ( !BotPrefab.IsValid() )\r\n        {\r\n            Log.Warning( \u0022[BotSpawner] BotPrefab \u043D\u0435 \u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D \u0432 \u0418\u043D\u0441\u043F\u0435\u043A\u0442\u043E\u0440\u0435!\u0022 );\r\n            return;\r\n        }\r\n\r\n        _activeBots.RemoveAll( bot =\u003E !bot.IsValid() );\r\n\r\n        if ( _activeBots.Count \u003E= MaxBots ) return;\r\n\r\n        // \u0421\u043F\u0430\u0432\u043D \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u0441\u043F\u0430\u0432\u043D\u0435\u0440\u0430\r\n        var randomX = Random.Shared.Float( -150f, 150f );\r\n        var randomY = Random.Shared.Float( -150f, 150f );\r\n        var spawnPos = WorldPosition \u002B new Vector3( randomX, randomY, 200f );\r\n\r\n        var botInstance = BotPrefab.Clone( spawnPos );\r\n        if ( !botInstance.IsValid() ) return;\r\n\r\n        _activeBots.Add( botInstance );\r\n\r\n        if ( Network.Active )\r\n        {\r\n            botInstance.NetworkSpawn();\r\n        }\r\n\r\n        Log.Info( $\u0022[BotSpawner] \u0411\u043E\u0442 \u0437\u0430\u0441\u043F\u0430\u0432\u043D\u0435\u043D \u0432 {spawnPos}\u0022 );\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"SaveManager.cs","FileName":"SaveManager.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\n\r\npublic class PlayerSaveData\r\n{\r\n\tpublic int HighScore { get; set; } = 0;\r\n\tpublic int TotalPushes { get; set; } = 0;\r\n}\r\n\r\npublic static class SaveManager\r\n{\r\n\tprivate const string SaveFileName = \u0022player_save.json\u0022;\r\n\tpublic static PlayerSaveData Current { get; private set; } = new();\r\n\r\n\t// \u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445\r\n\tpublic static void Load()\r\n\t{\r\n\t\tif ( FileSystem.Data.FileExists( SaveFileName ) )\r\n\t\t{\r\n\t\t\tCurrent = FileSystem.Data.ReadJson\u003CPlayerSaveData\u003E( SaveFileName ) ?? new PlayerSaveData();\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tCurrent = new PlayerSaveData();\r\n\t\t\tSave();\r\n\t\t}\r\n\t}\r\n\r\n\t// \u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0445 \u043D\u0430 \u0434\u0438\u0441\u043A\r\n\tpublic static void Save()\r\n\t{\r\n\t\tFileSystem.Data.WriteJson( SaveFileName, Current );\r\n\t}\r\n\r\n\t// \u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u0438 \u0437\u0430\u043F\u0438\u0441\u044C \u043D\u043E\u0432\u043E\u0433\u043E \u0440\u0435\u043A\u043E\u0440\u0434\u0430\r\n\tpublic static void TryUpdateHighScore( int currentScore )\r\n\t{\r\n\t\tif ( currentScore \u003E Current.HighScore )\r\n\t\t{\r\n\t\t\tCurrent.HighScore = currentScore;\r\n\t\t\tSave();\r\n\t\t}\r\n\t}\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"ShopManager.cs","FileName":"ShopManager.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\n\r\npublic class PushItem\r\n{\r\n    public string Id { get; set; }\r\n    public string NameRu { get; set; }\r\n    public string NameEn { get; set; }\r\n    public int Cost { get; set; }\r\n    public float ForceMultiplier { get; set; }\r\n    public string Key { get; set; }\r\n    public bool IsUnlocked { get; set; }\r\n\r\n    public string GetName( string lang ) =\u003E lang == \u0022EN\u0022 ? NameEn : NameRu;\r\n}\r\n\r\npublic class ShopManager : Component\r\n{\r\n    public static ShopManager Instance { get; private set; }\r\n\r\n    public List\u003CPushItem\u003E Items { get; private set; } = new()\r\n    {\r\n        new PushItem { Id = \u0022basic\u0022, NameRu = \u0022\u041E\u0431\u044B\u0447\u043D\u044B\u0439\u0022, NameEn = \u0022Basic\u0022, Cost = 0, ForceMultiplier = 1.0f, Key = \u00221\u0022, IsUnlocked = true },\r\n        new PushItem { Id = \u0022heavy\u0022, NameRu = \u0022\u0422\u044F\u0436\u0435\u043B\u044B\u0439\u0022, NameEn = \u0022Heavy\u0022, Cost = 10, ForceMultiplier = 1.5f, Key = \u00222\u0022, IsUnlocked = false },\r\n        new PushItem { Id = \u0022force\u0022, NameRu = \u0022\u0418\u043C\u043F\u0443\u043B\u044C\u0441\u0022, NameEn = \u0022Impulse\u0022, Cost = 25, ForceMultiplier = 2.2f, Key = \u00223\u0022, IsUnlocked = false },\r\n        new PushItem { Id = \u0022mega\u0022, NameRu = \u0022\u041C\u0435\u0433\u0430-\u0442\u043E\u043B\u0447\u043E\u043A\u0022, NameEn = \u0022Mega Push\u0022, Cost = 50, ForceMultiplier = 3.5f, Key = \u00224\u0022, IsUnlocked = false }\r\n    };\r\n\r\n    public PushItem SelectedItem { get; private set; }\r\n\r\n    protected override void OnStart()\r\n    {\r\n        Instance = this;\r\n        SelectedItem = Items.FirstOrDefault( x =\u003E x.IsUnlocked );\r\n    }\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( Input.Pressed( \u0022slot1\u0022 ) ) SelectByKey( \u00221\u0022 );\r\n        if ( Input.Pressed( \u0022slot2\u0022 ) ) SelectByKey( \u00222\u0022 );\r\n        if ( Input.Pressed( \u0022slot3\u0022 ) ) SelectByKey( \u00223\u0022 );\r\n        if ( Input.Pressed( \u0022slot4\u0022 ) ) SelectByKey( \u00224\u0022 );\r\n    }\r\n\r\n    public void SelectByKey( string key )\r\n    {\r\n        var item = Items.FirstOrDefault( x =\u003E x.Key == key );\r\n        if ( item != null ) TryBuyOrSelect( item );\r\n    }\r\n\r\n    public bool TryBuyOrSelect( PushItem item )\r\n    {\r\n        if ( item.IsUnlocked )\r\n        {\r\n            SelectedItem = item;\r\n            return true;\r\n        }\r\n\r\n        int currentScore = ScoreManager.Instance?.Score ?? 0;\r\n        if ( currentScore \u003E= item.Cost )\r\n        {\r\n            item.IsUnlocked = true;\r\n            SelectedItem = item;\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public float GetCurrentForceMultiplier()\r\n    {\r\n        return SelectedItem?.ForceMultiplier ?? 1.0f;\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"ArenaShrinker.cs","FileName":"ArenaShrinker.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\n\r\npublic sealed class ArenaShrinker : Component\r\n{\r\n    [Property] public float RoundTime { get; set; } = 120f;\r\n    [Property] public float ShrinkInterval { get; set; } = 15f;\r\n    [Property] public float WarningDuration { get; set; } = 3f;\r\n\r\n    public float TimeRemaining { get; private set; }\r\n\r\n    private float nextShrinkTime;\r\n    private bool isWarningActive = false;\r\n    private List\u003CArenaTile\u003E activeWarningTiles = new();\r\n\r\n    protected override void OnStart()\r\n    {\r\n        StartRound();\r\n    }\r\n\r\n    public void StartRound()\r\n    {\r\n        TimeRemaining = RoundTime;\r\n        nextShrinkTime = RoundTime - ShrinkInterval;\r\n        isWarningActive = false;\r\n        activeWarningTiles.Clear();\r\n\r\n        var tiles = Scene.GetAllComponents\u003CArenaTile\u003E();\r\n        foreach ( var tile in tiles )\r\n        {\r\n            tile.ResetTile();\r\n        }\r\n\r\n        Log.Info( \u0022[ArenaShrinker] Round started!\u0022 );\r\n    }\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( TimeRemaining \u003C= 0 )\r\n        {\r\n            if ( RoundManager.Instance != null \u0026\u0026 RoundManager.Instance.IsInRound )\r\n            {\r\n                _ = RoundManager.Instance.EndRound();\r\n            }\r\n            return;\r\n        }\r\n\r\n        TimeRemaining -= Time.Delta;\r\n\r\n        if ( !isWarningActive \u0026\u0026 TimeRemaining \u003C= (nextShrinkTime \u002B WarningDuration) )\r\n        {\r\n            TriggerWarning();\r\n        }\r\n\r\n        if ( isWarningActive \u0026\u0026 TimeRemaining \u003C= nextShrinkTime )\r\n        {\r\n            DropWarnedTiles();\r\n        }\r\n    }\r\n\r\n    private void TriggerWarning()\r\n    {\r\n        isWarningActive = true;\r\n        activeWarningTiles.Clear();\r\n\r\n        var availableTiles = Scene.GetAllComponents\u003CArenaTile\u003E()\r\n            .Where( t =\u003E !t.IsFalling )\r\n            .ToList();\r\n\r\n        if ( availableTiles.Count \u003C= 2 ) return;\r\n\r\n        Vector3 center = Vector3.Zero;\r\n        foreach ( var tile in availableTiles )\r\n        {\r\n            center \u002B= tile.WorldPosition;\r\n        }\r\n        center /= availableTiles.Count;\r\n\r\n        var sortedTiles = availableTiles\r\n            .OrderByDescending( t =\u003E Vector3.DistanceBetween( t.WorldPosition, center ) )\r\n            .ToList();\r\n\r\n        int tilesToDropCount = Math.Max( 1, (int)(sortedTiles.Count * 0.25f) );\r\n\r\n        if ( sortedTiles.Count - tilesToDropCount \u003C 2 )\r\n        {\r\n            tilesToDropCount = Math.Max( 0, sortedTiles.Count - 2 );\r\n        }\r\n\r\n        if ( tilesToDropCount \u003C= 0 ) return;\r\n\r\n        activeWarningTiles = sortedTiles.Take( tilesToDropCount ).ToList();\r\n\r\n        foreach ( var tile in activeWarningTiles )\r\n        {\r\n            tile.HighlightWarning( true );\r\n        }\r\n\r\n        Log.Info( $\u0022[ArenaShrinker] Warning started for {activeWarningTiles.Count} outer tiles!\u0022 );\r\n    }\r\n\r\n    private void DropWarnedTiles()\r\n    {\r\n        foreach ( var tile in activeWarningTiles )\r\n        {\r\n            tile.HighlightWarning( false );\r\n            tile.Drop();\r\n        }\r\n\r\n        activeWarningTiles.Clear();\r\n        isWarningActive = false;\r\n        nextShrinkTime -= ShrinkInterval;\r\n\r\n        Log.Info( \u0022[ArenaShrinker] Outer ring dropped successfully!\u0022 );\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"HeavyAnvil.cs","FileName":"HeavyAnvil.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\n\r\npublic sealed class HeavyAnvil : Component, Component.ICollisionListener\r\n{\r\n    [Property] public float PushResistanceMultiplier { get; set; } = 0.25f;\r\n    [Property] public float CrushSpeedThreshold { get; set; } = 300f;\r\n    [Property] public float CrushImpactForce { get; set; } = 75000f;\r\n    [Property] public SoundEvent ImpactSound { get; set; }\r\n\r\n    public void OnCollisionStart( Collision collision )\r\n    {\r\n        if ( collision.Contact.Speed.Length \u003C CrushSpeedThreshold ) return;\r\n\r\n        var targetObj = collision.Other.GameObject?.Root;\r\n        if ( !targetObj.IsValid() || targetObj == GameObject.Root ) return;\r\n\r\n        if ( ImpactSound != null )\r\n        {\r\n            Sound.Play( ImpactSound, WorldPosition );\r\n        }\r\n\r\n        var cc = targetObj.Components.Get\u003CCharacterController\u003E();\r\n        if ( cc.IsValid() )\r\n        {\r\n            var dir = (targetObj.WorldPosition - WorldPosition).Normal;\r\n            dir.z = 0.5f;\r\n            cc.Velocity \u002B= dir * 900f;\r\n        }\r\n\r\n        var rb = targetObj.Components.Get\u003CRigidbody\u003E();\r\n        if ( rb.IsValid() )\r\n        {\r\n            var dir = (targetObj.WorldPosition - WorldPosition).Normal;\r\n            dir.z = 0.5f;\r\n            rb.ApplyImpulse( dir * CrushImpactForce );\r\n        }\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"BotAI.cs","FileName":"BotAI.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"using Sandbox;\r\nusing System;\r\nusing System.Linq;\r\n\r\npublic sealed class BotAI : Component\r\n{\r\n    [Property] public float Speed { get; set; } = 220f;\r\n    [Property] public float AttackRange { get; set; } = 220f;\r\n\r\n    private CharacterController _cc;\r\n    private PushAbility _push;\r\n    private ManeuverAbility _maneuver;\r\n    private TimeUntil _nextDecision;\r\n    private Vector3 _moveDir;\r\n\r\n    protected override void OnAwake()\r\n    {\r\n        _cc = Components.Get\u003CCharacterController\u003E();\r\n        _push = Components.Get\u003CPushAbility\u003E();\r\n        _maneuver = Components.Get\u003CManeuverAbility\u003E();\r\n    }\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        if ( IsProxy ) return;\r\n\r\n        var target = FindTarget();\r\n\r\n        if ( target.IsValid() )\r\n        {\r\n            _moveDir = (target.WorldPosition - WorldPosition).WithZ( 0 ).Normal;\r\n\r\n            if ( _cc.IsValid() )\r\n            {\r\n                _cc.Velocity = _moveDir * Speed;\r\n                WorldRotation = Rotation.LookAt( _moveDir );\r\n            }\r\n\r\n            float dist = Vector3.DistanceBetween( WorldPosition, target.WorldPosition );\r\n            if ( dist \u003C= AttackRange \u0026\u0026 _push.IsValid() \u0026\u0026 _push.IsReady )\r\n            {\r\n                _push.TryExecuteBotPush();\r\n            }\r\n        }\r\n        else\r\n        {\r\n            if ( _nextDecision )\r\n            {\r\n                _nextDecision = Game.Random.Float( 2f, 4f );\r\n                float angle = Game.Random.Float( 0f, MathF.PI * 2f );\r\n                _moveDir = new Vector3( MathF.Cos( angle ), MathF.Sin( angle ), 0f );\r\n            }\r\n\r\n            if ( _cc.IsValid() )\r\n            {\r\n                _cc.Velocity = _moveDir * (Speed * 0.6f);\r\n            }\r\n        }\r\n\r\n        if ( _cc.IsValid() \u0026\u0026 !_cc.IsOnGround \u0026\u0026 _maneuver.IsValid() \u0026\u0026 _maneuver.IsDashReady )\r\n        {\r\n            _maneuver.TryExecuteBotDash( -_cc.Velocity.Normal );\r\n        }\r\n    }\r\n\r\n    private GameObject FindTarget()\r\n    {\r\n        return Scene.GetAllComponents\u003CCharacterController\u003E()\r\n            .Where( c =\u003E c.GameObject != GameObject \u0026\u0026 c.GameObject.IsValid() )\r\n            .OrderBy( c =\u003E Vector3.DistanceBetween( WorldPosition, c.WorldPosition ) )\r\n            .FirstOrDefault()?.GameObject;\r\n    }\r\n}"},{"Ident":"seilordstudio.one_more_push","Path":"PushHud.razor","FileName":"PushHud.razor","PackageType":"game","CodeKind":"Game","AssetVersionId":381888,"Code":"@using Sandbox;\r\n@using Sandbox.UI;\r\n@using System;\r\n@using System.Linq;\r\n@using System.Collections.Generic;\r\n@inherits PanelComponent\r\n@attribute [StyleSheet( \u0022PushHud.scss\u0022 )]\r\n\r\n\u003Croot class=\u0022hud-root\u0022\u003E\r\n\r\n    \u003Cdiv class=\u0022top-header-container\u0022\u003E\r\n        \u003Cdiv class=\u0022score-box\u0022\u003E\r\n            \u003Cdiv class=\u0022score-card time\u0022\u003E\r\n                \u003Clabel class=\u0022score-title\u0022\u003E@L( \u0022\u0412\u0440\u0435\u043C\u044F\u0022, \u0022Time\u0022 )\u003C/label\u003E\r\n                \u003Clabel class=\u0022score-value\u0022\u003E@GetFormattedTime()\u003C/label\u003E\r\n            \u003C/div\u003E\r\n            \u003Cdiv class=\u0022score-card\u0022\u003E\r\n                \u003Clabel class=\u0022score-title\u0022\u003E@L( \u0022\u0421\u0431\u0438\u0442\u043E\u0022, \u0022Score\u0022 )\u003C/label\u003E\r\n                \u003Clabel class=\u0022score-value\u0022\u003E@GetScore()\u003C/label\u003E\r\n            \u003C/div\u003E\r\n            \u003Cdiv class=\u0022score-card death\u0022\u003E\r\n                \u003Clabel class=\u0022score-title\u0022\u003E@L( \u0022\u0421\u043C\u0435\u0440\u0442\u0438\u0022, \u0022Deaths\u0022 )\u003C/label\u003E\r\n                \u003Clabel class=\u0022score-value\u0022\u003E@GetDeaths()\u003C/label\u003E\r\n            \u003C/div\u003E\r\n            \u003Cdiv class=\u0022score-card highlight\u0022\u003E\r\n                \u003Clabel class=\u0022score-title\u0022\u003E@L( \u0022\u0420\u0435\u043A\u043E\u0440\u0434\u0022, \u0022Best\u0022 )\u003C/label\u003E\r\n                \u003Clabel class=\u0022score-value\u0022\u003E@GetHighScore()\u003C/label\u003E\r\n            \u003C/div\u003E\r\n        \u003C/div\u003E\r\n\r\n        \u003Cdiv class=\u0022round-badge\u0022\u003E\r\n            @L( \u0022\u0420\u0410\u0423\u041D\u0414\u0022, \u0022ROUND\u0022 ) @(RoundManager.Instance?.CurrentRound ?? 1)\r\n        \u003C/div\u003E\r\n\r\n        @if ( MapEventManager.Instance != null \u0026\u0026 MapEventManager.Instance.CurrentEvent != WeatherType.None )\r\n        {\r\n            \u003Cdiv class=\u0022weather-banner @GetWeatherClass( MapEventManager.Instance.CurrentEvent )\u0022\u003E\r\n                \u003Clabel class=\u0022weather-icon\u0022\u003E@GetWeatherIcon( MapEventManager.Instance.CurrentEvent )\u003C/label\u003E\r\n                \u003Cdiv class=\u0022weather-info\u0022\u003E\r\n                    \u003Clabel class=\u0022weather-title\u0022\u003E@GetWeatherTitle( MapEventManager.Instance.CurrentEvent )\u003C/label\u003E\r\n                    \u003Clabel class=\u0022weather-sub\u0022\u003E@L( \u0022\u0410\u041A\u0422\u0418\u0412\u041D\u0410\u042F \u0410\u041D\u041E\u041C\u0410\u041B\u0418\u042F\u0022, \u0022ACTIVE ANOMALY\u0022 )\u003C/label\u003E\r\n                \u003C/div\u003E\r\n                \u003Cdiv class=\u0022weather-timer-badge\u0022\u003E\r\n                    \u003Clabel class=\u0022timer-text\u0022\u003E@($\u0022{MapEventManager.Instance.TimeRemaining:F1}s\u0022)\u003C/label\u003E\r\n                \u003C/div\u003E\r\n            \u003C/div\u003E\r\n        }\r\n    \u003C/div\u003E\r\n\r\n    \u003Cdiv class=\u0022scoreboard-box\u0022\u003E\r\n        \u003Cdiv class=\u0022scoreboard-header\u0022\u003E\r\n            \u003Clabel class=\u0022header-title\u0022\u003E@L( \u0022\u0418\u0413\u0420\u041E\u041A\u0418\u0022, \u0022PLAYERS\u0022 )\u003C/label\u003E\r\n        \u003C/div\u003E\r\n        \u003Cdiv class=\u0022player-list\u0022\u003E\r\n            @foreach ( var p in GetPlayerList() )\r\n            {\r\n                \u003Cdiv class=\u0022player-row @(p.IsLocal ? \u0022local\u0022 : \u0022\u0022)\u0022\u003E\r\n                    \u003Clabel class=\u0022player-name\u0022\u003E@p.Name\u003C/label\u003E\r\n                    \u003Clabel class=\u0022player-score\u0022\u003E@p.Score\u003C/label\u003E\r\n                \u003C/div\u003E\r\n            }\r\n        \u003C/div\u003E\r\n    \u003C/div\u003E\r\n\r\n    \u003Cdiv class=\u0022hotbar-container\u0022\u003E\r\n        @if ( ShopManager.Instance != null )\r\n        {\r\n            @foreach ( var item in ShopManager.Instance.Items )\r\n            {\r\n                bool isSelected = item == ShopManager.Instance.SelectedItem;\r\n                \r\n                \u003Cdiv class=\u0022slot-wrapper\u0022\u003E\r\n                    \u003Cdiv class=\u0022hotbar-slot @(isSelected ? \u0022selected\u0022 : \u0022\u0022) @(!item.IsUnlocked ? \u0022locked\u0022 : \u0022\u0022)\u0022 \r\n                         onclick=\u0022@(() =\u003E ShopManager.Instance.TryBuyOrSelect(item))\u0022\u003E\r\n                        \r\n                        \u003Clabel class=\u0022slot-name\u0022\u003E@item.GetName( CurrentLanguage )\u003C/label\u003E\r\n                        \r\n                        @if ( !item.IsUnlocked )\r\n                        {\r\n                            \u003Clabel class=\u0022slot-cost\u0022\u003E\uD83D\uDCB0 @item.Cost\u003C/label\u003E\r\n                        }\r\n                    \u003C/div\u003E\r\n                    \u003Cdiv class=\u0022key-badge @(isSelected ? \u0022selected\u0022 : \u0022\u0022)\u0022\u003E@item.Key\u003C/div\u003E\r\n                \u003C/div\u003E\r\n            }\r\n        }\r\n    \u003C/div\u003E\r\n\r\n    \u003Cdiv class=\u0022top-left-box\u0022\u003E\r\n        \u003Cdiv class=\u0022chat-box @(IsChatOpen ? \u0022open\u0022 : \u0022\u0022)\u0022\u003E\r\n            \u003Cdiv class=\u0022chat-messages\u0022\u003E\r\n                @foreach ( var msg in CanvasMessages )\r\n                {\r\n                    \u003Cdiv class=\u0022chat-row\u0022\u003E\r\n                        \u003Clabel class=\u0022chat-author\u0022\u003E@msg.Author:\u003C/label\u003E\r\n                        \u003Clabel class=\u0022chat-text\u0022\u003E@msg.Text\u003C/label\u003E\r\n                    \u003C/div\u003E\r\n                }\r\n            \u003C/div\u003E\r\n\r\n            @if ( IsChatOpen )\r\n            {\r\n                \u003Cdiv class=\u0022chat-input-row\u0022\u003E\r\n                    \u003Ctextentry @ref=\u0022ChatInput\u0022 onsubmit=\u0022@SendChatMessage\u0022 placeholder=\u0022@L( \u0022\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435...\u0022, \u0022Type a message...\u0022 )\u0022\u003E\u003C/textentry\u003E\r\n                \u003C/div\u003E\r\n            }\r\n            else\r\n            {\r\n                \u003Cdiv class=\u0022hints-row\u0022\u003E\r\n                    \u003Clabel class=\u0022chat-hint\u0022 onclick=\u0022@OpenChat\u0022\u003E@L( \u0022\u041D\u0430\u0436\u043C\u0438\u0442\u0435 [Enter] \u0434\u043B\u044F \u0447\u0430\u0442\u0430\u0022, \u0022Press [Enter] to chat\u0022 )\u003C/label\u003E\r\n                    \u003Clabel class=\u0022chat-hint prop-hint\u0022 onclick=\u0022@TogglePropMenu\u0022\u003E@L( \u0022\u041D\u0430\u0436\u043C\u0438\u0442\u0435 [R] \u041F\u0440\u043E\u043F\u0441\u044B\u0022, \u0022Press [R] Props\u0022 )\u003C/label\u003E\r\n                \u003C/div\u003E\r\n            }\r\n        \u003C/div\u003E\r\n    \u003C/div\u003E\r\n\r\n    @if ( IsPropMenuOpen )\r\n    {\r\n        \u003Cdiv class=\u0022menu-overlay\u0022 onclick=\u0022@ClosePropMenu\u0022\u003E\r\n            \u003Cdiv class=\u0022prop-menu-card\u0022 onclick=\u0022@((e) =\u003E e.StopPropagation())\u0022\u003E\r\n                \u003Clabel class=\u0022menu-title\u0022\u003E@L( \u0022\u0421\u041F\u0410\u0412\u041D \u041F\u0420\u041E\u041F\u0421\u041E\u0412\u0022, \u0022SPAWN PROPS\u0022 )\u003C/label\u003E\r\n\r\n                \u003Cdiv class=\u0022prop-grid\u0022\u003E\r\n                    \u003Cdiv class=\u0022prop-item\u0022 onclick=\u0022@(() =\u003E SelectAndSpawnProp(0))\u0022\u003E\r\n                        \u003Clabel class=\u0022prop-name\u0022\u003E\uD83D\uDCA5 @L( \u0022\u0411\u043E\u0447\u043A\u0430\u0022, \u0022Barrel\u0022 )\u003C/label\u003E\r\n                        \u003Clabel class=\u0022prop-cost\u0022\u003E\uD83D\uDCB0 15\u003C/label\u003E\r\n                    \u003C/div\u003E\r\n                    \u003Cdiv class=\u0022prop-item\u0022 onclick=\u0022@(() =\u003E SelectAndSpawnProp(1))\u0022\u003E\r\n                        \u003Clabel class=\u0022prop-name\u0022\u003E\uD83D\uDEE2\uFE0F @L( \u0022\u0421\u043C\u043E\u043B\u0430\u0022, \u0022Tar Zone\u0022 )\u003C/label\u003E\r\n                        \u003Clabel class=\u0022prop-cost\u0022\u003E\uD83D\uDCB0 20\u003C/label\u003E\r\n                    \u003C/div\u003E\r\n                    \u003Cdiv class=\u0022prop-item\u0022 onclick=\u0022@(() =\u003E SelectAndSpawnProp(2))\u0022\u003E\r\n                        \u003Clabel class=\u0022prop-name\u0022\u003E\u2693 @L( \u0022\u041D\u0430\u043A\u043E\u0432\u0430\u043B\u044C\u043D\u044F\u0022, \u0022Anvil\u0022 )\u003C/label\u003E\r\n                        \u003Clabel class=\u0022prop-cost\u0022\u003E\uD83D\uDCB0 25\u003C/label\u003E\r\n                    \u003C/div\u003E\r\n                    \u003Cdiv class=\u0022prop-item\u0022 onclick=\u0022@(() =\u003E SelectAndSpawnProp(3))\u0022\u003E\r\n                        \u003Clabel class=\u0022prop-name\u0022\u003E\uD83C\uDF00 @L( \u0022\u0411\u0430\u0442\u0443\u0442\u0022, \u0022Spring\u0022 )\u003C/label\u003E\r\n                        \u003Clabel class=\u0022prop-cost\u0022\u003E\uD83D\uDCB0 20\u003C/label\u003E\r\n                    \u003C/div\u003E\r\n                \u003C/div\u003E\r\n\r\n                \u003Cbutton class=\u0022menu-btn\u0022 onclick=\u0022@ClosePropMenu\u0022\u003E@L( \u0022\u0417\u0410\u041A\u0420\u042B\u0422\u042C [R]\u0022, \u0022CLOSE [R]\u0022 )\u003C/button\u003E\r\n            \u003C/div\u003E\r\n        \u003C/div\u003E\r\n    }\r\n\r\n    \u003Cdiv class=\u0022cooldown-box\u0022\u003E\r\n        \u003Clabel class=\u0022cooldown-title\u0022\u003E@L( \u0022\u041F\u0435\u0440\u0435\u0437\u0430\u0440\u044F\u0434\u043A\u0430\u0022, \u0022Cooldown\u0022 )\u003C/label\u003E\r\n        \u003Cdiv class=\u0022bar-background\u0022\u003E\r\n            \u003Cdiv class=\u0022bar-fill\u0022 style=\u0022width: @($\u0022{GetPercent():F1}%\u0022);\u0022\u003E\u003C/div\u003E\r\n        \u003C/div\u003E\r\n    \u003C/div\u003E\r\n\r\n    @if ( PushAbility != null \u0026\u0026 PushAbility.IsCharging )\r\n    {\r\n        \u003Cdiv class=\u0022charge-box\u0022\u003E\r\n            \u003Clabel class=\u0022charge-title\u0022\u003E@L( \u0022\u0417\u0410\u0420\u042F\u0414\u0022, \u0022CHARGE\u0022 )\u003C/label\u003E\r\n            \u003Cdiv class=\u0022bar-background\u0022\u003E\r\n                \u003Cdiv class=\u0022bar-fill charge\u0022 style=\u0022width: @($\u0022{PushAbility.ChargeProgress * 100f:F1}%\u0022);\u0022\u003E\u003C/div\u003E\r\n            \u003C/div\u003E\r\n        \u003C/div\u003E\r\n    }\r\n\r\n    @if ( !IsMenuOpen \u0026\u0026 !IsSettingsOpen \u0026\u0026 !IsPropMenuOpen )\r\n    {\r\n        \u003Cbutton class=\u0022side-settings-btn\u0022 onclick=\u0022@OpenMenu\u0022\u003E\r\n            \u003Clabel class=\u0022key-hint\u0022\u003E[ESC]\u003C/label\u003E\r\n            \u003Clabel class=\u0022icon\u0022\u003E\u2699\u003C/label\u003E\r\n        \u003C/button\u003E\r\n    }\r\n\r\n    @if ( IsMenuOpen )\r\n    {\r\n        \u003Cdiv class=\u0022menu-overlay\u0022\u003E\r\n            \u003Cdiv class=\u0022menu-card\u0022\u003E\r\n                \u003Clabel class=\u0022menu-title\u0022\u003EONE MORE PUSH\u003C/label\u003E\r\n                \u003Cbutton class=\u0022menu-btn play\u0022 onclick=\u0022@StartGame\u0022\u003E@L( \u0022\u0418\u0413\u0420\u0410\u0422\u042C\u0022, \u0022PLAY\u0022 )\u003C/button\u003E\r\n                \u003Cbutton class=\u0022menu-btn\u0022 onclick=\u0022@OpenSettings\u0022\u003E@L( \u0022\u041D\u0410\u0421\u0422\u0420\u041E\u0419\u041A\u0418\u0022, \u0022SETTINGS\u0022 )\u003C/button\u003E\r\n                \u003Cbutton class=\u0022menu-btn quit\u0022 onclick=\u0022@QuitGame\u0022\u003E@L( \u0022\u0412\u042B\u0425\u041E\u0414\u0022, \u0022QUIT\u0022 )\u003C/button\u003E\r\n            \u003C/div\u003E\r\n        \u003C/div\u003E\r\n    }\r\n\r\n    @if ( IsSettingsOpen )\r\n    {\r\n        \u003Cdiv class=\u0022menu-overlay\u0022\u003E\r\n            \u003Cdiv class=\u0022menu-card settings-card\u0022\u003E\r\n                \u003Clabel class=\u0022menu-title\u0022\u003E@L( \u0022\u041D\u0410\u0421\u0422\u0420\u041E\u0419\u041A\u0418\u0022, \u0022SETTINGS\u0022 )\u003C/label\u003E\r\n                \u003Cdiv class=\u0022settings-content\u0022\u003E\r\n                    \u003Cdiv class=\u0022setting-item lang-row\u0022\u003E\r\n                        \u003Clabel class=\u0022setting-label\u0022\u003E@L( \u0022\u042F\u0417\u042B\u041A:\u0022, \u0022LANGUAGE:\u0022 )\u003C/label\u003E\r\n                        \u003Cdiv class=\u0022lang-selector\u0022\u003E\r\n                            \u003Cbutton class=\u0022lang-btn @(CurrentLanguage == \u0022EN\u0022 ? \u0022active\u0022 : \u0022\u0022)\u0022 onclick=\u0022@(() =\u003E SetLanguage(\u0022EN\u0022))\u0022\u003EEN\u003C/button\u003E\r\n                            \u003Cbutton class=\u0022lang-btn @(CurrentLanguage == \u0022RU\u0022 ? \u0022active\u0022 : \u0022\u0022)\u0022 onclick=\u0022@(() =\u003E SetLanguage(\u0022RU\u0022))\u0022\u003ERU\u003C/button\u003E\r\n                        \u003C/div\u003E\r\n                    \u003C/div\u003E\r\n\r\n                    \u003Cdiv class=\u0022setting-item lang-row\u0022\u003E\r\n                        \u003Clabel class=\u0022setting-label\u0022\u003E@L( \u0022\u0421\u041F\u0410\u0412\u041D \u0411\u041E\u0422\u041E\u0412:\u0022, \u0022SPAWN BOTS:\u0022 )\u003C/label\u003E\r\n                        \u003Cbutton class=\u0022lang-btn @(BotSpawner.EnableBots ? \u0022active\u0022 : \u0022\u0022)\u0022 onclick=\u0022@ToggleBots\u0022\u003E\r\n                            @(BotSpawner.EnableBots ? L( \u0022\u0412\u041A\u041B\u0022, \u0022ON\u0022 ) : L( \u0022\u0412\u042B\u041A\u041B\u0022, \u0022OFF\u0022 ))\r\n                        \u003C/button\u003E\r\n                    \u003C/div\u003E\r\n\r\n                    \u003Cdiv class=\u0022setting-item lang-row\u0022\u003E\r\n                        \u003Clabel class=\u0022setting-label\u0022\u003E@L( \u0022\u041C\u0423\u0417\u042B\u041A\u0410:\u0022, \u0022MUSIC:\u0022 )\u003C/label\u003E\r\n                        \u003Cbutton class=\u0022lang-btn @(EnableMusic ? \u0022active\u0022 : \u0022\u0022)\u0022 onclick=\u0022@ToggleMusic\u0022\u003E\r\n                            @(EnableMusic ? L( \u0022\u0412\u041A\u041B\u0022, \u0022ON\u0022 ) : L( \u0022\u0412\u042B\u041A\u041B\u0022, \u0022OFF\u0022 ))\r\n                        \u003C/button\u003E\r\n                    \u003C/div\u003E\r\n\r\n                    \u003Clabel class=\u0022setting-item\u0022\u003E@L( \u0022\u0427\u0423\u0412\u0421\u0422\u0412\u0418\u0422\u0415\u041B\u042C\u041D\u041E\u0421\u0422\u042C: 1.0\u0022, \u0022SENSITIVITY: 1.0\u0022 )\u003C/label\u003E\r\n                \u003C/div\u003E\r\n                \u003Cbutton class=\u0022menu-btn\u0022 onclick=\u0022@CloseSettings\u0022\u003E@L( \u0022\u041D\u0410\u0417\u0410\u0414\u0022, \u0022BACK\u0022 )\u003C/button\u003E\r\n            \u003C/div\u003E\r\n        \u003C/div\u003E\r\n    }\r\n\r\n\u003C/root\u003E\r\n\r\n@code {\r\n    [Property] public PushAbility PushAbility { get; set; }\r\n\r\n    public bool IsMenuOpen { get; set; } = true;\r\n    public bool IsSettingsOpen { get; set; } = false;\r\n    public bool IsPropMenuOpen { get; set; } = false;\r\n\r\n    public static string CurrentLanguage { get; set; } = \u0022EN\u0022;\r\n\r\n    public struct ChatMessage\r\n    {\r\n        public string Author { get; set; }\r\n        public string Text { get; set; }\r\n    }\r\n\r\n    public List\u003CChatMessage\u003E CanvasMessages { get; set; } = new();\r\n    public bool IsChatOpen { get; set; } = false;\r\n    private TextEntry ChatInput { get; set; }\r\n\r\n    public struct PlayerInfo\r\n    {\r\n        public string Name { get; set; }\r\n        public int Score { get; set; }\r\n        public bool IsLocal { get; set; }\r\n    }\r\n\r\n    private string L( string ru, string en )\r\n    {\r\n        return CurrentLanguage == \u0022RU\u0022 ? ru : en;\r\n    }\r\n\r\n    private bool IsReady =\u003E PushAbility?.IsReady ?? false;\r\n\r\n    protected override void OnEnabled()\r\n    {\r\n        base.OnEnabled();\r\n        \r\n        AddMessage( L( \u0022\u0421\u0438\u0441\u0442\u0435\u043C\u0430\u0022, \u0022System\u0022 ), L( \u0022\u0427\u0430\u0442 \u0433\u043E\u0442\u043E\u0432. \u041D\u0430\u0436\u043C\u0438\u0442\u0435 Enter \u0434\u043B\u044F \u0432\u0432\u043E\u0434\u0430.\u0022, \u0022Chat ready. Press Enter to type.\u0022 ) );\r\n        ApplyMouseState();\r\n    }\r\n\r\n    protected override void OnUpdate()\r\n    {\r\n        base.OnUpdate();\r\n\r\n        if ( PushAbility == null )\r\n        {\r\n            PushAbility = Scene.GetAllComponents\u003CPushAbility\u003E()\r\n                .FirstOrDefault( x =\u003E !x.IsProxy );\r\n        }\r\n\r\n        if ( Input.EscapePressed || Input.Pressed( \u0022menu\u0022 ) )\r\n        {\r\n            Input.EscapePressed = false;\r\n            ToggleMenu();\r\n        }\r\n\r\n        if ( Input.Pressed( \u0022reload\u0022 ) || Input.Pressed( \u0022r\u0022 ) )\r\n        {\r\n            if ( !IsMenuOpen \u0026\u0026 !IsSettingsOpen \u0026\u0026 !IsChatOpen )\r\n            {\r\n                TogglePropMenu();\r\n            }\r\n        }\r\n\r\n        if ( Input.Pressed( \u0022chat\u0022 ) || Input.Pressed( \u0022enter\u0022 ) )\r\n        {\r\n            if ( !IsMenuOpen \u0026\u0026 !IsSettingsOpen \u0026\u0026 !IsPropMenuOpen )\r\n            {\r\n                if ( !IsChatOpen ) OpenChat();\r\n            }\r\n        }\r\n\r\n        ApplyMouseState();\r\n    }\r\n\r\n    private void SetLanguage( string lang )\r\n    {\r\n        CurrentLanguage = lang;\r\n        StateHasChanged();\r\n    }\r\n\r\n    private void ApplyMouseState()\r\n    {\r\n        bool needsMouse = IsMenuOpen || IsSettingsOpen || IsChatOpen || IsPropMenuOpen;\r\n        Mouse.Visibility = needsMouse ? MouseVisibility.Visible : MouseVisibility.Hidden;\r\n\r\n        if ( !needsMouse \u0026\u0026 Panel != null )\r\n        {\r\n            Panel.Focus();\r\n        }\r\n    }\r\n\r\n    private void TogglePropMenu()\r\n    {\r\n        IsPropMenuOpen = !IsPropMenuOpen;\r\n        ApplyMouseState();\r\n        StateHasChanged();\r\n    }\r\n\r\n    private void ClosePropMenu()\r\n    {\r\n        IsPropMenuOpen = false;\r\n        ApplyMouseState();\r\n        StateHasChanged();\r\n    }\r\n\r\n    private void SelectAndSpawnProp( int index )\r\n    {\r\n        if ( PropSpawner.Instance != null )\r\n        {\r\n            PropSpawner.Instance.SpawnByIndex( index );\r\n        }\r\n        ClosePropMenu();\r\n    }\r\n\r\n    private void ToggleMenu()\r\n    {\r\n        if ( IsSettingsOpen ) CloseSettings();\r\n        else if ( IsPropMenuOpen ) ClosePropMenu();\r\n        else if ( IsMenuOpen ) StartGame();\r\n        else OpenMenu();\r\n    }\r\n\r\n    private void StartGame()\r\n    {\r\n        IsMenuOpen = false;\r\n        IsSettingsOpen = false;\r\n        IsPropMenuOpen = false;\r\n        ApplyMouseState();\r\n    }\r\n\r\n    private void OpenMenu()\r\n    {\r\n        IsMenuOpen = true;\r\n        IsSettingsOpen = false;\r\n        IsPropMenuOpen = false;\r\n        ApplyMouseState();\r\n    }\r\n\r\n    private void OpenSettings()\r\n    {\r\n        IsMenuOpen = false;\r\n        IsSettingsOpen = true;\r\n        IsPropMenuOpen = false;\r\n        ApplyMouseState();\r\n    }\r\n\r\n    private void CloseSettings()\r\n    {\r\n        IsSettingsOpen = false;\r\n        IsMenuOpen = true;\r\n        IsPropMenuOpen = false;\r\n        ApplyMouseState();\r\n    }\r\n\r\n    private void QuitGame()\r\n    {\r\n        Game.Close();\r\n    }\r\n\r\n    private int GetScore()\r\n    {\r\n        return ScoreManager.Instance?.Score ?? 0;\r\n    }\r\n\r\n    private string GetFormattedTime()\r\n    {\r\n        var shrinker = Scene.GetAllComponents\u003CArenaShrinker\u003E().FirstOrDefault();\r\n        if ( !shrinker.IsValid() ) return \u002202:00\u0022;\r\n\r\n        int minutes = (int)Math.Max( 0, shrinker.TimeRemaining ) / 60;\r\n        int seconds = (int)Math.Max( 0, shrinker.TimeRemaining ) % 60;\r\n        return $\u0022{minutes:00}:{seconds:00}\u0022;\r\n    }\r\n\r\n    private float GetPercent()\r\n    {\r\n        if ( PushAbility == null ) return 0f;\r\n        return MathX.Clamp( PushAbility.CooldownProgress * 100f, 0f, 100f );\r\n    }\r\n\r\n    private void ToggleBots()\r\n    {\r\n        BotSpawner.EnableBots = !BotSpawner.EnableBots;\r\n        StateHasChanged();\r\n    }\r\n\r\n    private int GetHighScore()\r\n    {\r\n        return SaveManager.Current?.HighScore ?? 0;\r\n    }\r\n\r\n    private void OpenChat()\r\n    {\r\n        IsChatOpen = true;\r\n        IsPropMenuOpen = false;\r\n        ApplyMouseState();\r\n        StateHasChanged();\r\n        ChatInput?.Focus();\r\n    }\r\n\r\n    private void SendChatMessage()\r\n    {\r\n        if ( ChatInput == null || string.IsNullOrWhiteSpace( ChatInput.Text ) )\r\n        {\r\n            IsChatOpen = false;\r\n            ApplyMouseState();\r\n            return;\r\n        }\r\n\r\n        string name = Connection.Local?.DisplayName ?? L( \u0022\u0412\u044B\u0022, \u0022You\u0022 );\r\n        AddMessage( name, ChatInput.Text );\r\n\r\n        ChatInput.Text = \u0022\u0022;\r\n        IsChatOpen = false;\r\n        ApplyMouseState();\r\n    }\r\n\r\n    public void AddMessage( string author, string text )\r\n    {\r\n        CanvasMessages.Add( new ChatMessage { Author = author, Text = text } );\r\n        if ( CanvasMessages.Count \u003E 6 )\r\n        {\r\n            CanvasMessages.RemoveAt( 0 );\r\n        }\r\n        StateHasChanged();\r\n    }\r\n\r\n    private IEnumerable\u003CPlayerInfo\u003E GetPlayerList()\r\n    {\r\n        if ( Connection.All != null \u0026\u0026 Connection.All.Any() )\r\n        {\r\n            foreach ( var conn in Connection.All )\r\n            {\r\n                bool isLocal = conn == Connection.Local;\r\n                int score = isLocal ? GetScore() : 0;\r\n\r\n                yield return new PlayerInfo\r\n                {\r\n                    Name = string.IsNullOrEmpty( conn.DisplayName ) ? \u0022Player\u0022 : conn.DisplayName,\r\n                    Score = score,\r\n                    IsLocal = isLocal\r\n                };\r\n            }\r\n        }\r\n        else\r\n        {\r\n            yield return new PlayerInfo\r\n            {\r\n                Name = L( \u0022\u0412\u044B\u0022, \u0022You\u0022 ),\r\n                Score = GetScore(),\r\n                IsLocal = true\r\n            };\r\n        }\r\n    }\r\n\r\n    private string GetWeatherTitle( WeatherType type )\r\n    {\r\n        return type switch\r\n        {\r\n            WeatherType.LowGravity =\u003E L( \u0022\u041D\u0415\u0412\u0415\u0421\u041E\u041C\u041E\u0421\u0422\u042C\u0022, \u0022LOW GRAVITY\u0022 ),\r\n            WeatherType.SlipperyIce =\u003E L( \u0022\u0413\u041E\u041B\u041E\u041B\u0401\u0414\u0022, \u0022SLIPPERY ICE\u0022 ),\r\n            WeatherType.StrongWind =\u003E L( \u0022\u0428\u0422\u041E\u0420\u041C\u041E\u0412\u041E\u0419 \u0412\u0415\u0422\u0415\u0420\u0022, \u0022STRONG WIND\u0022 ),\r\n            _ =\u003E \u0022\u0022\r\n        };\r\n    }\r\n\r\n    private string GetWeatherIcon( WeatherType type )\r\n    {\r\n        return type switch\r\n        {\r\n            WeatherType.LowGravity =\u003E \u0022\uD83D\uDE80\u0022,\r\n            WeatherType.SlipperyIce =\u003E \u0022\u2744\uFE0F\u0022,\r\n            WeatherType.StrongWind =\u003E \u0022\uD83C\uDF2A\uFE0F\u0022,\r\n            _ =\u003E \u0022\u26A0\uFE0F\u0022\r\n        };\r\n    }\r\n\r\n    private string GetWeatherClass( WeatherType type )\r\n    {\r\n        return type switch\r\n        {\r\n            WeatherType.LowGravity =\u003E \u0022gravity\u0022,\r\n            WeatherType.SlipperyIce =\u003E \u0022ice\u0022,\r\n            WeatherType.StrongWind =\u003E \u0022wind\u0022,\r\n            _ =\u003E \u0022\u0022\r\n        };\r\n    }\r\n\r\n    private int GetDeaths()\r\n    {\r\n        return ScoreManager.Instance?.Deaths ?? 0;\r\n    }\r\n\r\n    public static bool EnableMusic { get; set; } = true;\r\n\r\n    private void ToggleMusic()\r\n    {\r\n        EnableMusic = !EnableMusic;\r\n        MusicManager.Instance?.ToggleMusic( EnableMusic );\r\n        StateHasChanged();\r\n    }\r\n\r\n    protected override int BuildHash()\r\n    {\r\n        var hash = new HashCode();\r\n        hash.Add( GetPercent() );\r\n        hash.Add( IsReady );\r\n        hash.Add( MapEventManager.Instance?.CurrentEvent );\r\n        hash.Add( (int)(MapEventManager.Instance?.TimeRemaining * 10f ?? 0) );\r\n        hash.Add( EnableMusic );\r\n        hash.Add( PushAbility?.ChargeProgress );\r\n        hash.Add( PushAbility?.IsCharging );\r\n        hash.Add( GetScore() );\r\n        hash.Add( GetDeaths() ); \r\n        hash.Add( GetFormattedTime() );\r\n        hash.Add( RoundManager.Instance?.CurrentRound );\r\n        hash.Add( IsMenuOpen );\r\n        hash.Add( IsPropMenuOpen );\r\n        hash.Add( ShopManager.Instance?.SelectedItem?.Id );\r\n        hash.Add( IsSettingsOpen );\r\n        hash.Add( CurrentLanguage );\r\n        hash.Add( IsChatOpen );\r\n        hash.Add( CanvasMessages.Count );\r\n        hash.Add( Connection.All?.Count() ?? 0 );\r\n        return hash.ToHashCode();\r\n    }\r\n}"}]}