using Barotrauma.Items.Components; using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; namespace Barotrauma { class ShipIssueWorkerOperateWeapons : ShipIssueWorkerItem { public override float RedundantIssueModifier => 0.8f; private readonly List targetingImportances = new List(); public override bool AllowEasySwitching => true; public ShipIssueWorkerOperateWeapons(ShipCommandManager shipCommandManager, Order order) : base(shipCommandManager, order) { } float GetTargetingImportance(Entity entity) { float currentDistanceToEnemy = Vector2.Distance(entity.WorldPosition, TargetItem.WorldPosition); if (currentDistanceToEnemy > Sonar.DefaultSonarRange) { return 0.0f; } float importance = MathHelper.Clamp(100 - (currentDistanceToEnemy / 100f), MaxImportance * 0.1f, MaxImportance * 0.5f); if (TargetItem.Submarine != null && importance > 0.0f) { if (TargetItemComponent is Turret turret) { if (!turret.IsWithinAimingRadius(entity.WorldPosition)) { importance *= 0.1f; } } else { Vector2 dir = entity.WorldPosition - TargetItem.WorldPosition; Vector2 submarineDir = TargetItem.WorldPosition - TargetItem.Submarine.WorldPosition; if (Vector2.Dot(dir, submarineDir) < 0) { //direction from the weapon to the target is opposite to the direction from the sub to the weapon // = the turret is most likely on the wrong side of the sub, reduce importance importance *= 0.1f; } } } return importance; } public override void CalculateImportanceSpecific() { targetingImportances.Clear(); foreach (Character character in shipCommandManager.EnemyCharacters) { targetingImportances.Add(GetTargetingImportance(character)); } // there should maybe be additional logic for targeting and destroying spires, because they currently cause some issues with pathing if (targetingImportances.Any(i => i > 0)) { targetingImportances.Sort(); Importance = Math.Max(targetingImportances.TakeLast(3).Sum(), ShipCommandManager.MinimumIssueThreshold); } if (TargetItemComponent is Turret turret && !turret.HasPowerToShoot()) { //operate (= recharge the turrets) with low priority if they're out of power //if something else (issues with reactor or the electrical grid) is preventing them from being charged, fixing those issues should take priority Importance = Math.Max(ShipCommandManager.MinimumIssueThreshold / RedundantIssueModifier, Importance); return; } } } }