Skip to content

Commit

Permalink
Диверсионный отряд (#985)
Browse files Browse the repository at this point in the history
* Диверсионный отряд

* фиксы

* фиксы линтера

* Спрайт терминала икаруса

* фикс пинпоинтера

* Доработки ДО

* Фиксы удалённого управления шаттлом

* Не запускать ДО если на может быть меньше 3 глав
  • Loading branch information
VigersRay authored Jan 1, 2025
1 parent dfa7738 commit f849696
Show file tree
Hide file tree
Showing 140 changed files with 11,290 additions and 83 deletions.
23 changes: 23 additions & 0 deletions Content.Client/_Sunrise/AssaultOps/AssaultOps/AssaultOpsSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Content.Shared._Sunrise.AssaultOps;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;

namespace Content.Client._Sunrise.AssaultOps.AssaultOps;

public sealed class AssaultOpsSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototype = default!;

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

SubscribeLocalEvent<AssaultOperativeComponent, GetStatusIconsEvent>(GetVampireIcon);
}

private void GetVampireIcon(EntityUid uid, AssaultOperativeComponent component, ref GetStatusIconsEvent args)
{
var iconPrototype = _prototype.Index(component.StatusIcon);
args.StatusIcons.Add(iconPrototype);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Content.Shared._Sunrise.AssaultOps.Icarus;

namespace Content.Client._Sunrise.AssaultOps.Icarus;

public sealed class IcarusTerminalBoundUserInterface : BoundUserInterface
{
private IcarusTerminalWindow? _window;

public IcarusTerminalBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}

protected override void Open()
{
base.Open();
_window = new IcarusTerminalWindow();
_window.OnClose += Close;
_window.OpenCentered();

_window.FireButtonPressed += OnFireButtonPressed;
}

private void OnFireButtonPressed()
{
if (_window == null)
return;

SendMessage(new IcarusTerminalFireMessage());
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

if (_window == null)
return;

if (state is not IcarusTerminalUiState cast)
return;

_window.UpdateState(cast);
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;

if (_window != null)
_window.OnClose -= Close;

_window?.Dispose();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<DefaultWindow xmlns="https://spacestation14.io"
Title="{Loc 'icarus-ui-window-title'}"
MinSize="300 120">
<BoxContainer Orientation="Vertical">
<Button Name="FireButton"
Text="{Loc 'icarus-ui-fire-button'}"
StyleClasses="Caution"
MinHeight="50"
Disabled="True" />
<BoxContainer Name="TimerBox" Orientation="Horizontal" Visible="False">
<Label Text="{Loc 'icarus-ui-timer-label'}" />
<Label Text=" " />
<Label Name="TimerValue" Text="-" />
</BoxContainer>
<BoxContainer Name="CooldownBox" Orientation="Horizontal" Visible="False">
<Label Text="{Loc 'icarus-ui-cooldown-label'}" />
<Label Text=" " />
<Label Name="CooldownValue" Text="-" />
</BoxContainer>
</BoxContainer>
</DefaultWindow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Content.Shared._Sunrise.AssaultOps.Icarus;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client._Sunrise.AssaultOps.Icarus;

[GenerateTypedNameReferences]
public sealed partial class IcarusTerminalWindow : DefaultWindow
{
public event Action? FireButtonPressed;

public IcarusTerminalWindow()
{
RobustXamlLoader.Load(this);

FireButton.OnPressed += _ => FireButtonPressed?.Invoke();
}

public void UpdateState(IcarusTerminalUiState state)
{
FireButton.Disabled = state.Status != IcarusTerminalStatus.FIRE_READY;
TimerBox.Visible = state.Status == IcarusTerminalStatus.FIRE_PREPARING;
CooldownBox.Visible = state.Status == IcarusTerminalStatus.COOLDOWN;

switch (state.Status)
{
case IcarusTerminalStatus.FIRE_PREPARING:
TimerValue.Text = state.RemainingTime.ToString();
break;
case IcarusTerminalStatus.COOLDOWN:
CooldownValue.Text = state.CooldownTime.ToString();
break;
}
}
}
54 changes: 54 additions & 0 deletions Content.Client/_Sunrise/Interrogator/InterrogatorSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Content.Shared._Sunrise.Interrogator;
using Content.Shared.Verbs;
using Robust.Client.GameObjects;
using DrawDepth = Content.Shared.DrawDepth.DrawDepth;

namespace Content.Client._Sunrise.Interrogator;

public sealed class InterrogatorSystem: SharedInterrogatorSystem
{
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;

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

SubscribeLocalEvent<InterrogatorComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<InterrogatorComponent, GetVerbsEvent<AlternativeVerb>>(AddAlternativeVerbs);

SubscribeLocalEvent<InterrogatorComponent, AppearanceChangeEvent>(OnAppearanceChange);
}

private void OnAppearanceChange(EntityUid uid, InterrogatorComponent component, ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
{
return;
}

if (!_appearance.TryGetData<bool>(uid, InterrogatorComponent.InterrogatorVisuals.ContainsEntity, out var isOpen, args.Component)
|| !_appearance.TryGetData<bool>(uid, InterrogatorComponent.InterrogatorVisuals.IsOn, out var isOn, args.Component))
{
return;
}

if (isOpen)
{
args.Sprite.LayerSetState(InterrogatorVisualLayers.Base, "open");
args.Sprite.LayerSetVisible(InterrogatorVisualLayers.Extract, false);
args.Sprite.DrawDepth = (int) DrawDepth.Objects;
}
else
{
args.Sprite.DrawDepth = (int) DrawDepth.Mobs;
args.Sprite.LayerSetState(InterrogatorVisualLayers.Extract, isOn ? "extraction-on" : "extraction-off");
args.Sprite.LayerSetVisible(InterrogatorVisualLayers.Extract, true);
}
}
}

public enum InterrogatorVisualLayers : byte
{
Base,
Extract,
}
15 changes: 15 additions & 0 deletions Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Server._Sunrise.AssaultOps;
using Content.Server.Administration.Commands;
using Content.Server.Antag;
using Content.Server.GameTicking.Rules.Components;
Expand Down Expand Up @@ -179,5 +180,19 @@ private void AddAntagVerbs(GetVerbsEvent<Verb> args)
Message = Loc.GetString("admin-verb-make-vampire"),
};
args.Verbs.Add(vampire);

