/// <summary>
 /// Create a new doorway for randomizing roms
 /// </summary>
 public DoorInfo(DoorType _type, ConnectionTypes _exit, ConnectionTypes _enter, int _romIndex, RoomInfo _baseRoom)
 {
     BaseRoom      = _baseRoom;
     doorType      = _type;
     enterStyle    = _enter;
     exitStyle     = _exit;
     romArrayIndex = _romIndex;
 }
Beispiel #2
0
        /// <summary>
        /// Eventual features:
        ///     Start Level with switch at start (golden passage style)
        ///
        /// Pseudo code for creating randomizer information
        /// Create an XML file to write to.
        /// foreach level
        ///     foreach door in game (ignoring portal)
        ///         Tell which vanilla room the door is in, and the door index
        ///         Ask if door is ignored.  If so, continue
        ///         Ask for room name to put door into
        ///         if room exists, add.
        ///         Display assumed door type, asking for correction
        ///         Ask for ways to enter doorway
        ///         Ask for ways to exit doorway
        ///     /foreach
        ///     foreach vanilla room
        ///         if room has subrooms
        ///             List subroom names
        ///             foreach Entity in vanilla room
        ///                 Ask if entity is contained within a certain subroom.
        ///                 If so, add entity to room
        ///
        ///             Ask for connections between subrooms
        ///             if no, then continue to next room
        ///             if yes, ask for connection information (which two rooms, connection type from 1 to 2, and connection type from 2 to 1)
        ///             foreach subroom
        ///                 Create header for subroom
        ///                 Write all connections
        ///                 Write all entity indexes
        ///                 foreach doorway
        ///                     if doorway ignored, write that and move on
        ///                     otherwise...
        ///                     Write rom index for doorway
        ///                     Write door type
        ///                     Write the enter/exit styles
        ///
        ///             /foreach
        ///         else
        ///             foreach Entity in vanilla room
        ///                 Ask if entity should be used.
        ///                 If so, add entity to room
        ///             Create header for room
        ///             foreach doorway
        ///                 if doorway ignored, write that and move on
        ///                 otherwise...
        ///                 Write rom index for doorway
        ///                 Write door type
        ///                 Write the enter/exit styles
        ///
        /// </summary>
        private static void CreateRandoInformation()
        {
            using (XmlWriter doc = XmlWriter.Create(directory + "\\" + patchPath + ".xml"))
            {
                //This is a dictionary displaying a list of subroom indexes (from the room dictionary) for each given room number
                Dictionary <int, List <string> > vanillaRooms = new Dictionary <int, List <string> >();
                Dictionary <string, RoomInfo>    rooms        = new Dictionary <string, RoomInfo>();

                doc.WriteStartElement("info");
                for (int passage = 0; passage < 6; passage++)
                {
                    for (int level = 0; level < (passage == 0 || passage == 5 ? 1 : 4); level++)
                    {
                        Console.Write("Starting Level " + passage + " - " + (level + 1) + ".  Do you wish randomize this level? ");
                        if (!GetBoolFromUser(true))
                        {
                            Console.Clear();
                            continue;
                        }

                        rooms.Clear();
                        vanillaRooms.Clear();
                        Console.WriteLine('\n');
                        doc.WriteStartElement("level_" + passage + "_" + level);

                        // Get the start of the level's doorway array

                        int levelID        = GetLevelID(passage, level);
                        int doorArrayIndex = GetPointer(PathCreator.DoorTableLocation + levelID * 4);

                        DebugLog(romBuffer[doorArrayIndex]);

                        int currentDoor = 1;
                        while (romBuffer[doorArrayIndex + currentDoor * 12] != 0x00)
                        {
                            new DoorInfo(doorArrayIndex, currentDoor++, ref rooms, ref vanillaRooms);
                            Console.Clear();
                        }

                        Console.WriteLine("Do you want to make any extra connections between rooms?  (format is \"VanillaRoomIndex-SubroomName\")");
                        List <RoomConnection> roomConnections = new List <RoomConnection>();

                        if (GetBoolFromUser(true))
                        {
                            do
                            {
                                Console.Write("Name of the first: ");
                                string first = ReadLine();
                                Console.Write("Name of the second: ");
                                string second = ReadLine();

                                RoomInfo roomOne = null, roomTwo = null;

                                for (int i = 0; i < vanillaRooms.Count; i++)
                                {
                                    if (vanillaRooms[i].Contains(first))
                                    {
                                        roomOne = rooms[first];
                                    }
                                    if (vanillaRooms[i].Contains(second))
                                    {
                                        roomTwo = rooms[second];
                                    }
                                }
                                if (roomOne == null && first.Split('-').Length > 1)
                                {
                                    Console.WriteLine(first + " does not exist.  Do you wish to create it?");
                                    if (GetBoolFromUser(true))
                                    {
                                        int value = int.Parse(first.Split('-')[0]);
                                        vanillaRooms[value].Add(first);
                                        rooms.Add(first, roomOne = new RoomInfo(first));
                                    }
                                }
                                if (roomTwo == null && second.Split('-').Length > 1)
                                {
                                    Console.WriteLine(second + " does not exist.  Do you wish to create it?");
                                    if (GetBoolFromUser(true))
                                    {
                                        int value = int.Parse(second.Split('-')[0]);
                                        vanillaRooms[value].Add(second);
                                        rooms.Add(second, roomTwo = new RoomInfo(second));
                                    }
                                }
                                if (roomOne != null && roomTwo != null)
                                {
                                    Console.WriteLine("Connection types - " + CONNECTION_TYPES_DISPLAY);
                                    roomConnections.Add(new RoomConnection(roomOne, roomTwo, ReadConnectionValues("Connection types from first to second: "), ReadConnectionValues("Connection types from second to first: ")));
                                }
                                else
                                {
                                    Console.WriteLine("Rooms name(s) invalid.");
                                }

                                Console.WriteLine("Do you want to make another?");
                            }while (GetBoolFromUser(true));
                        }

                        //Foreach vanilla room in game
                        foreach (int i in vanillaRooms.Keys)
                        {
                            if (vanillaRooms[i].Count == 1)
                            {
                                ///             Create header for room
                                ///             foreach Entity in vanilla room
                                ///                 Ask if entity should be used.
                                ///                 If so, write entityIndex
                                ///             foreach doorway
                                ///                 if doorway ignored, write that and move on
                                ///                 otherwise...
                                ///                 Write rom index for doorway
                                ///                 Write door type
                                ///                 Write the enter/exit styles

                                Console.Clear();
                                EntityInfo[] entities = PathCreator.GetEntities(passage, level, i);

                                doc.WriteStartElement("room_" + i);

                                for (int eI = 0; eI < entities.Length; eI++)
                                {
                                    WriteEntityToDoc(doc, entities[eI], eI, i);
                                }
                                foreach (DoorInfo door in rooms[vanillaRooms[i][0]].doorList)
                                {
                                    WriteDoorToDoc(doc, door);
                                }
                                doc.WriteEndElement();
                            }
                            else
                            {
                                ///             List subroom names
                                ///             foreach Entity in vanilla room
                                ///                 Ask if entity is contained within a certain subroom.
                                ///                 If so, add entity to room
                                ///
                                ///             Ask for connections between subrooms
                                ///             if no, then continue to next room
                                ///             if yes, ask for connection information (which two rooms, connection type from 1 to 2, and connection type from 2 to 1)
                                ///             foreach subroom
                                ///                 Create header for subroom
                                ///                 Write all connections
                                ///                 Write all entity indexes
                                ///                 foreach doorway
                                ///                     if doorway ignored, write that and move on
                                ///                     otherwise...
                                ///                     Write rom index for doorway
                                ///                     Write door type
                                ///                     Write the enter/exit styles
                                ///
                                ///             /foreach
                                Console.Clear();

                                Console.WriteLine("Current Room: " + i);
                                Console.WriteLine("Subroom names");
                                foreach (string s in vanillaRooms[i])
                                {
                                    Console.Write("\"{0}\" - ", s);
                                }

                                EntityInfo[] entities = PathCreator.GetEntities(passage, level, i);

                                for (int eI = 0; eI < entities.Length; eI++)
                                {
                                    Console.WriteLine("\nRoom:{2} X:{0} Y:{1} Type:{3}", entities[eI].X, entities[eI].Y, i, entities[eI].originalType);
                                    Console.WriteLine("What subroom do you want this entity to be placed in? (leave blank if ignoring entity)");
                                    string input = ReadLine();
                                    if (input == "")
                                    {
                                        continue;
                                    }
                                    else if (vanillaRooms[i].Contains(input))
                                    {
                                        rooms[input].entityList.Add(entities[eI]);
                                    }
                                    else if (vanillaRooms[i].Contains(i + "-" + input))
                                    {
                                        rooms[i + "-" + input].entityList.Add(entities[eI]);
                                    }
                                    else
                                    {
                                        Console.WriteLine("Sorry, but that subroom doesn't exist.  Please try again!");
                                        eI--;
                                    }
                                }

                                foreach (string s in vanillaRooms[i])
                                {
                                    doc.WriteStartElement("room_" + s);
                                    RoomInfo room = rooms[s];
                                    foreach (DoorInfo door in room.doorList)
                                    {
                                        WriteDoorToDoc(doc, door);
                                    }
                                    foreach (EntityInfo entity in room.entityList)
                                    {
                                        WriteEntityToDoc(doc, entity);
                                    }
                                    doc.WriteEndElement();
                                }
                            }
                        }
                        foreach (RoomConnection connection in roomConnections)
                        {
                            WriteRoomConnectionToDoc(doc, connection);
                        }
                        Console.Clear();
                        doc.WriteEndElement();
                    }
                }
                doc.WriteEndElement();

                doc.Flush();
            }
        }
