* Localize planet names (borer) * DatasetPrototype -> LocalizedDatasetPrototype * Apply requested changes
116 lines
4.0 KiB
C#
116 lines
4.0 KiB
C#
using System.Linq;
|
|
using Content.Shared.CCVar;
|
|
using Content.Shared.Dataset;
|
|
using Content.Shared.Procedural;
|
|
using Content.Shared.Procedural.Loot;
|
|
using Content.Shared.Random;
|
|
using Content.Shared.Random.Helpers;
|
|
using Content.Shared.Salvage.Expeditions;
|
|
using Content.Shared.Salvage.Expeditions.Modifiers;
|
|
using Robust.Shared.Configuration;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Random;
|
|
using Robust.Shared.Serialization;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Shared.Salvage;
|
|
|
|
public abstract partial class SharedSalvageSystem : EntitySystem
|
|
{
|
|
[Dependency] protected readonly IConfigurationManager CfgManager = default!;
|
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
|
|
|
/// <summary>
|
|
/// Main loot table for salvage expeditions.
|
|
/// </summary>
|
|
[ValidatePrototypeId<SalvageLootPrototype>]
|
|
public const string ExpeditionsLootProto = "SalvageLoot";
|
|
|
|
public string GetFTLName(LocalizedDatasetPrototype dataset, int seed)
|
|
{
|
|
var random = new System.Random(seed);
|
|
return $"{Loc.GetString(dataset.Values[random.Next(dataset.Values.Count)])}-{random.Next(10, 100)}-{(char) (65 + random.Next(26))}";
|
|
}
|
|
|
|
public SalvageMission GetMission(SalvageDifficultyPrototype difficulty, int seed)
|
|
{
|
|
// This is on shared to ensure the client display for missions and what the server generates are consistent
|
|
var modifierBudget = difficulty.ModifierBudget;
|
|
var rand = new System.Random(seed);
|
|
|
|
// Run budget in order of priority
|
|
// - Biome
|
|
// - Lighting
|
|
// - Atmos
|
|
var biome = GetMod<SalvageBiomeModPrototype>(rand, ref modifierBudget);
|
|
var light = GetBiomeMod<SalvageLightMod>(biome.ID, rand, ref modifierBudget);
|
|
var temp = GetBiomeMod<SalvageTemperatureMod>(biome.ID, rand, ref modifierBudget);
|
|
var air = GetBiomeMod<SalvageAirMod>(biome.ID, rand, ref modifierBudget);
|
|
var dungeon = GetBiomeMod<SalvageDungeonModPrototype>(biome.ID, rand, ref modifierBudget);
|
|
var factionProtos = _proto.EnumeratePrototypes<SalvageFactionPrototype>().ToList();
|
|
factionProtos.Sort((x, y) => string.Compare(x.ID, y.ID, StringComparison.Ordinal));
|
|
var faction = factionProtos[rand.Next(factionProtos.Count)];
|
|
|
|
var mods = new List<string>();
|
|
|
|
if (air.Description != string.Empty)
|
|
{
|
|
mods.Add(Loc.GetString(air.Description));
|
|
}
|
|
|
|
// only show the description if there is an atmosphere since wont matter otherwise
|
|
if (temp.Description != string.Empty && !air.Space)
|
|
{
|
|
mods.Add(Loc.GetString(temp.Description));
|
|
}
|
|
|
|
if (light.Description != string.Empty)
|
|
{
|
|
mods.Add(Loc.GetString(light.Description));
|
|
}
|
|
|
|
var duration = TimeSpan.FromSeconds(CfgManager.GetCVar(CCVars.SalvageExpeditionDuration));
|
|
|
|
return new SalvageMission(seed, dungeon.ID, faction.ID, biome.ID, air.ID, temp.Temperature, light.Color, duration, mods);
|
|
}
|
|
|
|
public T GetBiomeMod<T>(string biome, System.Random rand, ref float rating) where T : class, IPrototype, IBiomeSpecificMod
|
|
{
|
|
var mods = _proto.EnumeratePrototypes<T>().ToList();
|
|
mods.Sort((x, y) => string.Compare(x.ID, y.ID, StringComparison.Ordinal));
|
|
rand.Shuffle(mods);
|
|
|
|
foreach (var mod in mods)
|
|
{
|
|
if (mod.Cost > rating || (mod.Biomes != null && !mod.Biomes.Contains(biome)))
|
|
continue;
|
|
|
|
rating -= mod.Cost;
|
|
|
|
return mod;
|
|
}
|
|
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
public T GetMod<T>(System.Random rand, ref float rating) where T : class, IPrototype, ISalvageMod
|
|
{
|
|
var mods = _proto.EnumeratePrototypes<T>().ToList();
|
|
mods.Sort((x, y) => string.Compare(x.ID, y.ID, StringComparison.Ordinal));
|
|
rand.Shuffle(mods);
|
|
|
|
foreach (var mod in mods)
|
|
{
|
|
if (mod.Cost > rating)
|
|
continue;
|
|
|
|
rating -= mod.Cost;
|
|
|
|
return mod;
|
|
}
|
|
|
|
throw new InvalidOperationException();
|
|
}
|
|
}
|
|
|