Verb assaultOperative = new()
{
Text = Loc.GetString("admin-verb-text-make-assault-operative"),
Category = VerbCategory.Antag,
Icon = new SpriteSpecifier.Rsi(new ResPath("/Textures/Structures/Wallmounts/posters.rsi"), "poster46_contraband"),
Act = () =>
{
_antag.ForceMakeAntag<AssaultOpsRuleComponent>(targetPlayer, "AssaultOps");
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-assault-operative"),
};
args.Verbs.Add(assaultOperative);
}
}

This file was deleted.

57 changes: 57 additions & 0 deletions Content.Server/GameTicking/Rules/GameRuleSystem.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.Chat.Managers;
using Content.Server.Jobs;
using Content.Server.Preferences.Managers;
using Content.Server.Revolutionary.Components;
using Content.Shared.GameTicking.Components;
using Content.Shared.Preferences;
using Content.Shared.Roles;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;

Expand All @@ -13,6 +19,8 @@ public abstract partial class GameRuleSystem<T> : EntitySystem where T : ICompon
[Dependency] protected readonly IChatManager ChatManager = default!;
[Dependency] protected readonly GameTicker GameTicker = default!;
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] protected readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IComponentFactory _componentFactory = default!;

// Not protected, just to be used in utility methods
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
Expand All @@ -37,6 +45,55 @@ private void OnStartAttempt(RoundStartAttemptEvent args)
var query = QueryAllRules();
while (query.MoveNext(out var uid, out _, out var gameRule))
{
// Sunrise-Start
if (gameRule.MinCommandStaff > 0)
{
var availableHeads = new List<string>();

foreach (var playerSession in args.Players)
{
var userId = playerSession.UserId;
var preferencesManager = IoCManager.Resolve<IServerPreferencesManager>();
var prefs = preferencesManager.GetPreferences(userId);
var profile = prefs.SelectedCharacter as HumanoidCharacterProfile;
if (profile == null)
continue;
foreach (var profileJobPriority in profile.JobPriorities)
{
if (profileJobPriority.Value == JobPriority.Never)
continue;
if (!_prototype.TryIndex<JobPrototype>(profileJobPriority.Key.Id, out var job))
continue;
foreach (var special in job.Special)
{
if (special is not AddComponentSpecial componentSpecial)
continue;

foreach (var componentSpecialComponent in componentSpecial.Components)
{
var copy = _componentFactory.GetComponent(componentSpecialComponent.Value);
if (copy is CommandStaffComponent)
{
if (availableHeads.Contains(profileJobPriority.Key))
continue;
availableHeads.Add(profileJobPriority.Key);
}
}
}
}
}

if (gameRule.CancelPresetOnTooFewPlayers && availableHeads.Count < gameRule.MinCommandStaff)
{
ChatManager.SendAdminAnnouncement(Loc.GetString("preset-not-enough-ready-command-staff",
("readyCommandStaffCount", args.Players.Length),
("minimumCommandStaff", gameRule.MinCommandStaff),
("presetName", ToPrettyString(uid))));
args.Cancel();
}
}
// Sunrise-Edit

var minPlayers = gameRule.MinPlayers;
if (args.Players.Length >= minPlayers)
continue;
Expand Down
34 changes: 34 additions & 0 deletions Content.Server/Implants/SubdermalImplantSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server.Cuffs;
using Content.Server.Forensics;
using Content.Server.Humanoid;
Expand All @@ -19,9 +20,11 @@
using Robust.Shared.Physics.Components;
using Robust.Shared.Random;
using System.Numerics;
using Content.Server.Body.Components;
using Content.Shared.Movement.Pulling.Components;
using Content.Shared.Movement.Pulling.Systems;
using Content.Shared.Store.Components;
using Robust.Server.Containers;
using Robust.Shared.Collections;
using Robust.Shared.Map.Components;

Expand All @@ -41,6 +44,7 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
[Dependency] private readonly PullingSystem _pullingSystem = default!;
[Dependency] private readonly EntityLookupSystem _lookupSystem = default!;
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
[Dependency] private readonly ContainerSystem _container = default!;

private EntityQuery<PhysicsComponent> _physicsQuery;
private HashSet<Entity<MapGridComponent>> _targetGrids = [];
Expand All @@ -56,7 +60,37 @@ public override void Initialize()
SubscribeLocalEvent<SubdermalImplantComponent, ActivateImplantEvent>(OnActivateImplantEvent);
SubscribeLocalEvent<SubdermalImplantComponent, UseScramImplantEvent>(OnScramImplant);
SubscribeLocalEvent<SubdermalImplantComponent, UseDnaScramblerImplantEvent>(OnDnaScramblerImplant);
SubscribeLocalEvent<ImplantedComponent, BeingGibbedEvent>(OnGibbed);
}

