Skip to content

Commit

Permalink
Merge branch 'master' into hwid-ops
Browse files Browse the repository at this point in the history
  • Loading branch information
MilonPL authored Nov 28, 2024
2 parents 547fdec + bf7a8d9 commit 9ab63fb
Show file tree
Hide file tree
Showing 29 changed files with 532 additions and 180 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/labeler-needsreview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,41 @@
on:
pull_request_target:
types: [review_requested]
pull_request_review:
types: [submitted]

permissions:
pull-requests: write
contents: write

jobs:
add_label:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request_target'
steps:
- uses: actions-ecosystem/action-add-labels@v1
with:
labels: "S: Needs Review"
- uses: actions-ecosystem/action-remove-labels@v1
with:
labels: "S: Awaiting Changes"

handle_review:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request_review'
steps:
- uses: actions-ecosystem/action-add-labels@v1
if: |
github.event.review.state == 'changes_requested' &&
(github.event.review.author_association == 'OWNER' ||
github.event.review.author_association == 'MEMBER')
with:
labels: "S: Awaiting Changes"

- uses: actions-ecosystem/action-remove-labels@v1
if: |
github.event.review.state == 'changes_requested' &&
(github.event.review.author_association == 'OWNER' ||
github.event.review.author_association == 'MEMBER')
with:
labels: "S: Needs Review"
2 changes: 0 additions & 2 deletions .github/workflows/labeler-untriaged.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
on:
issues:
types: [opened]
pull_request_target:
types: [opened]

jobs:
add_label:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;

namespace Content.Server.DeltaV.GameTicking.Rules.Components;

/// <summary>
/// Delays adding components to the antags of a gamerule until some time has passed.
/// </summary>
/// <remarks>
/// This is used for the zombies gamemode so that new players don't hit the funny button immediately and ruin anyone else's plans.
/// </remarks>
[RegisterComponent, Access(typeof(DelayedRuleSystem))]
[AutoGenerateComponentPause]
public sealed partial class DelayedRuleComponent : Component
{
/// <summary>
/// The players must wait this length of time before <see cref="DelayedComponents"/> gets added.
/// If they are somehow found out and get gibbed/cremated/etc before this delay is up they will not turn.
/// </summary>
[DataField(required: true)]
public TimeSpan Delay;

/// <summary>
/// Whether to skip the delay if there is only 1 antag selected.
/// </summary>
[DataField]
public bool IgnoreSolo;

/// <summary>
/// When the <see cref="Delay"/> will end.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan DelayEnds;

/// <summary>
/// The components to add to each player's mob once the delay ends.
/// </summary>
[DataField(required: true)]
public ComponentRegistry DelayedComponents = new();

/// <summary>
/// Popup to show when the delay ends.
/// </summary>
[DataField(required: true)]
public LocId EndedPopup;
}
58 changes: 58 additions & 0 deletions Content.Server/DeltaV/GameTicking/Rules/DelayedRuleSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Content.Server.Antag.Components;
using Content.Server.GameTicking.Rules;
using Content.Server.DeltaV.GameTicking.Rules.Components;
using Content.Shared.GameTicking.Components;
using Content.Shared.Mind;
using Content.Shared.Popups;

namespace Content.Server.DeltaV.GameTicking.Rules;

public sealed class DelayedRuleSystem : GameRuleSystem<DelayedRuleComponent>
{
[Dependency] private readonly SharedPopupSystem _popup = default!;

protected override void Started(EntityUid uid, DelayedRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);

component.DelayEnds = Timing.CurTime + component.Delay;
}

protected override void ActiveTick(EntityUid uid, DelayedRuleComponent component, GameRuleComponent gameRule, float frameTime)
{
base.ActiveTick(uid, component, gameRule, frameTime);

CheckDelay((uid, component));
}

