mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-10-02 17:17:25 +00:00
* Fix ion laws reverting to old impl after upmerge * delectable publish
129 lines
4.6 KiB
C#
129 lines
4.6 KiB
C#
using Content.Shared._DV.IonLaws; // DeltaV - ion laws
|
|
using Content.Shared.Administration.Logs;
|
|
using Content.Shared.Database;
|
|
using Content.Shared.FixedPoint;
|
|
using Content.Shared.Silicons.Laws;
|
|
using Content.Shared.Silicons.Laws.Components;
|
|
using Robust.Shared.Random;
|
|
using System.Linq;
|
|
using Content.Shared.Random;
|
|
using Content.Shared.Random.Helpers;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Server.Silicons.Laws;
|
|
|
|
public sealed class IonStormSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
|
[Dependency] private readonly SiliconLawSystem _siliconLaw = default!;
|
|
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
|
// [Dependency] private readonly IonLawSystem _ionLaw = default!; // DeltaV - ion laws
|
|
[Dependency] private readonly DVIonLawSystem _dvIonLaw = default!; // DeltaV - ion laws
|
|
|
|
/// <summary>
|
|
/// Randomly alters the laws of an individual silicon.
|
|
/// </summary>
|
|
public void IonStormTarget(Entity<SiliconLawBoundComponent, IonStormTargetComponent> ent, bool adminlog = true)
|
|
{
|
|
var lawBound = ent.Comp1;
|
|
var target = ent.Comp2;
|
|
if (!_robustRandom.Prob(target.Chance))
|
|
return;
|
|
|
|
var laws = _siliconLaw.GetLaws(ent, lawBound);
|
|
if (laws.Laws.Count == 0)
|
|
return;
|
|
|
|
// try to swap it out with a random lawset
|
|
if (_robustRandom.Prob(target.RandomLawsetChance))
|
|
{
|
|
var lawsets = _proto.Index<WeightedRandomPrototype>(target.RandomLawsets);
|
|
var lawset = lawsets.Pick(_robustRandom);
|
|
laws = _siliconLaw.GetLawset(lawset);
|
|
}
|
|
// clone it so not modifying stations lawset
|
|
laws = laws.Clone();
|
|
|
|
// shuffle them all
|
|
if (_robustRandom.Prob(target.ShuffleChance))
|
|
{
|
|
// hopefully work with existing glitched laws if there are multiple ion storms
|
|
var baseOrder = FixedPoint2.New(1);
|
|
foreach (var law in laws.Laws)
|
|
{
|
|
if (law.Order < baseOrder)
|
|
baseOrder = law.Order;
|
|
}
|
|
|
|
_robustRandom.Shuffle(laws.Laws);
|
|
|
|
// change order based on shuffled position
|
|
for (int i = 0; i < laws.Laws.Count; i++)
|
|
{
|
|
laws.Laws[i].Order = baseOrder + i;
|
|
}
|
|
}
|
|
|
|
// see if we can remove a random law
|
|
if (laws.Laws.Count > 0 && _robustRandom.Prob(target.RemoveChance))
|
|
{
|
|
var i = _robustRandom.Next(laws.Laws.Count);
|
|
laws.Laws.RemoveAt(i);
|
|
}
|
|
|
|
// generate a new law...
|
|
var newLaw = _dvIonLaw.GenerateLaw(_robustRandom); // DeltaV - new ion laws // _ionLaw.GetIonLaw();
|
|
|
|
if (string.IsNullOrEmpty(newLaw))
|
|
return;
|
|
|
|
// see if the law we add will replace a random existing law or be a new glitched order one
|
|
if (laws.Laws.Count > 0 && _robustRandom.Prob(target.ReplaceChance))
|
|
{
|
|
var i = _robustRandom.Next(laws.Laws.Count);
|
|
laws.Laws[i] = new SiliconLaw()
|
|
{
|
|
LawString = newLaw,
|
|
Order = laws.Laws[i].Order
|
|
};
|
|
}
|
|
else
|
|
{
|
|
laws.Laws.Insert(0, new SiliconLaw
|
|
{
|
|
LawString = newLaw,
|
|
Order = -1,
|
|
LawIdentifierOverride = Loc.GetString("ion-storm-law-scrambled-number", ("length", _robustRandom.Next(5, 10)))
|
|
});
|
|
}
|
|
|
|
// sets all unobfuscated laws' indentifier in order from highest to lowest priority
|
|
// This could technically override the Obfuscation from the code above, but it seems unlikely enough to basically never happen
|
|
int orderDeduction = -1;
|
|
|
|
for (int i = 0; i < laws.Laws.Count; i++)
|
|
{
|
|
var notNullIdentifier = laws.Laws[i].LawIdentifierOverride ?? (i - orderDeduction).ToString();
|
|
|
|
if (notNullIdentifier.Any(char.IsSymbol))
|
|
{
|
|
orderDeduction += 1;
|
|
}
|
|
else
|
|
{
|
|
laws.Laws[i].LawIdentifierOverride = (i - orderDeduction).ToString();
|
|
}
|
|
}
|
|
|
|
// adminlog is used to prevent adminlog spam.
|
|
if (adminlog)
|
|
_adminLogger.Add(LogType.Mind, LogImpact.High, $"{ToPrettyString(ent):silicon} had its laws changed by an ion storm to {laws.LoggingString()}");
|
|
|
|
// laws unique to this silicon, dont use station laws anymore
|
|
EnsureComp<SiliconLawProviderComponent>(ent);
|
|
var ev = new IonStormLawsEvent(laws);
|
|
RaiseLocalEvent(ent, ref ev);
|
|
}
|
|
}
|