Beispiel #3
0
        public static void CreatePath(int passage, int level, XmlNode levelNode)
        {
            if (passage == 5)
            {
                hasEntities = false;
            }

            Console.WriteLine("--- Randomizing level {0};{1} ---", PassageName(passage), level + 1);
            int levelHeaderPointer = LevelHeadersLocation + Program.GetLevelHeaderIndex(passage, level) * 12;
            int roomMax            = Program.romBuffer[levelHeaderPointer + 1];

            for (int i = 0; i < roomMax; i++)
            {
                FillVanillaEntities(passage, level, i);
            }

            foreach (XmlNode node in levelNode.ChildNodes)
            {
                if (node.Name == "roomConnection")
                {
                    LoadRoomConnection(node);
                }
                else
                {
                    switch (node.Name.Split('_')[0])
                    {
                    case "room":
                        LoadRoom(node);
                        break;
                    }
                }
            }

            portalRoom = roomList[0];
            List <EntityInfo> levelEntities = new List <EntityInfo>();

            foreach (List <EntityInfo> info in vanillaEntities)
            {
                levelEntities.AddRange(info);
            }

            List <RoomInfo> inLogic = new List <RoomInfo>();

            roomsNotInLogic.AddRange(roomList);

            doorPairs.FinalizeDoors();

RestartLogic:

            BranchLogic(inLogic, portalRoom);

            List <RoomInfo> checkedRooms = new List <RoomInfo>();

            /// While there are still rooms not in logic yet
            ///     Get two empty pointers, one for door in logic, one out of logic
            ///     while failed
            ///         Pick random room in and out of logic.
            ///         Pick random door from out of logic room.
            ///         Save door type
            ///         Save all doors of the opposite type from in logic room in array
            ///         Pick two random doors.  If second array is empty, repick rooms from in and out of logic
            ///     (We don't need in logic room anymore)
            ///     Save the two rooms on each side of the in logic door
            ///     Save the two connected doors
            ///     Disconnect doors
            ///     if one of the two in logic room isn't connected to portal
            ///         reset all rooms on that branch
            ///     Set a pointer to one of the rooms still in logic
            ///     Connect the new doors
            ///     Redo before logic path on the once out of logic door's base room
            ///
            /// Connect up the rest of the doors
            count = 0;
            /// While there are still rooms not in logic yet
            while (roomsNotInLogic.Count > 0)
            {
                Program.DebugLog("StartOfLoop");
                for (int i = roomsNotInLogic.Count; i > 0; i--)
                {
                    if (roomsNotInLogic[i - 1].doorList.Count == 0)
                    {
                        roomsNotInLogic.RemoveAt(i - 1);
                    }
                }
                /// Get two empty pointers, one for door in logic, one out of logic
                DoorInfo inLogicDoor = null, outOfLogicDoor;

                /// Get all possible door pairings between out of logic doors and in logic doors that are already connected.
                {
                    DoorPairing[] pairs = FindPossiblePairs(roomsNotInLogic.ToArray(), inLogic.ToArray(), true);

                    if (pairs.Length == 0)
                    {
                        inLogic[Program.GetRandomInt(inLogic.Count)].ResetRoom(inLogic, roomsNotInLogic, doorPairs);
                        goto RestartLogic;
                    }
                    DoorPairing pair = pairs[Program.GetRandomInt(pairs.Length)];
                    /// Pick a random pair.
                    /// If no pairs exist, throw error
                    ///
                }
                /// while failed
                do
                {
                    /// Pick random room in logic...
                    int v = Program.GetRandomInt(inLogic.Count);
                    Program.DebugLog("Index {0}", v);
                    outOfLogicDoor = null;

                    RoomInfo inLogicRoom = inLogic[v], outofLogicRoom;

                    /// ...and out of logic.
                    /// Pick random door from out of logic room.
                    while (outOfLogicDoor == null || !outOfLogicDoor.CanWalkInto(Program.pathingLogicBefore))
                    {
                        outofLogicRoom = roomsNotInLogic[Program.GetRandomInt(roomsNotInLogic.Count)];
                        if (outofLogicRoom.doorList.Count > 0)
                        {
                            outOfLogicDoor = outofLogicRoom.doorList[Program.GetRandomInt(outofLogicRoom.doorList.Count)];
                        }
                    }

                    /// Save door type
                    DoorType type = outOfLogicDoor.doorType;

                    List <DoorInfo> inLogicDoors = new List <DoorInfo>();
                    /// Save all doors of the opposite type from in logic room in array
                    foreach (DoorInfo door in inLogicRoom.doorList)
                    {
                        if ((int)door.doorType == -(int)type && door.connectedDoor != null)
                        {
                            inLogicDoors.Add(door);
                        }
                    }
                    /// If second array is empty, redo loop
                    if (inLogicDoors.Count == 0)
                    {
                        continue;
                    }
                    /// Pick two random doors.
                    inLogicDoor = inLogicDoors[Program.GetRandomInt(inLogicDoors.Count)];

                    break;
                } while (true);

                /// Save the two connected doors
                DoorInfo firstDoor = inLogicDoor, secondDoor = inLogicDoor.connectedDoor;
                /// Save the two rooms on each side of the in logic door
                RoomInfo roomOne = firstDoor.BaseRoom, roomTwo = secondDoor.BaseRoom;

                /// Disconnect doors

                doorPairs.DisconnectDoor(firstDoor);

                /// if one of the two in logic room isn't connected to portal

                checkedRooms.Clear();
                if (!IsConnectedToFirstRoom(roomOne, checkedRooms))
                {
                    ClearRoom(inLogic, roomsNotInLogic, doorPairs);
                    checkedRooms.Clear();
                    ClearRoom = null;
                }
                if (!IsConnectedToFirstRoom(roomTwo, checkedRooms))
                {
                    ClearRoom = null;
                    checkedRooms.Clear();

                    BranchLogic(inLogic, outOfLogicDoor.BaseRoom);

                    doorPairs.ConnectDoors(firstDoor, secondDoor);

                    continue;
                }

                doorPairs.ConnectDoors(inLogicDoor, outOfLogicDoor);

                BranchLogic(inLogic, outOfLogicDoor.BaseRoom);
            }
            Program.DebugLog("NoMoreRooms out of Logic");

            //List<RoomInfo> tempRooms = new List<RoomInfo>();
            //checkedRooms.Clear();
            //foreach (RoomInfo info in roomList)
            //{
            //    if (checkedRooms.Contains(info))
            //        continue;
            //    if (!CanEnterFirstRoom(info, tempRooms, true))
            //    {
            //        foreach (RoomInfo roomBad in tempRooms)
            //        {
            //            roomBad.ResetRoom(inLogic, roomsNotInLogic, doorPairs);
            //        }
            //        goto RestartLogic;
            //    }
            //    checkedRooms.AddRange(tempRooms);
            //}

            //checkedRooms.Clear();
            //tempRooms.Clear();
            //foreach (RoomInfo info in roomList)
            //{
            //    if (checkedRooms.Contains(info))
            //        continue;
            //    if (!CanEnterFirstRoom(info, tempRooms, false))
            //    {
            //        foreach (RoomInfo roomBad in tempRooms)
            //        {
            //            roomBad.ResetRoom(inLogic, roomsNotInLogic, doorPairs);
            //        }
            //        goto RestartLogic;
            //    }
            //    checkedRooms.AddRange(tempRooms);
            //}

            doorPairs.ConnectLeftoverDoors();

            RandomizeEntities(inLogic);

            int levelID        = Program.GetLevelID(passage, level);
            int doorArrayStart = Program.GetPointer(DoorTableLocation + levelID * 4);

            foreach (RoomInfo room in inLogic)
            {
                foreach (DoorInfo door in room.doorList)
                {
                    door.SetRomInfo(doorArrayStart);
                }
                foreach (EntityInfo entity in room.entityList)
                {
                    entity.ChangeRom();
                }
            }

            Clear();
        }
