86 lines
2.2 KiB
C#
86 lines
2.2 KiB
C#
|
using UnityEngine;
|
||
|
using Fusion;
|
||
|
|
||
|
namespace TPSBR
|
||
|
{
|
||
|
public sealed class ThrowableWeapon : FirearmWeapon, IDynamicPickupProvider
|
||
|
{
|
||
|
// PRIVATE MEMBERS
|
||
|
|
||
|
[Header("Throwable")]
|
||
|
[SerializeField]
|
||
|
private KinematicProjectile _projectile;
|
||
|
[SerializeField]
|
||
|
private float _projectileSpeed = 100f;
|
||
|
[SerializeField]
|
||
|
private GameObject _dummyLoadedProjectile;
|
||
|
[SerializeField]
|
||
|
private float _minProjectileDespawnTime = 0.5f;
|
||
|
[SerializeField]
|
||
|
private AudioSetup _armSound;
|
||
|
|
||
|
[Networked][OnChangedRender(nameof(OnArmStarted))]
|
||
|
private int _armStartTick { get; set; }
|
||
|
|
||
|
// PUBLIC MEMBERS
|
||
|
|
||
|
public void ArmProjectile()
|
||
|
{
|
||
|
_armStartTick = Runner.Tick;
|
||
|
}
|
||
|
|
||
|
// FirearmWeapon INTERFACE
|
||
|
|
||
|
protected override bool FireProjectile(Vector3 firePosition, Vector3 targetPosition, Vector3 direction, float distanceToTarget, LayerMask hitMask, bool isFirst)
|
||
|
{
|
||
|
if (HasStateAuthority == false)
|
||
|
return false;
|
||
|
|
||
|
var ownerVelocity = Character != null ? Character.CharacterController.FixedData.RealVelocity : Vector3.zero;
|
||
|
if (ownerVelocity.y < 0f)
|
||
|
{
|
||
|
ownerVelocity.y = 0f;
|
||
|
}
|
||
|
|
||
|
var projectile = Runner.Spawn(_projectile, firePosition, Quaternion.LookRotation(direction), Object.InputAuthority);
|
||
|
if (projectile == null)
|
||
|
return false;
|
||
|
|
||
|
projectile.Fire(Owner, firePosition, direction * _projectileSpeed + ownerVelocity, hitMask, HitType);
|
||
|
|
||
|
float armedTime = (Runner.Tick - _armStartTick) * Runner.DeltaTime;
|
||
|
projectile.SetDespawnCooldown(Mathf.Max(_minProjectileDespawnTime, projectile.FireDespawnTime - armedTime));
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public override void Render()
|
||
|
{
|
||
|
base.Render();
|
||
|
|
||
|
_dummyLoadedProjectile.SetActiveSafe(IsReloading == false && MagazineAmmo > 0);
|
||
|
}
|
||
|
|
||
|
// IPickupProvider INTERFACE
|
||
|
|
||
|
string IDynamicPickupProvider.Description => GetPickupDescription();
|
||
|
float IDynamicPickupProvider.DespawnTime => WeaponAmmo == 0 && MagazineAmmo == 0 ? 1f : 60f;
|
||
|
|
||
|
// PRIVATE METHODS
|
||
|
|
||
|
private void OnArmStarted()
|
||
|
{
|
||
|
PlayLocalSound(_armSound);
|
||
|
}
|
||
|
|
||
|
private string GetPickupDescription()
|
||
|
{
|
||
|
// For prefab read initial data
|
||
|
if (gameObject.scene.rootCount == 0)
|
||
|
return $"Amount {_initialAmmo}";
|
||
|
|
||
|
return $"Amount {MagazineAmmo + WeaponAmmo}";
|
||
|
}
|
||
|
}
|
||
|
}
|