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 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); }
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); } }
public CompassPoint ToCompassPoint(CompassPoint defaultValue) { CompassPoint point; if (CompassPointHelper.FromName(Text, out point)) { return(point); } return(defaultValue); }
private static 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 void writeDoor(TextWriter writer, Location location, AutomapDirection direction, Exit exit) { var oppositeDirection = CompassPointHelper.GetOpposite(direction); var reciprocal = exit.Target.GetBestExit(oppositeDirection); writer.WriteLine($"{exit.ConnectionName} is a door. {exit.ConnectionName} is {direction.ToString().ToLower()} of {location.ExportName} and {oppositeDirection.ToString().ToLower()} of {exit.Target.ExportName}. "); writer.WriteLine($"{exit.ConnectionName} is {(exit.Door.Open ? "open" : "closed")} and {(exit.Door.Openable ? "openable" : "not openable")}."); writer.WriteLine($"{exit.ConnectionName} is {(exit.Door.Locked ? "locked" : "unlocked")} and {(exit.Door.Lockable ? "lockable" : "not lockable")}."); writer.WriteLine($"The description of {exit.ConnectionName} is {toInform7PrintableString(exit.ConnectionDescription)}."); reciprocal.Exported = true; writer.WriteLine(); }
/// <summary> /// Test whether an exit is reciprocated in the other direction; i.e. is there a bidirectional connection. /// </summary> public static bool IsReciprocated(Location source, AutomapDirection direction, Location target) { if (target != null) { var oppositeDirection = CompassPointHelper.GetOpposite(direction); var reciprocal = target.GetBestExit(oppositeDirection); if (reciprocal != null) { Debug.Assert(reciprocal.PrimaryDirection == oppositeDirection || reciprocal.SecondaryDirection == oppositeDirection, "Alleged opposite direction appears to lead somewhere else. Something went wrong whilst building the set of exits from each room."); return(reciprocal.Target == source); } } return(false); }
private void writeDoor(TextWriter writer, Location location, MappableDirection direction, Exit exit) { var oppositeDirection = CompassPointHelper.GetOpposite(direction); var reciprocal = exit.Target.GetBestExit(oppositeDirection); writer.WriteLine("Object {0} {1}", GetExportName(exit.ConnectionName, null), exit.ConnectionDescription); writer.WriteLine(" with name {0},", toI6Words(Deaccent(stripUnaccentedCharacters(exit.ConnectionName)))); writer.WriteLine(" description {0},", toI6String(exit.ConnectionDescription, DOUBLE_QUOTE)); writer.WriteLine(" found_in {0} {1},", location.ExportName, exit.Target.ExportName); writer.WriteLine(" door_to [; if (self in {0}) return {1}; return {0};],", location.ExportName, exit.Target.ExportName); writer.WriteLine(" door_dir [; if (self in {0}) return {1}; return {2}; ],", location.ExportName, toI6PropertyName(direction), toI6PropertyName(oppositeDirection)); writer.WriteLine(" has door {0} {1} {2} {3} ;", exit.Door.Openable ? "openable" : string.Empty, exit.Door.Open ? "open" : "~open", exit.Door.Lockable ? "lockable" : string.Empty, exit.Door.Locked ? "locked" : "~locked"); reciprocal.Exported = true; writer.WriteLine(); }
private static void annotate(XGraphics graphics, Palette palette, LineSegment lineSegment, TextBlock text, StringAlignment alignment) { Vector point; var delta = lineSegment.Delta; switch (alignment) { default: point = lineSegment.Start; delta.Negate(); break; case StringAlignment.Center: point = lineSegment.Mid; break; case StringAlignment.Far: point = lineSegment.End; break; } var bounds = new Rect(point, Vector.Zero); bounds.Inflate(Settings.TextOffsetFromConnection); float angle; var compassPoint = CompassPointHelper.DirectionFromAngle(out angle, delta); var pos = bounds.GetCorner(compassPoint); var format = new XStringFormat(); Drawing.SetAlignmentFromCardinalOrOrdinalDirection(format, compassPoint); if (alignment == StringAlignment.Center && Numeric.InRange(angle, -10, 10)) { // HACK: if the line segment is pretty horizontal and we're drawing mid-line text, // move text below the line to get it out of the way of any labels at the ends, // and center the text so it fits onto a line between two proximal rooms. pos = bounds.GetCorner(CompassPoint.South); format.Alignment = XStringAlignment.Center; format.LineAlignment = XLineAlignment.Near; } if (!Settings.DebugDisableTextRendering) { text.Draw(graphics, Settings.SubtitleFont, palette.LineTextBrush, pos, Vector.Zero, format); } }
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); } } }
private static void writeNormalExit(TextWriter writer, Location location, AutomapDirection direction, Exit exit) { writer.Write($"{getInform7Name(direction)} of {location.ExportName} is {exit.Target.ExportName}."); var oppositeDirection = CompassPointHelper.GetOpposite(direction); if (Exit.IsReciprocated(location, direction, exit.Target)) { // only export each connection once, if reciprocated; // I7 will infer that the direction is two way unless contradicted. var reciprocal = exit.Target.GetBestExit(oppositeDirection); reciprocal.Exported = true; } else if (exit.Target.GetBestExit(oppositeDirection) == null) { // if we aren't laying down a contradiction which I7 will pick up, // then be clear about one way connections. writer.Write($" {getInform7Name(oppositeDirection)} of {exit.Target.ExportName} is nowhere."); } writer.WriteLine(); }
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; } }
public void DrawBlock(XGraphics graphics) { var bounds = new Rect(Segment.Start, Vector.Zero); var compassPoint = CompassPointHelper.GetCompassPointFromDirectionVector(Segment.Delta); var pos = bounds.GetCorner(compassPoint); Size offsets = new Size(0, 0); switch (compassPoint) { case CompassPoint.NorthWest: offsets.Height = -(Offset * 12); offsets.Width = -(Offset * 10) - HORIZONTAL_LINE_OFFSET; break; case CompassPoint.NorthEast: offsets.Height = -(Offset * 12); offsets.Width = (Offset * 10) + HORIZONTAL_STEM_OFFSET; break; case CompassPoint.SouthEast: offsets.Height = (Offset * 12); offsets.Width = (Offset * 10) + HORIZONTAL_LINE_OFFSET; break; case CompassPoint.SouthWest: offsets.Height = (Offset * 12) + VERTICAL_LINE_OFFSET; offsets.Width = -(Offset * 10); break; case CompassPoint.East: offsets.Height = VERTICAL_LINE_OFFSET; offsets.Width = (Offset * 16) + HORIZONTAL_STEM_OFFSET; break; case CompassPoint.West: offsets.Height = VERTICAL_LINE_OFFSET; offsets.Width = -(Offset * 16) - (HORIZONTAL_LINE_OFFSET); break; case CompassPoint.South: offsets.Height = (Offset * 16) + VERTICAL_STEM_OFFSET; offsets.Width = -HORIZONTAL_LINE_OFFSET; break; case CompassPoint.North: offsets.Height = -(Offset * 16) - VERTICAL_STEM_OFFSET; offsets.Width = -HORIZONTAL_LINE_OFFSET; break; } // int dist = 15; // if (compassPoint == CompassPoint.NorthWest) // bounds.Inflate(-dist, -dist + 9); // // if (compassPoint == CompassPoint.NorthEast) // bounds.Inflate(-dist - 5, -dist); // // if (compassPoint == CompassPoint.SouthEast) // bounds.Inflate(-dist, dist - 9); // // if (compassPoint == CompassPoint.SouthWest) // bounds.Inflate(-dist, -dist); // graphics.DrawImage(Image, pos.ToPointF() + offsets); }
protected override void ExportContent(TextWriter writer) { // export location bool needConditionalFunction = false, wroteConditionalFunction = false; foreach (var location in LocationsInExportOrder) { location.Exported = true; writer.WriteLine(); writer.WriteLine($"<ROOM {location.ExportName}"); writer.WriteLine($" (DESC {toZILString(location.Room.Name)})"); writer.Write($" (IN ROOMS)"); if (!string.IsNullOrWhiteSpace(location.Room.PrimaryDescription)) { writer.WriteLine(); writer.Write($" (LDESC {toZILString(location.Room.PrimaryDescription)})"); } foreach (var direction in AllDirections) { var exit = location.GetBestExit(direction); if (exit != null && exit.Conditional) { writer.WriteLine(); writer.Write($" ({toZILPropertyName(direction)} PER TRIZBORT-CONDITIONAL-EXIT)"); needConditionalFunction = true; } else if (exit != null) { writer.WriteLine(); writer.Write($" ({toZILPropertyName(direction)} TO {exit.Target.ExportName})"); var oppositeDirection = CompassPointHelper.GetOpposite(direction); if (Exit.IsReciprocated(location, direction, exit.Target)) { var reciprocal = exit.Target.GetBestExit(oppositeDirection); reciprocal.Exported = true; } } } if (!location.Room.IsDark) { writer.WriteLine(); writer.Write(" (FLAGS LIGHTBIT)"); } writer.WriteLine(">"); writer.WriteLine(); if (needConditionalFunction && !wroteConditionalFunction) { writer.WriteLine(); writer.WriteLine("<ROUTINE TRIZBORT-CONDITIONAL-EXIT ()"); writer.WriteLine($" <TELL {DOUBLE_QUOTE}An export nymph appears on your keyboard. She says, 'You can't go that way, as that exit was marked as conditional, you know, a dotted line, in Trizbort. Obviously in your game you'll have a better rationale for this than, er, me.' She looks embarrassed. 'Bye!'{DOUBLE_QUOTE} CR>"); writer.WriteLine(" <RFALSE>>"); writer.WriteLine(); wroteConditionalFunction = true; } exportThings(writer, location.Things, null, 1); } }
/// <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> private static bool approximateDirectionMatch(CompassPoint one, CompassPoint two) { return(CompassPointHelper.GetAutomapDirectionVector(one) == CompassPointHelper.GetAutomapDirectionVector(two)); }
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; } }
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. }
protected override void ExportContent(TextWriter writer) { // export regions foreach (var region in RegionsInExportOrder) { writer.WriteLine("There is a region called {0}.", getExportName(region.ExportName, null)); writer.WriteLine(); } // export each location foreach (var location in LocationsInExportOrder) { // remember we've exported this location location.Exported = true; // tiresome format, avoids I7 errors: // these can occur with rooms called "West of House", or one room called "Cave" and one called "Damp Cave", etc. writer.Write("There is a room called {0}.", location.ExportName); if (location.ExportName != location.Room.Name) { writer.Write(" The printed name of it is {0}.", toInform7PrintableString(location.Room.Name)); } var description = location.Room.PrimaryDescription; if (!string.IsNullOrEmpty(description)) { writer.Write(" {0}{1}", toInform7PrintableString(description), description.EndsWith(".") ? string.Empty : "."); } if (location.Room.IsDark) { writer.Write(" It is dark."); } if (!string.IsNullOrEmpty(location.Room.Region) && !location.Room.Region.Equals(Region.DefaultRegion)) { writer.Write(" It is in {0}.", RegionsInExportOrder.Find(p => p.Region.RegionName == location.Room.Region).ExportName); } writer.WriteLine(); // end the previous line writer.WriteLine(); // blank line } // export the chosen exits from each location. foreach (var location in LocationsInExportOrder) { // export the chosen exits from this location. foreach (var direction in AllDirections) { var exit = location.GetBestExit(direction); if (exit != null && !exit.Exported) { // remember we've exported this exit exit.Exported = true; writer.Write("{0} of {1} is {2}.", getInform7Name(direction), location.ExportName, exit.Target.ExportName); var oppositeDirection = CompassPointHelper.GetOpposite(direction); if (Exit.IsReciprocated(location, direction, exit.Target)) { // only export each connection once, if reciprocated; // I7 will infer that the direction is two way unless contradicted. var reciprocal = exit.Target.GetBestExit(oppositeDirection); reciprocal.Exported = true; } else if (exit.Target.GetBestExit(oppositeDirection) == null) { // if we aren't laying down a contridiction which I7 will pick up, // then be clear about one way connections. writer.Write(" {0} of {1} is nowhere.", getInform7Name(oppositeDirection), exit.Target.ExportName); } writer.WriteLine(); } } } writer.WriteLine(); // if an exit is conditional, block it. var wroteConditionalFunction = false; foreach (var location in LocationsInExportOrder) { foreach (var direction in AllDirections) { var exit = location.GetBestExit(direction); if (exit != null && exit.Conditional) { if (!wroteConditionalFunction) { writer.WriteLine("To block conditional exits:"); writer.WriteLine("\tsay \"An export nymph appears on your keyboard. She says, 'You can't go that way, as that exit was marked as conditional, you know, a dotted line, in Trizbort. Obviously in your game you'll have a better rationale for this than, er, me.' She looks embarrassed. 'Bye!'\""); writer.WriteLine(); wroteConditionalFunction = true; } writer.WriteLine("Instead of going {0} from {1}, block conditional exits.", getInform7Name(direction).ToLowerInvariant(), location.ExportName); } } } if (wroteConditionalFunction) { // add a blank line if we need one writer.WriteLine(); } var exportedThings = false; foreach (var location in LocationsInExportOrder) { foreach (var thing in location.Things) { exportedThings = true; if (thing.Container == null) { writer.Write("{0}{1} {2} in {3}.", getArticle(thing.ExportName), thing.ExportName, isAre(thing.ExportName), thing.Location.ExportName); } else { writer.Write("{0}{1} {2} in the {3}.", getArticle(thing.ExportName), thing.ExportName, isAre(thing.ExportName), thing.Container.ExportName); } if (thing.DisplayName != thing.ExportName) { writer.Write(" It is privately-named. The printed name of it is {0}{1} Understand {2} as {3}.", toInform7PrintableString(thing.DisplayName), thing.DisplayName.EndsWith(".") ? string.Empty : ".", toInform7UnderstandWords(thing.DisplayName), thing.ExportName); } writer.WriteLine(); } } if (exportedThings) { // add a blank line if we need one writer.WriteLine(); } }