/// <summary>
/// Checks if the delay has ended.
/// </summary>
private void CheckDelay(Entity<DelayedRuleComponent> ent)
{
if (!TryComp<AntagSelectionComponent>(ent, out var selection))
return;

// skip the delay if it's just 1 player, theres no plan to ruin if you are the only one
var ends = ent.Comp.DelayEnds;
if (ent.Comp.IgnoreSolo && selection.SelectedMinds.Count < 2)
ends = Timing.CurTime;

if (Timing.CurTime < ends)
return;

var comps = ent.Comp.DelayedComponents;
foreach (var (mindId, _) in selection.SelectedMinds)
{
// using OriginalOwnedEntity as the player might have ghosted to try become an evil ghost antag
if (!TryComp<MindComponent>(mindId, out var mind) || !TryGetEntity(mind.OriginalOwnedEntity, out var mob))
continue;

var uid = mob.Value;
_popup.PopupEntity(Loc.GetString(ent.Comp.EndedPopup), uid, uid, PopupType.LargeCaution);
EntityManager.AddComponents(uid, comps);
}

RemCompDeferred<DelayedRuleComponent>(ent);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Content.Server.Silicons.Laws;
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;
using Content.Shared.Silicons.Laws;
using Content.Shared.Silicons.Laws.Components;
using Robust.Shared.Prototypes;

namespace Content.Server.Silicons.Borgs;

/// <summary>
/// Handles lawset patching when switching type.
/// If a borg is made emagged it needs its emag laws carried over.
/// </summary>
public sealed partial class BorgSwitchableTypeSystem
{
[Dependency] private readonly SiliconLawSystem _law = default!;

private void ConfigureLawset(EntityUid uid, ProtoId<SiliconLawsetPrototype> id)
{
var laws = _law.GetLawset(id);
_law.SetLaws(laws.Laws, uid);

// re-add law 0 and final law based on new lawset
if (CompOrNull<EmagSiliconLawComponent>(uid)?.OwnerName != null)
{
// raising the event manually to bypass re-emagging checks
var ev = new GotEmaggedEvent(uid); // user wont be used since OwnerName isnt null, safe to pass itself
RaiseLocalEvent(uid, ref ev);
}

// ion storms don't get mirrored because thats basically impossible to track
}
}
11 changes: 7 additions & 4 deletions Content.Server/Objectives/Systems/KillPersonConditionSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,17 @@ private void OnGetProgress(EntityUid uid, KillPersonConditionComponent comp, ref
args.Progress = GetProgress(target.Value, comp.RequireDead);
}

private void OnPersonAssigned(EntityUid uid, PickRandomPersonComponent comp, ref ObjectiveAssignedEvent args)
private void OnPersonAssigned(Entity<PickRandomPersonComponent> ent, ref ObjectiveAssignedEvent args)
{
AssignRandomTarget(uid, args, _ => true);
AssignRandomTarget(ent, args, _ => true);
}

private void OnHeadAssigned(EntityUid uid, PickRandomHeadComponent comp, ref ObjectiveAssignedEvent args)
private void OnHeadAssigned(Entity<PickRandomHeadComponent> ent, ref ObjectiveAssignedEvent args)
{
AssignRandomTarget(uid, args, mind => HasComp<CommandStaffComponent>(uid));
AssignRandomTarget(ent, args, mindId =>
TryComp<MindComponent>(mindId, out var mind) &&
mind.OwnedEntity is { } ownedEnt &&
HasComp<CommandStaffComponent>(ownedEnt));
}

private void AssignRandomTarget(EntityUid uid, ObjectiveAssignedEvent args, Predicate<EntityUid> filter, bool fallbackToAny = true)
Expand Down
7 changes: 6 additions & 1 deletion Content.Server/Silicons/Borgs/BorgSwitchableTypeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Content.Server.Silicons.Borgs;
/// <summary>
/// Server-side logic for borg type switching. Handles more heavyweight and server-specific switching logic.
/// </summary>
public sealed class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeSystem
public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeSystem // DeltaV: Made partial
{
[Dependency] private readonly BorgSystem _borgSystem = default!;
[Dependency] private readonly ServerInventorySystem _inventorySystem = default!;
Expand Down Expand Up @@ -59,6 +59,11 @@ protected override void SelectBorgModule(Entity<BorgSwitchableTypeComponent> ent
}
}

// Begin DeltaV Code: Custom lawset patching
if (prototype.Lawset is {} lawset)
ConfigureLawset(ent, lawset);
// End DeltaV Code

// Configure special components
if (Prototypes.TryIndex(ent.Comp.SelectedBorgType, out var previousPrototype))
{
Expand Down
3 changes: 2 additions & 1 deletion Content.Server/Silicons/Laws/SiliconLawSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,10 @@ private void OnEmagLawsAdded(EntityUid uid, SiliconLawProviderComponent componen
component.Lawset = GetLawset(component.Laws);

// Add the first emag law before the others
var name = CompOrNull<EmagSiliconLawComponent>(uid)?.OwnerName ?? Name(args.UserUid); // DeltaV: Reuse emagger name if possible
component.Lawset?.Laws.Insert(0, new SiliconLaw
{
LawString = Loc.GetString("law-emag-custom", ("name", Name(args.UserUid)), ("title", Loc.GetString(component.Lawset.ObeysTo))),
LawString = Loc.GetString("law-emag-custom", ("name", name), ("title", Loc.GetString(component.Lawset.ObeysTo))), // DeltaV: pass name from variable
Order = 0
});

Expand Down
32 changes: 32 additions & 0 deletions Content.Server/_CD/Engraving/EngraveableComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Content.Server._CD.Engraving;

/// <summary>
/// Allows an items' description to be modified with an engraving
/// </summary>
[RegisterComponent, Access(typeof(EngraveableSystem))]
public sealed partial class EngraveableComponent : Component
{
/// <summary>
/// Message given to user to notify them a message was sent
/// </summary>
[DataField]
public string EngravedMessage = string.Empty;

/// <summary>
/// The inspect text to use when there is no engraving
/// </summary>
[DataField]
public LocId NoEngravingText = "engraving-dogtags-no-message";

/// <summary>
/// The message to use when successfully engraving the item
/// </summary>
[DataField]
public LocId EngraveSuccessMessage = "engraving-dogtags-succeed";

/// <summary>
/// The inspect text to use when there is an engraving. The message will be shown seperately afterwards.
/// </summary>
[DataField]
public LocId HasEngravingText = "engraving-dogtags-has-message";
}
83 changes: 83 additions & 0 deletions Content.Server/_CD/Engraving/EngraveableSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using Content.Server.Administration;
using Content.Server.Administration.Logs;
using Content.Server.Popups;
using Content.Shared.Database;
using Content.Shared.Popups;
using Content.Shared.Examine;
using Content.Shared.Verbs;
using Robust.Shared.Player;
using Robust.Shared.Utility;

namespace Content.Server._CD.Engraving;

public sealed class EngraveableSystem : EntitySystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly QuickDialogSystem _dialog = default!;

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

SubscribeLocalEvent<EngraveableComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<EngraveableComponent, GetVerbsEvent<ActivationVerb>>(AddEngraveVerb);
}

private void OnExamined(Entity<EngraveableComponent> ent, ref ExaminedEvent args)
{
var msg = new FormattedMessage();
msg.AddMarkupOrThrow(Loc.GetString(ent.Comp.EngravedMessage == string.Empty
? ent.Comp.NoEngravingText
: ent.Comp.HasEngravingText));

if (ent.Comp.EngravedMessage != string.Empty)
msg.AddMarkupPermissive(Loc.GetString(ent.Comp.EngravedMessage));

args.PushMessage(msg, 1);
}

private void AddEngraveVerb(Entity<EngraveableComponent> ent, ref GetVerbsEvent<ActivationVerb> args)
{
// First check if it's already been engraved. If it has, don't let them do it again.
if (ent.Comp.EngravedMessage != string.Empty)
return;

// We need an actor to give the verb.
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
return;

// Make sure ghosts can't engrave stuff.
if (!args.CanInteract)
return;

var engraveVerb = new ActivationVerb
{
Text = Loc.GetString("engraving-verb-engrave"),
Act = () =>
{
_dialog.OpenDialog(actor.PlayerSession,
Loc.GetString("engraving-verb-engrave"),
Loc.GetString("engraving-popup-ui-message"),
(string message) =>
{
// If either the actor or comp have magically vanished
if (actor.PlayerSession.AttachedEntity == null || !HasComp<EngraveableComponent>(ent))
return;

ent.Comp.EngravedMessage = message;
_popup.PopupEntity(Loc.GetString(ent.Comp.EngraveSuccessMessage),
actor.PlayerSession.AttachedEntity.Value,
actor.PlayerSession,
PopupType.Medium);
_adminLogger.Add(LogType.Action,
LogImpact.Low,
$"{ToPrettyString(actor.PlayerSession.AttachedEntity):player} engraved an item with message: {message}");
});
},
Impact = LogImpact.Low,
};
engraveVerb.Impact = LogImpact.Low;
args.Verbs.Add(engraveVerb);
}
}
10 changes: 9 additions & 1 deletion Content.Shared/Silicons/Borgs/BorgTypePrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Shared.Inventory;
using Content.Shared.Radio;
using Content.Shared.Silicons.Borgs.Components;
using Content.Shared.Silicons.Laws; // DeltaV
using Content.Shared.Whitelist;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
Expand All @@ -12,7 +13,7 @@ namespace Content.Shared.Silicons.Borgs;
/// Information for a borg type that can be selected by <see cref="BorgSwitchableTypeComponent"/>.
/// </summary>
/// <seealso cref="SharedBorgSwitchableTypeSystem"/>
[Prototype]
[Prototype(-5)] // DeltaV - force load after shaders
public sealed partial class BorgTypePrototype : IPrototype
{
[ValidatePrototypeId<SoundCollectionPrototype>]
Expand Down Expand Up @@ -83,6 +84,13 @@ public sealed partial class BorgTypePrototype : IPrototype
[DataField]
public EntProtoId[] DefaultModules = [];

/// <summary>
/// DeltaV: Lawset to use instead of crewsimov.
/// If the chassis is emagged or ion stormed this is ignored.
/// </summary>
[DataField]
public ProtoId<SiliconLawsetPrototype>? Lawset;

/// <summary>
/// Additional components to add to the borg entity when this type is selected.
/// </summary>
Expand Down
Loading

0 comments on commit 9ab63fb

Please sign in to comment.