168 lines
5.1 KiB
C#
168 lines
5.1 KiB
C#
using RoR2;
|
|
using RoR2.Projectile;
|
|
using RoR2.UI;
|
|
using UnityEngine;
|
|
|
|
namespace EntityStates.Mage.Weapon;
|
|
|
|
public class PrepWall : BaseState
|
|
{
|
|
public static float baseDuration;
|
|
|
|
public static GameObject areaIndicatorPrefab;
|
|
|
|
public static GameObject projectilePrefab;
|
|
|
|
public static float damageCoefficient;
|
|
|
|
public static GameObject muzzleflashEffect;
|
|
|
|
public static GameObject goodCrosshairPrefab;
|
|
|
|
public static GameObject badCrosshairPrefab;
|
|
|
|
public static string prepWallSoundString;
|
|
|
|
public static float maxDistance;
|
|
|
|
public static string fireSoundString;
|
|
|
|
public static float maxSlopeAngle;
|
|
|
|
private float duration;
|
|
|
|
private float stopwatch;
|
|
|
|
private bool goodPlacement;
|
|
|
|
private GameObject areaIndicatorInstance;
|
|
|
|
private CrosshairUtils.OverrideRequest crosshairOverrideRequest;
|
|
|
|
private EffectManagerHelper _emh_areaIndicatorInstance;
|
|
|
|
private static int PrepWallStateHash = Animator.StringToHash("PrepWall");
|
|
|
|
private static int PrepWallParamHash = Animator.StringToHash("PrepWall.playbackRate");
|
|
|
|
private static int FireWallStateHash = Animator.StringToHash("FireWall");
|
|
|
|
public override void Reset()
|
|
{
|
|
base.Reset();
|
|
duration = 0f;
|
|
stopwatch = 0f;
|
|
goodPlacement = false;
|
|
areaIndicatorInstance = null;
|
|
_emh_areaIndicatorInstance = null;
|
|
}
|
|
|
|
public override void OnEnter()
|
|
{
|
|
base.OnEnter();
|
|
duration = baseDuration / attackSpeedStat;
|
|
base.characterBody.SetAimTimer(duration + 2f);
|
|
PlayAnimation("Gesture, Additive", PrepWallStateHash, PrepWallParamHash, duration);
|
|
Util.PlaySound(prepWallSoundString, base.gameObject);
|
|
if (!EffectManager.ShouldUsePooledEffect(areaIndicatorPrefab))
|
|
{
|
|
areaIndicatorInstance = Object.Instantiate(areaIndicatorPrefab);
|
|
}
|
|
else
|
|
{
|
|
_emh_areaIndicatorInstance = EffectManager.GetAndActivatePooledEffect(areaIndicatorPrefab, Vector3.zero, Quaternion.identity);
|
|
areaIndicatorInstance = _emh_areaIndicatorInstance.gameObject;
|
|
}
|
|
UpdateAreaIndicator();
|
|
}
|
|
|
|
private void UpdateAreaIndicator()
|
|
{
|
|
bool flag = goodPlacement;
|
|
goodPlacement = false;
|
|
areaIndicatorInstance.SetActive(value: true);
|
|
if ((bool)areaIndicatorInstance)
|
|
{
|
|
float num = maxDistance;
|
|
float extraRaycastDistance = 0f;
|
|
Ray aimRay = GetAimRay();
|
|
if (Physics.Raycast(CameraRigController.ModifyAimRayIfApplicable(aimRay, base.gameObject, out extraRaycastDistance), out var hitInfo, num + extraRaycastDistance, LayerIndex.world.mask))
|
|
{
|
|
areaIndicatorInstance.transform.position = hitInfo.point;
|
|
areaIndicatorInstance.transform.up = hitInfo.normal;
|
|
areaIndicatorInstance.transform.forward = -aimRay.direction;
|
|
goodPlacement = Vector3.Angle(Vector3.up, hitInfo.normal) < maxSlopeAngle;
|
|
}
|
|
if (flag != goodPlacement || crosshairOverrideRequest == null)
|
|
{
|
|
crosshairOverrideRequest?.Dispose();
|
|
GameObject crosshairPrefab = (goodPlacement ? goodCrosshairPrefab : badCrosshairPrefab);
|
|
crosshairOverrideRequest = CrosshairUtils.RequestOverrideForBody(base.characterBody, crosshairPrefab, CrosshairUtils.OverridePriority.Skill);
|
|
}
|
|
}
|
|
areaIndicatorInstance.SetActive(goodPlacement);
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
base.Update();
|
|
UpdateAreaIndicator();
|
|
}
|
|
|
|
public override void FixedUpdate()
|
|
{
|
|
base.FixedUpdate();
|
|
stopwatch += GetDeltaTime();
|
|
if (stopwatch >= duration && !base.inputBank.skill3.down && base.isAuthority)
|
|
{
|
|
outer.SetNextStateToMain();
|
|
}
|
|
}
|
|
|
|
public override void OnExit()
|
|
{
|
|
if (!outer.destroying)
|
|
{
|
|
if (goodPlacement)
|
|
{
|
|
PlayAnimation("Gesture, Additive", FireWallStateHash);
|
|
Util.PlaySound(fireSoundString, base.gameObject);
|
|
if ((bool)areaIndicatorInstance && base.isAuthority)
|
|
{
|
|
EffectManager.SimpleMuzzleFlash(muzzleflashEffect, base.gameObject, "MuzzleLeft", transmit: true);
|
|
EffectManager.SimpleMuzzleFlash(muzzleflashEffect, base.gameObject, "MuzzleRight", transmit: true);
|
|
Vector3 forward = areaIndicatorInstance.transform.forward;
|
|
forward.y = 0f;
|
|
forward.Normalize();
|
|
Vector3 vector = Vector3.Cross(Vector3.up, forward);
|
|
bool crit = Util.CheckRoll(critStat, base.characterBody.master);
|
|
ProjectileManager.instance.FireProjectile(projectilePrefab, areaIndicatorInstance.transform.position + Vector3.up, Util.QuaternionSafeLookRotation(vector), base.gameObject, damageStat * damageCoefficient, 0f, crit);
|
|
ProjectileManager.instance.FireProjectile(projectilePrefab, areaIndicatorInstance.transform.position + Vector3.up, Util.QuaternionSafeLookRotation(-vector), base.gameObject, damageStat * damageCoefficient, 0f, crit);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
base.skillLocator.utility.AddOneStock();
|
|
PlayCrossfade("Gesture, Additive", "BufferEmpty", 0.2f);
|
|
}
|
|
}
|
|
if (_emh_areaIndicatorInstance != null && _emh_areaIndicatorInstance.OwningPool != null)
|
|
{
|
|
_emh_areaIndicatorInstance.OwningPool.ReturnObject(_emh_areaIndicatorInstance);
|
|
}
|
|
else
|
|
{
|
|
EntityState.Destroy(areaIndicatorInstance.gameObject);
|
|
}
|
|
areaIndicatorInstance = null;
|
|
_emh_areaIndicatorInstance = null;
|
|
crosshairOverrideRequest?.Dispose();
|
|
base.OnExit();
|
|
}
|
|
|
|
public override InterruptPriority GetMinimumInterruptPriority()
|
|
{
|
|
return InterruptPriority.Pain;
|
|
}
|
|
}
|