1
0

SharedSalvageSystem.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System.Linq;
  2. using Content.Shared.CCVar;
  3. using Content.Shared.Dataset;
  4. using Content.Shared.Procedural;
  5. using Content.Shared.Procedural.Loot;
  6. using Content.Shared.Random;
  7. using Content.Shared.Random.Helpers;
  8. using Content.Shared.Salvage.Expeditions;
  9. using Content.Shared.Salvage.Expeditions.Modifiers;
  10. using Robust.Shared.Configuration;
  11. using Robust.Shared.Prototypes;
  12. using Robust.Shared.Random;
  13. using Robust.Shared.Serialization;
  14. using Robust.Shared.Utility;
  15. namespace Content.Shared.Salvage;
  16. public abstract partial class SharedSalvageSystem : EntitySystem
  17. {
  18. [Dependency] protected readonly IConfigurationManager CfgManager = default!;
  19. [Dependency] private readonly IPrototypeManager _proto = default!;
  20. /// <summary>
  21. /// Main loot table for salvage expeditions.
  22. /// </summary>
  23. [ValidatePrototypeId<SalvageLootPrototype>]
  24. public const string ExpeditionsLootProto = "SalvageLoot";
  25. public string GetFTLName(LocalizedDatasetPrototype dataset, int seed)
  26. {
  27. var random = new System.Random(seed);
  28. return $"{Loc.GetString(dataset.Values[random.Next(dataset.Values.Count)])}-{random.Next(10, 100)}-{(char) (65 + random.Next(26))}";
  29. }
  30. public SalvageMission GetMission(SalvageDifficultyPrototype difficulty, int seed)
  31. {
  32. // This is on shared to ensure the client display for missions and what the server generates are consistent
  33. var modifierBudget = difficulty.ModifierBudget;
  34. var rand = new System.Random(seed);
  35. // Run budget in order of priority
  36. // - Biome
  37. // - Lighting
  38. // - Atmos
  39. var biome = GetMod<SalvageBiomeModPrototype>(rand, ref modifierBudget);
  40. var light = GetBiomeMod<SalvageLightMod>(biome.ID, rand, ref modifierBudget);
  41. var temp = GetBiomeMod<SalvageTemperatureMod>(biome.ID, rand, ref modifierBudget);
  42. var air = GetBiomeMod<SalvageAirMod>(biome.ID, rand, ref modifierBudget);
  43. var dungeon = GetBiomeMod<SalvageDungeonModPrototype>(biome.ID, rand, ref modifierBudget);
  44. var factionProtos = _proto.EnumeratePrototypes<SalvageFactionPrototype>().ToList();
  45. factionProtos.Sort((x, y) => string.Compare(x.ID, y.ID, StringComparison.Ordinal));
  46. var faction = factionProtos[rand.Next(factionProtos.Count)];
  47. var mods = new List<string>();
  48. if (air.Description != string.Empty)
  49. {
  50. mods.Add(Loc.GetString(air.Description));
  51. }
  52. // only show the description if there is an atmosphere since wont matter otherwise
  53. if (temp.Description != string.Empty && !air.Space)
  54. {
  55. mods.Add(Loc.GetString(temp.Description));
  56. }
  57. if (light.Description != string.Empty)
  58. {
  59. mods.Add(Loc.GetString(light.Description));
  60. }
  61. var duration = TimeSpan.FromSeconds(CfgManager.GetCVar(CCVars.SalvageExpeditionDuration));
  62. return new SalvageMission(seed, dungeon.ID, faction.ID, biome.ID, air.ID, temp.Temperature, light.Color, duration, mods);
  63. }
  64. public T GetBiomeMod<T>(string biome, System.Random rand, ref float rating) where T : class, IPrototype, IBiomeSpecificMod
  65. {
  66. var mods = _proto.EnumeratePrototypes<T>().ToList();
  67. mods.Sort((x, y) => string.Compare(x.ID, y.ID, StringComparison.Ordinal));
  68. rand.Shuffle(mods);
  69. foreach (var mod in mods)
  70. {
  71. if (mod.Cost > rating || (mod.Biomes != null && !mod.Biomes.Contains(biome)))
  72. continue;
  73. rating -= mod.Cost;
  74. return mod;
  75. }
  76. throw new InvalidOperationException();
  77. }
  78. public T GetMod<T>(System.Random rand, ref float rating) where T : class, IPrototype, ISalvageMod
  79. {
  80. var mods = _proto.EnumeratePrototypes<T>().ToList();
  81. mods.Sort((x, y) => string.Compare(x.ID, y.ID, StringComparison.Ordinal));
  82. rand.Shuffle(mods);
  83. foreach (var mod in mods)
  84. {
  85. if (mod.Cost > rating)
  86. continue;
  87. rating -= mod.Cost;
  88. return mod;
  89. }
  90. throw new InvalidOperationException();
  91. }
  92. }