r2mods/ilspy_dump/ror2_csproj/RoR2.Projectile/ProjectileDirectionalTarget...

158 lines
4.2 KiB
C#

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Serialization;
namespace RoR2.Projectile;
[RequireComponent(typeof(ProjectileTargetComponent))]
[RequireComponent(typeof(TeamFilter))]
public class ProjectileDirectionalTargetFinder : MonoBehaviour
{
[Tooltip("How far ahead the projectile should look to find a target.")]
public float lookRange;
[Range(0f, 180f)]
[Tooltip("How wide the cone of vision for this projectile is in degrees. Limit is 180.")]
public float lookCone;
[Tooltip("How long before searching for a target.")]
public float targetSearchInterval = 0.5f;
[Tooltip("Will not search for new targets once it has one.")]
public bool onlySearchIfNoTarget;
[Tooltip("Allows the target to be lost if it's outside the acceptable range.")]
public bool allowTargetLoss;
[Tooltip("If set, targets can only be found when there is a free line of sight.")]
public bool testLoS;
[Tooltip("Whether or not airborne characters should be ignored.")]
public bool ignoreAir;
[Tooltip("The difference in altitude at which a result will be ignored.")]
[FormerlySerializedAs("altitudeTolerance")]
public float flierAltitudeTolerance = float.PositiveInfinity;
public UnityEvent onNewTargetFound;
[FormerlySerializedAs("ontargetLost")]
public UnityEvent onTargetLost;
private new Transform transform;
private TeamFilter teamFilter;
private ProjectileTargetComponent targetComponent;
private float searchTimer;
private bool hasTarget;
private bool hadTargetLastUpdate;
private BullseyeSearch bullseyeSearch;
private HurtBox lastFoundHurtBox;
private Transform lastFoundTransform;
private void Start()
{
if (!NetworkServer.active)
{
base.enabled = false;
return;
}
bullseyeSearch = new BullseyeSearch();
teamFilter = GetComponent<TeamFilter>();
targetComponent = GetComponent<ProjectileTargetComponent>();
transform = base.transform;
searchTimer = 0f;
}
private void FixedUpdate()
{
searchTimer -= Time.fixedDeltaTime;
if (!(searchTimer <= 0f))
{
return;
}
searchTimer += targetSearchInterval;
if (allowTargetLoss && (object)targetComponent.target != null && (object)lastFoundTransform == targetComponent.target && !PassesFilters(lastFoundHurtBox))
{
SetTarget(null);
}
if (!onlySearchIfNoTarget || targetComponent.target == null)
{
SearchForTarget();
}
hasTarget = targetComponent.target != null;
if (hadTargetLastUpdate != hasTarget)
{
if (hasTarget)
{
onNewTargetFound?.Invoke();
}
else
{
onTargetLost?.Invoke();
}
}
hadTargetLastUpdate = hasTarget;
}
private bool PassesFilters(HurtBox result)
{
CharacterBody body = result.healthComponent.body;
if (!body || (ignoreAir && body.isFlying))
{
return false;
}
if (body.isFlying && !float.IsInfinity(flierAltitudeTolerance) && flierAltitudeTolerance < Mathf.Abs(result.transform.position.y - transform.position.y))
{
return false;
}
return true;
}
private void SearchForTarget()
{
bullseyeSearch.teamMaskFilter = TeamMask.allButNeutral;
bullseyeSearch.teamMaskFilter.RemoveTeam(teamFilter.teamIndex);
bullseyeSearch.filterByLoS = testLoS;
bullseyeSearch.searchOrigin = transform.position;
bullseyeSearch.searchDirection = transform.forward;
bullseyeSearch.maxDistanceFilter = lookRange;
bullseyeSearch.sortMode = BullseyeSearch.SortMode.DistanceAndAngle;
bullseyeSearch.maxAngleFilter = lookCone;
bullseyeSearch.RefreshCandidates();
IEnumerable<HurtBox> source = bullseyeSearch.GetResults().Where(PassesFilters);
SetTarget(source.FirstOrDefault());
}
private void SetTarget(HurtBox hurtBox)
{
lastFoundHurtBox = hurtBox;
lastFoundTransform = hurtBox?.transform;
targetComponent.target = lastFoundTransform;
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Transform transform = base.transform;
Vector3 position = transform.position;
Gizmos.DrawWireSphere(position, lookRange);
Gizmos.DrawRay(position, transform.forward * lookRange);
Gizmos.DrawFrustum(position, lookCone * 2f, lookRange, 0f, 1f);
if (!float.IsInfinity(flierAltitudeTolerance))
{
Gizmos.DrawWireCube(position, new Vector3(lookRange * 2f, flierAltitudeTolerance * 2f, lookRange * 2f));
}
}
}