Weapons/Base/BaseWeapon.cs
using Opium;
/// <summary>
/// The base implementation of all weapons. There shouldn't be much in this class to begin with.
/// </summary>
public abstract partial class BaseWeapon : BaseInteract
{
/// <summary>
/// Holds a reference to the view model's gameobject (a prefab hopefully) and creates it on the player's camera
/// </summary>
[Property, Category( "Prefabs" )] public GameObject ViewModelPrefab { get; set; }
/// <summary>
/// The weapon's world model (if any)
/// </summary>
[Property] public SkinnedModelRenderer WorldModel { get; set; }
/// <summary>
/// When dropping the object, we want this to spawn
/// </summary>
[Property, Category( "Prefabs" )] public GameObject PickupPrefab { get; set; }
[Property] public bool Droppable { get; set; } = true;
public override bool ShowInteractionUI => true;
[Property] public GameObject ViewModel { get; set; }
/// <summary>
/// How quickly we can attack
/// </summary>
[Property] public float BaseShootRate { get; set; }
[Property] public float StaminaDrain { get; set; } = 0f;
/// <summary>
/// Generic event listener, doesn't pass any extra info.
/// </summary>
public Action<string> EventListener { get; set; }
/// <summary>
/// Time since we have attacked
/// </summary>
public TimeSince TimeSinceShoot { get; set; } = 10;
/// <summary>
/// Time since we aiming
/// </summary>
public TimeSince TimeSinceAim { get; set; } = 10;
/// <summary>
/// Damage
/// </summary>
[Property] public float BaseDamage { get; set; } = 25f;
/// <summary>
/// Damage?
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
protected virtual void CalculateDamage( in Sandbox.DamageInfo info )
{
var dmg = info.Damage;
if ( info.Hitbox?.Tags.Has( "head" ) ?? false )
{
dmg *= 3.0f;
}
info.Damage = dmg;
}
public Actor Actor { get; set; }
/// <summary>
/// Set the weapon as active?
/// </summary>
/// <param name="active"></param>
public void SetAsActive( bool active )
{
Actor.SetupViewModel( this, active );
if ( WorldModel.IsValid() )
{
WorldModel.GameObject.Enabled = false;
}
GameObject.Enabled = active;
}
/// <summary>
/// Can we attack?
/// </summary>
/// <returns></returns>
public virtual bool CanShoot()
{
if ( !Actor.CanShoot( this ) ) return false;
return TimeSinceShoot >= GetShootRate();
}
/// <summary>
/// Gets the attack rate, child components can override this, stuff like stats?
/// </summary>
/// <returns></returns>
protected virtual float GetShootRate()
{
return BaseShootRate;
}
/// <summary>
/// Called when attacking with this weapon.
/// </summary>
public virtual void Shoot()
{
TimeSinceShoot = 0;
}
public virtual void OnCreateViewModel()
{
//
}
public virtual void OnDamage( in Sandbox.DamageInfo damage )
{
//
}
public virtual void Aim()
{
TimeSinceAim = 0;
}
public virtual bool CanAim()
{
return false;
}
/// <summary>
/// Gets a surface from a trace. Trying to find a SurfaceComponent before using the one from the model.
/// </summary>
/// <param name="tr"></param>
/// <returns></returns>
[Obsolete( "Let's make surfaces not used here" )]
protected Surface GetSurfaceFromTrace( SceneTraceResult tr )
{
return tr.Surface;
}
}