PlayerAbilities.cs
using Sandbox;
using System;
public sealed class PlayerAbilities : Component
{
[Property] public GameObject HeavyObjectPrefab { get; set; }
[Property] public float DropCooldown { get; set; } = 8f;
[Property] public float ShieldCooldown { get; set; } = 6f;
[Property] public float ShieldDuration { get; set; } = 2f;
public bool IsShieldActive { get; private set; } = false;
private TimeSince _timeSinceDrop = 100f;
private TimeSince _timeSinceShield = 100f;
private TimeSince _shieldActiveTimer = 0f;
private Rigidbody _rb;
private float _originalMass = 0f;
protected override void OnStart()
{
_rb = Components.Get<Rigidbody>();
if ( _rb != null )
{
_originalMass = _rb.MassOverride;
}
}
protected override void OnUpdate()
{
if ( IsProxy ) return;
if ( IsShieldActive && _shieldActiveTimer > ShieldDuration )
{
DeactivateShield();
}
if ( Input.Pressed( "attack2" ) || Input.Pressed( "use" ) )
{
TryDropObject();
}
if ( Input.Pressed( "run" ) )
{
TryActivateShield();
}
}
private void TryDropObject()
{
if ( _timeSinceDrop < DropCooldown )
{
Log.Info( $"[Способности] Сброс на перезарядке! Осталось: {DropCooldown - _timeSinceDrop:F1} сек." );
return;
}
var headPos = Transform.Position + Vector3.Up * 50f;
var forwardPos = headPos + Transform.World.Forward * 600f;
var tr = Scene.Trace.Ray( headPos, forwardPos )
.IgnoreGameObjectHierarchy( GameObject )
.Run();
if ( tr.Hit && tr.GameObject != null )
{
var targetPos = tr.GameObject.Transform.Position;
var spawnPos = targetPos + Vector3.Up * 180f;
if ( HeavyObjectPrefab != null )
{
var obj = HeavyObjectPrefab.Clone( spawnPos );
if ( obj != null && Network.Active )
{
obj.NetworkSpawn();
}
_timeSinceDrop = 0;
Log.Info( "[Способности] Тяжелый объект сброшен прямо на врага!" );
}
else
{
Log.Warning( "[Способности] HeavyObjectPrefab не назначен в Инспекторе!" );
}
}
else
{
Log.Info( "[Способности] Никого не нашли перед собой для атаки!" );
}
}
private void TryActivateShield()
{
if ( _timeSinceShield < ShieldCooldown || IsShieldActive ) return;
IsShieldActive = true;
_shieldActiveTimer = 0;
_timeSinceShield = 0;
if ( _rb != null )
{
_originalMass = _rb.MassOverride;
_rb.MassOverride = 1000f;
}
Log.Info( "[Способности] ЩИТ АКТИВИРОВАН!" );
}
private void DeactivateShield()
{
IsShieldActive = false;
if ( _rb != null )
{
_rb.MassOverride = _originalMass;
}
Log.Info( "[Способности] Действие щита закончилось." );
}
}