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 safeZones = new List(); private Dictionary characterBodyToStacks = new Dictionary(); 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 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()) { 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 GetAffectedBodies() { TeamIndex currentTeam; if ((bool)teamFilter) { if (invertTeamFilter) { currentTeam = TeamIndex.Neutral; while (currentTeam < TeamIndex.Count) { IEnumerable affectedBodiesOnTeam = GetAffectedBodiesOnTeam(currentTeam); foreach (CharacterBody item in affectedBodiesOnTeam) { yield return item; } TeamIndex teamIndex = currentTeam + 1; currentTeam = teamIndex; } yield break; } IEnumerable affectedBodiesOnTeam2 = GetAffectedBodiesOnTeam(teamFilter.teamIndex); foreach (CharacterBody item2 in affectedBodiesOnTeam2) { yield return item2; } yield break; } currentTeam = TeamIndex.Neutral; while (currentTeam < TeamIndex.Count) { IEnumerable affectedBodiesOnTeam3 = GetAffectedBodiesOnTeam(currentTeam); foreach (CharacterBody item3 in affectedBodiesOnTeam3) { yield return item3; } TeamIndex teamIndex = currentTeam + 1; currentTeam = teamIndex; } } public IEnumerable 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() { } }