private static DoorInfo LoadDoor(XmlNode doorNode, RoomInfo baseRoom) { DoorInfo door; ConnectionTypes enterType = ConnectionTypes.Default, exitType = ConnectionTypes.Default; DoorType doorType = DoorType.Door; int index = 0; foreach (XmlNode node in doorNode) { switch (node.Name) { case "romIndex": index = int.Parse(node.InnerText); break; case "type": doorType = GetDoorType(node.InnerText); break; case "exitStyle": exitType = (ConnectionTypes)int.Parse(node.InnerText); break; case "enterStyle": enterType = (ConnectionTypes)int.Parse(node.InnerText); break; } } doorList.Add(door = new DoorInfo(doorType, exitType, enterType, index, baseRoom)); baseRoom.doorList.Add(door); doorPairs.AddDoor(door); return(door); }
private static void LoadRoom(XmlNode roomNode) { string name = roomNode.Name.Split('_')[1]; int vanillaRoomNumber = int.Parse(name.Contains('-') ? name.Split('-')[0] : name); if (!vanillaRoomNumbers.Contains(vanillaRoomNumber)) { vanillaRoomNumbers.Add(vanillaRoomNumber); } RoomInfo room; roomList.Add(room = new RoomInfo(name)); foreach (XmlNode node in roomNode.ChildNodes) { switch (node.Name) { case "door": DoorInfo door = LoadDoor(node, room); break; case "entity": room.entityList.Add(vanillaEntities[vanillaRoomNumber][int.Parse(node.InnerText)]); break; } } }
public void ConnectDoors(DoorInfo one, DoorInfo two) { if (!unconnectedDoors[one.doorType].Contains(one) || !unconnectedDoors[two.doorType].Contains(two)) { return; } unconnectedDoors[one.doorType].Remove(one); unconnectedDoors[two.doorType].Remove(two); connectedPairs.Add(new DoorPairing(one, two)); one.Connect(two); }
private static void BranchPathBeforeSwitch(RoomInfo room, List <RoomInfo> array, List <DoorInfo> doorArray, List <RoomInfo> roomConnections) { if (!array.Contains(room)) { array.Add(room); } else { return; } if (roomsNotInLogic.Contains(room)) { roomsNotInLogic.Remove(room); } foreach (DoorInfo door in room.doorList) { if (door.connectedDoor == null && door.CanWalkOutOf(Program.pathingLogicBefore) && doorPairs.HasConnections(door, Program.pathingLogicBefore)) { DoorPairing[] pairings = FindPossiblePairs(roomList.ToArray(), door, false); if (pairings.Length == 0) { return; } DoorInfo newDoor = pairings[Program.GetRandomInt(pairings.Length)].first; doorPairs.ConnectDoors(newDoor, door); BranchPathBeforeSwitch(newDoor.BaseRoom, array, doorArray, roomConnections); } else if (door.CanWalkOutOf(Program.pathingLogicAfter)) { if (doorArray != null) { doorArray.Add(door); } } } foreach (RoomConnection connection in room.connectionList) { if (connection.CanPassThrough(room, Program.pathingLogicBefore)) { BranchPathBeforeSwitch(connection.GetOtherRoom(room), array, doorArray, roomConnections); } else if (connection.CanPassThrough(room, Program.pathingLogicAfter)) { if (roomConnections != null) { roomConnections.Add(connection.firstRoom == room ? connection.secondRoom : connection.firstRoom); } } } }
public bool HasConnections(DoorInfo info, ConnectionTypes types) { DoorType type = (DoorType)(-(int)info.doorType); //return true; foreach (DoorInfo door in unconnectedDoors[type]) { if (door.CanWalkInto(types)) { return(true); } } return(false); }
private static void WriteDoorToDoc(XmlWriter doc, DoorInfo door) { doc.WriteStartElement("door"); if (door.isIgnored) { doc.WriteElementString("isIgnored", "1"); } else { doc.WriteElementString("romIndex", door.romArrayIndex.ToString()); doc.WriteElementString("type", door.doorType.ToString()); doc.WriteElementString("enterStyle", ((int)door.enterStyle).ToString()); doc.WriteElementString("exitStyle", ((int)door.exitStyle).ToString()); } doc.WriteEndElement(); }
public void DisconnectDoor(DoorInfo door) { DoorPairing?pairing = null; foreach (DoorPairing pair in connectedPairs) { if (door == pair.first || door == pair.second) { pairing = pair; break; } } if (pairing != null) { DoorInfo one = pairing.Value.first, two = pairing.Value.second; connectedPairs.Remove(pairing.Value); unconnectedDoors[one.doorType].Add(one); unconnectedDoors[two.doorType].Add(two); one.connectedDoor = null; two.connectedDoor = null; } }
private static DoorPairing[] FindPossiblePairs(RoomInfo[] listOne, DoorInfo two, bool?onlyConnected = null) { List <DoorPairing> retVal = new List <DoorPairing>(); foreach (RoomInfo outRoom in listOne) { foreach (DoorInfo outDoor in outRoom.doorList) { if (outDoor == two) { continue; } DoorType type = (DoorType)(-(int)outDoor.doorType); if ((onlyConnected == null || (onlyConnected.Value == (two.connectedDoor != null))) && two.doorType == type) { retVal.Add(new DoorPairing(outDoor, two)); } } } return(retVal.ToArray()); }
private static void BranchPathAfterSwitch(List <RoomInfo> alreadyFound, RoomInfo room) { if (alreadyFound.Contains(room)) { return; } alreadyFound.Add(room); if (roomsNotInLogic.Contains(room)) { roomsNotInLogic.Remove(room); } foreach (DoorInfo door in room.doorList) { if (door.connectedDoor == null && door.CanWalkOutOf(Program.pathingLogicAfter) && doorPairs.HasConnections(door, Program.pathingLogicBefore)) { DoorPairing[] pairings = FindPossiblePairs(roomList.ToArray(), door, false); if (pairings.Length == 0) { return; } DoorInfo newDoor = pairings[Program.GetRandomInt(pairings.Length)].first; doorPairs.ConnectDoors(door, newDoor); BranchPathAfterSwitch(alreadyFound, newDoor.BaseRoom); } } foreach (RoomConnection connection in room.connectionList) { if (connection.CanPassThrough(room, Program.pathingLogicAfter)) { BranchPathAfterSwitch(alreadyFound, connection.GetOtherRoom(room)); } } }
public void Connect(DoorInfo door) { door.connectedDoor = this; connectedDoor = door; }
public void AddDoor(DoorInfo door) { unconnectedDoors[door.doorType].Add(door); }
public DoorPairing(DoorInfo _first, DoorInfo _second) { first = _first; second = _second; }
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(); }