r2mods/ilspy_dump/ror2_csproj/RoR2/SojournVehicle.cs

483 lines
13 KiB
C#

using System.Collections.Generic;
using EntityStates.Seeker;
using RoR2.HudOverlay;
using RoR2.UI;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Serialization;
namespace RoR2;
[RequireComponent(typeof(VehicleSeat))]
public class SojournVehicle : NetworkBehaviour, ICameraStateProvider
{
[Header("Vehicle Parameters")]
public float nonLinearSpeedRate = 0.15f;
public float nonLinearSpeedInterval = 1f;
private float currentSpeed;
public float startingSpeedBoost = 25f;
private float startingSpeed;
public float endSpeedTarget;
public float endSpeedBodyInfluance = 1f;
private float trueEndSpeed;
public float cameraLerpTime = 1f;
public float cameraForward = 2f;
[Header("Blast Parameters")]
public bool detonateOnCollision;
public GameObject explosionEffectPrefab;
public float blastDamageCoefficient;
public float blastForce;
public BlastAttack.FalloffModel blastFalloffModel;
public DamageTypeCombo blastDamageType;
public Vector3 blastBonusForce;
public float blastProcCoefficient;
public string explosionSoundString;
public GameObject healingExplosionPrefab;
public float dmgAddedPerSecond = 0.5f;
[Header("Blast Growth Rate")]
private float blastRadius;
public float minBlastSize = 4f;
public float baseMaxBlastSize = 10f;
public float perChakraAddMax = 2f;
public float perChakraAddMin = 0.5f;
public float blastNonlinearGrowthRate = 1f;
[Tooltip("These are the explosion size indicators. They will be scaled up by blast size.")]
public GameObject[] blastRadiusIndicators = new GameObject[0];
[Tooltip("This is the scale of the visible size indicators.")]
public float blastRadiusIndicatorScale = 0.125f;
[Tooltip("This will be multiplied by the bast size before calculating collision. Larger will expand the collider.")]
public float blastRadiusCollisionMult = 1f;
public GameObject effectsToFlatten;
[Header("Overlap Parameters")]
public float overlapDamageCoefficient;
public float overlapProcCoefficient;
public float overlapForce;
public float overlapFirePeriod;
public float overlapVehicleDurationBonusPerHit;
public GameObject overlapHitEffectPrefab;
private float age;
private VehicleSeat vehicleSeat;
private Rigidbody vehicleRigidbody;
[Header("Camera Parameters")]
public PlayerCharacterMasterController playerCharacterMasterController;
public GameObject sojournOverlayPrefab;
private CameraTargetParams cameraTargetParams;
private CharacterBody characterBody;
[Header("Flight Parameters")]
private SeekerController seekerController;
private float increaseAgeCheck;
public float agePerTenthSecondsCheck = 0.1f;
public float incrementalFlightDamage = 0.075f;
[FormerlySerializedAs("initialFlightDamageDelay")]
public float initialFlightGracePeriod = 0.3f;
public float afterGraceLerpDownTime = 1f;
[Header("Healing Parameters")]
private float healingOverShield;
private float healingExplosionAmount;
private bool skillKeyWasDown = true;
private bool skillHeldDown = true;
private OverlayController overlayController;
private List<ImageFillController> fillUiList = new List<ImageFillController>();
private ChildLocator overlayInstanceChildLocator;
private OverlapAttack overlapAttack;
private float overlapFireAge;
private float overlapResetAge;
private float agePerSecond;
private float totalHealth;
public Sojourn sojournState;
public float barrierPercentage;
public GameObject effectGameObject;
public GameObject hitBox;
private LocalUser localUser;
private static int kRpcRpcEndSojournState;
private void CacheLocalUser()
{
localUser = null;
foreach (NetworkUser readOnlyLocalPlayers in NetworkUser.readOnlyLocalPlayersList)
{
if (readOnlyLocalPlayers.master == characterBody.master)
{
localUser = readOnlyLocalPlayers.localUser;
}
}
}
private void Awake()
{
playerCharacterMasterController = GetComponent<PlayerCharacterMasterController>();
vehicleSeat = GetComponent<VehicleSeat>();
vehicleSeat.onPassengerEnter += OnPassengerEnter;
vehicleSeat.onPassengerExit += OnPassengerExit;
vehicleRigidbody = GetComponent<Rigidbody>();
effectGameObject = base.transform.Find("Effect").gameObject;
hitBox = base.transform.Find("HitBox").gameObject;
increaseAgeCheck = agePerTenthSecondsCheck;
}
private void Start()
{
overlayController = HudOverlayManager.AddOverlay(base.gameObject, new OverlayCreationParams
{
prefab = sojournOverlayPrefab,
childLocatorEntry = "CrosshairExtras"
});
totalHealth = characterBody.baseMaxHealth + characterBody.levelMaxHealth * (float)((int)characterBody.level - 1);
UpdateBlastRadius();
}
private void OnPassengerExit(GameObject passenger)
{
foreach (CameraRigController readOnlyInstances in CameraRigController.readOnlyInstancesList)
{
if (readOnlyInstances.target == passenger)
{
readOnlyInstances.SetOverrideCam(this, 0f);
readOnlyInstances.SetOverrideCam(null, cameraLerpTime);
}
}
DetonateServer();
}
[ClientRpc]
private void RpcEndSojournState()
{
Util.PlaySound(explosionSoundString, base.gameObject);
seekerController.doesExitVehicle = true;
}
private void OnPassengerEnter(GameObject passenger)
{
skillHeldDown = vehicleSeat.currentPassengerInputBank.skill3.down;
vehicleSeat.currentPassengerBody.GetComponent<InteractionDriver>().interactableOverride = null;
Vector3 aimDirection = vehicleSeat.currentPassengerInputBank.aimDirection;
vehicleRigidbody.rotation = Quaternion.LookRotation(aimDirection);
characterBody = vehicleSeat.currentPassengerBody;
seekerController = characterBody.transform.GetComponent<SeekerController>();
CacheLocalUser();
overlapAttack = new OverlapAttack
{
attacker = characterBody.gameObject,
damage = 0f,
pushAwayForce = overlapForce,
isCrit = characterBody.RollCrit(),
damageColorIndex = DamageColorIndex.Item,
inflictor = base.gameObject,
procChainMask = default(ProcChainMask),
procCoefficient = overlapProcCoefficient,
teamIndex = characterBody.teamComponent.teamIndex,
hitBoxGroup = base.gameObject.GetComponent<HitBoxGroup>(),
hitEffectPrefab = overlapHitEffectPrefab,
damageType = DamageType.Stun1s
};
startingSpeed = characterBody.moveSpeed + startingSpeedBoost;
trueEndSpeed = endSpeedBodyInfluance * characterBody.moveSpeed + endSpeedTarget;
currentSpeed = startingSpeed;
vehicleRigidbody.velocity = aimDirection * currentSpeed;
}
[Server]
private void DetonateServer()
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.SojournVehicle::DetonateServer()' called on client");
return;
}
float num = blastRadius * blastRadiusCollisionMult;
EffectData effectData = new EffectData
{
origin = base.transform.position,
scale = num
};
EffectManager.SpawnEffect(explosionEffectPrefab, effectData, transmit: true);
BlastAttack blastAttack = new BlastAttack();
blastAttack.attacker = characterBody.gameObject;
blastAttack.baseDamage = blastDamageCoefficient * characterBody.damage;
blastAttack.baseForce = blastForce;
blastAttack.bonusForce = blastBonusForce;
blastAttack.attackerFiltering = AttackerFiltering.NeverHitSelf;
blastAttack.crit = characterBody.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 = num;
blastAttack.teamIndex = characterBody.teamComponent.teamIndex;
blastAttack.Fire();
Util.PlaySound(explosionSoundString, base.gameObject);
seekerController.doesExitVehicle = true;
CallRpcEndSojournState();
Object.Destroy(base.gameObject);
}
private void Update()
{
effectsToFlatten.transform.rotation = Quaternion.identity;
}
private void FixedUpdate()
{
age += Time.fixedDeltaTime;
if (NetworkServer.active)
{
FixedUpdateOverlayAttack();
if (age > agePerTenthSecondsCheck)
{
FixedUpdatePerTenthSecond();
agePerTenthSecondsCheck += increaseAgeCheck;
}
}
FixedUpdateMovement();
if (age > agePerSecond)
{
if (age > initialFlightGracePeriod)
{
blastForce += 25f;
characterBody.AddBuff(DLC2Content.Buffs.SojournHealing);
blastDamageCoefficient += dmgAddedPerSecond;
}
agePerSecond += 1f;
}
if (age > initialFlightGracePeriod)
{
float normalizedHealth = characterBody.healthComponent.GetNormalizedHealth();
float b = Mathf.Lerp(trueEndSpeed, startingSpeed, normalizedHealth);
float t = Mathf.Clamp01((age - initialFlightGracePeriod) / afterGraceLerpDownTime);
currentSpeed = Mathf.LerpUnclamped(startingSpeed, b, t);
}
UpdateBlastRadius();
if (localUser != null && vehicleSeat != null)
{
bool flag = localUser?.userProfile.toggleSeekerSojourn ?? true;
bool? flag2 = vehicleSeat.currentPassengerInputBank?.skill3.down;
if ((!flag && !flag2.Value) || (flag && flag2.Value && !skillKeyWasDown))
{
vehicleSeat.currentPassengerInputBank.skill3.hasPressBeenClaimed = true;
vehicleSeat.CallCmdEjectPassenger();
}
skillKeyWasDown = vehicleSeat.currentPassengerInputBank?.skill3.down ?? false;
}
_ = effectGameObject.transform.position != hitBox.transform.position;
}
private void UpdateBlastRadius()
{
int buffCount = characterBody.GetBuffCount(DLC2Content.Buffs.ChakraBuff);
float t = Util.ConvertAmplificationPercentageIntoReductionNormalized(blastNonlinearGrowthRate * age);
blastRadius = Mathf.Lerp(minBlastSize + perChakraAddMin * (float)buffCount, baseMaxBlastSize + perChakraAddMax * (float)buffCount, t);
Vector3 localScale = Vector3.one * (blastRadius * blastRadiusIndicatorScale);
GameObject[] array = blastRadiusIndicators;
for (int i = 0; i < array.Length; i++)
{
array[i].transform.localScale = localScale;
}
}
[Server]
private void FixedUpdateOverlayAttack()
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.SojournVehicle::FixedUpdateOverlayAttack()' called on client");
return;
}
overlapFireAge += Time.fixedDeltaTime;
overlapResetAge += Time.fixedDeltaTime;
if (overlapFireAge > overlapFirePeriod)
{
overlapAttack.Fire();
overlapFireAge = 0f;
}
}
private void FixedUpdateMovement()
{
if (vehicleSeat.currentPassengerInputBank != null)
{
Ray aimRay = vehicleSeat.currentPassengerInputBank.GetAimRay();
aimRay = CameraRigController.ModifyAimRayIfApplicable(aimRay, base.gameObject, out var _);
vehicleRigidbody.MoveRotation(Quaternion.LookRotation(aimRay.direction));
vehicleRigidbody.velocity = aimRay.direction * currentSpeed;
}
}
[Server]
private void FixedUpdatePerTenthSecond()
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.SojournVehicle::FixedUpdatePerTenthSecond()' called on client");
return;
}
float damage = totalHealth * incrementalFlightDamage;
DamageInfo damageInfo = new DamageInfo
{
damageType = DamageTypeExtended.SojournVehicleDamage,
damage = damage,
position = base.gameObject.transform.position
};
if (age > initialFlightGracePeriod)
{
if (characterBody.healthComponent.health < totalHealth * 0.15f)
{
vehicleSeat.CallCmdEjectPassenger();
}
else
{
characterBody.healthComponent.TakeDamage(damageInfo);
}
}
}
private void OnCollisionEnter(Collision collision)
{
if (detonateOnCollision && NetworkServer.active)
{
vehicleSeat.CallCmdEjectPassenger();
}
}
public void GetCameraState(CameraRigController cameraRigController, ref CameraState cameraState)
{
cameraState.position = base.transform.position + base.transform.forward * cameraForward;
}
public bool IsUserLookAllowed(CameraRigController cameraRigController)
{
return true;
}
public bool IsUserControlAllowed(CameraRigController cameraRigController)
{
return true;
}
public bool IsHudAllowed(CameraRigController cameraRigController)
{
return true;
}
private void UNetVersion()
{
}
protected static void InvokeRpcRpcEndSojournState(NetworkBehaviour obj, NetworkReader reader)
{
if (!NetworkClient.active)
{
Debug.LogError("RPC RpcEndSojournState called on server.");
}
else
{
((SojournVehicle)obj).RpcEndSojournState();
}
}
public void CallRpcEndSojournState()
{
if (!NetworkServer.active)
{
Debug.LogError("RPC Function RpcEndSojournState called on client.");
return;
}
NetworkWriter networkWriter = new NetworkWriter();
networkWriter.Write((short)0);
networkWriter.Write((short)2);
networkWriter.WritePackedUInt32((uint)kRpcRpcEndSojournState);
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
SendRPCInternal(networkWriter, 0, "RpcEndSojournState");
}
static SojournVehicle()
{
kRpcRpcEndSojournState = -1858892214;
NetworkBehaviour.RegisterRpcDelegate(typeof(SojournVehicle), kRpcRpcEndSojournState, InvokeRpcRpcEndSojournState);
NetworkCRC.RegisterBehaviour("SojournVehicle", 0);
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
bool result = default(bool);
return result;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
}
public override void PreStartClient()
{
}
}