r2mods/ilspy_dump/ror2_csproj/RoR2/BuffWard.cs

264 lines
5.4 KiB
C#

using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
namespace RoR2;
[RequireComponent(typeof(TeamFilter))]
public class BuffWard : NetworkBehaviour
{
public enum BuffWardShape
{
Sphere,
VerticalTube,
Count
}
[Tooltip("The shape of the area")]
public BuffWardShape shape;
[Tooltip("The area of effect.")]
[SyncVar]
public float radius;
[Tooltip("How long between buff pulses in the area of effect.")]
public float interval = 1f;
[Tooltip("The child range indicator object. Will be scaled to the radius.")]
public Transform rangeIndicator;
[Tooltip("The buff type to grant")]
public BuffDef buffDef;
[Tooltip("The buff duration")]
public float buffDuration;
[Tooltip("Should the ward be floored on start")]
public bool floorWard;
[Tooltip("Does the ward disappear over time?")]
public bool expires;
[Tooltip("If set, applies to all teams BUT the one selected.")]
public bool invertTeamFilter;
public float expireDuration;
public bool animateRadius;
public AnimationCurve radiusCoefficientCurve;
[Tooltip("If set, the ward will give you this amount of time to play removal effects.")]
public float removalTime;
private bool needsRemovalTime;
public string removalSoundString = "";
public UnityEvent onRemoval;
public bool requireGrounded;
private TeamFilter teamFilter;
private float buffTimer;
private float rangeIndicatorScaleVelocity;
private float stopwatch;
private float calculatedRadius;
public float Networkradius
{
get
{
return radius;
}
[param: In]
set
{
SetSyncVar(value, ref radius, 1u);
}
}
private void Awake()
{
teamFilter = GetComponent<TeamFilter>();
}
private void OnEnable()
{
if ((bool)rangeIndicator)
{
rangeIndicator.gameObject.SetActive(value: true);
}
}
private void OnDisable()
{
if ((bool)rangeIndicator)
{
rangeIndicator.gameObject.SetActive(value: false);
}
}
private void Start()
{
if (removalTime > 0f)
{
needsRemovalTime = true;
}
if (floorWard && Physics.Raycast(base.transform.position, Vector3.down, out var hitInfo, 500f, LayerIndex.world.mask))
{
base.transform.position = hitInfo.point;
base.transform.up = hitInfo.normal;
}
if ((bool)rangeIndicator && expires)
{
ScaleParticleSystemDuration component = rangeIndicator.GetComponent<ScaleParticleSystemDuration>();
if ((bool)component)
{
component.newDuration = expireDuration;
}
}
}
private void Update()
{
calculatedRadius = (animateRadius ? (radius * radiusCoefficientCurve.Evaluate(stopwatch / expireDuration)) : radius);
stopwatch += Time.deltaTime;
if (expires && NetworkServer.active)
{
if (needsRemovalTime)
{
if (stopwatch >= expireDuration - removalTime)
{
needsRemovalTime = false;
Util.PlaySound(removalSoundString, base.gameObject);
onRemoval.Invoke();
}
}
else if (expireDuration <= stopwatch)
{
Object.Destroy(base.gameObject);
}
}
if ((bool)rangeIndicator)
{
float num = Mathf.SmoothDamp(rangeIndicator.localScale.x, calculatedRadius, ref rangeIndicatorScaleVelocity, 0.2f);
rangeIndicator.localScale = new Vector3(num, num, num);
}
}
private void FixedUpdate()
{
if (!NetworkServer.active)
{
return;
}
buffTimer -= Time.fixedDeltaTime;
if (!(buffTimer <= 0f))
{
return;
}
buffTimer = interval;
float radiusSqr = calculatedRadius * calculatedRadius;
Vector3 position = base.transform.position;
if (invertTeamFilter)
{
for (TeamIndex teamIndex = TeamIndex.Neutral; teamIndex < TeamIndex.Count; teamIndex++)
{
if (teamIndex != teamFilter.teamIndex)
{
BuffTeam(TeamComponent.GetTeamMembers(teamIndex), radiusSqr, position);
}
}
}
else
{
BuffTeam(TeamComponent.GetTeamMembers(teamFilter.teamIndex), radiusSqr, position);
}
}
private void BuffTeam(IEnumerable<TeamComponent> recipients, float radiusSqr, Vector3 currentPosition)
{
if (!NetworkServer.active || !buffDef)
{
return;
}
foreach (TeamComponent recipient in recipients)
{
Vector3 vector = recipient.transform.position - currentPosition;
if (shape == BuffWardShape.VerticalTube)
{
vector.y = 0f;
}
if (vector.sqrMagnitude <= radiusSqr)
{
CharacterBody component = recipient.GetComponent<CharacterBody>();
if ((bool)component && (!requireGrounded || !component.characterMotor || component.characterMotor.isGrounded))
{
component.AddTimedBuff(buffDef.buffIndex, buffDuration);
}
}
}
}
private void OnValidate()
{
if (!buffDef)
{
Debug.LogWarningFormat(this, "BuffWard {0} has no buff specified.", this);
}
}
private void UNetVersion()
{
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (forceAll)
{
writer.Write(radius);
return true;
}
bool flag = false;
if ((base.syncVarDirtyBits & (true ? 1u : 0u)) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(radius);
}
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
}
return flag;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (initialState)
{
radius = reader.ReadSingle();
return;
}
int num = (int)reader.ReadPackedUInt32();
if (((uint)num & (true ? 1u : 0u)) != 0)
{
radius = reader.ReadSingle();
}
}
public override void PreStartClient()
{
}
}