/// <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; }
/// <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(); } }
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(); }
//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; } } }
public RoomInfo GetOtherRoom(RoomInfo room) { return(room == firstRoom ? secondRoom : firstRoom); }