Skip to content

Commit

Permalink
Merge branch 'RonRonstation:master' into Adds-poker-chips-and-adds-th…
Browse files Browse the repository at this point in the history
…em-to-good-clean-fun,-along-with-poker-cards-
  • Loading branch information
Merrokitsune authored Oct 19, 2024
2 parents ef4b051 + 5ce2829 commit 2fa048d
Show file tree
Hide file tree
Showing 60 changed files with 4,173 additions and 2,461 deletions.
11 changes: 1 addition & 10 deletions Content.Client/Info/PlaytimeStats/PlaytimeStatsEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,10 @@ public PlaytimeStatsEntry(string role, TimeSpan playtime, StyleBox styleBox)

RoleLabel.Text = role;
Playtime = playtime; // store the TimeSpan value directly
PlaytimeLabel.Text = ConvertTimeSpanToHoursMinutes(playtime); // convert to string for display
PlaytimeLabel.Text = playtime.ToString(Loc.GetString("ui-playtime-time-format")); // convert to string for display
BackgroundColorPanel.PanelOverride = styleBox;
}

private static string ConvertTimeSpanToHoursMinutes(TimeSpan timeSpan)
{
var hours = (int)timeSpan.TotalHours;
var minutes = timeSpan.Minutes;

var formattedTimeLoc = Loc.GetString("ui-playtime-time-format", ("hours", hours), ("minutes", minutes));
return formattedTimeLoc;
}

