Second step

This commit is contained in:
BIGZi0348
2025-01-26 18:55:10 +03:00
parent 7fa6f0a2e5
commit fdd7b607f3
12 changed files with 381 additions and 1 deletions

View File

@@ -0,0 +1,12 @@
using Content.Shared._Amour.ProtocolCRAB17;
namespace Content.Client._Amour.ProtocolCRAB17;
public sealed class ProtocolCRAB17System : SharedProtocolCRAB17System
{
public override void OnDoAfter(Entity<ProtocolCRAB17Component> ent, ref ProtocolCRAB17DoAfterEvent args)
{
}
}

View File

@@ -0,0 +1,109 @@
using Content.Server.Chat.Systems;
using Content.Server.StationEvents.Events;
using Content.Server.GameTicking.Components;
using Content.Shared._Amour.ProtocolCRAB17;
using Robust.Shared.Timing;
using Content.Shared._White.Economy;
using Content.Server._White.Economy;
namespace Content.Server._Amour.ProtocolCRAB17;
public sealed class ProtocolCRAB17Rule : StationEventSystem<ProtocolCRAB17RuleComponent>
{
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly BankCardSystem _bankCardSystem = default!;
public TimeSpan? LastTimeExecuted;
public override void Initialize()
{
base.Initialize();
}
protected override void Added(EntityUid uid, ProtocolCRAB17RuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
{
base.Added(uid, component, gameRule, args);
if (TryGetRandomStation(out var stationUid))
{
component.TargetStation = stationUid;
}
var query = AllEntityQuery<ProtocolCRAB17Component>();
while (query.MoveNext(out _, out var comp))
{
if (comp.BankAccountId == null)
continue;
component.Callers.Add((int) comp.BankAccountId);
}
}
protected override void Started(EntityUid uid, ProtocolCRAB17RuleComponent component, GameRuleComponent gameRule,
GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);
if (component.TargetStation == null)
{
ForceEndSelf(uid, gameRule);
return;
}
_chatSystem.DispatchStationAnnouncement((EntityUid) component.TargetStation, Loc.GetString("protocol-CRAB17-stage-1"),
colorOverride: Color.OrangeRed, sender: "Центральное Командование", announcementSound: ProtocolCRAB17RuleComponent.Announcement);
}
protected override void Ended(EntityUid uid, ProtocolCRAB17RuleComponent component, GameRuleComponent gameRule, GameRuleEndedEvent args)
{
base.Ended(uid, component, gameRule, args);
var allMoneyStolen = 0;
var query = AllEntityQuery<BankCardComponent>();
while (query.MoveNext(out _, out var bankCardComponent))
{
if (bankCardComponent.AccountId == null)
continue;
if (component.Callers.Contains((int) bankCardComponent.AccountId))
continue;
var money = _bankCardSystem.GetBalance((int) bankCardComponent.AccountId);
allMoneyStolen += money;
_bankCardSystem.TryChangeBalance((int) bankCardComponent.AccountId, -money);
}
var callersCount = component.Callers.Count;
foreach (var caller in component.Callers)
{
_bankCardSystem.TryChangeBalance(caller, (int) Math.Floor((double) (allMoneyStolen / callersCount)));
}
if (component.TargetStation != null)
_chatSystem.DispatchStationAnnouncement((EntityUid) component.TargetStation, Loc.GetString("protocol-CRAB17-stage-2", ("amount", allMoneyStolen)),
colorOverride: Color.OrangeRed, sender: "Центральное Командование");
var ertsys = _entities.System<ProtocolCRAB17Rule>();
ertsys.LastTimeExecuted = _timing.CurTime;
component.Callers.Clear();
}
public bool CanStartEvent()
{
var ertsys = _entities.System<ProtocolCRAB17Rule>();
if (ertsys.LastTimeExecuted == null)
return true;
else if (ertsys.LastTimeExecuted < _timing.CurTime - ProtocolCRAB17RuleComponent.TimeBetweenEvents)
return true;
return false;
}
}

View File

@@ -0,0 +1,19 @@
using Robust.Shared.Audio;
namespace Content.Server._Amour.ProtocolCRAB17;
[RegisterComponent]
public sealed partial class ProtocolCRAB17RuleComponent : Component
{
/// <summary>
/// Minimal time between events.
/// </summary>
public static TimeSpan TimeBetweenEvents = TimeSpan.FromMinutes(20);
public static SoundSpecifier Announcement = new SoundPathSpecifier("/Audio/_Amour/ProtocolCRAB17/Bogdanoff_is_calling.ogg");
[ViewVariables]
public EntityUid? TargetStation;
[ViewVariables]
public HashSet<int> Callers = new();
}

