コード例 #1
0
        /// <summary>
        /// Join 2 doors with a corridor. They must be on the opposite sides of their parent rooms (for now)
        /// </summary>
        public bool JoinDoorsWithCorridor(DoorInfo firstDoor, DoorInfo secondDoor, RoomTemplate corridorTemplate)
        {
            try
            {
                if (connectionDoors.ContainsKey(new Connection(firstDoor.OwnerRoomIndex, secondDoor.OwnerRoomIndex).Ordered))
                {
                    LogFile.Log.LogEntryDebug("No allowing 2nd connection between rooms for now - revisit past 7DRL", LogDebugLevel.High);
                    return(false);
                }

                var firstDoorLoc  = RoomTemplateUtilities.GetDoorLocation(firstDoor.OwnerRoom.Room, firstDoor.DoorIndexInRoom);
                var secondDoorLoc = RoomTemplateUtilities.GetDoorLocation(secondDoor.OwnerRoom.Room, secondDoor.DoorIndexInRoom);

                var firstDoorCoord  = firstDoor.MapCoords;
                var secondDoorCoord = secondDoor.MapCoords;

                var corridorTermini = RoomTemplateUtilities.CorridorTerminalPointsBetweenDoors(firstDoor.MapCoords, firstDoor.DoorLocation, secondDoor.MapCoords, secondDoor.DoorLocation);

                bool canDoLSharedCorridor  = RoomTemplateUtilities.CanBeConnectedWithLShapedCorridor(firstDoorCoord, firstDoorLoc, secondDoorCoord, secondDoorLoc);
                bool canDoBendCorridor     = RoomTemplateUtilities.CanBeConnectedWithBendCorridor(firstDoorCoord, firstDoorLoc, secondDoorCoord, secondDoorLoc);
                bool canDoStraightCorridor = RoomTemplateUtilities.CanBeConnectedWithStraightCorridor(firstDoorCoord, firstDoorLoc, secondDoorCoord, secondDoorLoc);
                bool areAdjacent           = corridorTermini.Item1 == secondDoorCoord && corridorTermini.Item2 == firstDoorCoord;
                bool areOverlapping        = firstDoorCoord == secondDoorCoord;

                if (!canDoLSharedCorridor && !canDoBendCorridor && !canDoStraightCorridor && !areAdjacent && !areOverlapping)
                {
                    throw new ApplicationException("No corridor available to connect this type of door");
                }

                if (areAdjacent || areOverlapping)
                {
                    //Add a direct connection in the connectivity graph
                    connectivityMap.AddRoomConnection(firstDoor.OwnerRoomIndex, secondDoor.OwnerRoomIndex);
                    connectionDoors.Add(new Connection(firstDoor.OwnerRoomIndex, secondDoor.OwnerRoomIndex).Ordered, firstDoor);
                }
                else
                {
                    //Create template

                    var horizontal = false;
                    if (firstDoorLoc == RoomTemplate.DoorLocation.Left || firstDoorLoc == RoomTemplate.DoorLocation.Right)
                    {
                        horizontal = true;
                    }

                    int xOffset = corridorTermini.Item2.x - corridorTermini.Item1.x;
                    int yOffset = corridorTermini.Item2.y - corridorTermini.Item1.y;

                    RoomTemplate expandedCorridor;
                    Point        corridorTerminus1InTemplate;

                    if (canDoBendCorridor)
                    {
                        int transition = (int)Math.Floor(yOffset / 2.0);
                        if (horizontal == true)
                        {
                            transition = (int)Math.Floor(xOffset / 2.0);
                        }
                        var expandedCorridorAndPoint = RoomTemplateUtilities.ExpandCorridorTemplateBend(xOffset, yOffset, transition, horizontal, corridorTemplate);
                        expandedCorridor            = expandedCorridorAndPoint.Item1;
                        corridorTerminus1InTemplate = expandedCorridorAndPoint.Item2;
                    }
                    else if (canDoLSharedCorridor)
                    {
                        var expandedCorridorAndPoint = RoomTemplateUtilities.ExpandCorridorTemplateLShaped(xOffset, yOffset, horizontal, corridorTemplate);
                        expandedCorridor            = expandedCorridorAndPoint.Item1;
                        corridorTerminus1InTemplate = expandedCorridorAndPoint.Item2;
                    }
                    else
                    {
                        var offsetToUse = horizontal ? xOffset : yOffset;
                        var expandedCorridorAndPoint = RoomTemplateUtilities.ExpandCorridorTemplateStraight(offsetToUse, horizontal, corridorTemplate);
                        expandedCorridor            = expandedCorridorAndPoint.Item1;
                        corridorTerminus1InTemplate = expandedCorridorAndPoint.Item2;
                    }

                    //Place corridor

                    //Match corridor tile to location of door
                    Point topLeftCorridor = corridorTermini.Item1 - corridorTerminus1InTemplate;

                    var corridorRoomIndex  = NextRoomIndex();
                    var positionedCorridor = new TemplatePositioned(topLeftCorridor.x, topLeftCorridor.y, 0, expandedCorridor, corridorRoomIndex);

                    if (!mapBuilder.CanBePlacedWithoutOverlappingOtherTemplates(positionedCorridor))
                    {
                        return(false);
                    }

                    //Place the corridor
                    mapBuilder.AddPositionedTemplate(positionedCorridor);
                    templates[corridorRoomIndex] = positionedCorridor;
                    IncreaseNextRoomIndex();

                    //Add connections to the old and new rooms
                    connectivityMap.AddRoomConnection(firstDoor.OwnerRoomIndex, corridorRoomIndex);
                    connectivityMap.AddRoomConnection(corridorRoomIndex, secondDoor.OwnerRoomIndex);

                    connectionDoors.Add(new Connection(firstDoor.OwnerRoomIndex, corridorRoomIndex).Ordered, firstDoor);
                    connectionDoors.Add(new Connection(corridorRoomIndex, secondDoor.OwnerRoomIndex).Ordered, secondDoor);
                }

                //Remove both doors from the potential list
                potentialDoors.Remove(firstDoor);
                potentialDoors.Remove(secondDoor);

                return(true);
            }
            catch (ApplicationException ex)
            {
                LogFile.Log.LogEntryDebug("Failed to join doors: " + ex.Message, LogDebugLevel.Medium);
                return(false);
            }
        }