Files
gm_construct_port/code/weapons/Flashlight.cs
2021-08-05 17:54:51 +03:00

212 lines
3.7 KiB
C#

using Sandbox;
[Library( "weapon_flashlight", Title = "Flashlight", Spawnable = true )]
partial class Flashlight : Weapon
{
public override string ViewModelPath => "weapons/rust_flashlight/v_rust_flashlight.vmdl";
public override float SecondaryRate => 2.0f;
protected virtual Vector3 LightOffset => Vector3.Forward * 10;
private SpotLightEntity worldLight;
private SpotLightEntity viewLight;
[Net, Local, Predicted]
private bool LightEnabled { get; set; } = true;
TimeSince timeSinceLightToggled;
public override void Spawn()
{
base.Spawn();
SetModel( "weapons/rust_pistol/rust_pistol.vmdl" );
worldLight = CreateLight();
worldLight.SetParent( this, "slide", new Transform( LightOffset ) );
worldLight.EnableHideInFirstPerson = true;
worldLight.Enabled = false;
}
public override void CreateViewModel()
{
base.CreateViewModel();
viewLight = CreateLight();
viewLight.SetParent( ViewModelEntity, "light", new Transform( LightOffset ) );
viewLight.EnableViewmodelRendering = true;
viewLight.Enabled = LightEnabled;
}
private SpotLightEntity CreateLight()
{
var light = new SpotLightEntity
{
Enabled = true,
DynamicShadows = true,
Range = 512,
Falloff = 1.0f,
LinearAttenuation = 0.0f,
QuadraticAttenuation = 1.0f,
Brightness = 2,
Color = Color.White,
InnerConeAngle = 20,
OuterConeAngle = 40,
FogStength = 1.0f,
Owner = Owner,
};
light.UseFog();
return light;
}
public override void Simulate( Client cl )
{
if ( cl == null )
return;
base.Simulate( cl );
bool toggle = Input.Pressed( InputButton.Flashlight ) || Input.Pressed( InputButton.Attack1 );
if ( timeSinceLightToggled > 0.1f && toggle )
{
LightEnabled = !LightEnabled;
PlaySound( LightEnabled ? "flashlight-on" : "flashlight-off" );
if ( worldLight.IsValid() )
{
worldLight.Enabled = LightEnabled;
}
if ( viewLight.IsValid() )
{
viewLight.Enabled = LightEnabled;
}
timeSinceLightToggled = 0;
}
}
public override bool CanReload()
{
return false;
}
public override void AttackSecondary()
{
if ( MeleeAttack() )
{
OnMeleeHit();
}
else
{
OnMeleeMiss();
}
PlaySound( "rust_flashlight.attack" );
}
private bool MeleeAttack()
{
var forward = Owner.EyeRot.Forward;
forward = forward.Normal;
bool hit = false;
foreach ( var tr in TraceBullet( Owner.EyePos, Owner.EyePos + forward * 80, 20.0f ) )
{
if ( !tr.Entity.IsValid() ) continue;
tr.Surface.DoBulletImpact( tr );
hit = true;
if ( !IsServer ) continue;
using ( Prediction.Off() )
{
var damageInfo = DamageInfo.FromBullet( tr.EndPos, forward * 100, 25 )
.UsingTraceResult( tr )
.WithAttacker( Owner )
.WithWeapon( this );
tr.Entity.TakeDamage( damageInfo );
}
}
return hit;
}
[ClientRpc]
private void OnMeleeMiss()
{
Host.AssertClient();
if ( IsLocalPawn )
{
_ = new Sandbox.ScreenShake.Perlin();
}
ViewModelEntity?.SetAnimBool( "attack", true );
}
[ClientRpc]
private void OnMeleeHit()
{
Host.AssertClient();
if ( IsLocalPawn )
{
_ = new Sandbox.ScreenShake.Perlin( 1.0f, 1.0f, 3.0f );
}
ViewModelEntity?.SetAnimBool( "attack_hit", true );
}
private void Activate()
{
if ( worldLight.IsValid() )
{
worldLight.Enabled = LightEnabled;
}
}
private void Deactivate()
{
if ( worldLight.IsValid() )
{
worldLight.Enabled = false;
}
}
public override void ActiveStart( Entity ent )
{
base.ActiveStart( ent );
if ( IsServer )
{
Activate();
}
}
public override void ActiveEnd( Entity ent, bool dropped )
{
base.ActiveEnd( ent, dropped );
if ( IsServer )
{
if ( dropped )
{
Activate();
}
else
{
Deactivate();
}
}
}
}