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; } }
public void SelectRoom(Room room) { try { m_control.Invoke((MethodInvoker) delegate { m_canvas.SelectRoom(room); }); } catch (Exception) { } }
public void RemoveExitStub(Room room, AutomapDirection direction) { try { m_control.Invoke((MethodInvoker) delegate { m_canvas.RemoveExitStub(room, direction); }); } catch (Exception) { } }
public Room CreateRoom(Room existing, AutomapDirection directionFromExisting, string roomName, string line) { Room room = null; try { m_control.Invoke((MethodInvoker) delegate { room = m_canvas.CreateRoom(existing, directionFromExisting, roomName,line); }); } catch (Exception) { } return room; }
Room IAutomapCanvas.CreateRoom(Room existing, string name) { // start by placing the room at the origin var room = new Room(Project.Current); room.Name = name; if (existing != null) { // if we know which room we were just in, start at that instead room.Position = existing.Position; } room.Position = Settings.Snap(room.Position); // while we can't place the room, try to the left, then the right, // expanding our distance as we go, until we find a blank space. var tryOtherSideNext = false; var tryLeft = true; var distance = 0; var initialPosition = room.Position; while (AnyRoomsIntersect(room)) { if (tryOtherSideNext) { tryLeft = !tryLeft; tryOtherSideNext = false; } else { tryOtherSideNext = true; ++distance; } if (tryLeft) { room.Position = Settings.Snap(new Vector(initialPosition.X - distance*(Settings.PreferredDistanceBetweenRooms + room.Width), room.Position.Y)); } else { room.Position = Settings.Snap(new Vector(initialPosition.X + distance*(Settings.PreferredDistanceBetweenRooms + room.Width), room.Position.Y)); } Debug.WriteLine(string.Format("Try again, more to the {0}.", tryLeft ? "left" : "right")); } // after we set the position, set this flag, // since setting the position clears this flag if set. room.ArbitraryAutomappedPosition = true; Project.Current.Elements.Add(room); return room; }
public void AddAmbiguousRoom(Room room) { m_roomNamesListBox.Items.Add(new AmbiguousRoom(room)); }
private void DeduceExitsFromDescription(Room room, string description) { if (!m_settings.GuessExits) { // we're disabled; do nothing return; } if (string.IsNullOrEmpty(description)) { // we don't have a description to work from return; } // lowercase the description description = description.ToLowerInvariant(); // search it for the names of compass directions foreach (var pair in s_namesForExitsInRoomDescriptions) { var directions = pair.Key; var namesOfExits = pair.Value; foreach (var directionName in namesOfExits) { var index = description.IndexOf(directionName); if (index != -1) { // we found one if (index == 0 || !char.IsLetterOrDigit(description[index - 1])) { // it's not the middle/end of a longer word if (index + directionName.Length == description.Length || !char.IsLetterOrDigit(description[index + directionName.Length])) { // it's not the middle/start of a longer word // add all relevant exits foreach (var direction in directions) { m_canvas.AddExitStub(room, direction); } } } } } } }
private bool? Match(Room room, string name, string description) { if (room == null) { // never match a null room; this shouldn't happen anyway return false; } if (room.Name != name) { return false; } if (!m_settings.VerboseTranscript) { // transcript is not verbose; // must assume room with same name is same room, // otherwise the user has to disambiguate potentially without descriptions, and very frequently. return true; } if (m_settings.AssumeRoomsWithSameNameAreSameRoom) { // ignore the description return true; } if (room.MatchDescription(description)) { // the descriptions match; they're the same room return true; } // the descriptions don't match; they may or may not be the same room return null; }
private void PositionRelativeTo(Room room, Room existing, CompassPoint existingCompassPoint, out Vector delta) { delta = CompassPointHelper.GetAutomapDirectionVector(existingCompassPoint); delta.X *= Settings.PreferredDistanceBetweenRooms + room.Width; delta.Y *= Settings.PreferredDistanceBetweenRooms + room.Height; var newRoomCenter = existing.InnerBounds.Center + delta; room.Position = Settings.Snap(new Vector(newRoomCenter.X - room.Width/2, newRoomCenter.Y - room.Height/2)); }
private Connection FindConnection(Room source, Room target, CompassPoint? directionFromSource, out bool wrongWay) { foreach (var element in Project.Current.Elements) { if (element is Connection) { var connection = (Connection) element; CompassPoint fromDirection, toDirection; var fromRoom = connection.GetSourceRoom(out fromDirection); var toRoom = connection.GetTargetRoom(out toDirection); if (fromRoom == source && toRoom == target && (directionFromSource == null || ApproximateDirectionMatch(directionFromSource.Value, fromDirection))) { // the two rooms are connected already in the given direction, A to B or both ways. wrongWay = false; return connection; } if (fromRoom == target && toRoom == source && (directionFromSource == null || ApproximateDirectionMatch(directionFromSource.Value, toDirection))) { // the two rooms are connected already in the given direction, B to A or both ways. wrongWay = connection.Flow == ConnectionFlow.OneWay; return connection; } } } wrongWay = false; return null; }
private bool AnyRoomsIntersect(Room room) { var bounds = room.InnerBounds; foreach (var element in Project.Current.Elements) { if (element is Room && element != room && element.Intersects(bounds)) { Debug.WriteLine("{0} is blocking {1}.", (element as Room).Name, room.Name); return true; } } return false; }
void IAutomapCanvas.SelectRoom(Room room) { if (!Project.Current.Elements.Contains(room)) { // avoid issues if the user has just deleted this room return; } SelectedElement = room; if (room != null) { EnsureVisible(room); } }
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); } } }
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; }
private bool TryMoveRoomForTidyConnection(Room source, CompassPoint targetCompassPoint, Room target) { var sourceArbitrary = source.ArbitraryAutomappedPosition; var sourcePosition = source.Position; Vector delta; PositionRelativeTo(source, target, targetCompassPoint, out delta); if (AnyRoomsIntersect(source)) { // didn't work; restore previous position source.Position = sourcePosition; source.ArbitraryAutomappedPosition = sourceArbitrary; return false; } // that's better return true; }
void IAutomapCanvas.Connect(Room source, AutomapDirection directionFromSource, Room target) { 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); connection.Style = ConnectionStyle.Solid; connection.Flow = 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 TryMoveRoomsForTidyConnection(Room source, CompassPoint sourceCompassPoint, Room target, CompassPoint targetCompassPoint) { if (source.ArbitraryAutomappedPosition && !source.IsConnected) { if (TryMoveRoomForTidyConnection(source, targetCompassPoint, target)) { return; } } if (target.ArbitraryAutomappedPosition && !target.IsConnected) { TryMoveRoomForTidyConnection(target, sourceCompassPoint, source); } }
private void NowInRoom(Room room) { m_lastKnownRoom = room; m_canvas.SelectRoom(room); }
public void Connect(Room source, AutomapDirection directionFromSource, Room target) { try { m_control.Invoke((MethodInvoker) delegate { m_canvas.Connect(source, directionFromSource, target); }); } catch (Exception) { } }
public AmbiguousRoom(Room room) { Room = room; }
public Room CreateRoom(Room existing, string name) { Room room = null; try { m_control.Invoke((MethodInvoker) delegate { room = m_canvas.CreateRoom(existing, name); }); } catch (Exception) { } return room; }
public bool Load() { try { if (new FileInfo(FileName).Length == 0) { // this is an empty file, probably thanks to our Explorer New->Trizbort Map menu option. Settings.Reset(); return true; } var doc = new XmlDocument(); doc.Load(FileName); var root = new XmlElementReader(doc.DocumentElement); if (!root.HasName("trizbort")) throw new InvalidDataException(string.Format("Not a {0} map file.", Application.ProductName)); // load info Title = root["info"]["title"].Text; Author = root["info"]["author"].Text; Description = root["info"]["description"].Text; History = root["info"]["history"].Text; // load all elements var map = root["map"]; var mapConnectionToLoadState = new Dictionary<Connection, object>(); foreach (var element in map.Children) { if (element.HasName("room")) { var room = new Room(this); room.ID = element.Attribute("id").ToInt(room.ID); room.Load(element); Elements.Add(room); } else if (element.HasName("line")) { var connection = new Connection(this); connection.ID = element.Attribute("id").ToInt(connection.ID); var loadState = connection.BeginLoad(element); if (loadState != null) { mapConnectionToLoadState.Add(connection, loadState); } Elements.Add(connection); } } // connect them together foreach (var pair in mapConnectionToLoadState) { var connection = pair.Key; var state = pair.Value; connection.EndLoad(state); } // load settings last, since their load can't be undone Settings.Reset(); Settings.Load(root["settings"]); return true; } catch (Exception ex) { MessageBox.Show(Program.MainForm, string.Format("There was a problem loading the map:\n\n{0}", ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } }
public CompassPort(CompassPoint compassPoint, Room room) : base(room) { CompassPoint = compassPoint; Room = room; }