using System.Collections.Generic; using System.Linq; using Questionable.Model; using Questionable.Model.Questing; namespace Questionable.Validation.Validators; internal sealed class UniqueStartStopValidator : IQuestValidator { public IEnumerable Validate(Quest quest) { bool skipMissingStartStop = !(quest.Id is QuestId); List<(QuestSequence Sequence, int StepId, QuestStep Step)> questAccepts = (from x in FindQuestStepsWithInteractionType(quest, new List { EInteractionType.AcceptQuest }) where x.Step.PickUpQuestId == null select x).ToList(); foreach (var item in questAccepts) { if (item.Sequence.Sequence != 0 || item.StepId != quest.FindSequence(0).Steps.Count - 1) { yield return new ValidationIssue { PathType = EPathType.Quest, Id = quest.Id.ToString(), Location = SchemaValidationHelper.FormatQuestLocation(item.Sequence.Sequence, item.StepId), Type = EIssueType.UnexpectedAcceptQuestStep, Severity = EIssueSeverity.Error, Description = "Unexpected AcceptQuest step" }; } } if (!skipMissingStartStop && quest.FindSequence(0) != null && questAccepts.Count == 0) { yield return new ValidationIssue { PathType = EPathType.Quest, Id = quest.Id.ToString(), Location = SchemaValidationHelper.FormatQuestLocation(0, null), Type = EIssueType.MissingQuestAccept, Severity = EIssueSeverity.Error, Description = "No AcceptQuest step" }; } List<(QuestSequence Sequence, int StepId, QuestStep Step)> questCompletes = (from x in FindQuestStepsWithInteractionType(quest, new List { EInteractionType.CompleteQuest }) where x.Step.TurnInQuestId == null select x).ToList(); foreach (var item2 in questCompletes) { if (item2.Sequence.Sequence != byte.MaxValue || item2.StepId != quest.FindSequence(byte.MaxValue).Steps.Count - 1) { yield return new ValidationIssue { PathType = EPathType.Quest, Id = quest.Id.ToString(), Location = SchemaValidationHelper.FormatQuestLocation(item2.Sequence.Sequence, item2.StepId), Type = EIssueType.UnexpectedCompleteQuestStep, Severity = EIssueSeverity.Error, Description = "Unexpected CompleteQuest step" }; } } if (!skipMissingStartStop && quest.FindSequence(byte.MaxValue) != null && questCompletes.Count == 0) { yield return new ValidationIssue { PathType = EPathType.Quest, Id = quest.Id.ToString(), Location = SchemaValidationHelper.FormatQuestLocation((byte)byte.MaxValue, null), Type = EIssueType.MissingQuestComplete, Severity = EIssueSeverity.Error, Description = "No CompleteQuest step" }; } } private static IEnumerable<(QuestSequence Sequence, int StepId, QuestStep Step)> FindQuestStepsWithInteractionType(Quest quest, List interactionType) { return from x in quest.AllSteps() where interactionType.Contains(x.Step.InteractionType) select x; } }