/// <summary> /// Randomly generates and places a corridor of traps. /// </summary> /// <param name="offset">Distance forward from the origin in spaces</param> public void CreateCorridor(int offset = 0) { iterations++; float trap_density = trap_density_per_distance_curve.Evaluate(iterations * corridor_height); float pickup_density = pickup_density_per_distance_curve.Evaluate(iterations * corridor_height); pickup_gen.CreateCorridor(corridor_height, corridor_width, offset, pickup_density); TrapInfo[,] corridor = new TrapInfo[corridor_width, corridor_height]; HashSet <TrapInfo> placed_traps = new HashSet <TrapInfo>(); //Populates the corridor with random traps for (int x = 0; x < corridor.GetLength(0); x++) { for (int y = 0; y < corridor.GetLength(1); y++) { if (Random.Range(0f, 1f) <= trap_density) { TrapInfo blueprint = traps[Random.Range(0, traps.Count)]; corridor[x, y] = new TrapInfo(blueprint, x, y); placed_traps.Add(corridor[x, y]); } } } //Clears overlapping traps //trap_infos tracks remaining traps, which are the one that haven't been expanded and are ok to clear for other traps. List <TrapInfo> trap_infos = placed_traps.ToList(); //List of traps that have been orignally seeded into the corridor HashSet <TrapInfo> trapset = new HashSet <TrapInfo>(); //Set of traps that have been checked and expanded and will actually be built while (trap_infos.Count != 0) { TrapInfo trap = trap_infos[trap_infos.Count - 1]; bool has_space = true; //checks if its origin is on the edge if required if (trap.needs_edge) { if (trap.pos_x != 0 && trap.pos_x != corridor.GetLength(0) - 1) { has_space = false; } } //checks if it has space to expand in the correct direction that doesn't get in the way of anything. for (int x = trap.pos_x; Mathf.Abs(x - trap.pos_x) < Mathf.Abs(trap.width); x += (int)Mathf.Sign(trap.width)) { for (int y = trap.pos_y; Mathf.Abs(y - trap.pos_y) < Mathf.Abs(trap.height); y += (int)Mathf.Sign(trap.height)) { if (x >= 0 && x < corridor.GetLength(0) && y >= 0 && y < corridor.GetLength(1)) { if (trapset.Contains(corridor[x, y])) //i.e. there is an already expanded trap there { has_space = false; } } else { has_space = false; } } } //Expands itself if there is space for it, otherwise removes itself if (has_space) { trapset.Add(trap); for (int x = trap.pos_x; Mathf.Abs(x - trap.pos_x) < Mathf.Abs(trap.width); x += (int)Mathf.Sign(trap.width)) { for (int y = trap.pos_y; Mathf.Abs(y - trap.pos_y) < Mathf.Abs(trap.height); y += (int)Mathf.Sign(trap.height)) { if (corridor[x, y] != trap) { trap_infos.Remove(corridor[x, y]); } corridor[x, y] = trap; } } } else { //if nothing else has expanded to take its space, nullify itself. if (corridor[trap.pos_x, trap.pos_y] == trap) { corridor[trap.pos_x, trap.pos_y] = null; } } trap_infos.Remove(trap); } //Actually puts traps objects in the world. foreach (TrapInfo trap_info in corridor) { if (trap_info != null) { trapset.Add(trap_info); } } TrapInfo[] traps_to_build = trapset.ToArray(); foreach (TrapInfo trap_info in traps_to_build) { Quaternion rotation = Quaternion.identity; for (int i = 0; i < trap_info.rotation; i++) { rotation *= Quaternion.Euler(0, 90, 0); } Trap new_trap = Instantiate(trap_info.prefab, new Vector3(trap_info.pos_x, 0, trap_info.pos_y + offset), rotation).GetComponentInChildren <Trap>(); new_trap.IncrementDirection(trap_info.rotation); } //Creating Floor for (int x = 0; x < corridor.GetLength(0); x++) { for (int y = 0; y < corridor.GetLength(1); y++) { //Rotation is to cancel out the axis mismatch with blender. GameObject floor = floor_prefabs[Random.Range(0, floor_prefabs.Count())]; Instantiate(floor, new Vector3(x, 0, y + offset), Quaternion.Euler(Vector3.right * -90 + Vector3.up * 90 * Random.Range(0, 4))); } } //Creating Walls for (int y = 0; y < corridor.GetLength(1); y++) { GameObject wall = wall_prefabs[Random.Range(0, wall_prefabs.Count())]; Instantiate(wall, new Vector3(-1, 0, y + offset), Quaternion.Euler(Vector3.right * -90)); wall = wall_prefabs[Random.Range(0, wall_prefabs.Count())]; Instantiate(wall, new Vector3(corridor.GetLength(0), 0, y + offset), Quaternion.Euler(Vector3.right * -90 + Vector3.up * 180)); } }