Room IAutomapCanvas.CreateRoom(Room existing, AutomapDirection directionFromExisting, string roomName, string line) { if (!Project.Current.Elements.Contains(existing)) { // avoid issues if the user has just deleted the existing room return(null); } var room = new Room(Project.Current) { Name = roomName }; if (line != roomName) { room.SubTitle = line.Replace(roomName, ""); } Vector delta; positionRelativeTo(room, existing, CompassPointHelper.GetCompassDirection(directionFromExisting), out delta); if (anyRoomsIntersect(room)) { ShiftMap(room.InnerBounds, delta); Debug.WriteLine("Shift map."); } Project.Current.Elements.Add(room); return(room); }
void IAutomapCanvas.RemoveExitStub(Room room, MappableDirection direction) { if (!Project.Current.Elements.Contains(room)) { return; } var compassPoint = CompassPointHelper.GetCompassDirection(direction); foreach (var connection in room.GetConnections(compassPoint)) { var source = connection.GetSourceRoom(out var sourceCompassPoint); var target = connection.GetTargetRoom(out var targetCompassPoint); if (source == room && target == room && sourceCompassPoint == compassPoint && targetCompassPoint == compassPoint) { Project.Current.Elements.Remove(connection); } } }
void IAutomapCanvas.RemoveExitStub(Room room, AutomapDirection direction) { if (!Project.Current.Elements.Contains(room)) { // avoid issues if the user has just deleted one of these rooms return; } var compassPoint = CompassPointHelper.GetCompassDirection(direction); foreach (var connection in room.GetConnections(compassPoint)) { CompassPoint sourceCompassPoint, targetCompassPoint; var source = connection.GetSourceRoom(out sourceCompassPoint); var target = connection.GetTargetRoom(out targetCompassPoint); if (source == room && target == room && sourceCompassPoint == compassPoint && targetCompassPoint == compassPoint) { Project.Current.Elements.Remove(connection); } } }
void IAutomapCanvas.AddExitStub(Room room, MappableDirection direction) { if (!Project.Current.Elements.Contains(room)) { return; } var sourceCompassPoint = CompassPointHelper.GetCompassDirection(direction); var connection = addConnection(room, sourceCompassPoint, room, sourceCompassPoint); switch (direction) { case MappableDirection.Up: connection.StartText = Connection.Up; break; case MappableDirection.Down: connection.StartText = Connection.Down; break; } }
void IAutomapCanvas.AddExitStub(Room room, AutomapDirection direction) { if (!Project.Current.Elements.Contains(room)) { // avoid issues if the user has just deleted one of these rooms return; } var sourceCompassPoint = CompassPointHelper.GetCompassDirection(direction); var connection = addConnection(room, sourceCompassPoint, room, sourceCompassPoint); switch (direction) { case AutomapDirection.Up: connection.StartText = Connection.Up; break; case AutomapDirection.Down: connection.StartText = Connection.Down; break; } }
void IAutomapCanvas.Connect(Room source, AutomapDirection directionFromSource, Room target, bool assumeTwoWayConnections) { if (!Project.Current.Elements.Contains(source) || !Project.Current.Elements.Contains(target)) { // avoid issues if the user has just deleted one of these rooms return; } // work out the correct compass point to use for the given direction // look for existing connections: // if the given direction is up/down/in/out, any existing connection will suffice; // otherwise, only match an existing connection if it's pretty close to the one we want. var sourceCompassPoint = CompassPointHelper.GetCompassDirection(directionFromSource); CompassPoint?acceptableSourceCompassPoint; switch (directionFromSource) { case AutomapDirection.Up: case AutomapDirection.Down: case AutomapDirection.In: case AutomapDirection.Out: acceptableSourceCompassPoint = null; // any existing connection will do break; default: acceptableSourceCompassPoint = sourceCompassPoint; break; } bool wrongWay; var connection = findConnection(source, target, acceptableSourceCompassPoint, out wrongWay); if (connection == null) { // there is no suitable connection between these rooms: var targetCompassPoint = CompassPointHelper.GetAutomapOpposite(sourceCompassPoint); // check whether we can move one of the rooms to make the connection tidier; // we won't need this very often, but it can be useful especially if the user teleports into a room // and then steps out into an existing one (this can appear to happen if the user moves into a // dark room, turns on the light, then leaves). tryMoveRoomsForTidyConnection(source, sourceCompassPoint, target, targetCompassPoint); // add a new connection connection = addConnection(source, sourceCompassPoint, target, targetCompassPoint); if (mAutomap.UseDottedConnection) { connection.Style = ConnectionStyle.Dashed; mAutomap.UseDottedConnection = false; } else { connection.Style = ConnectionStyle.Solid; } connection.Flow = assumeTwoWayConnections ? ConnectionFlow.TwoWay : ConnectionFlow.OneWay; } else if (wrongWay) { // there is a suitable connection between these rooms, but it goes the wrong way; // make it bidirectional since we can now go both ways. connection.Flow = ConnectionFlow.TwoWay; } // if this is an up/down/in/out connection, mark it as such; // but don't override any existing text. switch (directionFromSource) { case AutomapDirection.Up: case AutomapDirection.Down: case AutomapDirection.In: case AutomapDirection.Out: if (string.IsNullOrEmpty(connection.StartText) && string.IsNullOrEmpty(connection.EndText)) { switch (directionFromSource) { case AutomapDirection.Up: connection.SetText(wrongWay ? ConnectionLabel.Down : ConnectionLabel.Up); break; case AutomapDirection.Down: connection.SetText(wrongWay ? ConnectionLabel.Up : ConnectionLabel.Down); break; case AutomapDirection.In: connection.SetText(wrongWay ? ConnectionLabel.Out : ConnectionLabel.In); break; case AutomapDirection.Out: connection.SetText(wrongWay ? ConnectionLabel.In : ConnectionLabel.Out); break; } } break; } }
private void ProcessPromptCommand(string command) { // unless we find one, this command does not involve moving in a given direction m_lastMoveDirection = null; // first process trizbort commands if (command.ToUpper().StartsWith(m_settings.AddRegionCommand.ToUpper())) { var regionName = command.Substring(m_settings.AddRegionCommand.Length).Trim(); if (!string.IsNullOrEmpty(regionName) && m_lastKnownRoom != null) { // region already exists, just set the room to it if (Settings.Regions.Find(p => p.RegionName.Equals(regionName, StringComparison.OrdinalIgnoreCase)) == null) { Settings.Regions.Add(new Region { RegionName = regionName, TextColor = Settings.Color[Colors.Subtitle], RColor = System.Drawing.Color.White }); } m_lastKnownRoom.Region = regionName; } return; } if (command.ToUpper().StartsWith(m_settings.AddObjectCommand.ToUpper())) { // the user wants to add an object to the map var objectName = command.Substring(m_settings.AddObjectCommand.Length).Trim(); if (!string.IsNullOrEmpty(objectName) && m_lastKnownRoom != null) { if (!string.IsNullOrEmpty(m_lastKnownRoom.Objects)) { var alreadyExists = false; foreach (var line in m_lastKnownRoom.Objects.Replace("\r", string.Empty).Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) { if (StringComparer.InvariantCultureIgnoreCase.Compare(line.Trim(), objectName) == 0) { alreadyExists = true; break; } } if (!alreadyExists) { m_lastKnownRoom.Objects += "\r\n" + objectName; } } else { m_lastKnownRoom.Objects = objectName; } } return; } // TODO: We entirely don't handle "go east. n. s then w." etc. and I don't see an easy way of doing so. // split the command into individual words var parts = command.Split(s_wordSeparators, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 0) { // there's no command left over return; } // strip out words we consider fluff, like "to". var words = new List <string>(); foreach (var word in parts) { var stripWord = false; foreach (var strippable in s_wordsToStripFromCommands) { if (StringComparer.InvariantCultureIgnoreCase.Compare(word, strippable) == 0) { stripWord = true; break; } } if (word[0] == '[') { for (var temp = 1; temp < word.Length; temp++) { if (word[temp] == ']') { stripWord = true; break; } if ((word[temp] < '0') || (word[temp] > '9')) { break; } } } if (stripWord) { continue; } words.Add(word); } // if the command starts with a word meaning "go", remove it. if (words.Count > 0) { foreach (var wordMeaningGo in s_wordsMeaningGo) { if (StringComparer.InvariantCultureIgnoreCase.Compare(words[0], wordMeaningGo) == 0) { words.RemoveAt(0); break; } } } if ((words.Count == 2) && (words[0].Equals("trypush"))) { foreach (var pair in s_namesForMovementCommands) { var direction = pair.Key; var wordsForDirection = pair.Value; foreach (var wordForDirection in wordsForDirection) { if (StringComparer.InvariantCultureIgnoreCase.Compare(words[1], wordForDirection) == 0) { Vector delta = CompassPointHelper.GetAutomapDirectionVector(CompassPointHelper.GetCompassDirection(direction)); delta.X *= m_lastKnownRoom.Width + Settings.PreferredDistanceBetweenRooms; delta.X += m_lastKnownRoom.X; delta.Y *= m_lastKnownRoom.Height + Settings.PreferredDistanceBetweenRooms; delta.Y += m_lastKnownRoom.Y; m_lastKnownRoom.Position = Settings.Snap(delta); } } } } // look for custom tb trizbort commands if (words.Count > 0) { if (words[0].Equals("tb", StringComparison.OrdinalIgnoreCase)) { if (words.Count > 1) { if (words[1].Equals("dotted", StringComparison.OrdinalIgnoreCase)) { UseDottedConnection = true; } if (words[1].Equals("exit", StringComparison.OrdinalIgnoreCase)) { if (words.Count > 2) { var direction = getDirection(words[2]); if (direction != MappableDirection.None) { m_canvas.AddExitStub(m_lastKnownRoom, direction); } } } if (words[1].Equals("noexit", StringComparison.OrdinalIgnoreCase)) { if (words.Count > 2) { var direction = getDirection(words[2]); if (direction != MappableDirection.None) { m_canvas.RemoveExitStub(m_lastKnownRoom, direction); } } } } } } // we should have just one word left if (words.Count != 1) { // we have no words left, or more than one return; } // the word we have left is hopefully a direction var possibleDirection = words[0]; // work out which direction it is, if any foreach (var pair in s_namesForMovementCommands) { var direction = pair.Key; var wordsForDirection = pair.Value; foreach (var wordForDirection in wordsForDirection) { if (StringComparer.InvariantCultureIgnoreCase.Compare(possibleDirection, wordForDirection) == 0) { // aha, we know which direction it was m_lastMoveDirection = direction; // remove any stub exit in this direction; // we'll either add a proper connection shortly, or they player can't go that way m_canvas.RemoveExitStub(m_lastKnownRoom, m_lastMoveDirection.Value); return; } } } // the word wasn't for a direction after all. }
private async Task ProcessTranscriptText(List <string> lines) { string previousLine = null; for (var index = 0; index < lines.Count; ++index) { var line = lines[index]; string roomName; if (ExtractRoomName(line, previousLine, out roomName)) { string roomDescription; ExtractParagraph(lines, index + 1, out roomDescription); // work out which room the transcript is referring to here, asking them if necessary var room = FindRoom(roomName, roomDescription, line); if (room == null) { // new room if (m_lastKnownRoom != null && m_lastMoveDirection != null) { // player moved to new room // is there already a connection in that direction? var mOtherRoom = m_lastKnownRoom.GetConnections(CompassPointHelper.GetCompassDirection(m_lastMoveDirection.Value)).FirstOrDefault()?.GetTargetRoom(); if (mOtherRoom != null) { var frm = new AutomapRoomSameDirectionDialog { Room1 = mOtherRoom, Room2 = roomName }; frm.ShowDialog(); switch (frm.Result) { case AutomapSameDirectionResult.KeepRoom1: break; case AutomapSameDirectionResult.KeepRoom2: room = m_canvas.CreateRoom(m_lastKnownRoom, m_lastMoveDirection.Value, roomName, line); m_canvas.Connect(m_lastKnownRoom, m_lastMoveDirection.Value, room, m_settings.AssumeTwoWayConnections); m_canvas.RemoveRoom(mOtherRoom); break; case AutomapSameDirectionResult.KeepBoth: room = m_canvas.CreateRoom(m_lastKnownRoom, m_lastMoveDirection.Value, roomName, line); m_canvas.Connect(m_lastKnownRoom, m_lastMoveDirection.Value, room, m_settings.AssumeTwoWayConnections); break; default: throw new ArgumentOutOfRangeException(); } } else { // if not added already, add room to map; and join it up to the previous one room = m_canvas.CreateRoom(m_lastKnownRoom, m_lastMoveDirection.Value, roomName, line); m_canvas.Connect(m_lastKnownRoom, m_lastMoveDirection.Value, room, m_settings.AssumeTwoWayConnections); Trace("{0}: {1} is now {2} from {3}.", FormatTranscriptLineForDisplay(line), roomName, m_lastMoveDirection.Value.ToString().ToLower(), m_lastKnownRoom.Name); } } else { if ((m_firstRoom) || (m_gameName == roomName)) { // most likely this is the game title m_firstRoom = false; m_gameName = roomName; await WaitForStep(); } else { // player teleported to new room; // don't connect it up, as we don't know how they got there room = m_canvas.CreateRoom(m_lastKnownRoom, roomName); if (m_lastKnownRoom == null) { room.IsStartRoom = true; } Trace("{0}: teleported to new room, {1}.", FormatTranscriptLineForDisplay(line), roomName); await WaitForStep(); } } if (room != null) { DeduceExitsFromDescription(room, roomDescription); NowInRoom(room); } await WaitForStep(); } else if (room != m_lastKnownRoom) { // player moved to existing room if (m_lastKnownRoom != null && m_lastMoveDirection != null) { // player moved sensibly; ensure rooms are connected up m_canvas.Connect(m_lastKnownRoom, m_lastMoveDirection.Value, room, m_settings.AssumeTwoWayConnections); Trace("{0}: {1} is now {2} from {3}.", FormatTranscriptLineForDisplay(line), roomName, m_lastMoveDirection.Value.ToString().ToLower(), m_lastKnownRoom.Name); } NowInRoom(room); await WaitForStep(); } else { // player didn't change rooms Trace("{0}: still in {1}.", FormatTranscriptLineForDisplay(line), m_lastKnownRoom.Name); } // add this description if the room doesn't have it already if (room != null) { room.AddDescription(roomDescription); } // now forget the last movement direction we saw. // we'll still place any rooms we see before we see a movement direction, // but we won't join them up to this room. // we might end up caring if, for example, the user gives multiple commands at one prompt, // or they're moved to one room and then teleported to another. m_lastMoveDirection = null; } else { Trace("{0}: {1}{2}{3}", FormatTranscriptLineForDisplay(line), HaveFailureReason() ? "not a room name because " : string.Empty, GetFailureReason(), HaveFailureReason() ? "." : string.Empty); } previousLine = line; } }