public static int BentConnections(bool ignoreAnnos) { return(Project.Current.Elements.OfType <Connection>().Count(p => { var port1 = (Room.CompassPort)p.VertexList[0].Port; var port2 = (Room.CompassPort)p.VertexList[1].Port; if (port1 == null || port2 == null) { return false; } var firstRoomConnectionDir = port1.CompassPoint; var secondRoomConnectionDir = port2.CompassPoint; if (ignoreAnnos) { return !Project.Current.Canvas.EqualEnough(firstRoomConnectionDir, CompassPointHelper.GetOpposite(secondRoomConnectionDir)); } if (p.VertexList[0].Connection.StartText != "" || p.VertexList[1].Connection.EndText != "") { return false; } // if the port directions are not (roughly) opposite, then we have a bent connection. Note NN(EW) = N, WW(NS) = W, etc. return !Project.Current.Canvas.EqualEnough(firstRoomConnectionDir, CompassPointHelper.GetOpposite(secondRoomConnectionDir)); } )); }
Room IAutomapCanvas.CreateRoom(Room existing, AutomapDirection directionFromExisting, string name) { 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); room.Name = name; 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); }
public void Element(string localName, CompassPoint value) { string name; if (CompassPointHelper.ToName(value, out name)) { Writer.WriteElementString(localName, name); } }
public void Value(CompassPoint value) { string name; if (CompassPointHelper.ToName(value, out name)) { Writer.WriteValue(name); } }
public void Attribute(string localName, CompassPoint value) { string name; if (CompassPointHelper.ToName(value, out name)) { Writer.WriteAttributeString(localName, name); } }
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)); }
public CompassPoint ToCompassPoint(CompassPoint defaultValue) { CompassPoint point; if (CompassPointHelper.FromName(Text, out point)) { return(point); } return(defaultValue); }
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, 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 Vector GetCorner(CompassPoint point, RoomShape myRmShape = RoomShape.SquareCorners, CornerRadii corners = null) { bool isOctagonal = (myRmShape == RoomShape.Octagonal); bool isRounded = (myRmShape == RoomShape.RoundedCorners); bool isEllipse = (myRmShape == RoomShape.Ellipse); double angleInRadians; if (myRmShape == RoomShape.Ellipse) { angleInRadians = CompassPointHelper.CalcRadianForEllipse(point, this); return(new Vector(Center.X + (float)((Width / 2.0) * Math.Cos(angleInRadians)), Center.Y + (float)((Height / 2.0) * Math.Sin(angleInRadians)))); } if (myRmShape == RoomShape.Ellipse) { if (point == CompassPoint.NorthEast || point == CompassPoint.NorthWest || point == CompassPoint.SouthWest || point == CompassPoint.SouthEast) { angleInRadians = CompassPointHelper.CalcRadianForEllipse(point, this); if (point == CompassPoint.NorthEast) { var rect = new Rect(X + Width, Y, (float)corners.TopRight, (float)corners.TopRight); return(new Vector((rect.Center.X - (float)(corners.TopRight / 2.0)) - (float)((corners.TopRight / 2.0) * Math.Cos(angleInRadians)), (rect.Center.Y + (float)(corners.TopLeft / 4.0)) + (float)((corners.TopRight / 2.0) * Math.Sin(angleInRadians)))); } if (point == CompassPoint.NorthWest) { var rect = new Rect(X, Y, (float)corners.TopLeft, (float)corners.TopLeft); return(new Vector((rect.Center.X - (float)(corners.TopLeft / 2.0)) - (float)((corners.TopLeft / 2.0) * Math.Cos(angleInRadians)), (rect.Center.Y + (float)(corners.TopLeft / 4.0)) + (float)((corners.TopLeft / 2.0) * Math.Sin(angleInRadians)))); } if (point == CompassPoint.SouthWest) { var rect = new Rect(X, Y + Height, (float)corners.BottomLeft, (float)corners.BottomLeft); return(new Vector((rect.Center.X - (float)(corners.BottomLeft / 2.0)) - (float)((corners.BottomLeft / 2.0) * Math.Cos(angleInRadians)), (rect.Center.Y - (float)(corners.BottomLeft / 2.0)) - (float)((corners.BottomLeft / 2.0) * Math.Sin(angleInRadians)))); } if (point == CompassPoint.SouthEast) { var rect = new Rect(X + Width, Y + Height, (float)corners.BottomRight, (float)corners.BottomRight); return(new Vector((rect.Center.X - (float)(corners.BottomRight / 2.0)) - (float)((corners.BottomRight / 2.0) * Math.Cos(angleInRadians)), (rect.Center.Y - (float)(corners.BottomRight / 2.0)) - (float)((corners.BottomRight / 2.0) * Math.Sin(angleInRadians)))); } } } switch (point) { case CompassPoint.North: return(new Vector(X + Width / 2, Y)); case CompassPoint.NorthNorthEast: return(new Vector(X + Width * 3 / 4, Y)); case CompassPoint.NorthEast: if (isOctagonal) { return(new Vector(X + Width * 7 / 8, Y + Height * 1 / 8)); } if (isRounded) { return(new Vector((float)(X + Width - 0.25 * corners.TopLeft), (float)(Y + 0.25 * corners.TopLeft))); } return(new Vector(X + Width, Y)); case CompassPoint.EastNorthEast: return(new Vector(X + Width, Y + Height / 4)); case CompassPoint.East: return(new Vector(X + Width, Y + Height / 2)); case CompassPoint.EastSouthEast: return(new Vector(X + Width, Y + Height * 3 / 4)); case CompassPoint.SouthEast: if (isOctagonal) { return(new Vector(X + Width * 7 / 8, Y + Height * 7 / 8)); } if (isRounded) { return(new Vector((float)(X + Width - 0.25 * corners.TopLeft), (float)(Y + Height - 0.25 * corners.TopLeft))); } return(new Vector(X + Width, Y + Height)); case CompassPoint.SouthSouthEast: return(new Vector(X + Width * 3 / 4, Y + Height)); case CompassPoint.South: return(new Vector(X + Width / 2, Y + Height)); case CompassPoint.SouthSouthWest: return(new Vector(X + Width / 4, Y + Height)); case CompassPoint.SouthWest: if (isOctagonal) { return(new Vector(X + Width * 1 / 8, Y + Height * 7 / 8)); } if (isRounded) { return(new Vector((float)(X + 0.3 * corners.TopLeft), (float)(Y + Height - 0.3 * corners.TopLeft))); } return(new Vector(X, Y + Height)); case CompassPoint.WestSouthWest: return(new Vector(X, Y + Height * 3 / 4)); case CompassPoint.West: return(new Vector(X, Y + Height / 2)); case CompassPoint.WestNorthWest: return(new Vector(X, Y + Height / 4)); case CompassPoint.NorthWest: if (isOctagonal) { return(new Vector(X + Width * 1 / 8, Y + Height * 1 / 8)); } if (isRounded) { return(new Vector((float)(X + 0.3 * corners.TopLeft), (float)(Y + 0.3 * corners.TopLeft))); } return(new Vector(X, Y)); case CompassPoint.NorthNorthWest: return(new Vector(X + Width / 4, Y)); default: throw new InvalidOperationException(); } }
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; } }
/// <summary> /// Approximately match two directions, allowing for aesthetic rearrangement by the user. /// </summary> /// <remarks> /// Two compass points match if they are on the same side of a box representing the room. /// </remarks> bool ApproximateDirectionMatch(CompassPoint one, CompassPoint two) { return(CompassPointHelper.GetAutomapDirectionVector(one) == CompassPointHelper.GetAutomapDirectionVector(two)); }
public Vector GetCorner(CompassPoint point, bool ellipse = false, CornerRadii corners = null) { if (ellipse) { return(new Vector(Center.X + (float)((Width / 2.0) * Math.Cos(CompassPointHelper.GetAngleInRadians(point))), Center.Y + (float)((Height / 2.0) * Math.Sin(CompassPointHelper.GetAngleInRadians(point))))); } if (corners != null) { if (point != CompassPoint.East && point != CompassPoint.West && point != CompassPoint.North && point != CompassPoint.South) { if (corners.TopRight > 10.0 && (point == CompassPoint.EastNorthEast || point == CompassPoint.NorthEast || point == CompassPoint.NorthNorthEast)) { return(new Vector(Center.X + (float)((Width / 2.0) * Math.Cos(CompassPointHelper.GetAngleInRadians(point))), Center.Y + (float)((Height / 2.0) * Math.Sin(CompassPointHelper.GetAngleInRadians(point))))); } if (corners.TopLeft > 10.0 && (point == CompassPoint.WestNorthWest || point == CompassPoint.NorthWest || point == CompassPoint.NorthNorthWest)) { return(new Vector(Center.X + (float)((Width / 2.0) * Math.Cos(CompassPointHelper.GetAngleInRadians(point))), Center.Y + (float)((Height / 2.0) * Math.Sin(CompassPointHelper.GetAngleInRadians(point))))); } if (corners.BottomLeft > 10.0 && (point == CompassPoint.WestSouthWest || point == CompassPoint.SouthWest || point == CompassPoint.SouthSouthWest)) { return(new Vector(Center.X + (float)((Width / 2.0) * Math.Cos(CompassPointHelper.GetAngleInRadians(point))), Center.Y + (float)((Height / 2.0) * Math.Sin(CompassPointHelper.GetAngleInRadians(point))))); } if (corners.BottomRight > 10.0 && (point == CompassPoint.SouthSouthEast || point == CompassPoint.SouthEast || point == CompassPoint.EastSouthEast)) { return(new Vector(Center.X + (float)((Width / 2.0) * Math.Cos(CompassPointHelper.GetAngleInRadians(point))), Center.Y + (float)((Height / 2.0) * Math.Sin(CompassPointHelper.GetAngleInRadians(point))))); } } } switch (point) { case CompassPoint.North: return(new Vector(X + Width / 2, Y)); case CompassPoint.NorthNorthEast: return(new Vector(X + Width * 3 / 4, Y)); case CompassPoint.NorthEast: return(new Vector(X + Width, Y)); case CompassPoint.EastNorthEast: return(new Vector(X + Width, Y + Height / 4)); case CompassPoint.East: return(new Vector(X + Width, Y + Height / 2)); case CompassPoint.EastSouthEast: return(new Vector(X + Width, Y + Height * 3 / 4)); case CompassPoint.SouthEast: return(new Vector(X + Width, Y + Height)); case CompassPoint.SouthSouthEast: return(new Vector(X + Width * 3 / 4, Y + Height)); case CompassPoint.South: return(new Vector(X + Width / 2, Y + Height)); case CompassPoint.SouthSouthWest: return(new Vector(X + Width / 4, Y + Height)); case CompassPoint.SouthWest: return(new Vector(X, Y + Height)); case CompassPoint.WestSouthWest: return(new Vector(X, Y + Height * 3 / 4)); case CompassPoint.West: return(new Vector(X, Y + Height / 2)); case CompassPoint.WestNorthWest: return(new Vector(X, Y + Height / 4)); case CompassPoint.NorthWest: return(new Vector(X, Y)); case CompassPoint.NorthNorthWest: return(new Vector(X + Width / 4, Y)); default: throw new InvalidOperationException(); } }