private void OnGibbed(EntityUid uid, ImplantedComponent component, BeingGibbedEvent args)
{
if (!_container.TryGetContainer(uid, ImplanterComponent.ImplantSlotId, out var implantContainer))
return;

foreach (var implant in implantContainer.ContainedEntities)
{
if (!TryComp<SubdermalImplantComponent>(implant, out var subdermalImplant))
continue;

if (!subdermalImplant.DropContainerItemsIfGibbed)
continue;

if (!_container.TryGetContainer(implant, BaseStorageId, out var storageImplant))
continue;

var entCoords = Transform(uid).Coordinates;

var containedEntites = storageImplant.ContainedEntities.ToArray();

foreach (var entity in containedEntites)
{
if (Terminating(entity))
continue;

_container.RemoveEntity(storageImplant.Owner, entity, force: true, destination: entCoords);
}
}
}

private void OnStoreRelay(EntityUid uid, StoreComponent store, ImplantRelayEvent<AfterInteractUsingEvent> implantRelay)
Expand Down
11 changes: 11 additions & 0 deletions Content.Server/Mindshield/MindShieldSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SubdermalImplantComponent, ImplantImplantedEvent>(ImplantCheck);
SubscribeLocalEvent<SubdermalImplantComponent, ImplantEjectEvent>(ImplantCheck);
}

/// <summary>
Expand All @@ -43,6 +44,16 @@ public void ImplantCheck(EntityUid uid, SubdermalImplantComponent comp, ref Impl
}
}

// Sunrise-Start
public void ImplantCheck(EntityUid uid, SubdermalImplantComponent comp, ref ImplantEjectEvent ev)
{
if (_tag.HasTag(ev.Implant, MindShieldTag) && ev.Implanted != null)
{
RemCompDeferred<MindShieldComponent>(ev.Implanted.Value);
}
}
// Sunrise-End

/// <summary>
/// Checks if the implanted person was a Rev or Head Rev and remove role or destroy mindshield respectively.
/// </summary>
Expand Down
Loading

0 comments on commit f849696

Please sign in to comment.