diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs index ac1fcdd8b0..4052a6e5ed 100644 --- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs +++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs @@ -227,6 +227,7 @@ namespace Content.Client.Lobby.UI { SpeciesButton.SelectId(args.Id); SetSpecies(_species[args.Id].ID); + RefreshTraits(); // DeltaV - Allows for hiding traits UpdateHairPickers(); OnSkinColorOnValueChanged(); }; @@ -559,6 +560,14 @@ namespace Content.Client.Lobby.UI foreach (var trait in traits) { + // Begin DeltaV Additions - Species trait exclusion + if (Profile?.Species is { } selectedSpecies && trait.ExcludedSpecies.Contains(selectedSpecies)) + { + Profile = Profile?.WithoutTraitPreference(trait.ID, _prototypeManager); + continue; + } + // End DeltaV Additions + if (trait.Category == null) { defaultTraits.Add(trait.ID); diff --git a/Content.Server/StationEvents/Events/IonStormRule.cs b/Content.Server/StationEvents/Events/IonStormRule.cs index e7c2d563ba..66d03eb7f7 100644 --- a/Content.Server/StationEvents/Events/IonStormRule.cs +++ b/Content.Server/StationEvents/Events/IonStormRule.cs @@ -1,14 +1,22 @@ +using Content.Server._CD.Traits; // CD - synth trait using Content.Server.Silicons.Laws; using Content.Server.StationEvents.Components; using Content.Shared.GameTicking.Components; using Content.Shared.Silicons.Laws.Components; using Content.Shared.Station.Components; +// CD - start synth trait +using Content.Server.Chat.Managers; +using Content.Shared.Chat; +using Robust.Shared.Player; +using Robust.Shared.Random; +// CD - end synth trait namespace Content.Server.StationEvents.Events; public sealed class IonStormRule : StationEventSystem { [Dependency] private readonly IonStormSystem _ionStorm = default!; + [Dependency] private readonly IChatManager _chatManager = default!; // CD - Used for synth trait protected override void Started(EntityUid uid, IonStormRuleComponent comp, GameRuleComponent gameRule, GameRuleStartedEvent args) { @@ -17,6 +25,22 @@ public sealed class IonStormRule : StationEventSystem if (!TryGetRandomStation(out var chosenStation)) return; + // CD - Go through everyone with the SynthComponent and inform them a storm is happening. + var synthQuery = EntityQueryEnumerator(); + while (synthQuery.MoveNext(out var ent, out var synthComp)) + { + if (RobustRandom.Prob(synthComp.AlertChance)) + continue; + + if (!TryComp(ent, out var actor)) + continue; + + var msg = Loc.GetString("station-event-ion-storm-synth"); + var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg)); + _chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.Channel, colorOverride: Color.Yellow); + } + // CD - End of synth trait + var query = EntityQueryEnumerator(); while (query.MoveNext(out var ent, out var lawBound, out var xform, out var target)) { diff --git a/Content.Server/_CD/Traits/SynthComponent.cs b/Content.Server/_CD/Traits/SynthComponent.cs new file mode 100644 index 0000000000..e5279ae438 --- /dev/null +++ b/Content.Server/_CD/Traits/SynthComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Server._CD.Traits; + +/// +/// Set players' blood to coolant, and is used to notify them of ion storms +/// +[RegisterComponent, Access(typeof(SynthSystem))] +public sealed partial class SynthComponent : Component +{ + /// + /// The chance that the synth is alerted of an ion storm + /// + [DataField] + public float AlertChance = 0.3f; +} diff --git a/Content.Server/_CD/Traits/SynthSystem.cs b/Content.Server/_CD/Traits/SynthSystem.cs new file mode 100644 index 0000000000..f49d490a00 --- /dev/null +++ b/Content.Server/_CD/Traits/SynthSystem.cs @@ -0,0 +1,36 @@ +using Content.Server.Body.Systems; +using Content.Server.Database; +using Content.Shared.Chat.TypingIndicator; +using Content.Shared.Chemistry.Reagent; +using Robust.Shared.Prototypes; + +namespace Content.Server._CD.Traits; + +public sealed class SynthSystem : EntitySystem +{ + // Begin DeltaV - make strings static readonly + private static readonly ProtoId RobotTypingIndicator = "robot"; + private static readonly ProtoId SynthBloodReagent = "SynthBlood"; + // End DeltaV + + [Dependency] private readonly BloodstreamSystem _bloodstream = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(EntityUid uid, SynthComponent component, ComponentStartup args) + { + if (TryComp(uid, out var indicator)) + { + indicator.TypingIndicatorPrototype = RobotTypingIndicator; // DeltaV - make strings static readonly + Dirty(uid, indicator); + } + + // Give them synth blood. Ion storm notif is handled in that system + _bloodstream.ChangeBloodReagent(uid, SynthBloodReagent); // DeltaV - make strings static readonly + } +} diff --git a/Content.Shared/Chat/TypingIndicator/TypingIndicatorComponent.cs b/Content.Shared/Chat/TypingIndicator/TypingIndicatorComponent.cs index f263de4913..9dd977ad6c 100644 --- a/Content.Shared/Chat/TypingIndicator/TypingIndicatorComponent.cs +++ b/Content.Shared/Chat/TypingIndicator/TypingIndicatorComponent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.GameStates; +using Robust.Shared.GameStates; using Robust.Shared.Prototypes; namespace Content.Shared.Chat.TypingIndicator; @@ -7,13 +7,13 @@ namespace Content.Shared.Chat.TypingIndicator; /// Show typing indicator icon when player typing text in chat box. /// Added automatically when player poses entity. /// -[RegisterComponent, NetworkedComponent] -[Access(typeof(SharedTypingIndicatorSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] // CD - AutoGenerateComponentState fixes a bug with synth trait +// [Access(typeof(SharedTypingIndicatorSystem))] CD - Restricted access breaks synth trait because it rewrites the speech bubble over the default race indicator public sealed partial class TypingIndicatorComponent : Component { /// /// Prototype id that store all visual info about typing indicator. /// - [DataField("proto")] + [DataField("proto"), AutoNetworkedField] // CD - AutoNetworkedField fixes a bug in synth trait public ProtoId TypingIndicatorPrototype = "default"; } diff --git a/Content.Shared/Traits/TraitPrototype.cs b/Content.Shared/Traits/TraitPrototype.cs index c79d3cbf30..7ae1c34b4a 100644 --- a/Content.Shared/Traits/TraitPrototype.cs +++ b/Content.Shared/Traits/TraitPrototype.cs @@ -1,5 +1,6 @@ using Content.Shared.Whitelist; using Robust.Shared.Prototypes; +using Content.Shared.Humanoid.Prototypes; // DeltaV - Trait species hiding namespace Content.Shared.Traits; @@ -60,4 +61,10 @@ public sealed partial class TraitPrototype : IPrototype /// [DataField] public ProtoId? Category; + + /// + /// DeltaV - Hides traits from specific species + /// + [DataField] + public HashSet> ExcludedSpecies = new(); } diff --git a/Resources/Locale/en-US/_CD/reagents/meta/biological.ftl b/Resources/Locale/en-US/_CD/reagents/meta/biological.ftl new file mode 100644 index 0000000000..2fa5d3c8be --- /dev/null +++ b/Resources/Locale/en-US/_CD/reagents/meta/biological.ftl @@ -0,0 +1,2 @@ +reagent-name-synth-blood = synth blood +reagent-desc-synth-blood = Not quite coolant, not quite blue powerade. diff --git a/Resources/Locale/en-US/_CD/station/events.ftl b/Resources/Locale/en-US/_CD/station/events.ftl new file mode 100644 index 0000000000..5e5d242061 --- /dev/null +++ b/Resources/Locale/en-US/_CD/station/events.ftl @@ -0,0 +1 @@ +station-event-ion-storm-synth = You detect an Ion Storm. Your internal systems may be tampered with or damaged as a result. diff --git a/Resources/Locale/en-US/_CD/traits/traits.ftl b/Resources/Locale/en-US/_CD/traits/traits.ftl new file mode 100644 index 0000000000..86bd5a72b2 --- /dev/null +++ b/Resources/Locale/en-US/_CD/traits/traits.ftl @@ -0,0 +1,2 @@ +trait-synth-name = Synthetic +trait-synth-desc = You are a biomechanical construct, who bleeds coolant and is notified of ongoing Ion Storms. diff --git a/Resources/Prototypes/_CD/Reagents/biological.yml b/Resources/Prototypes/_CD/Reagents/biological.yml new file mode 100644 index 0000000000..31e79558b1 --- /dev/null +++ b/Resources/Prototypes/_CD/Reagents/biological.yml @@ -0,0 +1,23 @@ +- type: reagent + id: SynthBlood + name: reagent-name-synth-blood + group: Biological + desc: reagent-desc-synth-blood + flavor: metallic + color: "#00b8f5" + recognizable: true + physicalDesc: reagent-physical-desc-reflective + slippery: false + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 1.5 + conditions: + - !type:OrganType + type: Human + shouldHave: false + footstepSound: + collection: FootstepBlood + params: + volume: 6 diff --git a/Resources/Prototypes/_CD/Traits/traits.yml b/Resources/Prototypes/_CD/Traits/traits.yml new file mode 100644 index 0000000000..3037261eb7 --- /dev/null +++ b/Resources/Prototypes/_CD/Traits/traits.yml @@ -0,0 +1,15 @@ +- type: trait + category: Quirks + id: Synthetic + name: trait-synth-name + description: trait-synth-desc + # Begin DeltaV Additions - blacklist IPCs + blacklist: + components: + - Silicon + - BorgChassis + excludedSpecies: + - IPC + # End DeltaV Additions - blacklist IPCs + components: + - type: Synth