diff --git a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs index 76ef518215..be67bd9497 100644 --- a/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/TraitorRuleComponent.cs @@ -1,5 +1,6 @@ using Content.Shared._White.Mood; using Content.Shared.Dataset; +using Content.Shared.FixedPoint; using Content.Shared.NPC.Prototypes; using Content.Shared.Random; using Content.Shared.Roles; @@ -34,7 +35,25 @@ public sealed partial class TraitorRuleComponent : Component [DataField] public ProtoId ObjectiveIssuers = "TraitorCorporations"; + // WD EDIT START AHEAD OF WIZDEN UPSTREAM + /// + /// Give this traitor an Uplink on spawn. + /// + [DataField] + public bool GiveUplink = true; + /// + /// Give this traitor the codewords. + /// + [DataField] + public bool GiveCodewords = true; + + /// + /// Give this traitor a briefing in chat. + /// + [DataField] + public bool GiveBriefing = true; + // WD EDIT END AHEAD OF WIZDEN UPSTREAM // WD edit start [DataField] public ProtoId MoodBuffEffect = "TraitorFocused"; @@ -77,7 +96,7 @@ public sealed partial class TraitorRuleComponent : Component /// The amount of TC traitors start with. /// [DataField] - public int StartingBalance = 20; + public FixedPoint2 StartingBalance = 20; // WD EDIT AHEAD OF WIZDEN UPSTREAM [DataField] public int MaxDifficulty = 5; diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index bf24cfac7d..15f5d2ceb2 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -5,6 +5,7 @@ using Content.Server.Objectives; using Content.Server.PDA.Ringer; using Content.Server.Roles; using Content.Server.Traitor.Uplink; +using Content.Shared.FixedPoint; using Content.Shared.Mind; using Content.Shared.NPC.Systems; using Content.Shared.Objectives.Components; @@ -74,7 +75,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem } } - public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool giveUplink = true, bool giveObjectives = true) + public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool giveObjectives = true) // WD EDIT AHEAD OF WIZDEN UPSTREAM { //Grab the mind if it wasnt provided if (!_mindSystem.TryGetMind(traitor, out var mindId, out var mind)) @@ -83,39 +84,46 @@ public sealed class TraitorRuleSystem : GameRuleSystem // WD START var richAspect = _gameTicker.GetActiveGameRules().Where(HasComp).Any(); // WD END + // WD EDIT START AHEAD OF WIZDEN UPSTREAM + var briefing = ""; - var briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords))); + if (component.GiveCodewords) + briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords))); + // WD EDIT END AHEAD OF WIZDEN UPSTREAM var issuer = _random.Pick(_prototypeManager.Index(component.ObjectiveIssuers).Values); Note[]? code = null; - if (giveUplink) + if (component.GiveUplink) // WD EDIT AHEAD OF WIZDEN UPSTREAM { // Calculate the amount of currency on the uplink. var startingBalance = component.StartingBalance; if (_jobs.MindTryGetJob(mindId, out _, out var prototype)) - startingBalance = Math.Max(startingBalance - prototype.AntagAdvantage, 0); + // WD EDIT START START AHEAD OF WIZDEN UPSTREAM + { + if (startingBalance < prototype.AntagAdvantage) // Can't use Math functions on FixedPoint2 + startingBalance = 0; + else + startingBalance = startingBalance - prototype.AntagAdvantage; + } if (richAspect) { startingBalance += 10; } - // creadth: we need to create uplink for the antag. - // PDA should be in place already - var pda = _uplink.FindUplinkTarget(traitor); - if (pda == null || !_uplink.AddUplink(traitor, startingBalance)) - return false; - - // Give traitors their codewords and uplink code to keep in their character info menu - code = EnsureComp(pda.Value).Code; - - // If giveUplink is false the uplink code part is omitted - briefing = string.Format("{0}\n{1}", briefing, - Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#")))); + // Choose and generate an Uplink, and return the uplink code if applicable + var uplinkParams = RequestUplink(traitor, startingBalance, briefing); + code = uplinkParams.Item1; + briefing = uplinkParams.Item2; } - _antag.SendBriefing(traitor, GenerateBriefing(component.Codewords, code, issuer), null, component.GreetSoundNotification); + string[]? codewords = null; + if (component.GiveCodewords) + codewords = component.Codewords; + if (component.GiveBriefing) + _antag.SendBriefing(traitor, GenerateBriefing(codewords, code, issuer), null, component.GreetSoundNotification); + // WD EDIT END AHEAD OF WIZDEN UPSTREAM component.TraitorMinds.Add(mindId); // Assign briefing @@ -146,7 +154,33 @@ public sealed class TraitorRuleSystem : GameRuleSystem return true; } + // WD EDIT START AHEAD OF WIZDEN UPSTREAM + private (Note[]?, string) RequestUplink(EntityUid traitor, FixedPoint2 startingBalance, string briefing) + { + var pda = _uplink.FindUplinkTarget(traitor); + Note[]? code = null; + var uplinked = _uplink.AddUplink(traitor, startingBalance, pda, true); + + if (pda is not null && uplinked) + { + // Codes are only generated if the uplink is a PDA + code = EnsureComp(pda.Value).Code; + + // If giveUplink is false the uplink code part is omitted + briefing = string.Format("{0}\n{1}", + briefing, + Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#")))); + return (code, briefing); + } + else if (pda is null && uplinked) + { + briefing += "\n" + Loc.GetString("traitor-role-uplink-implant-short"); + } + + return (null, briefing); + } + // WD EDIT END AHEAD OF WIZDEN UPSTREAM private void OnObjectivesTextGetInfo(EntityUid uid, TraitorRuleComponent comp, ref ObjectivesTextGetInfoEvent args) { args.Minds = _antag.GetAntagMindEntityUids(uid); @@ -158,13 +192,16 @@ public sealed class TraitorRuleSystem : GameRuleSystem args.Text += "\n" + Loc.GetString("traitor-round-end-codewords", ("codewords", string.Join(", ", comp.Codewords))); } - private string GenerateBriefing(string[] codewords, Note[]? uplinkCode, string? objectiveIssuer = null) + private string GenerateBriefing(string[]? codewords, Note[]? uplinkCode, string? objectiveIssuer = null) { var sb = new StringBuilder(); sb.AppendLine(Loc.GetString("traitor-role-greeting", ("corporation", objectiveIssuer ?? Loc.GetString("objective-issuer-unknown")))); - sb.AppendLine(Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", codewords)))); + if (codewords != null) // WD EDIT AHEAD OF WIZDEN UPSTREAM + sb.AppendLine(Loc.GetString("traitor-role-codewords", ("codewords", string.Join(", ", codewords)))); if (uplinkCode != null) sb.AppendLine(Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", uplinkCode).Replace("sharp", "#")))); + else // WD EDIT AHEAD OF WIZDEN UPSTREAM + sb.AppendLine(Loc.GetString("traitor-role-uplink-implant")); return sb.ToString(); } diff --git a/Content.Server/Traitor/Components/AutoTraitorComponent.cs b/Content.Server/Traitor/Components/AutoTraitorComponent.cs index ab4bee2f26..0699319174 100644 --- a/Content.Server/Traitor/Components/AutoTraitorComponent.cs +++ b/Content.Server/Traitor/Components/AutoTraitorComponent.cs @@ -1,4 +1,5 @@ using Content.Server.Traitor.Systems; +using Robust.Shared.Prototypes; namespace Content.Server.Traitor.Components; @@ -9,14 +10,8 @@ namespace Content.Server.Traitor.Components; public sealed partial class AutoTraitorComponent : Component { /// - /// Whether to give the traitor an uplink or not. + /// The traitor profile to use /// - [DataField("giveUplink"), ViewVariables(VVAccess.ReadWrite)] - public bool GiveUplink = true; - - /// - /// Whether to give the traitor objectives or not. - /// - [DataField("giveObjectives"), ViewVariables(VVAccess.ReadWrite)] - public bool GiveObjectives = true; + [DataField] + public EntProtoId Profile = "Traitor"; // WD EDIT AHEAD OF WIZDEN UPSTREAM } diff --git a/Content.Server/Traitor/Systems/AutoTraitorSystem.cs b/Content.Server/Traitor/Systems/AutoTraitorSystem.cs index e9307effbc..ea23fef3f5 100644 --- a/Content.Server/Traitor/Systems/AutoTraitorSystem.cs +++ b/Content.Server/Traitor/Systems/AutoTraitorSystem.cs @@ -12,9 +12,6 @@ public sealed class AutoTraitorSystem : EntitySystem { [Dependency] private readonly AntagSelectionSystem _antag = default!; - [ValidatePrototypeId] - private const string DefaultTraitorRule = "Traitor"; - public override void Initialize() { base.Initialize(); @@ -24,6 +21,6 @@ public sealed class AutoTraitorSystem : EntitySystem private void OnMindAdded(EntityUid uid, AutoTraitorComponent comp, MindAddedMessage args) { - _antag.ForceMakeAntag(args.Mind.Comp.Session, DefaultTraitorRule); + _antag.ForceMakeAntag(args.Mind.Comp.Session, comp.Profile); // WD EDIT AHEAD OF WIZDEN UPSTREAM } } diff --git a/Content.Server/Traitor/Uplink/UplinkComponent.cs b/Content.Server/Traitor/Uplink/UplinkComponent.cs new file mode 100644 index 0000000000..35f11ce9ef --- /dev/null +++ b/Content.Server/Traitor/Uplink/UplinkComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Server.Traitor.Uplink; + +/// +/// This is used for identifying something as a hidden uplink and showing the UI. +/// +[RegisterComponent] +public sealed partial class UplinkComponent : Component; diff --git a/Content.Server/Traitor/Uplink/UplinkSystem.cs b/Content.Server/Traitor/Uplink/UplinkSystem.cs index 5670e28ec9..baf31e34db 100644 --- a/Content.Server/Traitor/Uplink/UplinkSystem.cs +++ b/Content.Server/Traitor/Uplink/UplinkSystem.cs @@ -1,94 +1,130 @@ using Content.Server.Store.Systems; +using Content.Shared.FixedPoint; using Content.Shared.Hands.EntitySystems; +using Content.Shared.Implants; using Content.Shared.Inventory; using Content.Shared.PDA; -using Content.Server.Store.Components; -using Content.Shared.FixedPoint; using Content.Shared.Store; +using Content.Server.Store.Components; +using Robust.Shared.Prototypes; -namespace Content.Server.Traitor.Uplink +namespace Content.Server.Traitor.Uplink; + +public sealed class UplinkSystem : EntitySystem // WD EDIT AHEAD OF WIZDEN UPSTREAM { - public sealed class UplinkSystem : EntitySystem + [Dependency] private readonly InventorySystem _inventorySystem = default!; + [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly StoreSystem _store = default!; + [Dependency] private readonly SharedSubdermalImplantSystem _subdermalImplant = default!; + + [ValidatePrototypeId] + public const string TelecrystalCurrencyPrototype = "Telecrystal"; + private const string FallbackUplinkImplant = "UplinkImplant"; + private const string FallbackUplinkCatalog = "UplinkUplinkImplanter"; + + /// + /// Adds an uplink to the target + /// + /// The person who is getting the uplink + /// The amount of currency on the uplink. If null, will just use the amount specified in the preset. + /// The entity that will actually have the uplink functionality. Defaults to the PDA if null. + /// Marker that enables discounts for uplink items. + /// Whether or not the uplink was added successfully + public bool AddUplink( + EntityUid user, + FixedPoint2 balance, + EntityUid? uplinkEntity = null, + bool giveDiscounts = false) { - [Dependency] private readonly InventorySystem _inventorySystem = default!; - [Dependency] private readonly SharedHandsSystem _handsSystem = default!; - [Dependency] private readonly StoreSystem _store = default!; + // Try to find target item if none passed + uplinkEntity ??= FindUplinkTarget(user); + if (uplinkEntity == null) + return ImplantUplink(user, balance, giveDiscounts); - [ValidatePrototypeId] - public const string TelecrystalCurrencyPrototype = "Telecrystal"; + EnsureComp(uplinkEntity.Value); - /// - /// Gets the amount of TC on an "uplink" - /// Mostly just here for legacy systems based on uplink. - /// - /// - /// the amount of TC - public int GetTCBalance(StoreComponent component) + SetUplink(user, uplinkEntity.Value, balance, giveDiscounts); + + // TODO add BUI. Currently can't be done outside of yaml -_- + // ^ What does this even mean? + + return true; + } + + /// + /// Configure TC for the uplink + /// + private void SetUplink(EntityUid user, EntityUid uplink, FixedPoint2 balance, bool giveDiscounts) + { + var store = EnsureComp(uplink); + store.AccountOwner = user; + _store.InitializeFromPreset("StorePresetUplink", uplink, store); // WD + store.Balance.Clear(); + _store.TryAddCurrency(new Dictionary { { TelecrystalCurrencyPrototype, balance } }, + uplink, + store); + // WD REMOVED UNTIL PROPER UPSTREAM + // var uplinkInitializedEvent = new StoreInitializedEvent( + // TargetUser: user, + // Store: uplink, + // UseDiscounts: giveDiscounts, + // Listings: _store.GetAvailableListings(user, uplink, store) + // .ToArray()); + // RaiseLocalEvent(ref uplinkInitializedEvent); + } + + /// + /// Implant an uplink as a fallback measure if the traitor had no PDA + /// + private bool ImplantUplink(EntityUid user, FixedPoint2 balance, bool giveDiscounts) + { + var implantProto = new string(FallbackUplinkImplant); + + if (!_proto.TryIndex(FallbackUplinkCatalog, out var catalog)) + return false; + + if (!catalog.Cost.TryGetValue(TelecrystalCurrencyPrototype, out var cost)) + return false; + + if (balance < cost) // Can't use Math functions on FixedPoint2 + balance = 0; + else + balance = balance - cost; + + var implant = _subdermalImplant.AddImplant(user, implantProto); + + if (!HasComp(implant)) + return false; + + SetUplink(user, implant.Value, balance, giveDiscounts); + return true; + } + + /// + /// Finds the entity that can hold an uplink for a user. + /// Usually this is a pda in their pda slot, but can also be in their hands. (but not pockets or inside bag, etc.) + /// + public EntityUid? FindUplinkTarget(EntityUid user) + { + // Try to find PDA in inventory + if (_inventorySystem.TryGetContainerSlotEnumerator(user, out var containerSlotEnumerator)) { - FixedPoint2? tcBalance = component.Balance.GetValueOrDefault(TelecrystalCurrencyPrototype); - return tcBalance?.Int() ?? 0; + while (containerSlotEnumerator.MoveNext(out var pdaUid)) + { + if (!pdaUid.ContainedEntity.HasValue) + continue; + if (HasComp(pdaUid.ContainedEntity.Value) || HasComp(pdaUid.ContainedEntity.Value)) + return pdaUid.ContainedEntity.Value; + } + } + // Also check hands + foreach (var item in _handsSystem.EnumerateHeld(user)) + { + if (HasComp(item) || HasComp(item)) + return item; } - /// - /// Adds an uplink to the target - /// - /// The person who is getting the uplink - /// The amount of currency on the uplink. If null, will just use the amount specified in the preset. - /// The id of the storepreset - /// The entity that will actually have the uplink functionality. Defaults to the PDA if null. - /// Whether or not the uplink was added successfully - public bool AddUplink(EntityUid user, FixedPoint2? balance, string uplinkPresetId = "StorePresetUplink", EntityUid? uplinkEntity = null) - { - // Try to find target item - if (uplinkEntity == null) - { - uplinkEntity = FindUplinkTarget(user); - if (uplinkEntity == null) - return false; - } - - var store = EnsureComp(uplinkEntity.Value); - _store.InitializeFromPreset(uplinkPresetId, uplinkEntity.Value, store); - store.AccountOwner = user; - store.Balance.Clear(); - - if (balance != null) - { - store.Balance.Clear(); - _store.TryAddCurrency(new Dictionary { { TelecrystalCurrencyPrototype, balance.Value } }, uplinkEntity.Value, store); - } - - // TODO add BUI. Currently can't be done outside of yaml -_- - - return true; - } - - /// - /// Finds the entity that can hold an uplink for a user. - /// Usually this is a pda in their pda slot, but can also be in their hands. (but not pockets or inside bag, etc.) - /// - public EntityUid? FindUplinkTarget(EntityUid user) - { - // Try to find PDA in inventory - if (_inventorySystem.TryGetContainerSlotEnumerator(user, out var containerSlotEnumerator)) - { - while (containerSlotEnumerator.MoveNext(out var pdaUid)) - { - if (!pdaUid.ContainedEntity.HasValue) continue; - - if (HasComp(pdaUid.ContainedEntity.Value) || HasComp(pdaUid.ContainedEntity.Value)) - return pdaUid.ContainedEntity.Value; - } - } - - // Also check hands - foreach (var item in _handsSystem.EnumerateHeld(user)) - { - if (HasComp(item) || HasComp(item)) - return item; - } - - return null; - } + return null; } } diff --git a/Content.Shared/Implants/SharedSubdermalImplantSystem.cs b/Content.Shared/Implants/SharedSubdermalImplantSystem.cs index f5a2dd1bc7..d54b88e018 100644 --- a/Content.Shared/Implants/SharedSubdermalImplantSystem.cs +++ b/Content.Shared/Implants/SharedSubdermalImplantSystem.cs @@ -108,22 +108,38 @@ public abstract class SharedSubdermalImplantSystem : EntitySystem /// public void AddImplants(EntityUid uid, IEnumerable implants) { - var coords = Transform(uid).Coordinates; foreach (var id in implants) { - var ent = Spawn(id, coords); - if (TryComp(ent, out var implant)) - { - ForceImplant(uid, ent, implant); - } - else - { - Log.Warning($"Found invalid starting implant '{id}' on {uid} {ToPrettyString(uid):implanted}"); - Del(ent); - } + AddImplant(uid, id); } } + /// + /// Adds a single implant to a person, and returns the implant. + /// Logs any implant ids that don't have . + /// + /// + /// The implant, if it was successfully created. Otherwise, null. + /// > + public EntityUid? AddImplant(EntityUid uid, String implantId) // WD EDIT AHEAD OF WIZDEN UPSTREAM + { + var coords = Transform(uid).Coordinates; + var ent = Spawn(implantId, coords); + + if (TryComp(ent, out var implant)) + { + ForceImplant(uid, ent, implant); + } + else + { + Log.Warning($"Found invalid starting implant '{implantId}' on {uid} {ToPrettyString(uid):implanted}"); + Del(ent); + return null; + } + + return ent; + } + /// /// Forces an implant into a person /// Good for on spawn related code or admin additions @@ -184,7 +200,7 @@ public abstract class SharedSubdermalImplantSystem : EntitySystem var relayEv = new ImplantRelayEvent(args); foreach (var implant in implantContainer.ContainedEntities) { - if (args is HandledEntityEventArgs { Handled : true }) + if (args is HandledEntityEventArgs { Handled: true }) return; RaiseLocalEvent(implant, relayEv); @@ -223,7 +239,7 @@ public abstract class SharedSubdermalImplantSystem : EntitySystem // Remove the implant from the donor's implant container _container.Remove(donorImplant, donorImplantContainer, force: true); - if(!TryComp(donorImplant, out var subdermal)) + if (!TryComp(donorImplant, out var subdermal)) return; // Insert the implant into the recipient's implant container diff --git a/Resources/Locale/en-US/game-ticking/game-presets/preset-traitor.ftl b/Resources/Locale/en-US/game-ticking/game-presets/preset-traitor.ftl index e92676a216..c32718d6a8 100644 --- a/Resources/Locale/en-US/game-ticking/game-presets/preset-traitor.ftl +++ b/Resources/Locale/en-US/game-ticking/game-presets/preset-traitor.ftl @@ -26,7 +26,7 @@ traitor-death-match-end-round-description-entry = {$originalName}'s PDA, with {$ traitor-role-greeting = You are an agent sent by {$corporation} on behalf of The Syndicate. Your objectives and codewords are listed in the character menu. - Use the uplink loaded into your PDA to buy the tools you'll need for this mission. + Use your uplink to buy the tools you'll need for this mission. Death to Nanotrasen! traitor-role-codewords = The codewords are: @@ -36,9 +36,13 @@ traitor-role-codewords = traitor-role-uplink-code = Set your ringtone to the notes {$code} to lock or unlock your uplink. Remember to lock it after, or the stations crew will easily open it too! +traitor-role-uplink-implant = + Your uplink implant has been activated, access it from your hotbar. + The uplink is secure unless someone removes it from your body. # don't need all the flavour text for character menu traitor-role-codewords-short = The codewords are: {$codewords}. traitor-role-uplink-code-short = Your uplink code is {$code}. Set it as your PDA ringtone to access uplink. +traitor-role-uplink-implant-short = Your uplink was implanted. Access it from your hotbar. diff --git a/Resources/Locale/ru-RU/game-ticking/game-presets/preset-traitor.ftl b/Resources/Locale/ru-RU/game-ticking/game-presets/preset-traitor.ftl index 42e5446b05..50d216e059 100644 --- a/Resources/Locale/ru-RU/game-ticking/game-presets/preset-traitor.ftl +++ b/Resources/Locale/ru-RU/game-ticking/game-presets/preset-traitor.ftl @@ -25,7 +25,7 @@ traitor-death-match-end-round-description-entry = ПДА { $originalName }, с { traitor-role-greeting = Вы - агент Синдиката. Ваши цели и кодовые слова перечислены в меню персонажа. - Воспользуйтесь аплинком, встроенным в ваш ПДА, чтобы приобрести всё необходимое для выполнения работы. + Воспользуйтесь аплинком, чтобы приобрести всё необходимое для выполнения работы. Смерть НаноТрейзен! traitor-role-codewords = @@ -37,6 +37,9 @@ traitor-role-codewords = traitor-role-uplink-code = Установите мелодия рингтона на {$code} чтобы разблокировать аплинк. Не забудьте заблокировать его после этого, иначе сотрудники станции тоже легко откроют его! +traitor-role-uplink-implant = + Ваш имплант аплинк активирован, воспользуйтесь им из хотбара. + Аплинк надежно защищён, пока кто-нибудь не извлечёт его из вашего тела. # don't need all the flavour text for character menu traitor-role-codewords-short = @@ -44,3 +47,4 @@ traitor-role-codewords-short = {$codewords}. traitor-role-uplink-code-short = Код от вашего аплинка - {$code}. Установите его в качестве рингтона на своём ПДА для доступа к аплинку. +traitor-role-uplink-implant-short = Ваш аплинк был имплантирован. Воспользуйтесь им из хотбара. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 87b7ad9328..88e8c800f1 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -1335,8 +1335,7 @@ components: # make the player a traitor once its taken - type: AutoTraitor - giveUplink: false - giveObjectives: false + profile: TraitorReinforcement - type: entity id: MobMonkeySyndicateAgentNukeops # Reinforcement exclusive to nukeops uplink @@ -1491,8 +1490,7 @@ components: # make the player a traitor once its taken - type: AutoTraitor - giveUplink: false - giveObjectives: false + profile: TraitorReinforcement - type: entity id: MobKoboldSyndicateAgentNukeops # Reinforcement exclusive to nukeops uplink diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index 2c7ad4972c..000ef32aee 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -27,8 +27,7 @@ components: # make the player a traitor once its taken - type: AutoTraitor - giveUplink: false - giveObjectives: false + profile: TraitorReinforcement - type: entity parent: MobHumanSyndicateAgentBase diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 377e15d738..ed9b763de8 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -163,6 +163,20 @@ - type: TraitorRole prototype: Traitor +- type: entity # WD AHEAD OF WIZDEN UPSTREAM + id: TraitorReinforcement + parent: Traitor + components: + - type: TraitorRule + giveUplink: false + giveCodewords: false # It would actually give them a different set of codewords than the regular traitors, anyway + giveBriefing: false + - type: AntagSelection + definitions: + - prefRoles: [ Traitor ] + mindRoles: + - MindRoleTraitor + - type: entity id: Revolutionary parent: BaseGameRule