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 /// /// Randomly alters the laws of an individual silicon. /// public void IonStormTarget(Entity 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(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(ent); var ev = new IonStormLawsEvent(laws); RaiseLocalEvent(ent, ref ev); } }