private void PopulateSpecialRoom(Scene scene, Zone zone, Vector3 roomCenter, PopulateSchemeFlags flags, ref PopulateRoomResults results) { int rng = rand.Next(8); if (flags.ClearPerimeter) { if (rng == 7) { SceneStructures.Arena(WallTexture)(scene, zone, roomCenter); } } if (flags.ClearFloor) { if (rng < 7 || !flags.ClearPerimeter) { results.GenerateFloor = false; SceneStructures.Pit(FloorTexture, WallTexture)(scene, zone, roomCenter); SceneStructures.PitFloor(Assets.iceTexture)(scene, zone, roomCenter); if (rng < 3 && flags.ClearCenter) { SceneStructures.PitPillar(WallTexture)(scene, zone, roomCenter); } } } if (rand.Next(2) == 0) { SceneStructures.IceCutCorners(Assets.iceTexture)(scene, zone, roomCenter); } }
private void PopulateSpecialRoom(Scene scene, Zone zone, Vector3 roomCenter, PopulateSchemeFlags flags, ref PopulateRoomResults results) { int rng = rand.Next(6); if (flags.ClearPerimeter) { if (rng == 0 || rng == 1) { SceneStructures.Arena(WallTexture)(scene, zone, roomCenter); } } if (flags.ClearFloor) { if (rng == 2 || rng == 3) { results.GenerateFloor = false; SceneStructures.Pit(FloorTexture, WallTexture)(scene, zone, roomCenter); if (rng == 3 && flags.ClearCenter) { SceneStructures.PitPillar(WallTexture)(scene, zone, roomCenter); } } } }
private void PopulateRoomWalls(Scene scene, Zone zone, Vector3 roomCenter, PopulateSchemeFlags flags) { int rnd = rand.Next(4); if (flags.NotJoint && rnd == 0) { SceneStructures.CutCorners(WallTexture)(scene, zone, roomCenter); } else if (rnd == 1) { SceneStructures.Pillars4Outer(WallTexture)(scene, zone, roomCenter); } }
private void PopulateRoomCenter(Scene scene, Zone zone, Vector3 roomCenter, PopulateSchemeFlags flags) { int rnd = rand.Next(3); if (flags.ClearCenter) { if (rnd == 0) { SceneStructures.PillarSmall(WallTexture)(scene, zone, roomCenter); } else if (rnd == 1) { SceneStructures.PillarBig(WallTexture)(scene, zone, roomCenter); } } else { if (rnd == 2) { SceneStructures.Pillars4Inner(WallTexture)(scene, zone, roomCenter); } } }
protected override PopulateRoomResults PopulateRoom(Scene scene, Zone zone, int x, int y, PopulateSchemeFlags flags) { PopulateRoomResults results = new PopulateRoomResults { GenerateFloor = true }; float left = x * tileSize - size * tileSize / 2; float right = left + tileSize; float bottom = y * tileSize - size * tileSize / 2; float top = bottom + tileSize; Vector3 roomCenter = new Vector3((left + right) / 2, 0f, (top + bottom) / 2); bool[] roomCorridors = Enumerable.Range(0, 4).Select(t => corridorLayout[x, y, t]).ToArray(); if ((x != exitRoom.X || y != exitRoom.Y) && (x != size / 2 || y != size / 2)) { int monsterCount = rand.Next(2, monstersPerRoom + 1); game.PlayerStats.totalMonsters += monsterCount; List <Vector3> spawnPoints = new List <Vector3>(); Vector2 shift = monsterCount == 1 ? Vector2.Zero : new Vector2(30f, 0f); float angleOffset = (float)(rand.NextDouble() * Math.PI * 2f); for (int i = 0; i < monsterCount; i++) { Vector2 position = new Vector2(roomCenter.X, roomCenter.Z); position += Vector2.Transform(shift, Mathg.RotationMatrix2D(angleOffset + i * (float)Math.PI * 2f / monsterCount)); Vector3 position3 = new Vector3(position.X, -1f, position.Y); Monster monster = Mathg.DiscreteChoiceFn(rand, new Func <Monster>[] { () => new BasicMonster(position3, monsterHP, monsterDamage), () => new BasicMonster(position3, monsterHP, monsterDamage), () => new ShotgunDude(position3, monsterHP, monsterDamage), () => new SpinnyBoi(position3, monsterHP * 2, monsterDamage), () => new Spooper(position3, monsterHP * 1.5f, monsterDamage) }, monsterChances); scene.AddGameObject(monster); } } if (rand.Next(7) == 0) { SceneStructures.PitWithBridges(FloorTexture, WallTexture, FloorTexture, roomCorridors).Invoke(scene, zone, roomCenter); SceneGenUtils.AddFloor(zone, -50f * Vector2.One, 50f * Vector2.One, -10f, Assets.lavaTexture, true, roomCenter, 75f); results.GenerateFloor = false; } else if (rand.Next(3) == 0) { if (x != size / 2 || y != size / 2) { SpawnPools(scene, x, y, roomCenter, flags); } List <Generator> generators = new List <Generator> { SceneStructures.Pillars4Inner(WallTexture), SceneStructures.Pillars4Outer(WallTexture) }; if (flags.ClearCenter) { generators.Add(SceneStructures.PillarBig(WallTexture)); generators.Add(SceneStructures.PillarSmall(WallTexture)); } Mathg.DiscreteChoice(rand, generators).Invoke(scene, zone, roomCenter); } return(results); }
private void SpawnPools(Scene scene, int x, int y, Vector3 roomCenter, PopulateSchemeFlags flags) { List <Func <(Vector2, Vector2)[]> > lavaFormations = new List <Func <(Vector2, Vector2)[]> >
protected override PopulateRoomResults PopulateRoom(Scene scene, Zone zone, int x, int y, PopulateSchemeFlags flags) { PopulateRoomResults results = new PopulateRoomResults { GenerateFloor = true }; float left = x * tileSize - size * tileSize / 2; float right = left + tileSize; float bottom = y * tileSize - size * tileSize / 2; float top = bottom + tileSize; Vector3 roomCenter = new Vector3((left + right) / 2, 0f, (top + bottom) / 2); float[] roomCorridors = Enumerable.Range(0, 4).Select(t => corridorWidths[x, y, t]).ToArray(); if ((x != exitRoom.X || y != exitRoom.Y) && (x != size / 2 || y != size / 2)) { int monsterCount = rand.Next(2, monstersPerRoom + 1); game.PlayerStats.totalMonsters += monsterCount; List <Vector3> spawnPoints = new List <Vector3>(); new List <(int, int)> { (-1, -1), (-1, 1), (1, -1), (1, 1) }
private void GenerateRooms(Scene scene, Zone[,] zones) { // Generating geometry and colliders for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { if (accessible[x, y]) { float left = x * tileSize - size * tileSize / 2; float right = left + tileSize; float bottom = y * tileSize - size * tileSize / 2; float top = bottom + tileSize; zones[x, y] = new Zone(new RectangleF(left, bottom, tileSize, tileSize)); scene.AddZone(zones[x, y]); float[] roomCorridors = Enumerable.Range(0, 4).Select(t => corridorWidths[x, y, t]).ToArray(); // Walls List <Vector2[]> walls = SceneGenUtils.MakeRoomWalls(tileSize, tileSize, roomCorridors, 2f); Vector2 roomCenter = new Vector2((left + right) / 2, (top + bottom) / 2); List <Triangle> wallTriangles = new List <Triangle>(); foreach (Vector2[] wall in walls) { wallTriangles.AddRange(SceneGenUtils.MakeWall(wall, -4f, 4f, WallTexture)); scene.AddObstacle(wall[0] + roomCenter, wall[1] + roomCenter, ObstacleLayer.Wall); } MeshObject wallObject = new MeshObject(wallTriangles, new Vector3(roomCenter.X, 0f, roomCenter.Y), 0f); zones[x, y].AddMesh(wallObject); bool flagIsSpecial = (x == exitRoom.X && y == exitRoom.Y) || (x == size / 2 && y == size / 2); PopulateSchemeFlags flags = new PopulateSchemeFlags { IsSpecial = flagIsSpecial, ClearCenter = scene.Collectibles[x, y] == null && !flagIsSpecial, NotJoint = true, ClearPerimeter = true, ClearFloor = scene.Collectibles[x, y] == null && !flagIsSpecial }; for (int t = 0; t < 4; t++) { if (corridorLayout[x, y, t] && corridorWidths[x, y, t] > 15f) { flags.NotJoint = false; } } if (scene.Collectibles[x, y] != null) { Collectible.Type type = scene.Collectibles[x, y].Value; AsciiTexture texture = null; switch (type) { case Collectible.Type.Armor: texture = Assets.barrelGreenTexture; break; case Collectible.Type.Health: texture = Assets.barrelRedTexture; break; case Collectible.Type.Skill: texture = Assets.barrelBlueTexture; break; } MeshObject barrel = new MeshObject(Assets.barrelModel, texture, new Vector3(roomCenter.X, -3f, roomCenter.Y)); scene.AddGameObject(new Collectible(barrel, type, x, y)); } if (x == exitRoom.X && y == exitRoom.Y) { flags.ClearCenter = false; flags.ClearPerimeter = false; flags.ClearFloor = false; MeshObject exit = new MeshObject(Assets.exitModel, Assets.exitTexture, new Vector3(roomCenter.X, -3.25f, roomCenter.Y)); zones[x, y].AddMesh(exit); game.PlayerStats.exitPosition = new Vector2(roomCenter.X, roomCenter.Y); } PopulateRoomResults results = PopulateRoom(scene, zones[x, y], x, y, flags); if (results.GenerateFloor) { zones[x, y].AddMesh(SceneGenUtils.MakeFloor(left, right, bottom, top, -4f, FloorTexture, true)); zones[x, y].AddMesh(SceneGenUtils.MakeFloor(left, right, bottom, top, 4f, FloorTexture, false)); } } } } }
protected abstract PopulateRoomResults PopulateRoom(Scene scene, Zone zone, int x, int y, PopulateSchemeFlags flags);
protected override PopulateRoomResults PopulateRoom(Scene scene, Zone zone, int x, int y, PopulateSchemeFlags flags) { PopulateRoomResults results = new PopulateRoomResults { GenerateFloor = true }; float left = x * tileSize - size * tileSize / 2; float right = left + tileSize; float bottom = y * tileSize - size * tileSize / 2; float top = bottom + tileSize; Vector3 roomCenter = new Vector3((left + right) / 2, 0f, (top + bottom) / 2); if (!flags.IsSpecial) { int monsterCount = rand.Next(flags.ClearCenter ? 1 : 2, monstersPerRoom + 1); game.PlayerStats.totalMonsters += monsterCount; Vector2 shift = monsterCount == 1 ? Vector2.Zero : new Vector2(30f, 0f); float angleOffset = (float)(rand.NextDouble() * Math.PI * 2f); for (int i = 0; i < monsterCount; i++) { Vector2 position = new Vector2(roomCenter.X, roomCenter.Z); position += Vector2.Transform(shift, Mathg.RotationMatrix2D(angleOffset + i * (float)Math.PI * 2f / monsterCount)); Vector3 position3 = new Vector3(position.X, -1f, position.Y); Monster monster = Mathg.DiscreteChoiceFn(rand, new Func <Monster>[] { () => new BasicMonster(position3, monsterHP, monsterDamage), () => new IceMonster(position3, monsterHP, monsterDamage * 0.3f), () => new ShotgunDude(position3, monsterHP, monsterDamage), () => new IceShotgunDude(position3, monsterHP, monsterDamage * 0.3f), () => new SpinnyBoi(position3, monsterHP * 2, monsterDamage), () => new Spooper(position3, monsterHP * 1.5f, monsterDamage) }, monsterChances); scene.AddGameObject(monster); } if (monsterCount != 1) { flags.ClearPerimeter = false; } else { flags.ClearCenter = false; } } if (rand.Next(4) == 0 || (flags.ClearPerimeter && rand.Next(2) == 0)) // special room { PopulateSpecialRoom(scene, zone, roomCenter, flags, ref results); } else { PopulateRoomCenter(scene, zone, roomCenter, flags); PopulateRoomWalls(scene, zone, roomCenter, flags); } return(results); }