166 lines
4.2 KiB
C#
166 lines
4.2 KiB
C#
|
using RoR2;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace EntityStates.Mage.Weapon;
|
||
|
|
||
|
public class ChargeMeteor : BaseState
|
||
|
{
|
||
|
public static float baseChargeDuration;
|
||
|
|
||
|
public static float baseDuration;
|
||
|
|
||
|
public static GameObject areaIndicatorPrefab;
|
||
|
|
||
|
public static float minMeteorRadius = 0f;
|
||
|
|
||
|
public static float maxMeteorRadius = 10f;
|
||
|
|
||
|
public static GameObject meteorEffect;
|
||
|
|
||
|
public static float minDamageCoefficient;
|
||
|
|
||
|
public static float maxDamageCoefficient;
|
||
|
|
||
|
public static float procCoefficient;
|
||
|
|
||
|
public static float force;
|
||
|
|
||
|
public static GameObject muzzleflashEffect;
|
||
|
|
||
|
private float stopwatch;
|
||
|
|
||
|
private GameObject areaIndicatorInstance;
|
||
|
|
||
|
private bool fireMeteor;
|
||
|
|
||
|
private float radius;
|
||
|
|
||
|
private float chargeDuration;
|
||
|
|
||
|
private float duration;
|
||
|
|
||
|
private BlastAttack blastAttack;
|
||
|
|
||
|
private EffectData _effectData;
|
||
|
|
||
|
private Vector3 _cachedScale = Vector3.one;
|
||
|
|
||
|
private EffectManagerHelper _emh_areaIndicatorInstance;
|
||
|
|
||
|
public override void Reset()
|
||
|
{
|
||
|
base.Reset();
|
||
|
stopwatch = 0f;
|
||
|
areaIndicatorInstance = null;
|
||
|
fireMeteor = false;
|
||
|
radius = 0f;
|
||
|
chargeDuration = 0f;
|
||
|
duration = 0f;
|
||
|
if (blastAttack != null)
|
||
|
{
|
||
|
blastAttack.Reset();
|
||
|
}
|
||
|
if (_effectData != null)
|
||
|
{
|
||
|
_effectData.Reset();
|
||
|
}
|
||
|
_emh_areaIndicatorInstance = null;
|
||
|
}
|
||
|
|
||
|
public override void OnEnter()
|
||
|
{
|
||
|
base.OnEnter();
|
||
|
chargeDuration = baseChargeDuration / attackSpeedStat;
|
||
|
duration = baseDuration / attackSpeedStat;
|
||
|
UpdateAreaIndicator();
|
||
|
}
|
||
|
|
||
|
private void UpdateAreaIndicator()
|
||
|
{
|
||
|
if ((bool)areaIndicatorInstance)
|
||
|
{
|
||
|
float maxDistance = 1000f;
|
||
|
if (Physics.Raycast(GetAimRay(), out var hitInfo, maxDistance, LayerIndex.world.mask))
|
||
|
{
|
||
|
areaIndicatorInstance.transform.position = hitInfo.point;
|
||
|
areaIndicatorInstance.transform.up = hitInfo.normal;
|
||
|
}
|
||
|
}
|
||
|
else if (!EffectManager.ShouldUsePooledEffect(areaIndicatorPrefab))
|
||
|
{
|
||
|
areaIndicatorInstance = Object.Instantiate(areaIndicatorPrefab);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_emh_areaIndicatorInstance = EffectManager.GetAndActivatePooledEffect(areaIndicatorPrefab, Vector3.zero, Quaternion.identity);
|
||
|
areaIndicatorInstance = _emh_areaIndicatorInstance.gameObject;
|
||
|
}
|
||
|
radius = Util.Remap(Mathf.Clamp01(stopwatch / chargeDuration), 0f, 1f, minMeteorRadius, maxMeteorRadius);
|
||
|
_cachedScale.x = radius;
|
||
|
_cachedScale.y = radius;
|
||
|
_cachedScale.z = radius;
|
||
|
areaIndicatorInstance.transform.localScale = _cachedScale;
|
||
|
}
|
||
|
|
||
|
public override void Update()
|
||
|
{
|
||
|
base.Update();
|
||
|
UpdateAreaIndicator();
|
||
|
}
|
||
|
|
||
|
public override void FixedUpdate()
|
||
|
{
|
||
|
base.FixedUpdate();
|
||
|
stopwatch += GetDeltaTime();
|
||
|
if ((stopwatch >= duration || base.inputBank.skill2.justReleased) && base.isAuthority)
|
||
|
{
|
||
|
fireMeteor = true;
|
||
|
outer.SetNextStateToMain();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void OnExit()
|
||
|
{
|
||
|
EffectManager.SimpleMuzzleFlash(muzzleflashEffect, base.gameObject, "Muzzle", transmit: false);
|
||
|
if ((bool)areaIndicatorInstance)
|
||
|
{
|
||
|
if (fireMeteor)
|
||
|
{
|
||
|
float num = Util.Remap(Mathf.Clamp01(stopwatch / chargeDuration), 0f, 1f, minDamageCoefficient, maxDamageCoefficient);
|
||
|
if (_effectData == null)
|
||
|
{
|
||
|
_effectData = new EffectData();
|
||
|
}
|
||
|
_effectData.origin = areaIndicatorInstance.transform.position;
|
||
|
_effectData.scale = radius;
|
||
|
EffectManager.SpawnEffect(meteorEffect, _effectData, transmit: true);
|
||
|
if (blastAttack == null)
|
||
|
{
|
||
|
blastAttack = new BlastAttack();
|
||
|
}
|
||
|
blastAttack.radius = radius;
|
||
|
blastAttack.procCoefficient = procCoefficient;
|
||
|
blastAttack.position = areaIndicatorInstance.transform.position;
|
||
|
blastAttack.attacker = base.gameObject;
|
||
|
blastAttack.crit = Util.CheckRoll(base.characterBody.crit, base.characterBody.master);
|
||
|
blastAttack.baseDamage = base.characterBody.damage * num;
|
||
|
blastAttack.falloffModel = BlastAttack.FalloffModel.SweetSpot;
|
||
|
blastAttack.baseForce = force;
|
||
|
blastAttack.teamIndex = TeamComponent.GetObjectTeam(blastAttack.attacker);
|
||
|
blastAttack.Fire();
|
||
|
}
|
||
|
if (_emh_areaIndicatorInstance != null && _emh_areaIndicatorInstance.OwningPool != null)
|
||
|
{
|
||
|
_emh_areaIndicatorInstance.OwningPool.ReturnObject(_emh_areaIndicatorInstance);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
EntityState.Destroy(areaIndicatorInstance.gameObject);
|
||
|
}
|
||
|
areaIndicatorInstance = null;
|
||
|
_emh_areaIndicatorInstance = null;
|
||
|
}
|
||
|
base.OnExit();
|
||
|
}
|
||
|
}
|