using Barotrauma.Networking; using System.Collections.Generic; using System.Linq; namespace Barotrauma { partial class Traitor { public sealed class GoalKillTarget : Goal { public TraitorMission.CharacterFilter Filter { get; private set; } public List Targets { get; private set; } public override IEnumerable InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[targetname]", "[causeofdeath]", "[targethullname]" }); public override IEnumerable InfoTextValues(Traitor traitor) => base.InfoTextValues(traitor).Concat(new string[] { traitor.Mission.GetTargetNames(Targets) ?? "(unknown)", GetCauseOfDeath().Value, targetHull != null ? TextManager.Get($"roomname.{targetHull}").Value : string.Empty }); private bool isCompleted = false; public override bool IsCompleted => isCompleted; public override bool IsEnemy(Character character) => base.IsEnemy(character) || (!isCompleted && Targets.Contains(character)); private CauseOfDeathType requiredCauseOfDeath; private string afflictionId; private string targetHull; private int targetCount; private float targetPercentage; public override void Update(float deltaTime) { base.Update(deltaTime); isCompleted = DoesDeathMatchCriteria(); } private bool DoesDeathMatchCriteria() { if (Targets == null || Targets.Any(t => !t.IsDead)) return false; bool typeMatch = false; for (int i = 0; i < Targets.Count; i++) { // No specified cause of death required or missing cause of death if (requiredCauseOfDeath == CauseOfDeathType.Unknown || Targets[i].CauseOfDeath == null) { typeMatch = true; } else { switch (Targets[i].CauseOfDeath.Type) { // If a cause of death is labeled as unknown, side with the traitor and accept this regardless of the required type case CauseOfDeathType.Unknown: typeMatch = true; break; case CauseOfDeathType.Pressure: case CauseOfDeathType.Suffocation: case CauseOfDeathType.Drowning: typeMatch = requiredCauseOfDeath == Targets[i].CauseOfDeath.Type; break; case CauseOfDeathType.Affliction: typeMatch = Targets[i].CauseOfDeath.Type == requiredCauseOfDeath && Targets[i].CauseOfDeath.Affliction.Identifier == afflictionId; break; case CauseOfDeathType.Disconnected: typeMatch = false; break; } } if (targetHull != null) { if (Targets[i].CurrentHull != null) { if (typeMatch && Targets[i].CurrentHull.RoomName == targetHull || Targets[i].CurrentHull.RoomName.Contains(targetHull)) { continue; } else { return false; } } else { // Outside the submarine, not supported for now return false; } } else { if (typeMatch) { continue; } else { return false; } } } return true; } private LocalizedString GetCauseOfDeath() { if (requiredCauseOfDeath != CauseOfDeathType.Affliction || afflictionId == string.Empty) { return requiredCauseOfDeath.ToString().ToLower(); } else { return TextManager.Get($"afflictionname.{afflictionId}").ToLower(); } } public override bool Start(Traitor traitor) { if (!base.Start(traitor)) { return false; } Targets = traitor.Mission.FindKillTarget(traitor.Character, Filter, targetCount, targetPercentage); return Targets != null && !Targets.All(t => t.IsDead); } public GoalKillTarget(TraitorMission.CharacterFilter filter, CauseOfDeathType requiredCauseOfDeath, string afflictionId, string targetHull, int targetCount, float targetPercentage) : base() { Filter = filter; this.requiredCauseOfDeath = requiredCauseOfDeath; this.afflictionId = afflictionId; this.targetHull = targetHull; this.targetCount = targetCount; this.targetPercentage = targetPercentage / 100f; if (this.targetPercentage < 1f) { if (this.requiredCauseOfDeath == CauseOfDeathType.Unknown && targetHull == null) { InfoTextId = "traitorgoalkilltargetinfo"; } else if (this.requiredCauseOfDeath != CauseOfDeathType.Unknown && targetHull == null) { InfoTextId = "traitorgoalkilltargetinfowithcause"; } else if (this.requiredCauseOfDeath == CauseOfDeathType.Unknown && targetHull != null) { InfoTextId = "traitorgoalkilltargetinfowithhull"; } else if (this.requiredCauseOfDeath != CauseOfDeathType.Unknown && targetHull != null) { InfoTextId = "traitorgoalkilltargetinfowithcauseandhull"; } } else { InfoTextId = "traitorgoalkilleveryoneinfo"; } } } } }