Skip to content
Open
15 changes: 15 additions & 0 deletions Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Robust.Shared.Utility;
using Content.Shared.Roles.Components;
using Content.Server._Scp.GameTicking.Rules.Components; // Fire edit
using Content.Shared.Mind; // Fire edit

namespace Content.Server.Administration.Systems;

Expand Down Expand Up @@ -355,6 +356,20 @@ private void AddAntagVerbs(GetVerbsEvent<Verb> args)
Act = () =>
{
_antag.ForceMakeAntag<ChaosSleepSpyRuleComponent>(targetPlayer, DefaultScpSleepChaosSpyRule);
if (!TryComp<ActorComponent>(args.User, out var actor))
return;
Comment thread
WardexOfficial marked this conversation as resolved.
Outdated

if (!_mindSystem.TryGetMind(args.Target, out var targetMindId, out _))
return;
Comment thread
EngineerLND marked this conversation as resolved.

TryComp<MindComponent>(targetMindId, out var targetMind);
if (targetMind == null)
return;
Comment on lines +291 to +292

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У тебя функция выше (_mindSystem.TryGetMind(args.Target, out var targetMindId, out _)) возвращает MindComponent вторым out, это лишний TryComp<>()


var targetName = targetMind.CharacterName ?? Name(args.Target);
_chatManager.DispatchServerMessage(actor.PlayerSession,
Loc.GetString("admin-verb-result-make-chaos-sleep-spy",
("targetName", targetName)));
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-chaos-sleep-spy"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Mind;
using Content.Server.Objectives;
using Content.Server.Roles.RoleCodeword;
using Content.Shared._Scp.Chaos;
using Content.Shared.GameTicking.Components;
using Content.Shared.Mind;
using Content.Shared.Mobs.Systems;
using Content.Shared.Roles.RoleCodeword;
using Content.Shared.Speech;
using Content.Shared.Speech.Components;
Expand All @@ -19,8 +22,10 @@ public sealed class ChaosSleepSpyRuleSystem : GameRuleSystem<ChaosSleepSpyRuleCo
{
[Dependency] private readonly RoleCodewordSystem _roleCodeword = default!;
[Dependency] private readonly AntagSelectionSystem _antag = default!;
[Dependency] private readonly ObjectivesSystem _objectives = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;

public override void Initialize()
{
Expand Down Expand Up @@ -59,6 +64,37 @@ private void AfterEntitySelected(Entity<ChaosSleepSpyRuleComponent> ent, ref Aft

var sleepSpyMobComp = EnsureComp<ChaosSleepSpyMobComponent>(args.EntityUid);
sleepSpyMobComp.CodeWords = ent.Comp.CodeWords;


EntityUid? selectedMindId = null;
MindComponent? selectedMindComp = null;
int minObjectives = int.MaxValue;

var query = EntityQueryEnumerator<ChaosSpyMobComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (!_mind.TryGetMind(uid, out var thisMindId, out var mindComp))
continue;
Comment thread
EngineerLND marked this conversation as resolved.

if(_mobState.IsDead(uid))
continue;

var count = mindComp.Objectives.Count;
if (count < minObjectives)
{
minObjectives = count;
selectedMindId = thisMindId;
selectedMindComp = mindComp;
}
}

if (selectedMindId.HasValue && selectedMindComp != null)
{
if (_objectives.TryCreateObjective(selectedMindId.Value, selectedMindComp, "ChaosSpyActivateSleepSpyObjective") is not { } objectiveUid)
return;

_mind.AddObjective(selectedMindId.Value, selectedMindComp, objectiveUid);
}
Comment thread
EngineerLND marked this conversation as resolved.
}

private void OnListen(Entity<ChaosSleepSpyMobComponent> ent, ref ListenEvent args)
Expand All @@ -82,6 +118,7 @@ private void TryUnsleepSpy(Entity<ChaosSleepSpyMobComponent> ent)
return;

_antag.ForceMakeAntag<ChaosSpyRuleComponent>(actorComp.PlayerSession, ent.Comp.DefaultChaosSpyRule);
EnsureComp<ChaosSpyMobComponent>(ent);
RemCompDeferred<ActiveListenerComponent>(ent);
RemCompDeferred<ChaosSleepSpyMobComponent>(ent);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ private void OnObjectivesTextPrepend(Entity<ChaosSpyRuleComponent> ent, ref Obje
args.Text += "\n" + Loc.GetString("chaos-spy-round-end-codewords", ("codewords", string.Join(", ", ent.Comp.CodeWords)));
}

private string GenerateBriefing(string[]? codewords, Note[]? uplinkCode,bool isSleepSpy , string? objectiveIssuer = null)
private string GenerateBriefing(string[]? codewords, Note[]? uplinkCode, bool isSleepSpy, string? objectiveIssuer = null)
{
var sb = new StringBuilder();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Content.Server._Scp.Objectives.Systems;

namespace Content.Server._Scp.Objectives.Components;

[RegisterComponent, Access(typeof(ScpActivateSleepSpyConditionSystem))]
public sealed partial class ScpActivateSleepSpyConditionComponent : Component
{
/// <summary>The sleep spy target that an active Chaos Spy must activate.</summary>
[ViewVariables]
public EntityUid? Target;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using Content.Server._Scp.Objectives.Components;
using Content.Server.Mind;
using Content.Server.Objectives.Components;
using Content.Server.Objectives.Systems;
using Content.Shared._Scp.Chaos;
using Content.Shared.Mobs.Systems;
using Content.Shared.Objectives.Components;
using Content.Shared.Roles.Jobs;
using Robust.Shared.Random;

namespace Content.Server._Scp.Objectives.Systems;

public sealed class ScpActivateSleepSpyConditionSystem : EntitySystem
{
[Dependency] private readonly CodeConditionSystem _condition = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly SharedJobSystem _job = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly IRobustRandom _random = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ScpActivateSleepSpyConditionComponent, ObjectiveAssignedEvent>(OnAssigned);
SubscribeLocalEvent<ScpActivateSleepSpyConditionComponent, ObjectiveAfterAssignEvent>(OnAfterAssign);
SubscribeLocalEvent<ScpActivateSleepSpyConditionComponent, ObjectiveGetProgressEvent>(OnGetProgress, after: [typeof(CodeConditionSystem)]);
}

private void OnAssigned(Entity<ScpActivateSleepSpyConditionComponent> ent, ref ObjectiveAssignedEvent args)
{
var candidates = new HashSet<EntityUid>();

var query = EntityQueryEnumerator<ChaosSleepSpyMobComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (comp.IsAssigned)
continue;

if (!_mobState.IsAlive(uid))
continue;

candidates.Add(uid);
}


if (candidates.Count >= 1)
{
ent.Comp.Target = _random.Pick(candidates);
Comment thread
EngineerLND marked this conversation as resolved.
TryComp<ChaosSleepSpyMobComponent>(ent.Comp.Target.Value, out var sleepSpyComp);
if(sleepSpyComp != null)
sleepSpyComp.IsAssigned = true;
}
else
args.Cancelled = true;

}

private void OnAfterAssign(Entity<ScpActivateSleepSpyConditionComponent> ent, ref ObjectiveAfterAssignEvent args)
{

if (ent.Comp.Target is not { } target || Deleted(target))
return;
Comment on lines +63 to +64

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Бессмысленная проверка Deleted(target)


if (!_mind.TryGetMind(target, out var mindId, out _))
return;

if (!_job.MindTryGetJob(mindId, out var jobPrototype))
return;

if (!_job.TryGetDepartment(jobPrototype.ID, out var departmentPrototype))
return;

_metaData.SetEntityName(ent, Loc.GetString("objective-condition-chaos-spy-activate-sleep-spy-title"), args.Meta);
_metaData.SetEntityDescription(ent, Loc.GetString("objective-condition-chaos-spy-activate-sleep-spy-description", ("department", Loc.GetString(departmentPrototype.Name))), args.Meta);
Comment thread
EngineerLND marked this conversation as resolved.
}

private void OnGetProgress(Entity<ScpActivateSleepSpyConditionComponent> ent, ref ObjectiveGetProgressEvent args)
{
if (TryComp<CodeConditionComponent>(ent, out var code) && code.Completed)
{
args.Progress = 1f;
return;
}

if (HasComp<ChaosSpyMobComponent>(ent.Comp.Target))
{
_condition.SetCompleted((ent.Owner, code), true);
args.Progress = 1f;
return;
}

args.Progress = 0f;
}
}
4 changes: 4 additions & 0 deletions Content.Shared/_Scp/Chaos/ChaosSleepSpyMobComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public sealed partial class ChaosSleepSpyMobComponent : Component
[DataField]
public EntProtoId DefaultChaosSpyRule = "ScpChaosLowSpy";

/// <summary>Whether this sleep spy has already been assigned as an activation target.</summary>
[ViewVariables]
public bool IsAssigned;
Comment thread
EngineerLND marked this conversation as resolved.

[ViewVariables]
public string[]? CodeWords;
}
6 changes: 6 additions & 0 deletions Content.Shared/_Scp/Chaos/ChaosSpyMobComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Robust.Shared.GameStates;

namespace Content.Shared._Scp.Chaos;

[RegisterComponent, NetworkedComponent]
public sealed partial class ChaosSpyMobComponent : Component;
Comment thread
EngineerLND marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ ent-ChaosSpyStealIdCardsObjective = { ent-BaseChaosSpyStealObjective }
.desc = { ent-BaseChaosSpyStealObjective.desc }
ent-ChaosSpyHelpRandomSpyObjective = { ent-BaseHelpProgressObjective }
.desc = Help another Chaos spy complete their objectives.
ent-ChaosSpyActivateSleepSpyObjective = Activate the sleeper agent.
.desc = Find and activate the sleeper agent. Do this as discreetly as possible.
ent-ChaosSpyStealItemScpsObjective = { ent-BaseChaosSpyStealObjective }
.desc = { ent-BaseChaosSpyStealObjective.desc }
ent-ChaosSpyHelpChaosRaidObjective = Help the Chaos raid.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
admin-verb-make-chaos-raider = Make the target into a Chaos Raider
admin-verb-make-chaos-spy = Make the target into a Chaos Spy

admin-verb-make-chaos-sleep-spy = Make the target into a Chaos Sleep Spy
admin-verb-text-make-chaos-raider = Make Chaos Raider

admin-verb-text-make-chaos-spy = Make Chaos Spy
admin-verb-text-make-chaos-sleep-spy = Make Chaos Sleep Spy
admin-verb-text-make-chaos-sleep-spy = Make Chaos Sleep Spy
admin-verb-result-make-chaos-sleep-spy = Player "{$targetName}" is now a sleeper agent of the Chaos Insurgency. An objective to activate them will be given to a random active spy.
Comment thread
EngineerLND marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
objective-condition-chaos-spy-activate-sleep-spy-title = Activate the sleeper agent.
objective-condition-chaos-spy-activate-sleep-spy-description = Find and activate the sleeper agent in the "{$department}" department. Do this as discreetly as possible.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ ent-ChaosSpyStealIdCardsObjective = { ent-BaseChaosSpyStealObjective }
.desc = { ent-BaseChaosSpyStealObjective.desc }
ent-ChaosSpyHelpRandomSpyObjective = { ent-BaseHelpProgressObjective }
.desc = Помогите другому шпиону Повстанцев Хаоса выполнить его цели.
ent-ChaosSpyActivateSleepSpyObjective = Активируйте cпящего агента.
.desc = Найдите и активируйте спящего агента. Сделайте это как можно незаметнее.
Comment thread
EngineerLND marked this conversation as resolved.
Outdated
Comment thread
coderabbitai[bot] marked this conversation as resolved.
ent-ChaosSpyStealItemScpsObjective = { ent-BaseChaosSpyStealObjective }
.desc = { ent-BaseChaosSpyStealObjective.desc }
ent-ChaosSpyHelpChaosRaidObjective = Помочь рейдерам Повстанцев Хаоса.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ admin-verb-text-make-chaos-spy = Сделать шпионом Повстанц

admin-verb-make-chaos-sleep-spy = Сделать цель спящим агентом Повстанцев Хаоса
admin-verb-text-make-chaos-sleep-spy = Сделать спящим агентом Повстанцев Хаоса
admin-verb-result-make-chaos-sleep-spy = Игрок "{$targetName}" теперь спящий агент Повстанцев Хаоса. Цель на его активацию будет отправлена случайному активному шпиону.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
objective-condition-chaos-spy-activate-sleep-spy-title = Активируйте cпящего агента.
Comment thread
EngineerLND marked this conversation as resolved.
objective-condition-chaos-spy-activate-sleep-spy-description = Найдите и активируйте спящего агента из отдела "{$department}". Сделайте это как можно незаметнее.
4 changes: 4 additions & 0 deletions Resources/Prototypes/_Scp/GameRules/roundstart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@
playerRatio: 10
pickCommandStaff: true
ignoreCanBeAntag: true
components:
- type: ChaosSpyMob
blacklist:
components:
- AntagImmune
Expand Down Expand Up @@ -267,6 +269,8 @@
max: 5
playerRatio: 10
pickCommandStaff: false
components:
- type: ChaosSpyMob
blacklist:
components:
- AntagImmune
Expand Down
13 changes: 13 additions & 0 deletions Resources/Prototypes/_Scp/Objectives/chaosSpy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@
components:
- HelpProgressCondition

- type: entity
parent: [BaseChaosSpyObjective, BaseCodeObjective]
id: ChaosSpyActivateSleepSpyObjective
name: activate "sleeper" cells
description: Activate "sleeper" cells of the Chaos Insurgency.
Comment thread
EngineerLND marked this conversation as resolved.
components:
- type: Objective
difficulty: 1.1
icon:
sprite: _Scp/Interface/Misc/chaos_objectives_icons.rsi
state: StealItemScp
- type: ScpActivateSleepSpyCondition

Comment thread
EngineerLND marked this conversation as resolved.
- type: entity
parent: BaseChaosSpyStealObjective
id: ChaosSpyStealItemScpsObjective
Expand Down
4 changes: 2 additions & 2 deletions Resources/Prototypes/_Scp/Objectives/objectiveGroups.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
weights:
ChaosSpyObjectiveGroupSteal: 1
#ChaosSpyObjectiveGroupDestroy: 0.6 # временно вырезано из пула тасков
ChaosSpyObjectiveGroupClassD: 0.8
ChaosSpyObjectiveGroupClassD: 0.5
ChaosSpyObjectiveGroupKill: 0.8
ChaosSpyObjectiveGroupSabotage: 0.8
ChaosSpyObjectiveGroupSabotage: 0.5
ChaosSpyObjectiveGroupSocial: 0.5

- type: weightedRandom
Expand Down
Loading