using Content.Server.Zombies;
using Content.Shared.Administration;
using Content.Shared.Database;
+using Content.Shared.Humanoid;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Verbs;
// All antag verbs have names so invokeverb works.
private void AddAntagVerbs(GetVerbsEvent<Verb> args)
{
- if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
+ if (!TryComp<ActorComponent>(args.User, out var actor))
return;
var player = actor.PlayerSession;
if (!_adminManager.HasAdminFlag(player, AdminFlags.Fun))
return;
- var targetHasMind = TryComp(args.Target, out MindContainerComponent? targetMindComp);
- if (!targetHasMind || targetMindComp == null)
+ if (!TryComp<MindContainerComponent>(args.Target, out var targetMindComp))
return;
Verb traitor = new()
if (!_minds.TryGetSession(targetMindComp.Mind, out var session))
return;
- _traitorRule.MakeTraitor(session);
+ // if its a monkey or mouse or something dont give uplink or objectives
+ var isHuman = HasComp<HumanoidAppearanceComponent>(args.Target);
+ _traitorRule.MakeTraitor(session, giveUplink: isHuman, giveObjectives: isHuman);
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-traitor"),
return results;
}
- public bool MakeTraitor(ICommonSession traitor)
+ public bool MakeTraitor(ICommonSession traitor, bool giveUplink = true, bool giveObjectives = true)
{
var traitorRule = EntityQuery<TraitorRuleComponent>().FirstOrDefault();
if (traitorRule == null)
if (_jobs.MindTryGetJob(mindId, out _, out var prototype))
startingBalance = Math.Max(startingBalance - prototype.AntagAdvantage, 0);
- // creadth: we need to create uplink for the antag.
- // PDA should be in place already
- var pda = _uplink.FindUplinkTarget(mind.OwnedEntity!.Value);
- if (pda == null || !_uplink.AddUplink(mind.OwnedEntity.Value, startingBalance))
- return false;
-
- // Add the ringtone uplink and get its code for greeting
- var code = EnsureComp<RingerUplinkComponent>(pda.Value).Code;
+ // Give traitors their codewords and uplink code to keep in their character info menu
+ var briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", traitorRule.Codewords)));
+ Note[]? code = null;
+ if (giveUplink)
+ {
+ // creadth: we need to create uplink for the antag.
+ // PDA should be in place already
+ var pda = _uplink.FindUplinkTarget(mind.OwnedEntity!.Value);
+ if (pda == null || !_uplink.AddUplink(mind.OwnedEntity.Value, startingBalance))
+ return false;
+
+ // Give traitors their codewords and uplink code to keep in their character info menu
+ code = EnsureComp<RingerUplinkComponent>(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","#"))));
+ }
// Prepare traitor role
- // Give traitors their codewords and uplink code to keep in their character info menu
- var briefing =
- $"{Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", traitorRule.Codewords)))}\n{Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#")))}";
var traitorRole = new TraitorRoleComponent
{
PrototypeId = traitorRule.TraitorPrototypeId,
_npcFaction.AddFaction(entity, "Syndicate");
// Give traitors their objectives
- var maxDifficulty = _cfg.GetCVar(CCVars.TraitorMaxDifficulty);
- var maxPicks = _cfg.GetCVar(CCVars.TraitorMaxPicks);
- var difficulty = 0f;
- for (var pick = 0; pick < maxPicks && maxDifficulty > difficulty; pick++)
+ if (giveObjectives)
{
- var objective = _objectives.GetRandomObjective(mindId, mind, "TraitorObjectiveGroups");
+ var maxDifficulty = _cfg.GetCVar(CCVars.TraitorMaxDifficulty);
+ var maxPicks = _cfg.GetCVar(CCVars.TraitorMaxPicks);
+ var difficulty = 0f;
+ for (var pick = 0; pick < maxPicks && maxDifficulty > difficulty; pick++)
+ {
+ var objective = _objectives.GetRandomObjective(mindId, mind, "TraitorObjectiveGroups");
+ if (objective == null)
+ continue;
- if (objective == null)
- continue;
- if (_mindSystem.TryAddObjective(mindId, mind, objective))
- difficulty += objective.Difficulty;
+ if (_mindSystem.TryAddObjective(mindId, mind, objective))
+ difficulty += objective.Difficulty;
+ }
}
return true;
/// <param name="mind">A mind (player)</param>
/// <param name="codewords">Codewords</param>
/// <param name="code">Uplink codes</param>
- private void SendTraitorBriefing(EntityUid mind, string[] codewords, Note[] code)
+ private void SendTraitorBriefing(EntityUid mind, string[] codewords, Note[]? code)
{
- if (_mindSystem.TryGetSession(mind, out var session))
- {
- _chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-greeting"));
- _chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-codewords", ("codewords", string.Join(", ", codewords))));
+ if (!_mindSystem.TryGetSession(mind, out var session))
+ return;
+
+ _chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-greeting"));
+ _chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-codewords", ("codewords", string.Join(", ", codewords))));
+ if (code != null)
_chatManager.DispatchServerMessage(session, Loc.GetString("traitor-role-uplink-code", ("code", string.Join("-", code).Replace("sharp","#"))));
- }
}
private void HandleLatejoin(PlayerSpawnCompleteEvent ev)
--- /dev/null
+using Content.Server.GameTicking.Rules;
+using Content.Server.Traitor.Components;
+using Content.Shared.Mind;
+using Content.Shared.Mind.Components;
+
+namespace Content.Server.Traitor.Systems;
+
+/// <summary>
+/// Makes entities with <see cref="AutoTraitorComponent"/> a traitor either immediately if they have a mind or when a mind is added.
+/// </summary>
+public sealed class AutoTraitorSystem : EntitySystem
+{
+ [Dependency] private readonly TraitorRuleSystem _traitorRule = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<AutoTraitorComponent, MapInitEvent>(OnMapInit);
+ SubscribeLocalEvent<AutoTraitorComponent, MindAddedMessage>(OnMindAdded);
+ }
+
+ private void OnMapInit(EntityUid uid, AutoTraitorComponent comp, MapInitEvent args)
+ {
+ TryMakeTraitor(uid, comp);
+ }
+
+ private void OnMindAdded(EntityUid uid, AutoTraitorComponent comp, MindAddedMessage args)
+ {
+ TryMakeTraitor(uid, comp);
+ }
+
+ /// <summary>
+ /// Sets the GiveUplink field.
+ /// </summary>
+ public void SetGiveUplink(EntityUid uid, bool giveUplink, AutoTraitorComponent? comp = null)
+ {
+ if (!Resolve(uid, ref comp))
+ return;
+
+ comp.GiveUplink = giveUplink;
+ }
+
+ /// <summary>
+ /// Sets the GiveObjectives field.
+ /// </summary>
+ public void SetGiveObjectives(EntityUid uid, bool giveObjectives, AutoTraitorComponent? comp = null)
+ {
+ if (!Resolve(uid, ref comp))
+ return;
+
+ comp.GiveObjectives = giveObjectives;
+ }
+
+ /// <summary>
+ /// Checks if there is a mind, then makes it a traitor using the options.
+ /// </summary>
+ public bool TryMakeTraitor(EntityUid uid, AutoTraitorComponent? comp = null)
+ {
+ if (!Resolve(uid, ref comp))
+ return false;
+
+ if (!TryComp<MindContainerComponent>(uid, out var mindContainer) || mindContainer.Mind == null)
+ return false;
+
+ var mindId = mindContainer.Mind.Value;
+ if (!TryComp<MindComponent>(mindId, out var mind) || mind.Session == null)
+ return false;
+
+ var session = mind.Session;
+ _traitorRule.MakeTraitor(session, giveUplink: comp.GiveUplink, giveObjectives: comp.GiveObjectives);
+ // prevent spamming anything if it fails
+ RemComp<AutoTraitorComponent>(uid);
+ return true;
+ }
+}