View File

@@ -0,0 +1,38 @@
using Content.Shared._Amour.ProtocolCRAB17;
using Content.Server.GameTicking;
using Content.Server.Popups;
namespace Content.Server._Amour.ProtocolCRAB17;
public sealed class ProtocolCRAB17System : SharedProtocolCRAB17System
{
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly ProtocolCRAB17Rule _protocolCRAB17Rule = default!;
public override void OnDoAfter(Entity<ProtocolCRAB17Component> ent, ref ProtocolCRAB17DoAfterEvent args)
{
if (args.Cancelled || args.Handled)
return;
if (_gameTicker.IsGameRuleActive("ProtocolCRAB17Event"))
{
_popupSystem.PopupEntity(Loc.GetString("protocol-CRAB17-event-running"), ent, args.User);
args.Handled = true;
return;
}
if (!_protocolCRAB17Rule.CanStartEvent())
{
_popupSystem.PopupEntity(Loc.GetString("protocol-CRAB17-timeout"), ent, args.User);
args.Handled = true;
return;
}
_popupSystem.PopupEntity(Loc.GetString("protocol-CRAB17-activated"), ent, args.User);
_gameTicker.AddGameRule("ProtocolCRAB17Event");
args.Handled = true;
return;
}
}

View File

@@ -0,0 +1,31 @@
using Content.Shared.DoAfter;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared._Amour.ProtocolCRAB17;
/// <summary>
/// WD
/// </summary>
[NetworkedComponent, RegisterComponent]
public sealed partial class ProtocolCRAB17Component : Component
{
[ViewVariables]
public int? BankAccountId;
[ViewVariables]
public bool HasBankAccountId = false;
[DataField]
public SoundSpecifier UseSound = new SoundPathSpecifier("/Audio/_Amour/ProtocolCRAB17/Phone_Dial.ogg");
[DataField]
public SoundSpecifier SoundApply = new SoundPathSpecifier("/Audio/White/Machines/chime.ogg");
}
[Serializable, NetSerializable]
public sealed partial class ProtocolCRAB17DoAfterEvent : SimpleDoAfterEvent
{
}

View File

@@ -0,0 +1,71 @@
using Content.Shared._White.Economy;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Content.Shared.Popups;
using Content.Shared.Timing;
using Robust.Shared.Audio.Systems;
namespace Content.Shared._Amour.ProtocolCRAB17;
public abstract class SharedProtocolCRAB17System : EntitySystem
{
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly UseDelaySystem _useDelay = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ProtocolCRAB17Component, UseInHandEvent>(OnUseInHand);
SubscribeLocalEvent<ProtocolCRAB17Component, ProtocolCRAB17DoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<ProtocolCRAB17Component, InteractUsingEvent>(OnInteractUsing);
}
private void OnInteractUsing(EntityUid uid, ProtocolCRAB17Component component, InteractUsingEvent args)
{
if (!TryComp(args.Used, out BankCardComponent? bankCard))
return;
if (!TryComp(uid, out UseDelayComponent? useDelay) ||
!_useDelay.TryResetDelay((uid, useDelay), true))
return;
component.BankAccountId = bankCard.AccountId;
component.HasBankAccountId = true;
_popupSystem.PopupPredicted(Loc.GetString("protocol-CRAB17-card-accepted"), uid, args.User);
_audioSystem.PlayPredicted(component.SoundApply, uid, args.User);
}
private void OnUseInHand(EntityUid uid, ProtocolCRAB17Component component, ref UseInHandEvent args)
{
if (args.Handled ||
!TryComp(uid, out UseDelayComponent? useDelay) ||
!_useDelay.TryResetDelay((uid, useDelay), true))
return;
if (component.HasBankAccountId == false)
{
_popupSystem.PopupClient(Loc.GetString("protocol-CRAB17-no-card"), uid, args.User);
return;
}
var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, useDelay.Delay, new ProtocolCRAB17DoAfterEvent(), uid, target: uid)
{
BreakOnMove = true,
BreakOnDamage = true,
NeedHand = true
};
// TODO find a way to stop playsound on doafter cancel
_audioSystem.PlayPredicted(component.UseSound, uid, args.User);
_popupSystem.PopupClient(Loc.GetString("protocol-CRAB17-try-activate"), uid, args.User);
_doAfterSystem.TryStartDoAfter(doAfterEventArgs);
args.Handled = true;
}
public abstract void OnDoAfter(Entity<ProtocolCRAB17Component> ent, ref ProtocolCRAB17DoAfterEvent args);
}

