|
1 | 1 | using System; |
| 2 | +using System.Collections.Generic; |
2 | 3 | using System.Linq; |
3 | 4 | using FunkEngine.Classes.MidiMaestro; |
4 | 5 | using Godot; |
@@ -251,6 +252,13 @@ public enum Stages |
251 | 252 | Quit, |
252 | 253 | Map, |
253 | 254 | Load, |
| 255 | + Continue, |
| 256 | +} |
| 257 | + |
| 258 | +public enum Area |
| 259 | +{ |
| 260 | + Forest = 0, |
| 261 | + City = 1, |
254 | 262 | } |
255 | 263 |
|
256 | 264 | public enum Rarity |
@@ -308,59 +316,111 @@ public void AddChild(int newIdx) |
308 | 316 | } |
309 | 317 | } |
310 | 318 |
|
| 319 | + //TODO: Make odds for rooms based on y-level, e.g. elites only spawn on y > 3 |
| 320 | + public struct MapConfig |
| 321 | + { |
| 322 | + public int Width { get; private set; } |
| 323 | + public int Height { get; private set; } |
| 324 | + public int Paths { get; private set; } |
| 325 | + |
| 326 | + /// <summary> |
| 327 | + /// Rooms that exist at set levels, only one room can be set per y-level. |
| 328 | + /// </summary> |
| 329 | + public Dictionary<int, Stages> SetRooms { get; private set; } = |
| 330 | + new() |
| 331 | + { |
| 332 | + { 0, Stages.Battle }, //The first, e.g. y = 0 room, should always be a battle. |
| 333 | + }; |
| 334 | + |
| 335 | + public const int NumStages = 2; |
| 336 | + |
| 337 | + public static readonly Stages[] StagsToRoll = new[] { Stages.Battle, Stages.Chest }; |
| 338 | + |
| 339 | + /// <summary> |
| 340 | + /// The odds for each stage to appear in a non-set room position. |
| 341 | + /// </summary> |
| 342 | + public float[] StageOdds = new float[2]; |
| 343 | + |
| 344 | + public MapConfig(int width, int height, int paths, float[] odds) |
| 345 | + { |
| 346 | + Width = width; |
| 347 | + Height = height; |
| 348 | + Paths = paths; |
| 349 | + for (int i = 0; i < NumStages; i++) |
| 350 | + { |
| 351 | + StageOdds[i] = odds[i]; |
| 352 | + } |
| 353 | + } |
| 354 | + |
| 355 | + /// <summary> |
| 356 | + /// Adds a set room type to be generated guaranteed. Additional entries in the same y-level are ignored. |
| 357 | + /// </summary> |
| 358 | + /// <param name="height">The y-level of the rooms</param> |
| 359 | + /// <param name="roomType">The room type to be set.</param> |
| 360 | + public MapConfig AddSetRoom(int height, Stages roomType) |
| 361 | + { |
| 362 | + SetRooms.TryAdd(height, roomType); |
| 363 | + return this; |
| 364 | + } |
| 365 | + } |
| 366 | + |
311 | 367 | /** |
312 | 368 | * <summary>Initializes the map with max <c>width</c>, max <c>height</c>, and with number of <c>paths</c>.</summary> |
313 | 369 | */ |
314 | | - public void InitMapGrid(int width, int height, int paths) |
| 370 | + public void InitMapGrid(MapConfig curConfig) |
315 | 371 | { |
316 | 372 | _curIdx = 0; |
317 | | - _rooms = Array.Empty<Room>(); |
318 | | - _map = new int[width, height]; //x,y |
| 373 | + _rooms = []; |
| 374 | + _map = new int[curConfig.Width, curConfig.Height]; //x,y |
319 | 375 |
|
320 | | - int startX = (width / 2); |
| 376 | + int startX = (curConfig.Width / 2); |
321 | 377 | _rooms = _rooms.Append(new Room(_curIdx, startX, 0)).ToArray(); |
322 | 378 | _rooms[0].SetType(Stages.Battle); |
323 | 379 | _map[startX, 0] = _curIdx++; |
324 | 380 |
|
325 | | - for (int i = 0; i < paths; i++) |
| 381 | + for (int i = 0; i < curConfig.Paths; i++) |
326 | 382 | { |
327 | | - GeneratePath_r(startX, 0, width, height); |
| 383 | + GeneratePath_r(startX, 0, curConfig); |
328 | 384 | } |
329 | | - CreateCommonChildren(width, height); |
330 | | - AddBossRoom(width, height); |
| 385 | + CreateCommonChildren(curConfig.Width, curConfig.Height); |
| 386 | + AddBossRoom(curConfig.Width, curConfig.Height); |
331 | 387 | } |
332 | 388 |
|
333 | 389 | /**Start at x, y, assume prev room exists. Picks new x pos within +/- 1, attaches recursively*/ |
334 | | - private void GeneratePath_r(int x, int y, int width, int height) |
| 390 | + private void GeneratePath_r(int x, int y, MapConfig curConfig) |
335 | 391 | { |
336 | 392 | int nextX = StageProducer.GlobalRng.RandiRange( |
337 | 393 | Math.Max(x - 1, 0), |
338 | | - Math.Min(x + 1, width - 1) |
| 394 | + Math.Min(x + 1, curConfig.Width - 1) |
339 | 395 | ); |
340 | 396 | if (_map[nextX, y + 1] == 0) |
341 | 397 | { |
342 | 398 | _rooms = _rooms.Append(new Room(_curIdx, nextX, y + 1)).ToArray(); |
343 | 399 | _map[nextX, y + 1] = _curIdx; |
344 | 400 | _rooms[_map[x, y]].AddChild(_curIdx++); |
345 | | - _rooms[^1].SetType(PickRoomType(x, y)); |
| 401 | + _rooms[^1].SetType(PickRoomType(x, y, curConfig)); |
346 | 402 | } |
347 | 403 | else |
348 | 404 | { |
349 | 405 | _rooms[_map[x, y]].AddChild(_map[nextX, y + 1]); |
350 | 406 | } |
351 | | - if (y < height - 2) |
| 407 | + if (y < curConfig.Height - 2) |
352 | 408 | { |
353 | | - GeneratePath_r(nextX, y + 1, width, height); |
| 409 | + GeneratePath_r(nextX, y + 1, curConfig); |
354 | 410 | } |
355 | 411 | } |
356 | 412 |
|
357 | | - private Stages PickRoomType(int x, int y) |
| 413 | + private Stages PickRoomType(int x, int y, MapConfig curConfig) |
358 | 414 | { |
359 | | - if (y % 3 == 0) |
360 | | - return Stages.Chest; |
361 | | - if (StageProducer.GlobalRng.Randf() < .08) |
362 | | - return Stages.Chest; |
363 | | - return Stages.Battle; |
| 415 | + //If the y has a set room return it. |
| 416 | + if (curConfig.SetRooms.TryGetValue(y, out Stages result)) |
| 417 | + { |
| 418 | + return result; |
| 419 | + } |
| 420 | + |
| 421 | + //Random roll for the room type. |
| 422 | + int idx = (int)StageProducer.GlobalRng.RandWeighted(curConfig.StageOdds); |
| 423 | + return MapConfig.StagsToRoll[idx]; |
364 | 424 | } |
365 | 425 |
|
366 | 426 | //Asserts that if there is a room at the same x, but y+1 they are connected |
|
0 commit comments