BiomeSelectionSystem.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using System.Linq;
  2. using Content.Server.Worldgen.Components;
  3. using Content.Server.Worldgen.Prototypes;
  4. using Robust.Shared.Prototypes;
  5. using Robust.Shared.Serialization.Manager;
  6. namespace Content.Server.Worldgen.Systems.Biomes;
  7. /// <summary>
  8. /// This handles biome selection, evaluating which biome to apply to a chunk based on noise channels.
  9. /// </summary>
  10. public sealed class BiomeSelectionSystem : BaseWorldSystem
  11. {
  12. [Dependency] private readonly NoiseIndexSystem _noiseIdx = default!;
  13. [Dependency] private readonly IPrototypeManager _proto = default!;
  14. [Dependency] private readonly ISerializationManager _ser = default!;
  15. /// <inheritdoc />
  16. public override void Initialize()
  17. {
  18. SubscribeLocalEvent<BiomeSelectionComponent, ComponentStartup>(OnBiomeSelectionStartup);
  19. SubscribeLocalEvent<BiomeSelectionComponent, WorldChunkAddedEvent>(OnWorldChunkAdded);
  20. }
  21. private void OnWorldChunkAdded(EntityUid uid, BiomeSelectionComponent component, ref WorldChunkAddedEvent args)
  22. {
  23. var coords = args.Coords;
  24. foreach (var biomeId in component.Biomes)
  25. {
  26. var biome = _proto.Index<BiomePrototype>(biomeId);
  27. if (!CheckBiomeValidity(args.Chunk, biome, coords))
  28. continue;
  29. biome.Apply(args.Chunk, _ser, EntityManager);
  30. return;
  31. }
  32. Log.Error($"Biome selection ran out of biomes to select? See biomes list: {component.Biomes}");
  33. }
  34. private void OnBiomeSelectionStartup(EntityUid uid, BiomeSelectionComponent component, ComponentStartup args)
  35. {
  36. // surely this can't be THAAAAAAAAAAAAAAAT bad right????
  37. var sorted = component.Biomes
  38. .Select(x => (Id: x, _proto.Index<BiomePrototype>(x).Priority))
  39. .OrderByDescending(x => x.Priority)
  40. .Select(x => x.Id)
  41. .ToList();
  42. component.Biomes = sorted; // my hopes and dreams rely on this being pre-sorted by priority.
  43. }
  44. private bool CheckBiomeValidity(EntityUid chunk, BiomePrototype biome, Vector2i coords)
  45. {
  46. foreach (var (noise, ranges) in biome.NoiseRanges)
  47. {
  48. var value = _noiseIdx.Evaluate(chunk, noise, coords);
  49. var anyValid = false;
  50. foreach (var range in ranges)
  51. {
  52. if (range.X < value && value < range.Y)
  53. {
  54. anyValid = true;
  55. break;
  56. }
  57. }
  58. if (!anyValid)
  59. return false;
  60. }
  61. return true;
  62. }
  63. }