using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Xml.Linq; namespace Barotrauma { partial class AITarget { public static List List = new List(); public Entity Entity { get; private set; } private float soundRange; private float sightRange; public float SoundRange { get { return soundRange; } set { soundRange = MathHelper.Clamp(value, MinSoundRange, MaxSoundRange); } } public float SightRange { get { return sightRange; } set { sightRange = MathHelper.Clamp(value, MinSightRange, MaxSightRange); } } private float sectorRad = MathHelper.TwoPi; public float SectorDegrees { get { return MathHelper.ToDegrees(sectorRad); } set { sectorRad = MathHelper.ToRadians(value); } } private Vector2 sectorDir; public Vector2 SectorDir { get { return sectorDir; } set { if (!MathUtils.IsValid(value)) { string errorMsg = "Invalid AITarget sector direction (" + value + ")\n" + Environment.StackTrace; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("AITarget.SectorDir:" + Entity?.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); return; } sectorDir = value; } } public string SonarLabel; public bool Enabled = true; public float MinSoundRange, MinSightRange; public float MaxSoundRange = float.MaxValue, MaxSightRange = float.MaxValue; public Vector2 WorldPosition { get { if (Entity == null || Entity.Removed) { #if DEBUG DebugConsole.ThrowError("Attempted to access a removed AITarget\n" + Environment.StackTrace); #endif GameAnalyticsManager.AddErrorEventOnce("AITarget.WorldPosition:EntityRemoved", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, "Attempted to access a removed AITarget\n" + Environment.StackTrace); return Vector2.Zero; } return Entity.WorldPosition; } } public Vector2 SimPosition { get { if (Entity == null || Entity.Removed) { #if DEBUG DebugConsole.ThrowError("Attempted to access a removed AITarget\n" + Environment.StackTrace); #endif GameAnalyticsManager.AddErrorEventOnce("AITarget.WorldPosition:EntityRemoved", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, "Attempted to access a removed AITarget\n" + Environment.StackTrace); return Vector2.Zero; } return Entity.SimPosition; } } public AITarget(Entity e, XElement element) : this(e) { SightRange = element.GetAttributeFloat("sightrange", 0.0f); SoundRange = element.GetAttributeFloat("soundrange", 0.0f); MinSightRange = element.GetAttributeFloat("minsightrange", SightRange); MinSoundRange = element.GetAttributeFloat("minsoundrange", SoundRange); MaxSightRange = element.GetAttributeFloat("maxsightrange", SightRange); MaxSoundRange = element.GetAttributeFloat("maxsoundrange", SoundRange); SonarLabel = element.GetAttributeString("sonarlabel", ""); } public AITarget(Entity e, float sightRange = 3000, float soundRange = 0) { Entity = e; SightRange = sightRange; SoundRange = soundRange; List.Add(this); } public bool IsWithinSector(Vector2 worldPosition) { if (sectorRad >= MathHelper.TwoPi) return true; Vector2 diff = worldPosition - WorldPosition; return MathUtils.GetShortestAngle(MathUtils.VectorToAngle(diff), MathUtils.VectorToAngle(sectorDir)) <= sectorRad * 0.5f; } public void Remove() { List.Remove(this); Entity = null; } } }