Weapons/SatchelChargeWeapon.cs
public sealed class SatchelChargeWeapon : BaseWeapon
{
[Property] public GameObject SatchelCharge { get; set; }
IEnumerable<SatchelChargeThrown> Satchels => !Owner.IsValid() ? Enumerable.Empty<SatchelChargeThrown>() : Scene.GetAllComponents<SatchelChargeThrown>().Where( x => x.Instigator == Owner.PlayerData );
bool HasDeployedSatchels => Satchels.Any();
public override void OnControl( Player player )
{
if ( TimeUntilNextShotAllowed > 0 ) return;
// left click first deploy
// then trigger
if ( Input.Pressed( "Attack1" ) )
{
if ( HasDeployedSatchels )
{
Trigger();
return;
}
Throw( player );
}
// right click always deploy
if ( Input.Pressed( "Attack2" ) )
{
Throw( player );
}
}
void Trigger()
{
TriggerExplode();
if ( !HasAmmo() )
{
SwitchAway();
GameObject.Destroy();
}
}
protected override void OnEnabled()
{
base.OnEnabled();
AddShootDelay( 0.5f );
}
public void Throw( Player player )
{
if ( !CanShoot() )
return;
if ( !TakeAmmo( 1 ) )
{
DryFire();
return;
}
AddShootDelay( GameSettings.SatchelThrowDelay );
ThrowSatchel();
if ( !player.Controller.ThirdPerson && player.IsLocalPlayer )
{
new Sandbox.CameraNoise.Punch( new Vector3( Random.Shared.Float( -10, -15 ), Random.Shared.Float( -10, 0 ), 0 ), 1.0f, 3, 0.5f );
new Sandbox.CameraNoise.Shake( 0.3f, 1.2f );
}
}
[Rpc.Host]
private void ThrowSatchel()
{
if ( !Owner.IsValid() )
return;
var forward = Owner.EyeTransform.Rotation.Forward;
forward += Owner.EyeTransform.Rotation.Up * Random.Shared.Float( -1, 1 ) * 0.1f;
forward = forward.Normal;
var initialPos = Owner.EyeTransform.ForwardRay.Position + Vector3.Down * 16 + (forward * 16);
var go = SatchelCharge.Clone( initialPos );
var mine = go.GetComponent<SatchelChargeThrown>();
Assert.True( mine.IsValid(), "SatchelChargeThrown not on sachel prefab" );
mine.Instigator = Owner.PlayerData;
var rb = go.GetComponent<Rigidbody>();
var baseVelocity = Owner.Controller.Velocity;
rb.Velocity = baseVelocity + forward * GameSettings.SatchelThrowPower + Vector3.Up * 100f;
rb.AngularVelocity = go.WorldRotation.Right * 10f;
go.NetworkSpawn();
}
[Rpc.Host]
void TriggerExplode()
{
if ( !Owner.IsValid() )
return;
foreach ( var satchel in Satchels )
{
if ( satchel.IsValid() )
satchel.Explode();
}
}
}