public var container : Transform = null; //Le gameobject dans lequel les objets seront ajoutés. Doit etre vide. public var sizeX : int = 100; //La largeur max en blocs de chaque étage généré. public var sizeZ : int = 80; //La longueur max en blocs de chaque étage généré. public var desiredNumberOfRooms : int = 500; //Le nombre de salles souhaité public var roomsOpeningness : int = 9; //Les chances sur 10 de fermer une ouverture d'une salle pour les couloirs reliant les grandes salles. Plus le nombre est grand, plus ce sera des couloirs. private var oldRoomsOpeningness : int = 9; //Pour le reset, osef. public var newRoomsOpeningness : int = 5; //Les chances sur 10 de fermer une ouverture d'une salle qui est pas un couloir. Plus le nombre est grand, plus ce sera des couloirs. public var roomSize : int = 5; //La taille de chaque salle. (les salles doivent etre carrées) public var playerTransform : Transform; //Le transform du player, utilisé pour le replacer dans la salle de départ. public var startRoomAddon : Transform; //Le transform utilisé pour marquer la zone de départ. Une lumière colorée suffit. public var EndRoom : Transform[]; //Le transform de salle cul de sac. public var IRoom : Transform[]; //Le transform de salle en I public var LRoom : Transform[]; //Le transform de salle en L public var TRoom : Transform[]; //Le transform de salle en T public var OpenRoom : Transform[]; //Le transform de salle en croix public var BigRooms : Transform[]; //Le transform de salle 5x5, structure. public var seed : int = 123456; //Une seed similaire sur 2 postes fera toujours la meme map. private var roomsTable : int[,]; //Tableau disant quelle salle est prise ou pas private var numberOfRooms : int = 0; //Nombre de salles existantes. private var coordinatesToGenerate : Vector2[]; //Les coordonnées des salles à générer, se vide et remplit tout seul. private var remainingRoomsToGenerate : int = 0; //Le nombre de salles restantes à générer. private var generating : boolean = false; public var debugTransform : Transform; public var roomCreationDelay : float = 0.005f; function Start () { // Vérification qu'on a bien donné un container. Si non, on prend l'un des enfants de l'objet, s'il y a. Si y'a pas, ça buggera. if(container == null) { var allChildren = gameObject.GetComponentsInChildren(Transform); if(transform.Find("Blocks container")) { container = transform.Find("Blocks container"); } } // Vérification de seed non nulle. Si seed nulle, elle est définie à 123456. if(seed < 1000) { seed += 1000; Debug.LogError("seed < 1000 : On la passe à " + seed); } oldRoomsOpeningness = roomsOpeningness; // Finalement, on génère la map. regenerateMap(); } function Update () { } function OnGUI() { if(GUI.Button(Rect(10,10,100,100), "Regenerate")) regenerateMap(); if(GUI.Button(Rect(110,10,100,100), "Randomize")) { seed = Random.Range(1000,20000); regenerateMap(); } if(!generating) seed = parseInt(GUI.TextField(Rect(10,120,100,20), seed+"")); else GUI.Label(Rect(10,120,100,20), seed+""); if(seed < 1000) { seed += 1000; } } /** * Fonction qui génère la map, en remplissant le tableau des blocs, et ajoutant les blocs correspondants dans le container. * Place également le joueur dans la salle de début (marquée par le firstRoomAddon) */ function regenerateMap() { generating = true; // On reset le tableau, et on vide le container. roomsTable = null; emptyContainer(); numberOfRooms = 0; roomsOpeningness = newRoomsOpeningness; coordinatesToGenerate = null; coordinatesToGenerate = new Vector2[3000]; // On crée le tableau, il faudra changer ça, c'est moche et pourri y'a une solution simple mais je connais pas la syntaxe et ai pas le net. roomsTable = new int[sizeX,sizeZ]; for(var a : int = 0; a < sizeX; a++) { for(var b : int = 0; b < sizeZ; b++) { setRoomsTable(a,b, -1); //Non défini } } var tempNumberOfRooms : int = 0; var tempNumberOfRooms2 : int = 0; var bigRoomsCreated : Vector2[] = new Vector2[BigRooms.Length]; // On place les salles structures. // On prend juste le tableau BigRooms et on les place au pif dans le tas. // Pour pouvoir placer la salle, il faut que tous les blocs à son emplacement soient à -1, et que les sorties soient soit à 1 soit à -1. for(var idBig : int = 0; idBig < BigRooms.Length; idBig++) { var isBigRoomCreated : int = 5; //5 essais avant qu'on abandonne la création d'une grande salle. while(isBigRoomCreated > 0) { var bigRoomCoordinates : Vector2 = Vector2(randomWithSeed(5,sizeX-5, 12 + tempNumberOfRooms), randomWithSeed(5,sizeZ-5, 5 + tempNumberOfRooms)); //On va voir si les blocs sont libres ici var canPlaceHere : boolean = true; //Check de la salle, il faut que rien ne soit généré dedans, et à un bloc à coté ! for(var bigRoomX : int = -BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft - 1; bigRoomX <= BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 1; bigRoomX ++) { for(var bigRoomZ : int = -BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom - 1; bigRoomZ <= BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp + 1; bigRoomZ ++) { if(isThereARoom(bigRoomCoordinates.x + bigRoomX, bigRoomCoordinates.y + bigRoomZ) != -1) canPlaceHere = false; } } if(canPlaceHere) { //Y'a la place, youpi ! isBigRoomCreated = 0; //On commence par remplir le tableau des salles. for(bigRoomX = -BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft; bigRoomX <= BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight; bigRoomX ++) { for(bigRoomZ = -BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom; bigRoomZ <= BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp; bigRoomZ ++) { setRoomsTable(bigRoomCoordinates.x + bigRoomX, bigRoomCoordinates.y + bigRoomZ, 1); } } //Puis on met les ouvertures, et surtout les murs. //Haut-bas for(bigRoomX = -(BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft + 1); bigRoomX <= BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 1; bigRoomX ++) { //En haut if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnUp && bigRoomX == BigRooms[idBig].GetComponent(bigRoomScript).upOpeningOffset) { //Une sortie, on la fait générer coordinatesToGenerate[tempNumberOfRooms] = Vector2(bigRoomCoordinates.x + bigRoomX, bigRoomCoordinates.y + BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp + 1); tempNumberOfRooms++; coordinatesToGenerate[tempNumberOfRooms] = Vector2(bigRoomCoordinates.x + bigRoomX, bigRoomCoordinates.y + BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp + 2); tempNumberOfRooms++; } else { //Pas sortie, on bloque en 0 setRoomsTable(bigRoomCoordinates.x + bigRoomX, bigRoomCoordinates.y + (BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp + 1), 0); //var temp23 : Transform = Instantiate(debugTransform, Vector3((bigRoomCoordinates.x + bigRoomX) * roomSize, 0, (bigRoomCoordinates.y + BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom + 1) * roomSize), Quaternion.identity); //temp23.name = idBig + "up"; } //En bas if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnBottom && bigRoomX == BigRooms[idBig].GetComponent(bigRoomScript).bottomOpeningOffset) { //Une sortie, on la fait générer coordinatesToGenerate[tempNumberOfRooms] = Vector2(bigRoomCoordinates.x + bigRoomX, bigRoomCoordinates.y - (BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom + 1)); tempNumberOfRooms++; coordinatesToGenerate[tempNumberOfRooms] = Vector2(bigRoomCoordinates.x + bigRoomX, bigRoomCoordinates.y - (BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom + 2)); tempNumberOfRooms++; } else { //Pas sortie, on bloque en 0 setRoomsTable(bigRoomCoordinates.x + bigRoomX, bigRoomCoordinates.y - (BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom + 1), 0); //temp23 = Instantiate(debugTransform, Vector3((bigRoomCoordinates.x + bigRoomX) * roomSize, 0, (bigRoomCoordinates.y - (BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom + 1)) * roomSize), Quaternion.identity); //temp23.name = idBig + "bottom"; } } //Gauche-droite for(bigRoomZ = -BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom; bigRoomZ <= BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp; bigRoomZ ++) { //A droite if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnRight && bigRoomZ == BigRooms[idBig].GetComponent(bigRoomScript).rightOpeningOffset) { //Une sortie, on la fait générer coordinatesToGenerate[tempNumberOfRooms] = Vector2(bigRoomCoordinates.x + BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 1, bigRoomCoordinates.y + bigRoomZ); tempNumberOfRooms++; coordinatesToGenerate[tempNumberOfRooms] = Vector2(bigRoomCoordinates.x + BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 2, bigRoomCoordinates.y + bigRoomZ); tempNumberOfRooms++; } else { //Pas sortie, on bloque en 0 setRoomsTable(bigRoomCoordinates.x + BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 1, bigRoomCoordinates.y + bigRoomZ, 0); //temp23 = Instantiate(debugTransform, Vector3((bigRoomCoordinates.x + BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 1) * roomSize, 0, (bigRoomCoordinates.y + bigRoomZ) * roomSize), Quaternion.identity); //temp23.name = idBig + "right"; } //A gauche if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnLeft && bigRoomZ == BigRooms[idBig].GetComponent(bigRoomScript).leftOpeningOffset) { //Une sortie, on la fait générer coordinatesToGenerate[tempNumberOfRooms] = Vector2(bigRoomCoordinates.x - (BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft + 1), bigRoomCoordinates.y + bigRoomZ); tempNumberOfRooms++; coordinatesToGenerate[tempNumberOfRooms] = Vector2(bigRoomCoordinates.x - (BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft + 2), bigRoomCoordinates.y + bigRoomZ); tempNumberOfRooms++; } else { //Pas sortie, on bloque en 0 setRoomsTable(bigRoomCoordinates.x - BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft - 1, bigRoomCoordinates.y + bigRoomZ, 0); //temp23 = Instantiate(debugTransform, Vector3((bigRoomCoordinates.x - (BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft + 1)) * roomSize, 0, (bigRoomCoordinates.y + bigRoomZ) * roomSize), Quaternion.identity); //temp23.name = idBig + "left"; } } //Et finalement on spawne la salle. var bigRoomCreated : Transform = Instantiate(BigRooms[idBig], Vector3(bigRoomCoordinates.x * roomSize, 0, bigRoomCoordinates.y * roomSize), Quaternion.identity); bigRoomCreated.name = "Big ("+idBig+")"; bigRoomCreated.parent = container; //On l'ajoute à la liste bigRoomsCreated[idBig] = bigRoomCoordinates; // Si première salle, c'est le spawn. if(idBig == 0) { bigRoomCreated.name = "Start room"; var startRoomAddon : Transform = Instantiate(startRoomAddon, Vector3(bigRoomCoordinates.x * roomSize, 0, bigRoomCoordinates.y * roomSize), Quaternion.identity); startRoomAddon.parent = container; // On bouge le joueur dedans. playerTransform.position = Vector3(bigRoomCoordinates.x * roomSize, 0.2f, bigRoomCoordinates.y * roomSize); } } else { //Y'avait pas de place, alors on recommence, en enlevant un essai à faire. isBigRoomCreated--; } } } tempNumberOfRooms2 = tempNumberOfRooms; // Maintenant on relie les salles structures. Pour ça, on fait des pointillés un peu chiadés entre quelques unes d'entre elles, dans l'ordre. // On va lier chacune à la plus proche possible. for(idBig = 0; idBig < BigRooms.Length; idBig++) { if(bigRoomsCreated[idBig] != null) { //Check si la salle a été créée // D'abord relier les plus proches. var idDestination : int = 0; var distance : float = 10000; // On trouve la plus proche for(var idBig2 : int = 0; idBig2 < BigRooms.Length; idBig2 ++) { var tempDistance : float = 3 * Mathf.Sqrt(Mathf.Pow(Mathf.Abs(bigRoomsCreated[idBig2].x - bigRoomsCreated[idBig].x), 2) + Mathf.Pow(Mathf.Abs(bigRoomsCreated[idBig2].y - bigRoomsCreated[idBig].y), 2) ); if(tempDistance < distance && idBig != idBig2) { distance = tempDistance; idDestination = idBig2; } } while(idDestination != -1 && idDestination < bigRoomsCreated.Length) { //Petit truc sale pour faire la suite 1 fois avec le plus proche, et 1 fois avec le suivant si c'est pas le meme. if(idDestination != idBig - 1) { //On fait pas le chemin à l'envers. var numberOfSteps : float = Mathf.Sqrt(distance); var debut : Vector2 = bigRoomsCreated[idBig]; var fin : Vector2 = debut; var destination : Vector2 = bigRoomsCreated[idDestination]; //Le centre de la salle destination, c'est pas bon, il faut prendre l'une des sorties, si y'en a du bon coté ! // Amélioration du début et fin, pour prendre les sorties si on peut. // Gauche -> droite if(BigRooms[idDestination].GetComponent(bigRoomScript).isOpenOnLeft && debut.x + 5 < fin.x) { // Si le début est à gauche de la fin, et que la fin est ouverte à gauche, la destination est l'ouverture gauche. destination += Vector2(-BigRooms[idDestination].GetComponent(bigRoomScript).widthOnLeft - 2, BigRooms[idDestination].GetComponent(bigRoomScript).leftOpeningOffset); if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnRight) { // Si le début est ouvert à droite, le point de départ est l'ouverture droite debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 2, BigRooms[idBig].GetComponent(bigRoomScript).rightOpeningOffset); } else { // Si le début est fermé à droite, on check les autres sorties possibles if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnUp && debut.y + 5 < fin.y) { // Si le début est en bas de la fin, et qu'il est ouvert en haut, le départ est l'ouverture haut debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).upOpeningOffset, BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp + 2); } if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnBottom && debut.y - 5 > fin.y) { // Si le début est en haut de la fin, et qu'il est ouvert en bas, le départ est l'ouverture bas debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).bottomOpeningOffset, -BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom - 2); } } } // Droite -> Gauche if(BigRooms[idDestination].GetComponent(bigRoomScript).isOpenOnRight && debut.x - 5 > fin.x) { // Si le début est à droite de la fin, et que la fin est ouverte à droite, la destination est l'ouverture droite. destination += Vector2(BigRooms[idDestination].GetComponent(bigRoomScript).widthOnRight + 2, BigRooms[idDestination].GetComponent(bigRoomScript).rightOpeningOffset); if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnLeft) { // Si le début est ouvert à gauche, le point de départ est l'ouverture gauche debut += Vector2(-BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft - 2, BigRooms[idBig].GetComponent(bigRoomScript).leftOpeningOffset); } else { // Si le début est fermé à gauche, on check les autres sorties possibles if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnUp && debut.y + 5 < fin.y) { // Si le début est en bas de la fin, et qu'il est ouvert en haut, le départ est l'ouverture haut debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).upOpeningOffset, BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp + 2); } if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnBottom && debut.y - 5 > fin.y) { // Si le début est en haut de la fin, et qu'il est ouvert en bas, le départ est l'ouverture bas debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).bottomOpeningOffset, -BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom - 2); } } } // Haut -> Bas if(BigRooms[idDestination].GetComponent(bigRoomScript).isOpenOnUp && debut.y + 5 < fin.y) { // Si le début est en haut de la fin, et que la fin est ouverte en haut, la destination est l'ouverture haute. destination += Vector2(BigRooms[idDestination].GetComponent(bigRoomScript).upOpeningOffset, BigRooms[idDestination].GetComponent(bigRoomScript).heightOnUp + 2); if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnBottom) { // Si le début est ouvert en bas, le point de départ est l'ouverture bas debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).bottomOpeningOffset, -BigRooms[idBig].GetComponent(bigRoomScript).heightOnBottom - 2); } else { // Si le début est fermé en bas, on check les autres sorties possibles if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnRight && debut.x + 5 < fin.x) { // Si le début est à gauche de la fin, et qu'il est ouvert à droite, le départ est l'ouverture droite debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 2, BigRooms[idBig].GetComponent(bigRoomScript).rightOpeningOffset); } if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnLeft && debut.x - 5 > fin.x) { // Si le début est à droite de la fin, et qu'il est ouvert à gauche, le départ est l'ouverture gauche debut += Vector2(-BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft - 2, BigRooms[idBig].GetComponent(bigRoomScript).leftOpeningOffset); } } } // Bas -> Haut if(BigRooms[idDestination].GetComponent(bigRoomScript).isOpenOnBottom && debut.y - 5 > fin.y) { // Si le début est en bas de la fin, et que la fin est ouverte en bas, la destination est l'ouverture bas. destination += Vector2(BigRooms[idDestination].GetComponent(bigRoomScript).bottomOpeningOffset, -BigRooms[idDestination].GetComponent(bigRoomScript).heightOnBottom - 2); if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnUp) { // Si le début est ouvert en haut, le point de départ est l'ouverture haut debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).upOpeningOffset, BigRooms[idBig].GetComponent(bigRoomScript).heightOnUp + 2); } else { // Si le début est fermé en haut, on check les autres sorties possibles if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnRight && debut.x + 5 < fin.x) { // Si le début est à gauche de la fin, et qu'il est ouvert à droite, le départ est l'ouverture droite debut += Vector2(BigRooms[idBig].GetComponent(bigRoomScript).widthOnRight + 2, BigRooms[idBig].GetComponent(bigRoomScript).rightOpeningOffset); } if(BigRooms[idBig].GetComponent(bigRoomScript).isOpenOnLeft && debut.x - 5 > fin.x) { // Si le début est à droite de la fin, et qu'il est ouvert à gauche, le départ est l'ouverture gauche debut += Vector2(-BigRooms[idBig].GetComponent(bigRoomScript).widthOnLeft - 2, BigRooms[idBig].GetComponent(bigRoomScript).leftOpeningOffset); } } } //On fait le chemin en plusieurs étapes en zigzaguant à chaque fois. for(var i : int = 0; i <= numberOfSteps-1; i++) { // La destination de cette étape est le début + une portion de la destination finale. if(i < numberOfSteps -1) //Si c'est pas le dernier, on rajoute un random. fin = debut + ((1.2 / numberOfSteps) * (destination - debut)) + Vector2(randomWithSeed(0, 2.0*Mathf.Sqrt(distance)/3.0, i + numberOfSteps * 2) - Mathf.Sqrt(distance)/3.0, randomWithSeed(0, 2.0*Mathf.Sqrt(distance)/3.0, i + numberOfSteps * 6)-Mathf.Sqrt(distance)/3.0); else //Si c'est le dernier, on va à la fin. fin = destination; for(var stateOnPath : int = 0; stateOnPath <= 200; stateOnPath ++) { var pathX : int = debut.x + ((fin.x-debut.x) * stateOnPath * 0.005); var pathZ : int = debut.y + ((fin.y-debut.y) * stateOnPath * 0.005); if(isThereARoom(pathX, pathZ) == -1) { //Pas de duplicatas, et surtout pas en mettre dans des murs, gnié coordinatesToGenerate[tempNumberOfRooms] = Vector2(pathX, pathZ); setRoomsTable(pathX, pathZ, 1); tempNumberOfRooms++; } } debut = fin; } if(pathX != destination.x || pathZ != destination.y) { //Si, comme le code est dégueu, on est pas à la fin, ben on finit à la crado. fin = destination; for( stateOnPath = 0; stateOnPath <= 100; stateOnPath ++) { pathX = debut.x + ((fin.x-debut.x) * stateOnPath * 0.01); pathZ = debut.y + ((fin.y-debut.y) * stateOnPath * 0.01); if(isThereARoom(pathX, pathZ) == -1) { //Pas de duplicatas, et surtout pas en mettre dans des murs, gnié coordinatesToGenerate[tempNumberOfRooms] = Vector2(pathX, pathZ); setRoomsTable(pathX, pathZ, 1); tempNumberOfRooms++; } } } } // Si on vient de faire le plus proche et que c'est pas le suivant, on passe au suivant. Si c'était le suivant, on sort du while. if(idDestination != idBig+1) { idDestination = idBig+1; } else { idDestination = -1; } } } } roomsOpeningness = 2; //On met à 2 pour que les sorties des grandes salles soient super méga giga ouvertes de la mort. Parce que sinon ça fait méga chier. // Puis on génère les petites salles un peu partout, pour remplir. remainingRoomsToGenerate = tempNumberOfRooms; //Nombre de salles restantes à générer var roomsAdded : int = 0; var roomsAdded2 : int = 0; // A chaque fois qu'on ajoute une salle à faire, on augmente remainingRoomsToGenerate. Et quand on la génère, on le réduit. while(remainingRoomsToGenerate > 0) { var tempCoord = coordinatesToGenerate[0]; // On ajoute cette salle au nombre et à la liste de salles existantes. numberOfRooms++; // Quand les sorties de grandes salles sont finies, on va sur roomsOpeningness initial, qui correspond aux couloirs entre les grandes salles. if(roomsAdded2 >= 0) { roomsAdded2++; if(roomsAdded2 >= tempNumberOfRooms2) { roomsOpeningness = oldRoomsOpeningness; roomsAdded2 = -1; // Quand les couloirs sont finis, on repart sur newRoomsOpeningness, qui correspond à "normal". if(roomsAdded >= 0) { roomsAdded++; if(roomsAdded >= tempNumberOfRooms) { roomsOpeningness = newRoomsOpeningness; roomsAdded = -1; } }} } setRoomsTable(tempCoord.x, tempCoord.y, 1); // Quel genre de salle celle-ci va etre ? var whatKindOfRoom : int[] = whatKindOfRoomWillItBe(tempCoord.x, tempCoord.y); // Ensuite on la crée. var createdRoom : Transform; switch(whatKindOfRoom[0]) { case 1 : //Dead end createdRoom = Instantiate(EndRoom[randomWithSeed(0, EndRoom.Length-1, numberOfRooms)], Vector3(tempCoord.x * roomSize, 0.0f, tempCoord.y * roomSize), Quaternion.identity); createdRoom.name = "Dead end room"; break; case 2 : //I createdRoom = Instantiate(IRoom[randomWithSeed(0, IRoom.Length-1, numberOfRooms)], Vector3(tempCoord.x * roomSize, 0.0f, tempCoord.y * roomSize), Quaternion.identity); createdRoom.name = "I room"; break; case 3 : //L createdRoom = Instantiate(LRoom[randomWithSeed(0, LRoom.Length-1, numberOfRooms)], Vector3(tempCoord.x * roomSize, 0.0f, tempCoord.y * roomSize), Quaternion.identity); createdRoom.name = "L room"; break; case 4 : //T createdRoom = Instantiate(TRoom[randomWithSeed(0, TRoom.Length-1, numberOfRooms)], Vector3(tempCoord.x * roomSize, 0.0f, tempCoord.y * roomSize), Quaternion.identity); createdRoom.name = "T room"; break; case 5 : //Ouverte createdRoom = Instantiate(OpenRoom[randomWithSeed(0, OpenRoom.Length-1, numberOfRooms)], Vector3(tempCoord.x * roomSize, 0.0f, tempCoord.y * roomSize), Quaternion.identity); createdRoom.name = "Open room"; break; default : createdRoom = Instantiate(OpenRoom[randomWithSeed(0, OpenRoom.Length-1, numberOfRooms)], Vector3(tempCoord.x * roomSize, 0.0f, tempCoord.y * roomSize), Quaternion.identity); createdRoom.name = "Open room"; break; } createdRoom.name = " (" + numberOfRooms + ")" + createdRoom.name; // On l'oriente comme il faut. createdRoom.Rotate(Vector3(0,(1+whatKindOfRoom[1]) * 90, 0)); // On la range. createdRoom.parent = container; //Debug.Log("Salle en (" + tempCoord.x * roomSize + ", " + tempCoord.y * roomSize + "), rotation " + (whatKindOfRoom[1] * 90) + "°"); // Il nous reste un truc à faire, j'aurais pu grouper avec le switch d'avant mais c'est plus facile à comprendre et propre quand c'est à part. // On va voir si il faut ajouter des salles à générer dans la liste, et bloquer les endroits où il ne doit pas y en avoir. switch(whatKindOfRoom[0]) { case 1 : //Dead end if(whatKindOfRoom[1] != 0) setRoomsTable(tempCoord.x-1, tempCoord.y, 0); if(whatKindOfRoom[1] != 1) setRoomsTable(tempCoord.x, tempCoord.y+1, 0); if(whatKindOfRoom[1] != 2) setRoomsTable(tempCoord.x+1, tempCoord.y, 0); if(whatKindOfRoom[1] != 3) setRoomsTable(tempCoord.x, tempCoord.y-1, 0); break; case 2 : //I if(whatKindOfRoom[1] == 0 || whatKindOfRoom[1] == 2) { //Horizontal setRoomsTable(tempCoord.x, tempCoord.y+1, 0); setRoomsTable(tempCoord.x, tempCoord.y-1, 0); if(-1 == isThereARoom(tempCoord.x + 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x + 1, tempCoord.y); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x - 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x - 1, tempCoord.y); remainingRoomsToGenerate++; } } else { //Vertical setRoomsTable(tempCoord.x+1, tempCoord.y, 0); setRoomsTable(tempCoord.x-1, tempCoord.y, 0); if(-1 == isThereARoom(tempCoord.x, tempCoord.y + 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y + 1); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x, tempCoord.y - 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y - 1); remainingRoomsToGenerate++; } } break; case 3 : //L if(whatKindOfRoom[1] == 0) { //Gauche + haut setRoomsTable(tempCoord.x+1, tempCoord.y, 0); setRoomsTable(tempCoord.x, tempCoord.y-1, 0); if(-1 == isThereARoom(tempCoord.x - 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x - 1, tempCoord.y); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x, tempCoord.y + 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y + 1); remainingRoomsToGenerate++; } } if(whatKindOfRoom[1] == 1) { //Haut + droite setRoomsTable(tempCoord.x-1, tempCoord.y, 0); setRoomsTable(tempCoord.x, tempCoord.y-1, 0); if(-1 == isThereARoom(tempCoord.x, tempCoord.y + 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y + 1); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x + 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x + 1, tempCoord.y); remainingRoomsToGenerate++; } } if(whatKindOfRoom[1] == 2) { //Droite + bas setRoomsTable(tempCoord.x-1, tempCoord.y, 0); setRoomsTable(tempCoord.x, tempCoord.y+1, 0); if(-1 == isThereARoom(tempCoord.x + 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x + 1, tempCoord.y); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x, tempCoord.y - 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y - 1); remainingRoomsToGenerate++; } } if(whatKindOfRoom[1] == 3) { //Bas + gauche setRoomsTable(tempCoord.x+1, tempCoord.y, 0); setRoomsTable(tempCoord.x, tempCoord.y+1, 0); if(-1 == isThereARoom(tempCoord.x, tempCoord.y - 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y - 1); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x - 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x - 1, tempCoord.y); remainingRoomsToGenerate++; } } break; case 4 : //T if(whatKindOfRoom[1] != 0) { //Le mur de droite n'est pas fermé if(-1 == isThereARoom(tempCoord.x + 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x + 1, tempCoord.y); remainingRoomsToGenerate++; } } else { setRoomsTable(tempCoord.x+1, tempCoord.y, 0); } if(whatKindOfRoom[1] != 1) { //Le mur du bas n'est pas fermé if(-1 == isThereARoom(tempCoord.x, tempCoord.y - 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y - 1); remainingRoomsToGenerate++; } } else { setRoomsTable(tempCoord.x, tempCoord.y-1, 0); } if(whatKindOfRoom[1] != 2) { //Le mur de gauche n'est pas fermé if(-1 == isThereARoom(tempCoord.x - 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x - 1, tempCoord.y); remainingRoomsToGenerate++; } } else { setRoomsTable(tempCoord.x-1, tempCoord.y, 0); } if(whatKindOfRoom[1] != 3) { //Le mur du haut n'est pas fermé if(-1 == isThereARoom(tempCoord.x, tempCoord.y + 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y + 1); remainingRoomsToGenerate++; } } else { setRoomsTable(tempCoord.x, tempCoord.y+1, 0); } break; case 5 : //Ouverte if(-1 == isThereARoom(tempCoord.x, tempCoord.y - 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y - 1); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x, tempCoord.y + 1)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x, tempCoord.y + 1); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x - 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x - 1, tempCoord.y); remainingRoomsToGenerate++; } if(-1 == isThereARoom(tempCoord.x + 1, tempCoord.y)) { coordinatesToGenerate[remainingRoomsToGenerate] = Vector2(tempCoord.x + 1, tempCoord.y); remainingRoomsToGenerate++; } break; } if(roomCreationDelay > 0) yield WaitForSeconds(roomCreationDelay); // Et c'est bon, on a fini pour cette salle ! On l'enlève de la liste, et on passe à la suivante. for(i = 0; i < remainingRoomsToGenerate - 1; i++) { coordinatesToGenerate[i] = coordinatesToGenerate[i + 1]; } remainingRoomsToGenerate -- ; } generating = false; Debug.Log("Génération terminée! " + numberOfRooms + " salles générées."); } /** * Fonction qui vide le container, pour la régénération de la map. * Destroy tous les enfants du container. */ function emptyContainer() { var allChildren = container.GetComponentsInChildren(Transform); for (var child : Transform in container) { Destroy(child.gameObject); } } /** * Fonction qui donne quel type de salle on aura aux coordonnées données. * Prend en compte la seed, les salles déjà présentes autour, et la taille du niveau. * Retourne un tableau contenant : - Un entier représentant le type de salle * Type : * 1 : dead end * 2 : I * 3 : L * 4 : T * 5 : ouverte * 6 : grande salle - Un entier représentant la direction de la salle * Direction à multiplier par 90 pour obtenir l'angle désiré. - Zéro ou plusieurs entiers concernant les salles-structures. La nature et la signification de cette variable dépend du type de structure. */ function whatKindOfRoomWillItBe(x : int, z : int) { // Dans quelles direction la salle sera-t-elle ouverte ? // On commence avec tout à true, on met à false pour fermer (parfois à tort), // et on corrige à la fin si on a fermé des murs qu'on devait pas, en fonction des salles adjacentes. var goRight : boolean = true; var goLeft : boolean = true; var goUp : boolean = true; var goDown : boolean = true; var numberOfOpenings : int = 0; var direction : int = 0; // Les directions sont : 0 bas; 1 gauche; 2 haut; 3 droite; var roomTypeId : int = 0; // Les id de room sont : 1 : dead end; 2 : I; 3 : L; 4 : T; 5 : ouverte var isAStructure : boolean = false; // Peut etre que ça sera une structure, cad une zone entiere, faire avec plusieurs salles. var structureSize : int = 0; var retour : int[] = new int[8]; // Premièrement, on ajoute rien si on a déjà beaucoup de salles. La limite est fixée par desiredNumberOfRooms if( numberOfRooms > desiredNumberOfRooms ) { // On va tout passer à false, et on rouvrira là où il faut (pour les salles adjacentes) goRight = false; goLeft = false; goUp = false; goDown = false; } else { // Un petit coup de random, ouverture par ouverture. // Cependant si le niveau n'est pas fini du tout et que y'a plus rien de prévu à créer, ben on ne ferme rien, pour agrandir de force. if(!(numberOfRooms > (desiredNumberOfRooms / 4.0) && remainingRoomsToGenerate < 3)) { if(goRight) { if(randomWithSeed(1, 10, numberOfRooms + 1) > 10 - roomsOpeningness) { goRight = false; } } if(randomWithSeed(1, 10, numberOfRooms + 2) > 10 - roomsOpeningness) { if(goLeft) { goLeft = false; } } if(randomWithSeed(1, 10, numberOfRooms + 3) > 10 - roomsOpeningness) { if(goUp) { goUp = false; } } if(randomWithSeed(1, 10, numberOfRooms + 4) > 10 - roomsOpeningness) { if(goDown) { goDown = false; } } } } // Finalement, on corrige les ouvertures fermées qui doivent etre ouvertes. // on check d'abord si on est au bord de la map, puis si y'a une salle à coté. if(isThereARoom(x+1, z) == 1) { goRight = true; } if(isThereARoom(x-1, z) == 1) { goLeft = true; } if(isThereARoom(x, z+1) == 1) { goUp = true; } if(isThereARoom(x, z-1) == 1) { goDown = true; } if(isThereARoom(x+1, z) == 0) { goRight = false; } if(isThereARoom(x-1, z) == 0) { goLeft = false; } if(isThereARoom(x, z+1) == 0) { goUp = false; } if(isThereARoom(x, z-1) == 0) { goDown = false; } // On sait où on ouvre, où on n'ouvre pas, etc. Il est temps de définir ce qu'on a comme salle, et son orientation. (si c'est pas une structure) if(roomTypeId == 0) { if(goRight) numberOfOpenings++; if(goLeft) numberOfOpenings++; if(goUp) numberOfOpenings++; if(goDown) numberOfOpenings++; switch(numberOfOpenings) { case 1 : //Dead end roomTypeId = 1; if(goRight) //Ouverture à droite direction = 2; if(goLeft) direction = 0; if(goDown) direction = 3; if(goUp) direction = 1; break; case 2 : //Soit I, soit L if(goRight && goLeft || goUp && goDown) { //I roomTypeId = 2; if(goRight) { direction = 0; } else { direction = 1; } } else { roomTypeId = 3; if(goRight && goUp) { direction = 1; } if(goDown && goRight) { direction = 2; } if(goLeft && goDown) { direction = 3; } if(goUp && goLeft) { direction = 0; } } break; case 3 : //T roomTypeId = 4; //Pour aller plus vite on teste celui qui est fermé. if(!goRight) { direction = 0; } if(!goDown) { direction = 1; } if(!goLeft) { direction = 2; } if(!goUp) { direction = 3; } break; case 4 : //Ouverte roomTypeId = 5; direction = 0; break; } } else { //Si c'est une structure on va voir pour faire l'offset des portes (décalage par rapport au milieu) et celui du centre de la salle /* var roomXOffset : int = randomWithSeed(3 + minXLibre, maxXLibre - 3, numberOfRooms * 2); var roomZOffset : int = randomWithSeed(3 + minZLibre, maxZLibre - 3, numberOfRooms * 2); var leftOpeningOffset : int = 0; var rightOpeningOffset : int = 0; var upOpeningOffset : int = 0; var downOpeningOffset : int = 0; if(isThereARoom(x-1, z) == 1) { //Si on vient de la gauche leftOpeningOffset = - roomZOffset; } else { if(goLeft) { leftOpeningOffset = randomWithSeed(-3,3,numberOfRooms + 5); } else { leftOpeningOffset = 100; } } if(isThereARoom(x+1, z) == 1) { //Si on vient de la gauche rightOpeningOffset = - roomZOffset; } else { if(goRight) { rightOpeningOffset = randomWithSeed(-3,3,numberOfRooms + 3); } else { rightOpeningOffset = 100; } } if(isThereARoom(x-1, z) == 1) { //Si on vient de la gauche upOpeningOffset = - roomXOffset; } else { if(goUp) { upOpeningOffset = randomWithSeed(-3,3,numberOfRooms + 17); } else { upOpeningOffset = 100; } } if(isThereARoom(x-1, z) == 1) { //Si on vient de la gauche downOpeningOffset = - roomXOffset; } else { if(goDown) { downOpeningOffset = randomWithSeed(-3,3,numberOfRooms + 7); } else { downOpeningOffset = 100; } } retour[2] = roomXOffset; retour[3] = roomZOffset; retour[4] = leftOpeningOffset; retour[5] = rightOpeningOffset; retour[6] = upOpeningOffset; retour[7] = downOpeningOffset;*/ } retour[0] = roomTypeId; retour[1] = direction; return retour; } /** * Fonction qui teste si y'a une salle à l'endroit demandé * Renvoie 1 si y'a une salle (générée ou non), 0 si il ne doit rien y avoir (mur), et -1 si y'a rien pour l'instant. */ function isThereARoom(x : int, z : int) { // Hors limites, on empeche toute creation. if(x <= 1 || z <= 1 || x >= sizeX - 1 || z >= sizeZ - 1) { return 0; } // Si la salle est dans la liste de salles à générer, on renvoie 1 for(var j : int = 0; j < remainingRoomsToGenerate; j++) { if(coordinatesToGenerate[j].x == x && coordinatesToGenerate[j].y == z) { return 1; } } // Elle est pas dans la liste, on teste voir si elle a déjà été générée if(roomsTable[x,z] == 1) { //Traitée, et elle existe (salle) return 1; } else { if(roomsTable[x,z] == 0) { //Traitée, et elle est désactivée (mur) return 0; } } // Ni dans la liste, ni déjà créée, donc c'est -1. return -1; } /** * Fonction qui génère un nombre aléatoire entre start et end basé sur la seed. * end et start sont inclus dans le résultat ( randomWithSeed(0, 5, 0) donne 0,1,2,3,4 ou 5) * Change le résultat en fonction de kind, aussi, afin de pouvoir avoir des nombres aléatoires se chevauchant (0-3 et 0-10 par ex) qui ne donnent pas le meme resultat */ function randomWithSeed(start : int, end : int, kind : int) { if(start == end) return start; var tempSeed : int = seed; // Aléatoire fait un peu à l'arrache. if(start != 0) tempSeed *= ( start * 41 ) % ( start + 101 ) + 1; if(end != 0) tempSeed += ( end * 32 ) % ( end + 100 ) + 1; tempSeed += ( kind * 47 ) % ( kind + 73 ); var retour = tempSeed % (end - start + 1) + start; return retour; } function setRoomsTable(x : int, z : int, value : int) { if(x <= 0 || z <= 0 || x >= sizeX - 1 || z >= sizeZ -1) { return; } else { roomsTable[x,z] = value; } }