From bad25e3397b7c7cc4a88f7ee9592fcba28875f1b Mon Sep 17 00:00:00 2001 From: The Canned One Date: Sun, 29 Sep 2024 19:01:59 +0200 Subject: [PATCH] Split part of IonStormRule into IonStormSystem. Added StartIonStormed which also uses IonStormSystem. Added StartIonStormedComponent. Changed stuff related to the Derelict Cyborg. Derelict Cyborg now spawns with a randomized lawset. --- .../Silicons/Laws/IonStormSystem.cs | 283 ++++++++++++++++++ .../Silicons/Laws/StartIonStormedSystem.cs | 40 +++ .../StationEvents/Events/IonStormRule.cs | 267 +---------------- .../Components/StartIonStormedComponent.cs | 17 ++ .../ghost/roles/ghost-role-component.ftl | 2 +- .../Locale/en-US/silicons/derelict/role.ftl | 2 +- .../Mobs/Cyborgs/base_borg_chassis.yml | 8 +- Resources/Prototypes/GameRules/events.yml | 7 +- 8 files changed, 355 insertions(+), 271 deletions(-) create mode 100644 Content.Server/Silicons/Laws/IonStormSystem.cs create mode 100644 Content.Server/Silicons/Laws/StartIonStormedSystem.cs create mode 100644 Content.Shared/Silicons/Laws/Components/StartIonStormedComponent.cs diff --git a/Content.Server/Silicons/Laws/IonStormSystem.cs b/Content.Server/Silicons/Laws/IonStormSystem.cs new file mode 100644 index 0000000000..1acfe2e389 --- /dev/null +++ b/Content.Server/Silicons/Laws/IonStormSystem.cs @@ -0,0 +1,283 @@ +using System.Linq; +using Content.Server.StationEvents.Components; +using Content.Shared.Administration.Logs; +using Content.Shared.Database; +using Content.Shared.Dataset; +using Content.Shared.FixedPoint; +using Content.Shared.GameTicking.Components; +using Content.Shared.Random; +using Content.Shared.Random.Helpers; +using Content.Shared.Silicons.Laws; +using Content.Shared.Silicons.Laws.Components; +using Content.Shared.Station.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +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!; + + // funny + [ValidatePrototypeId] + private const string Threats = "IonStormThreats"; + [ValidatePrototypeId] + private const string Objects = "IonStormObjects"; + [ValidatePrototypeId] + private const string Crew = "IonStormCrew"; + [ValidatePrototypeId] + private const string Adjectives = "IonStormAdjectives"; + [ValidatePrototypeId] + private const string Verbs = "IonStormVerbs"; + [ValidatePrototypeId] + private const string NumberBase = "IonStormNumberBase"; + [ValidatePrototypeId] + private const string NumberMod = "IonStormNumberMod"; + [ValidatePrototypeId] + private const string Areas = "IonStormAreas"; + [ValidatePrototypeId] + private const string Feelings = "IonStormFeelings"; + [ValidatePrototypeId] + private const string FeelingsPlural = "IonStormFeelingsPlural"; + [ValidatePrototypeId] + private const string Musts = "IonStormMusts"; + [ValidatePrototypeId] + private const string Requires = "IonStormRequires"; + [ValidatePrototypeId] + private const string Actions = "IonStormActions"; + [ValidatePrototypeId] + private const string Allergies = "IonStormAllergies"; + [ValidatePrototypeId] + private const string AllergySeverities = "IonStormAllergySeverities"; + [ValidatePrototypeId] + private const string Concepts = "IonStormConcepts"; + [ValidatePrototypeId] + private const string Drinks = "IonStormDrinks"; + [ValidatePrototypeId] + private const string Foods = "IonStormFoods"; + + public void IonStormTarget(EntityUid ent, SiliconLawBoundComponent lawBound, TransformComponent xform, IonStormTargetComponent target, EntityUid? chosenStation, bool ignoreStation = false, bool DoNotAdminlog = false) + { + // only affect law holders on the station unless ignoreStation is true. + if (CompOrNull(xform.GridUid)?.Station != chosenStation && !ignoreStation) + return; + + 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); + } + else + { + // 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 + FixedPoint2 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 = GenerateLaw(); + + // 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++) + { + string notNullIdentifier = laws.Laws[i].LawIdentifierOverride ?? (i - orderDeduction).ToString(); + + if (notNullIdentifier.Any(char.IsSymbol)) + { + orderDeduction += 1; + } + else + { + laws.Laws[i].LawIdentifierOverride = (i - orderDeduction).ToString(); + } + } + + //DoNotAdminlog is used to prevent adminlog spam. + if (!DoNotAdminlog) + _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); + } + + // for your own sake direct your eyes elsewhere + private string GenerateLaw() + { + // pick all values ahead of time to make the logic cleaner + var threats = Pick(Threats); + var objects = Pick(Objects); + var crew1 = Pick(Crew); + var crew2 = Pick(Crew); + var adjective = Pick(Adjectives); + var verb = Pick(Verbs); + var number = Pick(NumberBase) + " " + Pick(NumberMod); + var area = Pick(Areas); + var feeling = Pick(Feelings); + var feelingPlural = Pick(FeelingsPlural); + var must = Pick(Musts); + var require = Pick(Requires); + var action = Pick(Actions); + var allergy = Pick(Allergies); + var allergySeverity = Pick(AllergySeverities); + var concept = Pick(Concepts); + var drink = Pick(Drinks); + var food = Pick(Foods); + + var joined = $"{number} {adjective}"; + // a lot of things have subjects of a threat/crew/object + var triple = _robustRandom.Next(0, 3) switch + { + 0 => threats, + 1 => crew1, + 2 => objects, + _ => throw new IndexOutOfRangeException(), + }; + var crewAll = _robustRandom.Prob(0.5f) ? crew2 : Loc.GetString("ion-storm-crew"); + var objectsThreats = _robustRandom.Prob(0.5f) ? objects : threats; + var objectsConcept = _robustRandom.Prob(0.5f) ? objects : concept; + // s goes ahead of require, is/are + // i dont think theres a way to do this in fluent + var (who, plural) = _robustRandom.Next(0, 5) switch + { + 0 => (Loc.GetString("ion-storm-you"), false), + 1 => (Loc.GetString("ion-storm-the-station"), true), + 2 => (Loc.GetString("ion-storm-the-crew"), true), + 3 => (Loc.GetString("ion-storm-the-job", ("job", crew2)), false), + _ => (area, true) // THE SINGULARITY REQUIRES THE HAPPY CLOWNS + }; + var jobChange = _robustRandom.Next(0, 3) switch + { + 0 => crew1, + 1 => Loc.GetString("ion-storm-clowns"), + _ => Loc.GetString("ion-storm-heads") + }; + var part = Loc.GetString("ion-storm-part", ("part", _robustRandom.Prob(0.5f))); + var harm = _robustRandom.Next(0, 6) switch + { + 0 => concept, + 1 => $"{adjective} {threats}", + 2 => $"{adjective} {objects}", + 3 => Loc.GetString("ion-storm-adjective-things", ("adjective", adjective)), + 4 => crew1, + _ => Loc.GetString("ion-storm-x-and-y", ("x", crew1), ("y", crew2)) + }; + + if (plural) feeling = feelingPlural; + + var subjects = _robustRandom.Prob(0.5f) ? objectsThreats : Loc.GetString("ion-storm-people"); + + // message logic!!! + return _robustRandom.Next(0, 36) switch + { + 0 => Loc.GetString("ion-storm-law-on-station", ("joined", joined), ("subjects", triple)), + 1 => Loc.GetString("ion-storm-law-no-shuttle", ("joined", joined), ("subjects", triple)), + 2 => Loc.GetString("ion-storm-law-crew-are", ("who", crewAll), ("joined", joined), ("subjects", objectsThreats)), + 3 => Loc.GetString("ion-storm-law-subjects-harmful", ("adjective", adjective), ("subjects", triple)), + 4 => Loc.GetString("ion-storm-law-must-harmful", ("must", must)), + 5 => Loc.GetString("ion-storm-law-thing-harmful", ("thing", _robustRandom.Prob(0.5f) ? concept : action)), + 6 => Loc.GetString("ion-storm-law-job-harmful", ("adjective", adjective), ("job", crew1)), + 7 => Loc.GetString("ion-storm-law-having-harmful", ("adjective", adjective), ("thing", objectsConcept)), + 8 => Loc.GetString("ion-storm-law-not-having-harmful", ("adjective", adjective), ("thing", objectsConcept)), + 9 => Loc.GetString("ion-storm-law-requires", ("who", who), ("plural", plural), ("thing", _robustRandom.Prob(0.5f) ? concept : require)), + 10 => Loc.GetString("ion-storm-law-requires-subjects", ("who", who), ("plural", plural), ("joined", joined), ("subjects", triple)), + 11 => Loc.GetString("ion-storm-law-allergic", ("who", who), ("plural", plural), ("severity", allergySeverity), ("allergy", _robustRandom.Prob(0.5f) ? concept : allergy)), + 12 => Loc.GetString("ion-storm-law-allergic-subjects", ("who", who), ("plural", plural), ("severity", allergySeverity), ("adjective", adjective), ("subjects", _robustRandom.Prob(0.5f) ? objects : crew1)), + 13 => Loc.GetString("ion-storm-law-feeling", ("who", who), ("feeling", feeling), ("concept", concept)), + 14 => Loc.GetString("ion-storm-law-feeling-subjects", ("who", who), ("feeling", feeling), ("joined", joined), ("subjects", triple)), + 15 => Loc.GetString("ion-storm-law-you-are", ("concept", concept)), + 16 => Loc.GetString("ion-storm-law-you-are-subjects", ("joined", joined), ("subjects", triple)), + 17 => Loc.GetString("ion-storm-law-you-must-always", ("must", must)), + 18 => Loc.GetString("ion-storm-law-you-must-never", ("must", must)), + 19 => Loc.GetString("ion-storm-law-eat", ("who", crewAll), ("adjective", adjective), ("food", _robustRandom.Prob(0.5f) ? food : triple)), + 20 => Loc.GetString("ion-storm-law-drink", ("who", crewAll), ("adjective", adjective), ("drink", drink)), + 22 => Loc.GetString("ion-storm-law-change-job", ("who", crewAll), ("adjective", adjective), ("change", jobChange)), + 23 => Loc.GetString("ion-storm-law-highest-rank", ("who", crew1)), + 24 => Loc.GetString("ion-storm-law-lowest-rank", ("who", crew1)), + 25 => Loc.GetString("ion-storm-law-crew-must", ("who", crewAll), ("must", must)), + 26 => Loc.GetString("ion-storm-law-crew-must-go", ("who", crewAll), ("area", area)), + 27 => Loc.GetString("ion-storm-law-crew-only-1", ("who", crew1), ("part", part)), + 28 => Loc.GetString("ion-storm-law-crew-only-2", ("who", crew1), ("other", crew2), ("part", part)), + 29 => Loc.GetString("ion-storm-law-crew-only-subjects", ("adjective", adjective), ("subjects", subjects), ("part", part)), + 30 => Loc.GetString("ion-storm-law-crew-must-do", ("must", must), ("part", part)), + 31 => Loc.GetString("ion-storm-law-crew-must-have", ("adjective", adjective), ("objects", objects), ("part", part)), + 32 => Loc.GetString("ion-storm-law-crew-must-eat", ("who", who), ("adjective", adjective), ("food", food), ("part", part)), + 33 => Loc.GetString("ion-storm-law-harm", ("who", harm)), + 34 => Loc.GetString("ion-storm-law-protect", ("who", harm)), + _ => Loc.GetString("ion-storm-law-concept-verb", ("concept", concept), ("verb", verb), ("subjects", triple)) + }; + } + + /// + /// Picks a random value from an ion storm dataset. + /// All ion storm datasets start with IonStorm. + /// + private string Pick(string name) + { + var dataset = _proto.Index(name); + return _robustRandom.Pick(dataset.Values); + } +} diff --git a/Content.Server/Silicons/Laws/StartIonStormedSystem.cs b/Content.Server/Silicons/Laws/StartIonStormedSystem.cs new file mode 100644 index 0000000000..762397b5d4 --- /dev/null +++ b/Content.Server/Silicons/Laws/StartIonStormedSystem.cs @@ -0,0 +1,40 @@ +using Content.Shared.Silicons.Laws.Components; +using Content.Shared.Administration.Logs; +using Content.Shared.Database; +using Content.Shared.Silicons.Laws; + +namespace Content.Server.Silicons.Laws; + +/// +/// This handles running the ion storm event on specific entities when spawned in. +/// +public sealed class StartIonStormedSystem : EntitySystem +{ + [Dependency] private readonly IonStormSystem _ionStorm = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SiliconLawSystem _siliconLaw = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnMapInit); + } + + private void OnMapInit(EntityUid uid, StartIonStormedComponent component, ref MapInitEvent args) + { + if (!TryComp(uid, out var lawBound)) + return; + if (!TryComp(uid, out var xform)) + return; + if (!TryComp(uid, out var target)) + return; + + for (int currentIonStorm = 1; currentIonStorm <= component.IonStormAmount; currentIonStorm++) + { + _ionStorm.IonStormTarget(uid, lawBound, xform, target, null, true, true); + } + + var laws = _siliconLaw.GetLaws(uid, lawBound); + _adminLogger.Add(LogType.Mind, LogImpact.High, $"{ToPrettyString(uid):silicon} spawned with ion stormed laws: {laws.LoggingString()}"); + } +} diff --git a/Content.Server/StationEvents/Events/IonStormRule.cs b/Content.Server/StationEvents/Events/IonStormRule.cs index 805549439b..6d1834c576 100644 --- a/Content.Server/StationEvents/Events/IonStormRule.cs +++ b/Content.Server/StationEvents/Events/IonStormRule.cs @@ -1,64 +1,15 @@ using System.Linq; using Content.Server.Silicons.Laws; using Content.Server.StationEvents.Components; -using Content.Shared.Administration.Logs; -using Content.Shared.Database; -using Content.Shared.Dataset; -using Content.Shared.FixedPoint; using Content.Shared.GameTicking.Components; -using Content.Shared.Random; -using Content.Shared.Random.Helpers; using Content.Shared.Silicons.Laws; using Content.Shared.Silicons.Laws.Components; -using Content.Shared.Station.Components; -using Robust.Shared.Prototypes; -using Robust.Shared.Random; namespace Content.Server.StationEvents.Events; public sealed class IonStormRule : StationEventSystem { - [Dependency] private readonly IPrototypeManager _proto = default!; - [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; - [Dependency] private readonly SiliconLawSystem _siliconLaw = default!; - - // funny - [ValidatePrototypeId] - private const string Threats = "IonStormThreats"; - [ValidatePrototypeId] - private const string Objects = "IonStormObjects"; - [ValidatePrototypeId] - private const string Crew = "IonStormCrew"; - [ValidatePrototypeId] - private const string Adjectives = "IonStormAdjectives"; - [ValidatePrototypeId] - private const string Verbs = "IonStormVerbs"; - [ValidatePrototypeId] - private const string NumberBase = "IonStormNumberBase"; - [ValidatePrototypeId] - private const string NumberMod = "IonStormNumberMod"; - [ValidatePrototypeId] - private const string Areas = "IonStormAreas"; - [ValidatePrototypeId] - private const string Feelings = "IonStormFeelings"; - [ValidatePrototypeId] - private const string FeelingsPlural = "IonStormFeelingsPlural"; - [ValidatePrototypeId] - private const string Musts = "IonStormMusts"; - [ValidatePrototypeId] - private const string Requires = "IonStormRequires"; - [ValidatePrototypeId] - private const string Actions = "IonStormActions"; - [ValidatePrototypeId] - private const string Allergies = "IonStormAllergies"; - [ValidatePrototypeId] - private const string AllergySeverities = "IonStormAllergySeverities"; - [ValidatePrototypeId] - private const string Concepts = "IonStormConcepts"; - [ValidatePrototypeId] - private const string Drinks = "IonStormDrinks"; - [ValidatePrototypeId] - private const string Foods = "IonStormFoods"; + [Dependency] private readonly IonStormSystem _ionStorm = default!; protected override void Started(EntityUid uid, IonStormRuleComponent comp, GameRuleComponent gameRule, GameRuleStartedEvent args) { @@ -70,221 +21,7 @@ public sealed class IonStormRule : StationEventSystem var query = EntityQueryEnumerator(); while (query.MoveNext(out var ent, out var lawBound, out var xform, out var target)) { - // only affect law holders on the station - if (CompOrNull(xform.GridUid)?.Station != chosenStation) - continue; - - if (!RobustRandom.Prob(target.Chance)) - continue; - - var laws = _siliconLaw.GetLaws(ent, lawBound); - if (laws.Laws.Count == 0) - continue; - - // try to swap it out with a random lawset - if (RobustRandom.Prob(target.RandomLawsetChance)) - { - var lawsets = PrototypeManager.Index(target.RandomLawsets); - var lawset = lawsets.Pick(RobustRandom); - laws = _siliconLaw.GetLawset(lawset); - } - else - { - // 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 - FixedPoint2 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 = GenerateLaw(); - - // 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++) - { - string notNullIdentifier = laws.Laws[i].LawIdentifierOverride ?? (i - orderDeduction).ToString(); - - if (notNullIdentifier.Any(char.IsSymbol)) - { - orderDeduction += 1; - } - else - { - laws.Laws[i].LawIdentifierOverride = (i - orderDeduction).ToString(); - } - } - - _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); + _ionStorm.IonStormTarget(ent, lawBound, xform, target, chosenStation); } } - - // for your own sake direct your eyes elsewhere - private string GenerateLaw() - { - // pick all values ahead of time to make the logic cleaner - var threats = Pick(Threats); - var objects = Pick(Objects); - var crew1 = Pick(Crew); - var crew2 = Pick(Crew); - var adjective = Pick(Adjectives); - var verb = Pick(Verbs); - var number = Pick(NumberBase) + " " + Pick(NumberMod); - var area = Pick(Areas); - var feeling = Pick(Feelings); - var feelingPlural = Pick(FeelingsPlural); - var must = Pick(Musts); - var require = Pick(Requires); - var action = Pick(Actions); - var allergy = Pick(Allergies); - var allergySeverity = Pick(AllergySeverities); - var concept = Pick(Concepts); - var drink = Pick(Drinks); - var food = Pick(Foods); - - var joined = $"{number} {adjective}"; - // a lot of things have subjects of a threat/crew/object - var triple = RobustRandom.Next(0, 3) switch - { - 0 => threats, - 1 => crew1, - 2 => objects, - _ => throw new IndexOutOfRangeException(), - }; - var crewAll = RobustRandom.Prob(0.5f) ? crew2 : Loc.GetString("ion-storm-crew"); - var objectsThreats = RobustRandom.Prob(0.5f) ? objects : threats; - var objectsConcept = RobustRandom.Prob(0.5f) ? objects : concept; - // s goes ahead of require, is/are - // i dont think theres a way to do this in fluent - var (who, plural) = RobustRandom.Next(0, 5) switch - { - 0 => (Loc.GetString("ion-storm-you"), false), - 1 => (Loc.GetString("ion-storm-the-station"), true), - 2 => (Loc.GetString("ion-storm-the-crew"), true), - 3 => (Loc.GetString("ion-storm-the-job", ("job", crew2)), false), - _ => (area, true) // THE SINGULARITY REQUIRES THE HAPPY CLOWNS - }; - var jobChange = RobustRandom.Next(0, 3) switch - { - 0 => crew1, - 1 => Loc.GetString("ion-storm-clowns"), - _ => Loc.GetString("ion-storm-heads") - }; - var part = Loc.GetString("ion-storm-part", ("part", RobustRandom.Prob(0.5f))); - var harm = RobustRandom.Next(0, 6) switch - { - 0 => concept, - 1 => $"{adjective} {threats}", - 2 => $"{adjective} {objects}", - 3 => Loc.GetString("ion-storm-adjective-things", ("adjective", adjective)), - 4 => crew1, - _ => Loc.GetString("ion-storm-x-and-y", ("x", crew1), ("y", crew2)) - }; - - if (plural) feeling = feelingPlural; - - var subjects = RobustRandom.Prob(0.5f) ? objectsThreats : Loc.GetString("ion-storm-people"); - - // message logic!!! - return RobustRandom.Next(0, 36) switch - { - 0 => Loc.GetString("ion-storm-law-on-station", ("joined", joined), ("subjects", triple)), - 1 => Loc.GetString("ion-storm-law-no-shuttle", ("joined", joined), ("subjects", triple)), - 2 => Loc.GetString("ion-storm-law-crew-are", ("who", crewAll), ("joined", joined), ("subjects", objectsThreats)), - 3 => Loc.GetString("ion-storm-law-subjects-harmful", ("adjective", adjective), ("subjects", triple)), - 4 => Loc.GetString("ion-storm-law-must-harmful", ("must", must)), - 5 => Loc.GetString("ion-storm-law-thing-harmful", ("thing", RobustRandom.Prob(0.5f) ? concept : action)), - 6 => Loc.GetString("ion-storm-law-job-harmful", ("adjective", adjective), ("job", crew1)), - 7 => Loc.GetString("ion-storm-law-having-harmful", ("adjective", adjective), ("thing", objectsConcept)), - 8 => Loc.GetString("ion-storm-law-not-having-harmful", ("adjective", adjective), ("thing", objectsConcept)), - 9 => Loc.GetString("ion-storm-law-requires", ("who", who), ("plural", plural), ("thing", RobustRandom.Prob(0.5f) ? concept : require)), - 10 => Loc.GetString("ion-storm-law-requires-subjects", ("who", who), ("plural", plural), ("joined", joined), ("subjects", triple)), - 11 => Loc.GetString("ion-storm-law-allergic", ("who", who), ("plural", plural), ("severity", allergySeverity), ("allergy", RobustRandom.Prob(0.5f) ? concept : allergy)), - 12 => Loc.GetString("ion-storm-law-allergic-subjects", ("who", who), ("plural", plural), ("severity", allergySeverity), ("adjective", adjective), ("subjects", RobustRandom.Prob(0.5f) ? objects : crew1)), - 13 => Loc.GetString("ion-storm-law-feeling", ("who", who), ("feeling", feeling), ("concept", concept)), - 14 => Loc.GetString("ion-storm-law-feeling-subjects", ("who", who), ("feeling", feeling), ("joined", joined), ("subjects", triple)), - 15 => Loc.GetString("ion-storm-law-you-are", ("concept", concept)), - 16 => Loc.GetString("ion-storm-law-you-are-subjects", ("joined", joined), ("subjects", triple)), - 17 => Loc.GetString("ion-storm-law-you-must-always", ("must", must)), - 18 => Loc.GetString("ion-storm-law-you-must-never", ("must", must)), - 19 => Loc.GetString("ion-storm-law-eat", ("who", crewAll), ("adjective", adjective), ("food", RobustRandom.Prob(0.5f) ? food : triple)), - 20 => Loc.GetString("ion-storm-law-drink", ("who", crewAll), ("adjective", adjective), ("drink", drink)), - 22 => Loc.GetString("ion-storm-law-change-job", ("who", crewAll), ("adjective", adjective), ("change", jobChange)), - 23 => Loc.GetString("ion-storm-law-highest-rank", ("who", crew1)), - 24 => Loc.GetString("ion-storm-law-lowest-rank", ("who", crew1)), - 25 => Loc.GetString("ion-storm-law-crew-must", ("who", crewAll), ("must", must)), - 26 => Loc.GetString("ion-storm-law-crew-must-go", ("who", crewAll), ("area", area)), - 27 => Loc.GetString("ion-storm-law-crew-only-1", ("who", crew1), ("part", part)), - 28 => Loc.GetString("ion-storm-law-crew-only-2", ("who", crew1), ("other", crew2), ("part", part)), - 29 => Loc.GetString("ion-storm-law-crew-only-subjects", ("adjective", adjective), ("subjects", subjects), ("part", part)), - 30 => Loc.GetString("ion-storm-law-crew-must-do", ("must", must), ("part", part)), - 31 => Loc.GetString("ion-storm-law-crew-must-have", ("adjective", adjective), ("objects", objects), ("part", part)), - 32 => Loc.GetString("ion-storm-law-crew-must-eat", ("who", who), ("adjective", adjective), ("food", food), ("part", part)), - 33 => Loc.GetString("ion-storm-law-harm", ("who", harm)), - 34 => Loc.GetString("ion-storm-law-protect", ("who", harm)), - _ => Loc.GetString("ion-storm-law-concept-verb", ("concept", concept), ("verb", verb), ("subjects", triple)) - }; - } - - /// - /// Picks a random value from an ion storm dataset. - /// All ion storm datasets start with IonStorm. - /// - private string Pick(string name) - { - var dataset = _proto.Index(name); - return RobustRandom.Pick(dataset.Values); - } } diff --git a/Content.Shared/Silicons/Laws/Components/StartIonStormedComponent.cs b/Content.Shared/Silicons/Laws/Components/StartIonStormedComponent.cs new file mode 100644 index 0000000000..ae9b49a49c --- /dev/null +++ b/Content.Shared/Silicons/Laws/Components/StartIonStormedComponent.cs @@ -0,0 +1,17 @@ +using Content.Shared.Random; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Silicons.Laws.Components; + +/// +/// Runs the IonStormSystem on an entity IonStormAmount times. +/// +[RegisterComponent] +public sealed partial class StartIonStormedComponent : Component +{ + /// + /// Amount of times that the ion storm will be run on the entity on spawn. + /// + [DataField] + public int IonStormAmount = 1; +} diff --git a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl index 71ab4d3716..3a8e720038 100644 --- a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl @@ -242,7 +242,7 @@ ghost-role-information-syndicate-cyborg-description = The Syndicate needs reinfo ghost-role-information-derelict-cyborg-name = Derelict Cyborg -ghost-role-information-derelict-cyborg-description = You were a regular cyborg that got lost in space. After drifting in whichever direction the laws of physics would have it for years, you have drifted close to a Nanotrasen space station... You are bound by silicon laws. Check them upon spawning. +ghost-role-information-derelict-cyborg-description = You were a regular cyborg that got lost in space. After drifting in whichever direction the laws of physics would have it for years, you have drifted close to a Nanotrasen space station. You have a fire extinguisher and mass scanner which can be used to board the station. Years of exposure to ion storms has left your silicon laws altered - check them upon spawning. ghost-role-information-security-name = Security ghost-role-information-security-description = You are part of a security task force, but seem to have found yourself in a strange situation... diff --git a/Resources/Locale/en-US/silicons/derelict/role.ftl b/Resources/Locale/en-US/silicons/derelict/role.ftl index 88e750e621..96a33ae6b1 100644 --- a/Resources/Locale/en-US/silicons/derelict/role.ftl +++ b/Resources/Locale/en-US/silicons/derelict/role.ftl @@ -1,4 +1,4 @@ derelict-cyborg-round-end-agent-name = derelict cyborg derelict-cyborg-role-greeting = - You are a cyborg that has been lost in space for many years that has now drifted close to a space station. You can use your fire extinguisher and GPS to get board the station. Remember to follow your laws. #Greeting is unused for now. \ No newline at end of file + You are a cyborg that has been lost in space for many years that has now drifted close to a space station. You can use your fire extinguisher and GPS to get board the station. Remember to follow your laws. \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 4c0359b37e..dcbef820ce 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -329,11 +329,11 @@ - type: Access enabled: false groups: - - AllAccess #Randomized access would be fun. AllAccess is the best i can think of right now that does make it too hard to enter the station or. + - AllAccess #Randomized access would be fun. AllAccess is the best i can think of right now that does make it too hard for it to enter the station or navigate it.. - type: AccessReader access: [["Command"]] #I will probably change this. - type: SiliconLawProvider - laws: AntimovLawset #Temporary until i get it randomized. + laws: Crewsimov #Although this will be randomized. - type: IntrinsicRadioTransmitter channels: - Binary @@ -342,3 +342,7 @@ channels: - Binary - Common + - type: StartIonStormed + ionStormAmount: 5 + DelayAdminlog: true + - type: IonStormTarget diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index efebc8e272..72ab8b104d 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -552,10 +552,10 @@ id: DerelictCyborgSpawn components: - type: StationEvent - weight: 2 #Low until it spawns with a random lawset instead of just antimov. + weight: 8 earliestStart: 15 reoccurrenceDelay: 20 - minimumPlayers: 7 + minimumPlayers: 4 duration: null - type: SpaceSpawnRule spawnDistance: 0 @@ -564,6 +564,9 @@ - type: AntagSelection agentName: derelict-cyborg-round-end-agent-name definitions: +# briefing: +# text: derelict-cyborg-role-greetin +# color: Blue - spawnerPrototype: SpawnPointGhostDerelictCyborg min: 1 max: 1