264 lines
6.3 KiB
C#
264 lines
6.3 KiB
C#
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Networking;
|
||
|
|
||
|
namespace RoR2;
|
||
|
|
||
|
public class FogDamageController : NetworkBehaviour
|
||
|
{
|
||
|
[Tooltip("Used to control which teams to damage. If it's null, it damages ALL teams")]
|
||
|
[SerializeField]
|
||
|
private TeamFilter teamFilter;
|
||
|
|
||
|
[Tooltip("If true, it damages all OTHER teams than the one specified. If false, it damages the specified team.")]
|
||
|
[SerializeField]
|
||
|
private bool invertTeamFilter;
|
||
|
|
||
|
[Tooltip("The period in seconds in between each tick")]
|
||
|
[SerializeField]
|
||
|
private float tickPeriodSeconds;
|
||
|
|
||
|
[Range(0f, 1f)]
|
||
|
[SerializeField]
|
||
|
[Tooltip("The fraction of combined health to deduct per second. Note that damage is actually applied per tick, not per second.")]
|
||
|
private float healthFractionPerSecond;
|
||
|
|
||
|
[SerializeField]
|
||
|
[Tooltip("The coefficient to increase the damage by, for every tick they take outside the zone.")]
|
||
|
private float healthFractionRampCoefficientPerSecond;
|
||
|
|
||
|
[Tooltip("The buff to apply when in danger, i.e not in the safe zone.")]
|
||
|
[SerializeField]
|
||
|
private BuffDef dangerBuffDef;
|
||
|
|
||
|
[SerializeField]
|
||
|
private float dangerBuffDuration;
|
||
|
|
||
|
[Tooltip("An initial list of safe zones behaviors which protect bodies from the fog")]
|
||
|
[SerializeField]
|
||
|
private BaseZoneBehavior[] initialSafeZones;
|
||
|
|
||
|
private float dictionaryValidationTimer;
|
||
|
|
||
|
private float damageTimer;
|
||
|
|
||
|
private List<IZone> safeZones = new List<IZone>();
|
||
|
|
||
|
private Dictionary<CharacterBody, int> characterBodyToStacks = new Dictionary<CharacterBody, int>();
|
||
|
|
||
|
private void Start()
|
||
|
{
|
||
|
BaseZoneBehavior[] array = initialSafeZones;
|
||
|
foreach (BaseZoneBehavior zone in array)
|
||
|
{
|
||
|
AddSafeZone(zone);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void AddSafeZone(IZone zone)
|
||
|
{
|
||
|
safeZones.Add(zone);
|
||
|
}
|
||
|
|
||
|
public void RemoveSafeZone(IZone zone)
|
||
|
{
|
||
|
safeZones.Remove(zone);
|
||
|
}
|
||
|
|
||
|
private void FixedUpdate()
|
||
|
{
|
||
|
MyFixedUpdate(Time.fixedDeltaTime);
|
||
|
}
|
||
|
|
||
|
private void MyFixedUpdate(float deltaTime)
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
damageTimer += deltaTime;
|
||
|
dictionaryValidationTimer += deltaTime;
|
||
|
if (dictionaryValidationTimer > 60f)
|
||
|
{
|
||
|
dictionaryValidationTimer = 0f;
|
||
|
CharacterBody[] array = new CharacterBody[characterBodyToStacks.Keys.Count];
|
||
|
characterBodyToStacks.Keys.CopyTo(array, 0);
|
||
|
for (int i = 0; i < array.Length; i++)
|
||
|
{
|
||
|
if (!array[i])
|
||
|
{
|
||
|
characterBodyToStacks.Remove(array[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
while (damageTimer > tickPeriodSeconds)
|
||
|
{
|
||
|
damageTimer -= tickPeriodSeconds;
|
||
|
if ((bool)teamFilter)
|
||
|
{
|
||
|
if (invertTeamFilter)
|
||
|
{
|
||
|
for (TeamIndex teamIndex = TeamIndex.Neutral; teamIndex < TeamIndex.Count; teamIndex++)
|
||
|
{
|
||
|
if (teamIndex != teamFilter.teamIndex && teamIndex != TeamIndex.None && teamIndex != 0)
|
||
|
{
|
||
|
EvaluateTeam(teamIndex);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
EvaluateTeam(teamFilter.teamIndex);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (TeamIndex teamIndex2 = TeamIndex.Neutral; teamIndex2 < TeamIndex.Count; teamIndex2++)
|
||
|
{
|
||
|
EvaluateTeam(teamIndex2);
|
||
|
}
|
||
|
}
|
||
|
foreach (KeyValuePair<CharacterBody, int> characterBodyToStack in characterBodyToStacks)
|
||
|
{
|
||
|
CharacterBody key = characterBodyToStack.Key;
|
||
|
if (!key || !key.transform || !key.healthComponent)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
int num = characterBodyToStack.Value - 1;
|
||
|
float num2 = healthFractionPerSecond * (1f + (float)num * healthFractionRampCoefficientPerSecond * tickPeriodSeconds) * tickPeriodSeconds * key.healthComponent.fullCombinedHealth;
|
||
|
if (num2 > 0f)
|
||
|
{
|
||
|
if (key.master != null && (bool)key.master.GetComponent<DevotedLemurianController>())
|
||
|
{
|
||
|
num2 *= 0.5f;
|
||
|
}
|
||
|
key.healthComponent.TakeDamage(new DamageInfo
|
||
|
{
|
||
|
damage = num2,
|
||
|
position = key.corePosition,
|
||
|
damageType = (DamageType.BypassArmor | DamageType.BypassBlock),
|
||
|
damageColorIndex = DamageColorIndex.Void
|
||
|
});
|
||
|
}
|
||
|
if ((bool)dangerBuffDef)
|
||
|
{
|
||
|
key.AddTimedBuff(dangerBuffDef, dangerBuffDuration);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public IEnumerable<CharacterBody> GetAffectedBodies()
|
||
|
{
|
||
|
TeamIndex currentTeam;
|
||
|
if ((bool)teamFilter)
|
||
|
{
|
||
|
if (invertTeamFilter)
|
||
|
{
|
||
|
currentTeam = TeamIndex.Neutral;
|
||
|
while (currentTeam < TeamIndex.Count)
|
||
|
{
|
||
|
IEnumerable<CharacterBody> affectedBodiesOnTeam = GetAffectedBodiesOnTeam(currentTeam);
|
||
|
foreach (CharacterBody item in affectedBodiesOnTeam)
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
TeamIndex teamIndex = currentTeam + 1;
|
||
|
currentTeam = teamIndex;
|
||
|
}
|
||
|
yield break;
|
||
|
}
|
||
|
IEnumerable<CharacterBody> affectedBodiesOnTeam2 = GetAffectedBodiesOnTeam(teamFilter.teamIndex);
|
||
|
foreach (CharacterBody item2 in affectedBodiesOnTeam2)
|
||
|
{
|
||
|
yield return item2;
|
||
|
}
|
||
|
yield break;
|
||
|
}
|
||
|
currentTeam = TeamIndex.Neutral;
|
||
|
while (currentTeam < TeamIndex.Count)
|
||
|
{
|
||
|
IEnumerable<CharacterBody> affectedBodiesOnTeam3 = GetAffectedBodiesOnTeam(currentTeam);
|
||
|
foreach (CharacterBody item3 in affectedBodiesOnTeam3)
|
||
|
{
|
||
|
yield return item3;
|
||
|
}
|
||
|
TeamIndex teamIndex = currentTeam + 1;
|
||
|
currentTeam = teamIndex;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public IEnumerable<CharacterBody> GetAffectedBodiesOnTeam(TeamIndex teamIndex)
|
||
|
{
|
||
|
foreach (TeamComponent teamMember in TeamComponent.GetTeamMembers(teamIndex))
|
||
|
{
|
||
|
CharacterBody body = teamMember.body;
|
||
|
bool flag = false;
|
||
|
foreach (IZone safeZone in safeZones)
|
||
|
{
|
||
|
if (safeZone.IsInBounds(teamMember.transform.position))
|
||
|
{
|
||
|
flag = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (!flag)
|
||
|
{
|
||
|
yield return body;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void EvaluateTeam(TeamIndex teamIndex)
|
||
|
{
|
||
|
foreach (TeamComponent teamMember in TeamComponent.GetTeamMembers(teamIndex))
|
||
|
{
|
||
|
CharacterBody body = teamMember.body;
|
||
|
bool flag = characterBodyToStacks.ContainsKey(body);
|
||
|
bool flag2 = false;
|
||
|
foreach (IZone safeZone in safeZones)
|
||
|
{
|
||
|
if (safeZone.IsInBounds(teamMember.transform.position))
|
||
|
{
|
||
|
flag2 = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (flag2)
|
||
|
{
|
||
|
if (flag)
|
||
|
{
|
||
|
characterBodyToStacks.Remove(body);
|
||
|
}
|
||
|
}
|
||
|
else if (!flag)
|
||
|
{
|
||
|
characterBodyToStacks.Add(body, 1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
characterBodyToStacks[body]++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void UNetVersion()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
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()
|
||
|
{
|
||
|
}
|
||
|
}
|