View File

@@ -0,0 +1,77 @@
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 7.1-c000 79.b0f8be9, 2021/12/08-19:11:22 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:xmpDM="http://ns.adobe.com/xmp/1.0/DynamicMedia/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<xmpDM:Tracks>
<rdf:Bag>
<rdf:li rdf:parseType="Resource">
<xmpDM:trackName>CuePoint Markers</xmpDM:trackName>
<xmpDM:trackType>Cue</xmpDM:trackType>
<xmpDM:frameRate>f44100</xmpDM:frameRate>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xmpDM:trackName>CD Track Markers</xmpDM:trackName>
<xmpDM:trackType>Track</xmpDM:trackType>
<xmpDM:frameRate>f44100</xmpDM:frameRate>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xmpDM:trackName>Subclip Markers</xmpDM:trackName>
<xmpDM:trackType>InOut</xmpDM:trackType>
<xmpDM:frameRate>f44100</xmpDM:frameRate>
</rdf:li>
</rdf:Bag>
</xmpDM:Tracks>
<xmp:MetadataDate>2025-01-26T18:51:20+03:00</xmp:MetadataDate>
<xmp:ModifyDate>2025-01-26T18:51:20+03:00</xmp:ModifyDate>
<xmpMM:InstanceID>xmp.iid:54b1ecf1-4293-e549-85f0-201b1c450278</xmpMM:InstanceID>
<xmpMM:DocumentID>xmp.did:07ec6da3-7091-9044-a75c-40bd06f0df0b</xmpMM:DocumentID>
<xmpMM:OriginalDocumentID>xmp.did:07ec6da3-7091-9044-a75c-40bd06f0df0b</xmpMM:OriginalDocumentID>
<xmpMM:History>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<stEvt:action>saved</stEvt:action>
<stEvt:instanceID>xmp.iid:07ec6da3-7091-9044-a75c-40bd06f0df0b</stEvt:instanceID>
<stEvt:when>2025-01-26T18:51:20+03:00</stEvt:when>
<stEvt:softwareAgent>Adobe Audition 24.0 (Windows)</stEvt:softwareAgent>
<stEvt:changed>/metadata</stEvt:changed>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<stEvt:action>saved</stEvt:action>
<stEvt:instanceID>xmp.iid:54b1ecf1-4293-e549-85f0-201b1c450278</stEvt:instanceID>
<stEvt:when>2025-01-26T18:51:20+03:00</stEvt:when>
<stEvt:softwareAgent>Adobe Audition 24.0 (Windows)</stEvt:softwareAgent>
<stEvt:changed>/</stEvt:changed>
</rdf:li>
</rdf:Seq>
</xmpMM:History>
<dc:format>audio/ogg; codec="vorbis"</dc:format>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>

Binary file not shown.

View File

@@ -1,2 +1,12 @@
ent-ProtocolCRAB17 = подозрительный телефон
.desc = Какой следующий шаг твоего мастер плана? Уничтожить этот рынок, не оставив выживших!
protocol-CRAB17-no-card = Протокол не может быть запущен без привязанной банковской карты.
protocol-CRAB17-card-accepted = Карта привязана.
protocol-CRAB17-try-activate = Вы вводите комбинацию и ожидаете ответ...
protocol-CRAB17-activated = Инициация протокола КРАБ-17 завершена. Ожидайте благополучных новостей.
protocol-CRAB17-event-running = Протокол уже запущен, ваши средства в безопасности!
protocol-CRAB17-timeout = Линия занята, повторите попытку позже...
protocol-CRAB17-stage-1 = Внимание! В централизованной системе учёта финансов обнаружена критическая ошибка. Сброс банковских данных станции неизбежен. Персоналу необходимо в кратчайшие сроки обналичить все счета, для избежания потери средств.
protocol-CRAB17-stage-2 = Системы банковского учёта сброшены до последней стабильной версии и готовы к дальнейшей работе. Оценочная суммарная потеря средств составляет: { $amount } кредитов.

View File

@@ -17,3 +17,16 @@
- type: EmitSoundOnLand
sound:
path: /Audio/White/Items/handling/component_drop.ogg
- type: ProtocolCRAB17
- type: UseDelay
delay: 4
- type: entity
id: ProtocolCRAB17Event
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 0
duration: 120
- type: ProtocolCRAB17Rule

View File

@@ -16,6 +16,6 @@
icon: { sprite: _Amour/Objects/Devices/protocolcrab17.rsi, state: icon }
productEntity: ProtocolCRAB17
cost:
Telecrystal: 8
Telecrystal: 6
categories:
- UplinkDisruption