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!;
///
/// Main loot table for salvage expeditions.
///
[ValidatePrototypeId]
public const string ExpeditionsLootProto = "NFSalvageLootModerate"; // Frontier: SalvageLoot(rand, ref modifierBudget);
var light = GetBiomeMod(biome.ID, rand, ref modifierBudget);
var temp = GetBiomeMod(biome.ID, rand, ref modifierBudget);
var air = GetBiomeMod(biome.ID, rand, ref modifierBudget);
var dungeon = GetBiomeMod(biome.ID, rand, ref modifierBudget);
// Frontier: restrict factions per difficulty
// var factionProtos = _proto.EnumeratePrototypes().ToList();
var factionProtos = _proto.EnumeratePrototypes()
.Where(x =>
{
return !x.Configs.TryGetValue("Difficulties", out var difficulties)
|| string.IsNullOrWhiteSpace(difficulties)
|| difficulties.Split(",").Contains(difficulty.ID.ToString());
}
).ToList();
// End Frontier: difficulties per faction
factionProtos.Sort((x, y) => string.Compare(x.ID, y.ID, StringComparison.Ordinal));
var faction = factionProtos[rand.Next(factionProtos.Count)];
var mods = new List();
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, difficulty.ID, config); // Frontier: add difficulty.ID, config
}
public T GetBiomeMod(string biome, System.Random rand, ref float rating) where T : class, IPrototype, IBiomeSpecificMod
{
var mods = _proto.EnumeratePrototypes().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(System.Random rand, ref float rating) where T : class, IPrototype, ISalvageMod
{
var mods = _proto.EnumeratePrototypes().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();
}
}
// Frontier: salvage mission type
[Serializable, NetSerializable]
public enum SalvageMissionType : byte
{
///
/// Destroy the specified structures in a dungeon.
///
Destruction = 0,
///
/// Kill a large creature in a dungeon.
///
Elimination = 1,
///
/// Maximum value for random generation, should not be used directly.
///
Max = Elimination,
}
// End Frontier