public void UpdateShading(StyleBoxFlat styleBox)
{
BackgroundColorPanel.PanelOverride = styleBox;
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Body/Systems/BloodstreamSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ public void ChangeBloodReagent(EntityUid uid, string reagent, BloodstreamCompone
return;
}

var currentVolume = bloodSolution.RemoveReagent(component.BloodReagent, bloodSolution.Volume);
var currentVolume = bloodSolution.RemoveReagent(component.BloodReagent, bloodSolution.Volume, ignoreReagentData: true);

component.BloodReagent = reagent;

Expand Down
13 changes: 10 additions & 3 deletions Content.Server/Botany/Systems/PlantHolderSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.Botany.Components;
using Content.Server.Fluids.Components;
using Content.Server.Kitchen.Components;
using Content.Server.Popups;
using Content.Shared.Chemistry.EntitySystems;
Expand All @@ -11,15 +10,13 @@
using Content.Shared.Coordinates.Helpers;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using Content.Shared.Fluids.Components;
using Content.Shared.Hands.Components;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Random;
using Content.Shared.Tag;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
Expand Down Expand Up @@ -159,6 +156,7 @@ private void OnInteractUsing(Entity<PlantHolderComponent> entity, ref InteractUs
if (!_botany.TryGetSeed(seeds, out var seed))
return;

args.Handled = true;
var name = Loc.GetString(seed.Name);
var noun = Loc.GetString(seed.Noun);
_popup.PopupCursor(Loc.GetString("plant-holder-component-plant-success-message",
Expand Down Expand Up @@ -186,13 +184,15 @@ private void OnInteractUsing(Entity<PlantHolderComponent> entity, ref InteractUs
return;
}

args.Handled = true;
_popup.PopupCursor(Loc.GetString("plant-holder-component-already-seeded-message",
("name", Comp<MetaDataComponent>(uid).EntityName)), args.User, PopupType.Medium);
return;
}

if (_tagSystem.HasTag(args.Used, "Hoe"))
{
args.Handled = true;
if (component.WeedLevel > 0)
{
_popup.PopupCursor(Loc.GetString("plant-holder-component-remove-weeds-message",
Expand All @@ -212,6 +212,7 @@ private void OnInteractUsing(Entity<PlantHolderComponent> entity, ref InteractUs

if (HasComp<ShovelComponent>(args.Used))
{
args.Handled = true;
if (component.Seed != null)
{
_popup.PopupCursor(Loc.GetString("plant-holder-component-remove-plant-message",
Expand All @@ -231,6 +232,7 @@ private void OnInteractUsing(Entity<PlantHolderComponent> entity, ref InteractUs

if (_tagSystem.HasTag(args.Used, "PlantSampleTaker"))
{
args.Handled = true;
if (component.Seed == null)
{
_popup.PopupCursor(Loc.GetString("plant-holder-component-nothing-to-sample-message"), args.User);
Expand Down Expand Up @@ -286,10 +288,15 @@ private void OnInteractUsing(Entity<PlantHolderComponent> entity, ref InteractUs
}

if (HasComp<SharpComponent>(args.Used))
{
args.Handled = true;
DoHarvest(uid, args.User, component);
return;
}

if (TryComp<ProduceComponent>(args.Used, out var produce))
{
args.Handled = true;
_popup.PopupCursor(Loc.GetString("plant-holder-component-compost-message",
("owner", uid),
("usingItem", args.Used)), args.User, PopupType.Medium);
Expand Down
37 changes: 34 additions & 3 deletions Content.Server/Database/ServerDbBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -875,10 +875,41 @@ public async Task UpdateAdminRankAsync(AdminRank rank, CancellationToken cancel)

public async Task AddAdminLogs(List<AdminLog> logs)
{
const int maxRetryAttempts = 5;
var initialRetryDelay = TimeSpan.FromSeconds(5);

DebugTools.Assert(logs.All(x => x.RoundId > 0), "Adding logs with invalid round ids.");
await using var db = await GetDb();
db.DbContext.AdminLog.AddRange(logs);
await db.DbContext.SaveChangesAsync();

var attempt = 0;
var retryDelay = initialRetryDelay;

while (attempt < maxRetryAttempts)
{
try
{
await using var db = await GetDb();
db.DbContext.AdminLog.AddRange(logs);
await db.DbContext.SaveChangesAsync();
_opsLog.Debug($"Successfully saved {logs.Count} admin logs.");
break;
}
catch (Exception ex)
{
attempt += 1;
_opsLog.Error($"Attempt {attempt} failed to save logs: {ex}");

if (attempt >= maxRetryAttempts)
{
_opsLog.Error($"Max retry attempts reached. Failed to save {logs.Count} admin logs.");
return;
}

_opsLog.Warning($"Retrying in {retryDelay.TotalSeconds} seconds...");
await Task.Delay(retryDelay);

retryDelay *= 2;
}
}
}

protected abstract IQueryable<AdminLog> StartAdminLogsQuery(ServerDbContext db, LogFilter? filter = null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Shared.Dataset;
using Content.Shared.FixedPoint;
using Content.Shared.NPC.Prototypes;
using Content.Shared.Random;
using Content.Shared.Roles;
Expand Down Expand Up @@ -31,6 +32,24 @@ public sealed partial class TraitorRuleComponent : Component
[DataField]
public ProtoId<DatasetPrototype> ObjectiveIssuers = "TraitorCorporations";

/// <summary>
/// Give this traitor an Uplink on spawn.
/// </summary>
[DataField]
public bool GiveUplink = true;

/// <summary>
/// Give this traitor the codewords.
/// </summary>
[DataField]
public bool GiveCodewords = true;

/// <summary>
/// Give this traitor a briefing in chat.
/// </summary>
[DataField]
public bool GiveBriefing = true;

public int TotalTraitors => TraitorMinds.Count;
public string[] Codewords = new string[3];

Expand Down Expand Up @@ -68,5 +87,5 @@ public enum SelectionState
/// The amount of TC traitors start with.
/// </summary>
[DataField]
public int StartingBalance = 20;
public FixedPoint2 StartingBalance = 20;
}
77 changes: 58 additions & 19 deletions Content.Server/GameTicking/Rules/TraitorRuleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Content.Server.Roles;
using Content.Server.Traitor.Uplink;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.GameTicking.Components;
using Content.Shared.Mind;
using Content.Shared.NPC.Systems;
Expand Down Expand Up @@ -75,38 +76,46 @@ public string[] GenerateTraitorCodewords(TraitorRuleComponent component)
return codewords;
}

public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool giveUplink = true)
public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component)
{
//Grab the mind if it wasn't provided
if (!_mindSystem.TryGetMind(traitor, out var mindId, out var mind))
return false;

var briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords)));
var briefing = "";

if (component.GiveCodewords)
briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords)));

var issuer = _random.Pick(_prototypeManager.Index(component.ObjectiveIssuers).Values);

// Uplink code will go here if applicable, but we still need the variable if there aren't any
Note[]? code = null;
if (giveUplink)

if (component.GiveUplink)
{
// Calculate the amount of currency on the uplink.
var startingBalance = component.StartingBalance;
if (_jobs.MindTryGetJob(mindId, 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(traitor);
if (pda == null || !_uplink.AddUplink(traitor, startingBalance, giveDiscounts: true))
return false;

// Give traitors their codewords and uplink code to keep in their character info menu
code = EnsureComp<RingerUplinkComponent>(pda.Value).Code;
{
if (startingBalance < prototype.AntagAdvantage) // Can't use Math functions on FixedPoint2
startingBalance = 0;
else
startingBalance = startingBalance - prototype.AntagAdvantage;
}

// 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);

component.TraitorMinds.Add(mindId);

Expand Down Expand Up @@ -134,20 +143,50 @@ public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool
return true;
}

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<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", "#"))));
return (code, briefing);
}
else if (pda is null && uplinked)
{
briefing += "\n" + Loc.GetString("traitor-role-uplink-implant-short");
}

return (null, briefing);
}

// TODO: AntagCodewordsComponent
private void OnObjectivesTextPrepend(EntityUid uid, TraitorRuleComponent comp, ref ObjectivesTextPrependEvent args)
{
args.Text += "\n" + Loc.GetString("traitor-round-end-codewords", ("codewords", string.Join(", ", comp.Codewords)));
}

// TODO: figure out how to handle this? add priority to briefing event?
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", ("codewords", string.Join(", ", codewords))));
if (codewords != null)
sb.AppendLine(Loc.GetString("traitor-role-codewords", ("codewords", string.Join(", ", codewords))));
if (uplinkCode != null)
sb.AppendLine(Loc.GetString("traitor-role-uplink-code", ("code", string.Join("-", uplinkCode).Replace("sharp", "#"))));
else
sb.AppendLine(Loc.GetString("traitor-role-uplink-implant"));


return sb.ToString();
}
Expand Down
10 changes: 6 additions & 4 deletions Content.Server/Ninja/Systems/SpiderChargeSystem.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
using Content.Server.Explosion.EntitySystems;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Mind;
using Content.Server.Objectives.Components;
using Content.Server.Popups;
using Content.Server.Roles;
using Content.Shared.Interaction;
using Content.Shared.Ninja.Components;
using Content.Shared.Ninja.Systems;
using Content.Shared.Roles;
using Content.Shared.Sticky;
using Robust.Shared.GameObjects;

namespace Content.Server.Ninja.Systems;

Expand All @@ -19,6 +17,7 @@ public sealed class SpiderChargeSystem : SharedSpiderChargeSystem
{
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly SharedRoleSystem _role = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SpaceNinjaSystem _ninja = default!;

Expand All @@ -41,7 +40,10 @@ private void OnAttemptStick(EntityUid uid, SpiderChargeComponent comp, ref Attem

var user = args.User;

if (!_mind.TryGetRole<NinjaRoleComponent>(user, out var _))
if (!_mind.TryGetMind(args.User, out var mind, out _))
return;

if (!_role.MindHasRole<NinjaRoleComponent>(mind))
{
_popup.PopupEntity(Loc.GetString("spider-charge-not-ninja"), user, user);
args.Cancelled = true;
Expand Down
10 changes: 4 additions & 6 deletions Content.Server/Objectives/Systems/KillPersonConditionSystem.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Content.Server.Objectives.Components;
using Content.Server.Revolutionary.Components;
using Content.Server.Shuttles.Systems;
using Content.Shared.CCVar;
using Content.Shared.Mind;
using Content.Shared.Objectives.Components;
using Content.Shared.Roles.Jobs;
using Robust.Shared.Configuration;
using Robust.Shared.Random;

Expand All @@ -17,7 +17,6 @@ public sealed class KillPersonConditionSystem : EntitySystem
[Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!;
[Dependency] private readonly IConfigurationManager _config = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedJobSystem _job = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly TargetObjectiveSystem _target = default!;

Expand Down Expand Up @@ -86,11 +85,10 @@ private void OnHeadAssigned(EntityUid uid, PickRandomHeadComponent comp, ref Obj
}

var allHeads = new List<EntityUid>();
foreach (var mind in allHumans)
foreach (var person in allHumans)
{
// RequireAdminNotify used as a cheap way to check for command department
if (_job.MindTryGetJob(mind, out var prototype) && prototype.RequireAdminNotify)
allHeads.Add(mind);
if (TryComp<MindComponent>(person, out var mind) && mind.OwnedEntity is { } ent && HasComp<CommandStaffComponent>(ent))
allHeads.Add(person);
}

if (allHeads.Count == 0)
Expand Down
Loading

0 comments on commit 2fa048d

Please sign in to comment.