Beispiel #4
0
        //private static DoorInfo GetRandomDoor(DoorInfo door)
        //{

        //}

        private static void RandomizeEntities(List <RoomInfo> accessFromStart)
        {
            if (!hasEntities)
            {
                return;
            }
            RoomInfo randomRoom = null;

            do
            {
                randomRoom = accessFromStart[Program.GetRandomInt(accessFromStart.Count)];
                if (randomRoom.entityList.Count == 0)
                {
                    randomRoom = null;
                }
            }while (randomRoom == null);

            randomRoom.entityList[Program.GetRandomInt(randomRoom.entityList.Count)].entityType = EntityType.FrogSwitch;
            randomRoom = null;

            for (int i = 1; i <= 9; i++)
            {
                randomRoom = null;
                do
                {
                    randomRoom = roomList[Program.GetRandomInt(roomList.Count)];
                    if (randomRoom.entityList.Count == 0)
                    {
                        randomRoom = null;
                        continue;
                    }
                    bool canPlaceEntity = false;
                    foreach (EntityInfo ent in randomRoom.entityList)
                    {
                        if (ent.entityType == EntityType.BigGem)
                        {
                            canPlaceEntity = true;
                            break;
                        }
                    }
                    if (!canPlaceEntity)
                    {
                        randomRoom = null;
                    }
                }while (randomRoom == null);

                int entityNumber = -1;
                do
                {
                    entityNumber = Program.GetRandomInt(randomRoom.entityList.Count);

                    if (randomRoom.entityList[entityNumber].entityType != EntityType.BigGem)
                    {
                        entityNumber = -1;
                    }
                }while (entityNumber == -1);
                randomRoom.entityList[entityNumber].entityType = (EntityType)i;

                if (i == 6)
                {
                    i = 8;
                }
            }
        }
Beispiel #5
0
 public RoomInfo GetOtherRoom(RoomInfo room)
 {
     return(room == firstRoom ? secondRoom : firstRoom);
 }