public void VisitNodeMovement(NodeMovement nm) { UsedCharacters.Add(nm.Character); switch (nm.MovementType) { case NodeMovement.MovementTypeEnum.Exit: if (!PresentCharacters.Contains(nm.Character)) { Report.AddMessage(ProjectReportMessage.MessageSeverity.Error, "A movement node is removing a character that is not in the scene.", nm); } else { PresentCharacters.Remove(nm.Character); } if (!PresentCharactersSide.ContainsKey(nm.MovementDirection) || PresentCharactersSide[nm.MovementDirection] != nm.Character) { Report.AddMessage(ProjectReportMessage.MessageSeverity.Error, "A movement node is removing a character from the wrong side or another character overwrote it.", nm); } else { PresentCharactersSide.Remove(nm.MovementDirection); } break; case NodeMovement.MovementTypeEnum.Enter: if (PresentCharacters.Contains(nm.Character)) { Report.AddMessage(ProjectReportMessage.MessageSeverity.Error, "A movement node is adding a character that is already in the scene.", nm); } else { PresentCharacters.Add(nm.Character); } if (PresentCharactersSide.ContainsKey(nm.MovementDirection)) { Report.AddMessage(ProjectReportMessage.MessageSeverity.Error, "A movement node is adding a character to an occupied location.", nm); } else { PresentCharactersSide.Add(nm.MovementDirection, nm.Character); } break; default: throw new ArgumentOutOfRangeException(nameof(nm.MovementType), nm.MovementType, null); } }