222 lines
5.9 KiB
C#
222 lines
5.9 KiB
C#
|
using UnityEngine;
|
||
|
using UnityEngine.Networking;
|
||
|
|
||
|
namespace RoR2;
|
||
|
|
||
|
[RequireComponent(typeof(VehicleSeat))]
|
||
|
[RequireComponent(typeof(Rigidbody))]
|
||
|
public class FireballVehicle : MonoBehaviour, ICameraStateProvider
|
||
|
{
|
||
|
[Header("Vehicle Parameters")]
|
||
|
public float duration = 3f;
|
||
|
|
||
|
public float initialSpeed = 120f;
|
||
|
|
||
|
public float targetSpeed = 40f;
|
||
|
|
||
|
public float acceleration = 20f;
|
||
|
|
||
|
public float cameraLerpTime = 1f;
|
||
|
|
||
|
[Header("Blast Parameters")]
|
||
|
public bool detonateOnCollision;
|
||
|
|
||
|
public GameObject explosionEffectPrefab;
|
||
|
|
||
|
public float blastDamageCoefficient;
|
||
|
|
||
|
public float blastRadius;
|
||
|
|
||
|
public float blastForce;
|
||
|
|
||
|
public BlastAttack.FalloffModel blastFalloffModel;
|
||
|
|
||
|
public DamageTypeCombo blastDamageType;
|
||
|
|
||
|
public Vector3 blastBonusForce;
|
||
|
|
||
|
public float blastProcCoefficient;
|
||
|
|
||
|
public string explosionSoundString;
|
||
|
|
||
|
[Header("Overlap Parameters")]
|
||
|
public float overlapDamageCoefficient;
|
||
|
|
||
|
public float overlapProcCoefficient;
|
||
|
|
||
|
public float overlapForce;
|
||
|
|
||
|
public float overlapFireFrequency;
|
||
|
|
||
|
public float overlapResetFrequency;
|
||
|
|
||
|
public float overlapVehicleDurationBonusPerHit;
|
||
|
|
||
|
public GameObject overlapHitEffectPrefab;
|
||
|
|
||
|
private float age;
|
||
|
|
||
|
private bool hasDetonatedServer;
|
||
|
|
||
|
private VehicleSeat vehicleSeat;
|
||
|
|
||
|
private Rigidbody rigidbody;
|
||
|
|
||
|
private OverlapAttack overlapAttack;
|
||
|
|
||
|
private float overlapFireAge;
|
||
|
|
||
|
private float overlapResetAge;
|
||
|
|
||
|
private void Awake()
|
||
|
{
|
||
|
vehicleSeat = GetComponent<VehicleSeat>();
|
||
|
vehicleSeat.onPassengerEnter += OnPassengerEnter;
|
||
|
vehicleSeat.onPassengerExit += OnPassengerExit;
|
||
|
rigidbody = GetComponent<Rigidbody>();
|
||
|
}
|
||
|
|
||
|
private void OnPassengerExit(GameObject passenger)
|
||
|
{
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
DetonateServer();
|
||
|
}
|
||
|
foreach (CameraRigController readOnlyInstances in CameraRigController.readOnlyInstancesList)
|
||
|
{
|
||
|
if (readOnlyInstances.target == passenger)
|
||
|
{
|
||
|
readOnlyInstances.SetOverrideCam(this, 0f);
|
||
|
readOnlyInstances.SetOverrideCam(null, cameraLerpTime);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnPassengerEnter(GameObject passenger)
|
||
|
{
|
||
|
if ((bool)vehicleSeat.currentPassengerInputBank)
|
||
|
{
|
||
|
Vector3 aimDirection = vehicleSeat.currentPassengerInputBank.aimDirection;
|
||
|
rigidbody.rotation = Quaternion.LookRotation(aimDirection);
|
||
|
rigidbody.velocity = aimDirection * initialSpeed;
|
||
|
CharacterBody currentPassengerBody = vehicleSeat.currentPassengerBody;
|
||
|
overlapAttack = new OverlapAttack
|
||
|
{
|
||
|
attacker = currentPassengerBody.gameObject,
|
||
|
damage = overlapDamageCoefficient * currentPassengerBody.damage,
|
||
|
pushAwayForce = overlapForce,
|
||
|
isCrit = currentPassengerBody.RollCrit(),
|
||
|
damageColorIndex = DamageColorIndex.Item,
|
||
|
inflictor = base.gameObject,
|
||
|
procChainMask = default(ProcChainMask),
|
||
|
procCoefficient = overlapProcCoefficient,
|
||
|
teamIndex = currentPassengerBody.teamComponent.teamIndex,
|
||
|
hitBoxGroup = base.gameObject.GetComponent<HitBoxGroup>(),
|
||
|
hitEffectPrefab = overlapHitEffectPrefab
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void DetonateServer()
|
||
|
{
|
||
|
if (!hasDetonatedServer)
|
||
|
{
|
||
|
hasDetonatedServer = true;
|
||
|
CharacterBody currentPassengerBody = vehicleSeat.currentPassengerBody;
|
||
|
if ((bool)currentPassengerBody)
|
||
|
{
|
||
|
EffectData effectData = new EffectData
|
||
|
{
|
||
|
origin = base.transform.position,
|
||
|
scale = blastRadius
|
||
|
};
|
||
|
EffectManager.SpawnEffect(explosionEffectPrefab, effectData, transmit: true);
|
||
|
BlastAttack blastAttack = new BlastAttack();
|
||
|
blastAttack.attacker = currentPassengerBody.gameObject;
|
||
|
blastAttack.baseDamage = blastDamageCoefficient * currentPassengerBody.damage;
|
||
|
blastAttack.baseForce = blastForce;
|
||
|
blastAttack.bonusForce = blastBonusForce;
|
||
|
blastAttack.attackerFiltering = AttackerFiltering.NeverHitSelf;
|
||
|
blastAttack.crit = currentPassengerBody.RollCrit();
|
||
|
blastAttack.damageColorIndex = DamageColorIndex.Item;
|
||
|
blastAttack.damageType = blastDamageType;
|
||
|
blastAttack.falloffModel = blastFalloffModel;
|
||
|
blastAttack.inflictor = base.gameObject;
|
||
|
blastAttack.position = base.transform.position;
|
||
|
blastAttack.procChainMask = default(ProcChainMask);
|
||
|
blastAttack.procCoefficient = blastProcCoefficient;
|
||
|
blastAttack.radius = blastRadius;
|
||
|
blastAttack.teamIndex = currentPassengerBody.teamComponent.teamIndex;
|
||
|
blastAttack.Fire();
|
||
|
}
|
||
|
Util.PlaySound(explosionSoundString, base.gameObject);
|
||
|
Object.Destroy(base.gameObject);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void FixedUpdate()
|
||
|
{
|
||
|
if (!vehicleSeat || !vehicleSeat.currentPassengerInputBank)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
age += Time.fixedDeltaTime;
|
||
|
overlapFireAge += Time.fixedDeltaTime;
|
||
|
overlapResetAge += Time.fixedDeltaTime;
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
if (overlapFireAge > 1f / overlapFireFrequency)
|
||
|
{
|
||
|
if (overlapAttack.Fire())
|
||
|
{
|
||
|
age = Mathf.Max(0f, age - overlapVehicleDurationBonusPerHit);
|
||
|
}
|
||
|
overlapFireAge = 0f;
|
||
|
}
|
||
|
if (overlapResetAge >= 1f / overlapResetFrequency)
|
||
|
{
|
||
|
overlapAttack.ResetIgnoredHealthComponents();
|
||
|
overlapResetAge = 0f;
|
||
|
}
|
||
|
}
|
||
|
Ray aimRay = vehicleSeat.currentPassengerInputBank.GetAimRay();
|
||
|
aimRay = CameraRigController.ModifyAimRayIfApplicable(aimRay, base.gameObject, out var _);
|
||
|
Vector3 velocity = rigidbody.velocity;
|
||
|
Vector3 target = aimRay.direction * targetSpeed;
|
||
|
Vector3 vector = Vector3.MoveTowards(velocity, target, acceleration * Time.fixedDeltaTime);
|
||
|
rigidbody.MoveRotation(Quaternion.LookRotation(aimRay.direction));
|
||
|
rigidbody.AddForce(vector - velocity, ForceMode.VelocityChange);
|
||
|
if (NetworkServer.active && duration <= age)
|
||
|
{
|
||
|
DetonateServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnCollisionEnter(Collision collision)
|
||
|
{
|
||
|
if (detonateOnCollision && NetworkServer.active)
|
||
|
{
|
||
|
DetonateServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void GetCameraState(CameraRigController cameraRigController, ref CameraState cameraState)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public bool IsUserLookAllowed(CameraRigController cameraRigController)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public bool IsUserControlAllowed(CameraRigController cameraRigController)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public bool IsHudAllowed(CameraRigController cameraRigController)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|