Пример #1
0
        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));
            }
                                                                        ));
        }
Пример #2
0
        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);
        }
Пример #3
0
        public void Element(string localName, CompassPoint value)
        {
            string name;

            if (CompassPointHelper.ToName(value, out name))
            {
                Writer.WriteElementString(localName, name);
            }
        }
Пример #4
0
        public void Value(CompassPoint value)
        {
            string name;

            if (CompassPointHelper.ToName(value, out name))
            {
                Writer.WriteValue(name);
            }
        }
Пример #5
0
        public void Attribute(string localName, CompassPoint value)
        {
            string name;

            if (CompassPointHelper.ToName(value, out name))
            {
                Writer.WriteAttributeString(localName, name);
            }
        }
Пример #6
0
        public CompassPoint ToCompassPoint(CompassPoint defaultValue)
        {
            CompassPoint point;

            if (CompassPointHelper.FromName(Text, out point))
            {
                return(point);
            }
            return(defaultValue);
        }
Пример #7
0
        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));
        }
Пример #8
0
        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();
        }
Пример #9
0
 /// <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);
 }
Пример #10
0
        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();
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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);
                }
            }
        }
Пример #13
0
        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();
        }
Пример #14
0
        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);
                }
            }
        }
Пример #15
0
        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;
            }
        }
Пример #16
0
        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;
            }
        }
Пример #17
0
        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);
        }
Пример #18
0
        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);
            }
        }
Пример #19
0
 /// <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));
 }
Пример #20
0
        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;
            }
        }
Пример #21
0
        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;
            }
        }
Пример #22
0
        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.
        }
Пример #23
0
        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();
            }
        }