Skip to content

Commit a1f7665

Browse files
committed
Roundstart Fugitive Make the Warrant happen somehow?
1 parent 59cb7f6 commit a1f7665

File tree

2 files changed

+253
-2
lines changed

2 files changed

+253
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
using Content.Shared.Random;
22
using Robust.Shared.Audio;
33
using Robust.Shared.Prototypes;
4+
using Content.Shared.Dataset;
5+
using Content.Server.StationEvents.Events;
6+
using Robust.Shared.Prototypes;
7+
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
8+
using Robust.Shared.Utility;
49

510
namespace Content.Server.GameTicking.Rules.Components;
611

@@ -9,4 +14,83 @@ namespace Content.Server.GameTicking.Rules.Components;
914
/// Stores data for <see cref="RoundstartFugitiveRuleSystem"/>.
1015
/// </summary>
1116
[RegisterComponent, Access(typeof(RoundstartFugitiveRuleSystem))]
12-
public sealed partial class RoundstartFugitiveRuleComponent : Component;
17+
[AutoGenerateComponentPause] //This is from FugitiveRuleComponenet
18+
//Everything below here is taken from FugitiveRuleComponent to hopefully make a miracle happen
19+
public sealed partial class RoundstartFugitiveRuleComponent : Component
20+
{
21+
[DataField]
22+
public LocId Announcement = "station-event-fugitive-hunt-announcement";
23+
24+
[DataField]
25+
public LocId Sender = "fugitive-announcement-GALPOL";
26+
27+
[DataField]
28+
public Color Color = Color.Yellow;
29+
30+
/// <summary>
31+
/// Report paper to spawn. Its content is generated from the fugitive.
32+
/// </summary>
33+
[DataField]
34+
public EntProtoId ReportPaper = "PaperFugitiveReport";
35+
36+
/// <summary>
37+
/// How long to wait after the antag spawns before announcing it.
38+
/// </summary>
39+
[DataField]
40+
public TimeSpan AnnounceDelay = TimeSpan.FromSeconds(5); //Should be FromMinutes(5) - changed for resting only!
41+
42+
/// <summary>
43+
/// Station to give the report to.
44+
/// </summary>
45+
[DataField]
46+
public EntityUid? Station;
47+
48+
/// <summary>
49+
/// The report generated for the spawned fugitive.
50+
/// </summary>
51+
[DataField]
52+
public string Report = string.Empty;
53+
54+
/// <summary>
55+
/// When the announcement will be made, if an antag has spawned yet.
56+
/// </summary>
57+
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
58+
public TimeSpan? NextAnnounce;
59+
60+
/// <summary>
61+
/// Dataset to pick crimes on the report from.
62+
/// </summary>
63+
[DataField]
64+
public ProtoId<LocalizedDatasetPrototype> CrimesDataset = "FugitiveCrimes";
65+
66+
/// <summary>
67+
/// Max number of unique crimes they can be charged with.
68+
/// Does not affect the counts of each crime.
69+
/// </summary>
70+
[DataField]
71+
public int MinCrimes = 2;
72+
73+
/// <summary>
74+
/// Min number of unique crimes they can be charged with.
75+
/// Does not affect the counts of each crime.
76+
/// </summary>
77+
[DataField]
78+
public int MaxCrimes = 7;
79+
80+
/// <summary>
81+
/// Min counts of each crime that can be rolled.
82+
/// </summary>
83+
[DataField]
84+
public int MinCounts = 1;
85+
86+
/// <summary>
87+
/// Max counts of each crime that can be rolled.
88+
/// </summary>
89+
[DataField]
90+
public int MaxCounts = 4;
91+
92+
public RoundstartFugitiveRuleComponent(TimeSpan? nextAnnounce)
93+
{
94+
NextAnnounce = nextAnnounce;
95+
}
96+
}

Content.Server/GameTicking/Rules/RoundstartFugitiveRuleSystem.cs

