예제 #1
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);
        }
예제 #2
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);
                }
            }
        }
예제 #3
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);
                }
            }
        }
예제 #4
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;
            }
        }
예제 #5
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;
            }
        }
예제 #6
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;
            }
        }
예제 #7
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.
        }
예제 #8
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;
            }
        }