+168-1
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
11
using Content.Server.Antag;
2+
using Content.Server.Chat.Systems;
23
using Content.Server.GameTicking.Rules.Components;
34
using Content.Server.Roles;
45
using Content.Shared.Humanoid;
6+
using Content.Server.Communications;
7+
using Content.Server.Forensics;
8+
using Content.Server.Station.Systems;
9+
using Content.Server.StationEvents.Components;
10+
using Content.Server.StationEvents.Events;
11+
using Content.Shared.GameTicking.Components;
12+
using Content.Shared.Ghost;
13+
using Content.Shared.Hands.EntitySystems;
14+
using Content.Shared.Humanoid;
15+
using Content.Shared.Humanoid.Prototypes;
16+
using Content.Shared.Inventory;
17+
using Content.Shared.Paper;
18+
using Content.Shared.Popups;
19+
using Content.Shared.Random.Helpers;
20+
using Content.Shared.Storage.EntitySystems;
21+
using Robust.Shared.Physics.Components;
22+
using Robust.Shared.Prototypes;
23+
using Robust.Shared.Utility;
524

625
namespace Content.Server.GameTicking.Rules;
726

827
/// <summary>
928
/// Copy of ThiefRuleSystem
1029
/// </summary>
11-
public sealed class RoundstartFugitiveRuleSystem : GameRuleSystem<RoundstartFugitiveRuleComponent>
30+
public sealed class RoundstartFugitiveRuleSystem : GameRuleSystem<RoundstartFugitiveRuleComponent> //Also need this somehow: StationEventSystem : StationEventSystem<FugitiveRuleComponent>
1231
{
1332
[Dependency] private readonly AntagSelectionSystem _antag = default!;
33+
[Dependency] private readonly InventorySystem _inventory = default!;
34+
[Dependency] private readonly PaperSystem _paper = default!;
35+
[Dependency] private readonly SharedHandsSystem _hands = default!;
36+
[Dependency] private readonly SharedPopupSystem _popup = default!;
37+
[Dependency] private readonly SharedStorageSystem _storage = default!;
38+
1439

1540
public override void Initialize()
1641
{
@@ -52,6 +77,148 @@ private string MakeBriefing(EntityUid ent)
5277
return briefing;
5378
}
5479
// Copy of parts from FugitiveRules below here, hopefully this will cause the Fugitive Fax event to trigger?
80+
81+
protected override void ActiveTick(EntityUid uid, RoundstartFugitiveRuleComponent comp, GameRuleComponent rule, float frameTime)
82+
{
83+
if (comp.NextAnnounce is not {} next || next > Timing.CurTime)
84+
return;
85+
86+
var announcement = Loc.GetString(comp.Announcement);
87+
var sender = Loc.GetString(comp.Sender);
88+
ChatSystem.DispatchGlobalAnnouncement(announcement, sender: sender, colorOverride: comp.Color);
89+
90+
// send the report to every comms console on the station
91+
var query = EntityQueryEnumerator<TransformComponent, CommunicationsConsoleComponent>();
92+
var consoles = new List<TransformComponent>();
93+
while (query.MoveNext(out var console, out var xform, out _))
94+
{
95+
if (StationSystem.GetOwningStation(console, xform) != comp.Station || HasComp<GhostComponent>(console))
96+
continue;
97+
98+
consoles.Add(xform);
99+
}
100+
101+
foreach (var xform in consoles)
102+
{
103+
SpawnReport(comp, xform);
104+
}
105+
106+
// prevent any possible funnies
107+
comp.NextAnnounce = null;
108+
109+
RemCompDeferred(uid, comp);
110+
}
111+
112+
private void OnEntitySelected(Entity<RoundstartFugitiveRuleComponent> ent, ref AfterAntagEntitySelectedEvent args)
113+
{
114+
var (uid, comp) = ent;
115+
if (comp.NextAnnounce != null)
116+
{
117+
Log.Error("Fugitive rule spawning multiple fugitives isn't supported, sorry.");
118+
return;
119+
}
120+
121+
var fugi = args.EntityUid;
122+
comp.Report = GenerateReport(fugi, comp).ToMarkup();
123+
comp.Station = StationSystem.GetOwningStation(fugi);
124+
comp.NextAnnounce = Timing.CurTime + comp.AnnounceDelay;
125+
126+
_popup.PopupEntity(Loc.GetString("fugitive-spawn"), fugi, fugi);
127+
128+
// give the fugi a report so they know what their charges are
129+
var report = SpawnReport(comp, Transform(fugi));
130+
131+
// try to insert it into their bag
132+
if (_inventory.TryGetSlotEntity(fugi, "back", out var backpack))
133+
{
134+
_storage.Insert(backpack.Value, report, out _, playSound: false);
135+
}
136+
else
137+
{
138+
// no bag somehow, at least pick it up
139+
_hands.TryPickup(fugi, report);
140+
}
141+
}
142+
143+
private Entity<PaperComponent> SpawnReport(RoundstartFugitiveRuleComponent rule, TransformComponent xform)
144+
{
145+
var report = Spawn(rule.ReportPaper, xform.Coordinates);
146+
var paper = Comp<PaperComponent>(report);
147+
var ent = (report, paper);
148+
_paper.SetContent(ent, rule.Report);
149+
return ent;
150+
}
151+
152+
private FormattedMessage GenerateReport(EntityUid uid, RoundstartFugitiveRuleComponent rule)
153+
{
154+
var report = new FormattedMessage();
155+
report.PushMarkup(Loc.GetString("fugitive-report-title"));
156+
report.PushNewline();
157+
report.PushMarkup(Loc.GetString("fugitive-report-first-line"));
158+
report.PushNewline();
159+
160+
if (!TryComp<HumanoidAppearanceComponent>(uid, out var humanoid))
161+
{
162+
report.AddMarkup(Loc.GetString("fugitive-report-inhuman", ("name", uid)));
163+
return report;
164+
}
165+
166+
var species = PrototypeManager.Index(humanoid.Species);
167+
168+
report.PushMarkup(Loc.GetString("fugitive-report-morphotype", ("species", Loc.GetString(species.Name))));
169+
report.PushMarkup(Loc.GetString("fugitive-report-age", ("age", humanoid.Age)));
170+
report.PushMarkup(Loc.GetString("fugitive-report-sex", ("sex", humanoid.Sex.ToString())));
171+
172+
if (TryComp<PhysicsComponent>(uid, out var physics))
173+
report.PushMarkup(Loc.GetString("fugitive-report-weight", ("weight", Math.Round(physics.FixturesMass))));
174+
175+
// add a random identifying quality that officers can use to track them down
176+
report.PushMarkup(RobustRandom.Next(0, 2) switch
177+
{
178+
0 => Loc.GetString("fugitive-report-detail-dna", ("dna", GetDNA(uid))),
179+
_ => Loc.GetString("fugitive-report-detail-prints", ("prints", GetPrints(uid)))
180+
});
181+
182+
report.PushNewline();
183+
report.PushMarkup(Loc.GetString("fugitive-report-crimes-header"));
184+
185+
// generate some random crimes to avoid this situation
186+
// "officer what are my charges?"
187+
// "uh i dunno a piece of paper said to arrest you thats it"
188+
AddCharges(report, rule);
189+
190+
report.PushNewline();
191+
report.AddMarkup(Loc.GetString("fugitive-report-last-line"));
192+
193+
return report;
194+
}
195+
196+
private string GetDNA(EntityUid uid)
197+
{
198+
return CompOrNull<DnaComponent>(uid)?.DNA ?? "?";
199+
}
200+
201+
private string GetPrints(EntityUid uid)
202+
{
203+
return CompOrNull<FingerprintComponent>(uid)?.Fingerprint ?? "?";
204+
}
205+
206+
private void AddCharges(FormattedMessage report, RoundstartFugitiveRuleComponent rule)
207+
{
208+
var crimeTypes = PrototypeManager.Index(rule.CrimesDataset);
209+
var crimes = new HashSet<LocId>();
210+
var total = RobustRandom.Next(rule.MinCrimes, rule.MaxCrimes + 1);
211+
while (crimes.Count < total)
212+
{
213+
crimes.Add(RobustRandom.Pick(crimeTypes));
214+
}
215+
216+
foreach (var crime in crimes)
217+
{
218+
var count = RobustRandom.Next(rule.MinCounts, rule.MaxCounts + 1);
219+
report.PushMarkup(Loc.GetString("fugitive-report-crime", ("crime", Loc.GetString(crime)), ("count", count)));
220+
}
221+
}
55222
}
56223

57224

0 commit comments

Comments
 (0)