diff --git a/Content.Client/AWS/Economy/ClientEconomyManager.cs b/Content.Client/AWS/Economy/ClientEconomyManager.cs
new file mode 100644
index 00000000000..961ba4f33bc
--- /dev/null
+++ b/Content.Client/AWS/Economy/ClientEconomyManager.cs
@@ -0,0 +1,78 @@
+using System.Collections.Frozen;
+using System.Diagnostics.CodeAnalysis;
+using Content.Shared.AWS.Economy;
+using Robust.Shared.Network;
+
+namespace Content.Client.AWS.Economy;
+
+public sealed class ClientEconomyManager : IClientEconomyManager
+{
+ [Dependency] private readonly IClientNetManager _netManager = default!;
+
+ public event EventHandler? AccountUpdateReceived;
+
+ ///
+ /// List of all cached accounts on this client.
+ ///
+ private FrozenDictionary _cachedAccounts = default!;
+
+ public void Initialize()
+ {
+ _netManager.RegisterNetMessage();
+
+ _netManager.RegisterNetMessage(AccountsUpdateMessage);
+ }
+
+ public bool IsValidAccount(string accountID)
+ {
+ AccountUpdateRequest();
+ return _cachedAccounts.ContainsKey(accountID);
+ }
+
+ public bool TryGetAccount(string accountID, [NotNullWhen(true)] out EconomyBankAccount? account)
+ {
+ AccountUpdateRequest();
+ return _cachedAccounts.TryGetValue(accountID, out account);
+ }
+
+ ///
+ /// Returns list of all cached accounts on this client. Use before using for fresh data.
+ ///
+ public IReadOnlyDictionary GetAccounts(EconomyBankAccountMask flag = EconomyBankAccountMask.NotBlocked)
+ {
+ if (flag == EconomyBankAccountMask.All)
+ return _cachedAccounts;
+
+ Dictionary list = new();
+ var accountsEnum = _cachedAccounts.GetEnumerator();
+ while (accountsEnum.MoveNext())
+ {
+ var account = accountsEnum.Current.Value;
+ switch (flag)
+ {
+ case EconomyBankAccountMask.NotBlocked:
+ if (!account.Blocked)
+ list.Add(account.AccountID, account);
+ break;
+ case EconomyBankAccountMask.Blocked:
+ if (account.Blocked)
+ list.Add(account.AccountID, account);
+ break;
+ }
+ }
+
+ return list;
+ }
+
+ public void AccountUpdateRequest()
+ {
+ var msg = new MsgEconomyAccountListRequest();
+ _netManager.ClientSendMessage(msg);
+ }
+
+ private void AccountsUpdateMessage(MsgEconomyAccountList message)
+ {
+ _cachedAccounts = message.Accounts.ToFrozenDictionary();
+ AccountUpdateReceived?.Invoke(this, EventArgs.Empty);
+ }
+}
\ No newline at end of file
diff --git a/Content.Client/AWS/Economy/IClientEconomyManager.cs b/Content.Client/AWS/Economy/IClientEconomyManager.cs
new file mode 100644
index 00000000000..5d93bafe0bd
--- /dev/null
+++ b/Content.Client/AWS/Economy/IClientEconomyManager.cs
@@ -0,0 +1,16 @@
+using Content.Shared.AWS.Economy;
+
+namespace Content.Client.AWS.Economy;
+
+public interface IClientEconomyManager : ISharedEconomyManager
+{
+ ///
+ /// Raised when the account list is received from the server.
+ ///
+ event EventHandler AccountUpdateReceived;
+
+ ///
+ /// Requests the server to send the account list.
+ ///
+ void AccountUpdateRequest();
+}
diff --git a/Content.Client/AWS/Economy/UI/EconomyLogConsoleBoundUserInterface.cs b/Content.Client/AWS/Economy/UI/EconomyLogConsoleBoundUserInterface.cs
index 04463cfa280..5ddf5044956 100644
--- a/Content.Client/AWS/Economy/UI/EconomyLogConsoleBoundUserInterface.cs
+++ b/Content.Client/AWS/Economy/UI/EconomyLogConsoleBoundUserInterface.cs
@@ -1,26 +1,32 @@
-using Content.Shared.AWS.Economy;
-using Content.Client.AWS.Economy.UI;
-
namespace Content.Client.AWS.Economy.UI;
public sealed class EconomyLogConsoleBoundUserInterface : BoundUserInterface
{
+ [Dependency] private readonly IClientEconomyManager _economyManager = default!;
+
[ViewVariables]
private EconomyLogConsoleMenu? _menu;
public EconomyLogConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
-
+ IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
+ // Requset accounts from the server, and when we receive them, open the menu.
+ _economyManager.AccountUpdateRequest();
+ _economyManager.AccountUpdateReceived += OnAccountUpdate;
+ }
+
+ private void OnAccountUpdate(object? sender, EventArgs e)
+ {
_menu = new EconomyLogConsoleMenu(this);
_menu.OnClose += Close;
- _menu.OpenCentered();
+ _menu?.OpenCentered();
}
protected override void Dispose(bool disposing)
@@ -28,6 +34,8 @@ protected override void Dispose(bool disposing)
base.Dispose(disposing);
if (!disposing)
return;
+
+ _economyManager.AccountUpdateReceived -= OnAccountUpdate;
_menu?.Dispose();
}
}
diff --git a/Content.Client/AWS/Economy/UI/EconomyLogConsoleMenu.xaml.cs b/Content.Client/AWS/Economy/UI/EconomyLogConsoleMenu.xaml.cs
index 8a6862199dd..8abb823b684 100644
--- a/Content.Client/AWS/Economy/UI/EconomyLogConsoleMenu.xaml.cs
+++ b/Content.Client/AWS/Economy/UI/EconomyLogConsoleMenu.xaml.cs
@@ -1,29 +1,31 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.AWS.Economy;
-using Content.Client.AWS.Economy.UI;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Client.UserInterface.Controls;
using System.Linq;
+using System.Collections.Frozen;
namespace Content.Client.AWS.Economy.UI;
[GenerateTypedNameReferences]
public sealed partial class EconomyLogConsoleMenu : FancyWindow
{
- [Dependency] private readonly IEntitySystemManager _entitySystem = default!;
+ [Dependency] private readonly IClientEconomyManager _economyManager = default!;
+
private EconomyLogConsoleBoundUserInterface Owner { get; set; }
- private Dictionary _accounts;
+ private FrozenDictionary _accounts = default!;
+
public EconomyLogConsoleMenu(EconomyLogConsoleBoundUserInterface owner)
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
- var economyBankAccount = _entitySystem.GetEntitySystem();
LogDetails.SelectMode = ItemList.ItemListSelectMode.None;
Owner = owner;
- _accounts = economyBankAccount.GetAccounts();
+
+ _accounts = _economyManager.GetAccounts().ToFrozenDictionary();
FillList();
@@ -36,16 +38,16 @@ private void OnSelectAccount(ItemList.Item accountId)
{
LogDetails.Clear();
- var accountComponent = (accountId.Metadata! as EconomyBankAccountComponent)!;
+ var account = (accountId.Metadata! as EconomyBankAccount)!;
- if (accountComponent.Logs.Count == 0)
+ if (account.Logs.Count == 0)
{
LogDetails.AddItem("No logs detected");
return;
}
- for (int i = accountComponent.Logs.Count - 1; i != -1; i--)
+ for (int i = account.Logs.Count - 1; i != -1; i--)
{
- var item = accountComponent.Logs[i];
+ var item = account.Logs[i];
LogDetails.AddItem("[" + item.Date.ToString("hh\\:mm\\:ss") + "] — " + item.Text);
}
}
@@ -84,11 +86,11 @@ private void OnTextEnteredLog(LineEdit.LineEditEventArgs eventArgs)
LogDetails.Clear();
var upText = eventArgs.Text.ToUpper();
- var accountComponent = (accountId.Metadata! as EconomyBankAccountComponent)!;
+ var account = (accountId.Metadata! as EconomyBankAccount)!;
- for (int i = accountComponent.Logs.Count - 1; i != -1; i--)
+ for (int i = account.Logs.Count - 1; i != -1; i--)
{
- var item = accountComponent.Logs[i];
+ var item = account.Logs[i];
if (item.Text.Contains(upText))
LogDetails.AddItem("[" + item.Date.ToString("hh\\:mm\\:ss") + "] — " + item.Text);
}
@@ -105,8 +107,8 @@ private void FillList()
AccountList.SortItemsByText();
}
- private string FormFieldName(EconomyBankAccountComponent comp)
+ private string FormFieldName(EconomyBankAccount account)
{
- return comp.AccountId + " — " + comp.AccountName;
+ return account.AccountID + " — " + account.AccountName;
}
}
diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs
index d93f79fc239..2fef5d36a53 100644
--- a/Content.Client/Entry/EntryPoint.cs
+++ b/Content.Client/Entry/EntryPoint.cs
@@ -37,6 +37,7 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Replays;
using Robust.Shared.Timing;
+using Content.Shared.AWS.Economy;
namespace Content.Client.Entry
{
@@ -73,6 +74,7 @@ public sealed class EntryPoint : GameClient
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly ContentReplayPlaybackManager _replayMan = default!;
[Dependency] private readonly DebugMonitorManager _debugMonitorManager = default!;
+ [Dependency] private readonly ISharedEconomyManager _economyManager = default!;
public override void Init()
{
@@ -134,6 +136,7 @@ public override void Init()
_extendedDisconnectInformation.Initialize();
_jobRequirements.Initialize();
_playbackMan.Initialize();
+ _economyManager.Initialize(); //AWS-economy
//AUTOSCALING default Setup!
_configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffX", 1080);
diff --git a/Content.Client/IoC/ClientContentIoC.cs b/Content.Client/IoC/ClientContentIoC.cs
index 7c53393fc8e..a34094f8875 100644
--- a/Content.Client/IoC/ClientContentIoC.cs
+++ b/Content.Client/IoC/ClientContentIoC.cs
@@ -21,6 +21,8 @@
using Content.Client.Lobby;
using Content.Shared.Administration.Managers;
using Content.Shared.Players.PlayTimeTracking;
+using Content.Shared.AWS.Economy;
+using Content.Client.AWS.Economy;
namespace Content.Client.IoC
{
@@ -52,6 +54,8 @@ public static void Register()
collection.Register();
collection.Register();
collection.Register();
+ collection.Register(); //AWS-economy
+ collection.Register(); //AWS-economy
}
}
}
diff --git a/Content.Server/AWS/Economy/EconomyBankAccountSystem.cs b/Content.Server/AWS/Economy/EconomyBankAccountSystem.cs
index 59122d24cd7..d50dae46159 100644
--- a/Content.Server/AWS/Economy/EconomyBankAccountSystem.cs
+++ b/Content.Server/AWS/Economy/EconomyBankAccountSystem.cs
@@ -7,13 +7,16 @@
using Content.Server.Popups;
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;
-using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Random;
using Robust.Shared.Prototypes;
using Content.Shared.Access.Components;
using Content.Server.Access.Components;
using JetBrains.Annotations;
+using Robust.Server.GameObjects;
+using Robust.Shared.Map;
+using Robust.Shared.Timing;
+using System.Diagnostics.CodeAnalysis;
namespace Content.Server.AWS.Economy
{
@@ -25,15 +28,20 @@ public sealed class EconomyBankAccountSystem : EconomyBankAccountSystemShared
[Dependency] private readonly VendingMachineSystem _vendingMachine = default!;
[Dependency] private readonly INetManager _netManager = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
+ [Dependency] private readonly TransformSystem _transformSystem = default!;
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+ [Dependency] private readonly IEconomyManager _economyManager = default!;
public override void Initialize()
{
+ SubscribeLocalEvent(OnAccountComponentInit);
+
SubscribeLocalEvent(OnTerminalInteracted);
SubscribeLocalEvent(OnATMEmagged);
SubscribeLocalEvent(OnATMInteracted);
-
- /*SubscribeLocalEvent(OnAccountComponentStartup);*/
+ SubscribeLocalEvent(OnATMWithdrawMessage);
+ SubscribeLocalEvent(OnATMTransferMessage);
}
private string GenerateAccountId(string prefix, uint strik, uint numbersPerStrik, string? descriptor)
@@ -55,29 +63,64 @@ private string GenerateAccountId(string prefix, uint strik, uint numbersPerStrik
return res;
}
+ ///
+ /// Enables a card or a bank account for usage.
+ ///
[PublicAPI]
public bool TryActivate(Entity entity)
{
- if (entity.Comp.ActivateOnSpawn)
- {
- entity.Comp.Activated = true;
- return true;
- }
if (!_prototypeManager.TryIndex(entity.Comp.AccountIdByProto, out EconomyAccountIdPrototype? proto))
return false;
- entity.Comp.AccountId = GenerateAccountId(proto.Prefix, proto.Strik, proto.NumbersPerStrik, proto.Descriptior);
+ var accountID = GenerateAccountId(proto.Prefix, proto.Streak, proto.NumbersPerStreak, proto.Descriptior);
+ var accountName = entity.Comp.AccountName;
+ var balance = (ulong)0;
if (TryComp(entity, out var idCardComponent))
- entity.Comp.AccountName = idCardComponent.FullName ?? entity.Comp.AccountName;
+ accountName = idCardComponent.FullName ?? entity.Comp.AccountName;
if (TryComp(entity, out var presetIdCardComponent))
if (_prototypeManager.TryIndex("NanotrasenDefaultSallaries", out var sallariesPrototype)
&& presetIdCardComponent.JobName is not null)
if (sallariesPrototype.Jobs.TryGetValue(presetIdCardComponent.JobName.Value, out var entry))
- entity.Comp.Balance = (ulong)(entry.StartMoney * _robustRandom.NextDouble(0.5, 1.5));
+ balance = (ulong)(entry.StartMoney * _robustRandom.NextDouble(0.5, 1.5));
+
+ if (entity.Comp.AccountSetup is { } setup && presetIdCardComponent is null && idCardComponent is null)
+ {
+ var setupID = setup.GenerateAccountID ? accountID :
+ setup.AccountID;
+
+ if (setupID is null)
+ return false;
+
+ var setupAccount = new EconomyBankAccount(setupID,
+ setup.AccountName,
+ setup.AllowedCurrency,
+ setup.Balance,
+ setup.Penalty,
+ setup.Blocked,
+ setup.CanReachPayDay);
+
+ if (!_economyManager.TryAddAccount(setupAccount))
+ return false;
+
+ entity.Comp.AccountID = setupAccount.AccountID;
+ entity.Comp.AccountName = setupAccount.AccountName;
+ Dirty(entity);
+ return true;
+ }
+
if (presetIdCardComponent is not null && idCardComponent is not null)
{
- entity.Comp.Activated = true;
+ var accountSetup = entity.Comp.AccountSetup;
+ balance = accountSetup?.Balance ?? balance;
+ var account = new EconomyBankAccount(accountID, accountName, accountSetup?.AllowedCurrency, balance,
+ accountSetup?.Penalty, accountSetup?.Blocked, accountSetup?.CanReachPayDay);
+
+ if (!_economyManager.TryAddAccount(account))
+ return false;
+
+ entity.Comp.AccountID = accountID;
+ entity.Comp.AccountName = accountName;
Dirty(entity);
return true;
}
@@ -85,6 +128,178 @@ public bool TryActivate(Entity entity)
return false;
}
+ private void Withdraw(EconomyBankAccountComponent component, EconomyBankATMComponent atm, ulong sum)
+ {
+ if (!_economyManager.TryChangeAccountBalance(component.AccountID, sum, false))
+ return;
+
+ var pos = _transformSystem.GetMapCoordinates(atm.Owner);
+ DropMoneyHandler(component.MoneyHolderEntId, sum, pos);
+
+ if (_economyManager.TryGetAccount(component.AccountID, out var account))
+ {
+ var log = new EconomyBankAccountLogField(_gameTiming.CurTime, Loc.GetString("economybanksystem-log-withdraw",
+ ("amount", sum), ("currencyName", account.AllowedCurrency)));
+ _economyManager.AddLog(component.AccountID, log);
+ }
+
+ _entManager.Dirty(component);
+ }
+
+ [PublicAPI]
+ public bool TryWithdraw(EconomyBankAccountComponent component, EconomyBankATMComponent atm, ulong sum, [NotNullWhen(false)] out string? errorMessage)
+ {
+ errorMessage = "";
+ if (!_economyManager.TryGetAccount(component.AccountID, out var account))
+ return false;
+
+ if (sum > 0 && account.Balance >= sum)
+ {
+ Withdraw(component, atm, sum);
+ return true;
+ }
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notenoughmoney");
+ return false;
+ }
+
+ [PublicAPI]
+ public Entity DropMoneyHandler(EntProtoId entId, ulong amount, MapCoordinates pos)
+ {
+ var ent = Spawn(entId, pos);
+
+ var moneyHolderComp = Comp(ent);
+ moneyHolderComp.Balance = amount;
+
+ _entManager.Dirty(moneyHolderComp);
+
+ return (ent, moneyHolderComp);
+ }
+
+ [PublicAPI]
+ public bool TrySendMoney(IEconomyMoneyHolder fromAccount, EconomyBankAccountComponent? recipientAccount, ulong amount, [NotNullWhen(false)] out string? errorMessage)
+ {
+ errorMessage = null;
+
+ if (fromAccount.Balance >= amount)
+ {
+ if (recipientAccount is not null)
+ {
+ return _economyManager.TryChangeAccountBalance(recipientAccount.AccountID, amount);
+ }
+
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notfoundaccout");
+ return false;
+ }
+
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notenoughmoney");
+ return false;
+ }
+
+ [PublicAPI]
+ public bool TrySendMoney(IEconomyMoneyHolder fromAccount, string recipientAccountId, ulong amount, [NotNullWhen(false)] out string? errorMessage)
+ {
+ errorMessage = null;
+
+ if (!_economyManager.IsValidAccount(recipientAccountId))
+ {
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notfoundaccout", ("accountId", recipientAccountId));
+ return false;
+ }
+
+ if (fromAccount.Balance < amount)
+ {
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notenoughmoney");
+ return false;
+ }
+
+ return _economyManager.TryChangeAccountBalance(recipientAccountId, amount);
+ }
+
+ [PublicAPI]
+ public bool TrySendMoney(EconomyBankAccountComponent fromAccount, string recipientAccountId, ulong amount, [NotNullWhen(false)] out string? errorMessage)
+ {
+ errorMessage = null;
+
+ if (!_economyManager.TryGetAccount(fromAccount.AccountID, out var fromBankAccount))
+ {
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notfoundaccout", ("accountId", fromAccount.AccountID));
+ return false;
+ }
+
+ if (!_economyManager.IsValidAccount(recipientAccountId))
+ {
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notfoundaccout", ("accountId", recipientAccountId));
+ return false;
+ }
+
+ if (fromBankAccount.Balance < amount)
+ {
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notenoughmoney");
+ return false;
+ }
+
+ return _economyManager.TryTransferMoney(fromBankAccount.AccountID, recipientAccountId, amount);
+ }
+
+ [PublicAPI]
+ public bool TrySendMoney(string fromAccountId, string recipientAccountId, ulong amount, [NotNullWhen(false)] out string? errorMessage)
+ {
+ errorMessage = null;
+
+ if (!_economyManager.TryGetAccount(fromAccountId, out var fromBankAccount))
+ {
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notfoundaccout", ("accountId", fromAccountId));
+ return false;
+ }
+
+ if (!_economyManager.IsValidAccount(recipientAccountId))
+ {
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notfoundaccout", ("accountId", recipientAccountId));
+ return false;
+ }
+
+ if (fromBankAccount.Balance < amount)
+ {
+ errorMessage = Loc.GetString("economybanksystem-transaction-error-notenoughmoney");
+ return false;
+ }
+
+ return _economyManager.TryTransferMoney(fromAccountId, recipientAccountId, amount);
+ }
+
+ private void OnAccountComponentInit(Entity entity, ref ComponentInit args)
+ {
+ // if has id card comp, then it will be initialized in other place
+ if (entity.Comp.AccountSetup is null || HasComp(entity))
+ return;
+
+ TryActivate(entity);
+ }
+
+ private void OnATMWithdrawMessage(EntityUid uid, EconomyBankATMComponent atm, EconomyBankATMWithdrawMessage args)
+ {
+ var bankAccount = GetATMInsertedAccount(atm);
+ if (bankAccount is null)
+ return;
+
+ string? error;
+
+ TryWithdraw(bankAccount, atm, args.Amount, out error);
+ UpdateATMUserInterface((uid, atm), error);
+ }
+
+ private void OnATMTransferMessage(EntityUid uid, EconomyBankATMComponent atm, EconomyBankATMTransferMessage args)
+ {
+ var bankAccount = GetATMInsertedAccount(atm);
+ if (bankAccount is null)
+ return;
+
+ string? error;
+
+ TrySendMoney(bankAccount, args.RecipientAccountId, args.Amount, out error);
+ UpdateATMUserInterface((uid, atm), error);
+ }
+
private void OnATMEmagged(EntityUid uid, EconomyBankATMComponent component, ref GotEmaggedEvent args)
{
if (HasComp(uid) || args.Handled)
@@ -100,7 +315,7 @@ private void OnATMEmagged(EntityUid uid, EconomyBankATMComponent component, ref
return;
var moneyHolderCount = _robustRandom.Next(1, component.EmagDropMoneyHolderRandomCount + 1);
- var mapPos = Comp(uid).MapPosition;
+ var mapPos = _transformSystem.GetMapCoordinates(uid);
for (int i = 0; i < moneyHolderCount; i++)
{
@@ -124,6 +339,12 @@ private void OnATMInteracted(EntityUid uid, EconomyBankATMComponent component, I
if (TrySendMoney(economyMoneyHolderComponent, insertedAccountComponent, amount, out var error))
{
+ if (insertedAccountComponent is not null && _economyManager.TryGetAccount(insertedAccountComponent.AccountID, out var account))
+ _economyManager.AddLog(account.AccountID,
+ new EconomyBankAccountLogField(_gameTiming.CurTime,
+ Loc.GetString("economybanksystem-log-insert",
+ ("amount", amount), ("currencyName", account.AllowedCurrency))));
+
if (_netManager.IsServer)
_popupSystem.PopupEntity(Loc.GetString("economybanksystem-atm-moneyentering"), uid, type: PopupType.Medium);
@@ -143,14 +364,10 @@ private void OnTerminalInteracted(EntityUid uid, EconomyBankTerminalComponent co
if (amount <= 0)
return;
- TryComp(usedEnt, out var economyMoneyHolderComponent);
- TryComp(usedEnt, out var economyBankAccountComponent);
-
- if (economyMoneyHolderComponent is null && economyBankAccountComponent is null)
+ if (!TryComp(usedEnt, out var economyMoneyHolderComponent) &
+ !TryComp(usedEnt, out var economyBankAccountComponent))
return;
- IEconomyMoneyHolder anyComp = (economyMoneyHolderComponent is not null ? economyMoneyHolderComponent : economyBankAccountComponent)!;
-
if (TryComp(uid, out var vendingMachineComponent))
{
if (vendingMachineComponent.SelectedItemId is not null)
@@ -177,16 +394,31 @@ private void OnTerminalInteracted(EntityUid uid, EconomyBankTerminalComponent co
}
- if (!TrySendMoney(anyComp, component.LinkedAccount, amount, out var err))
- {
- if (_netManager.IsServer)
- _popupSystem.PopupEntity(err, uid, type: PopupType.MediumCaution);
+ if (!_economyManager.TryGetAccount(component.LinkedAccount, out var receiverAccount))
return;
+
+ if (economyMoneyHolderComponent is not null)
+ {
+ if (!TrySendMoney(economyMoneyHolderComponent, component.LinkedAccount, amount, out var err))
+ {
+ if (_netManager.IsServer)
+ _popupSystem.PopupEntity(err, uid, type: PopupType.MediumCaution);
+ return;
+ }
+ }
+ else if (economyBankAccountComponent is not null)
+ {
+ if (!TrySendMoney(economyBankAccountComponent, component.LinkedAccount, amount, out var err))
+ {
+ if (_netManager.IsServer)
+ _popupSystem.PopupEntity(err, uid, type: PopupType.MediumCaution);
+ return;
+ }
}
UpdateTerminal((uid, component), 0, string.Empty);
- _popupSystem.PopupEntity(Loc.GetString("economybanksystem-transaction-success", ("amount", amount), ("currencyName", FindAccountById(component.LinkedAccount)!.AllowCurrency)), uid, type: PopupType.Medium);
+ _popupSystem.PopupEntity(Loc.GetString("economybanksystem-transaction-success", ("amount", amount), ("currencyName", receiverAccount.AllowedCurrency)), uid, type: PopupType.Medium);
}
}
}
diff --git a/Content.Server/AWS/Economy/EconomyManager.cs b/Content.Server/AWS/Economy/EconomyManager.cs
new file mode 100644
index 00000000000..cf027045691
--- /dev/null
+++ b/Content.Server/AWS/Economy/EconomyManager.cs
@@ -0,0 +1,144 @@
+using System.Collections.Frozen;
+using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
+using Content.Shared.AWS.Economy;
+using Robust.Server.Player;
+using Robust.Shared.Enums;
+using Robust.Shared.Network;
+using Robust.Shared.Player;
+using Robust.Shared.Timing;
+
+namespace Content.Server.AWS.Economy;
+
+public sealed class EconomyManager : IEconomyManager
+{
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+ [Dependency] private readonly IServerNetManager _netManager = default!;
+ [Dependency] private readonly IPlayerManager _playerManager = default!;
+
+ private Dictionary _accounts = new();
+
+ public void Initialize()
+ {
+ _netManager.RegisterNetMessage();
+
+ _netManager.RegisterNetMessage(AccountListUpdateRequest);
+
+ _playerManager.PlayerStatusChanged += OnPlayerJoinedGame;
+ }
+
+ public bool TryAddAccount(EconomyBankAccount account)
+ {
+ // Maybe do other checks here as well?
+ // If account already exists, return false.
+ if (IsValidAccount(account.AccountID))
+ return false;
+
+ return _accounts.TryAdd(account.AccountID, account);
+ }
+
+ public bool TryChangeAccountBalance(string accountID, ulong amount, bool addition = true)
+ {
+ if (!TryGetAccount(accountID, out var account))
+ return false;
+
+ if (!addition)
+ {
+ if (account.Balance - amount < 0)
+ return false;
+
+ account.Balance -= amount;
+ return true;
+ }
+
+ account.Balance += amount;
+ return true;
+ }
+
+ public bool TryTransferMoney(string senderID, string receiverID, ulong amount)
+ {
+ if (amount <= 0 ||
+ !TryGetAccount(senderID, out var sender) ||
+ !TryGetAccount(receiverID, out var receiver))
+ return false;
+
+ if (sender.Balance < amount)
+ return false;
+
+ sender.Balance -= amount;
+ sender.Logs.Add(new(_gameTiming.CurTime, Loc.GetString("economybanksystem-log-send-to",
+ ("amount", amount), ("currencyName", receiver.AllowedCurrency), ("accountId", receiver.AccountID))));
+ receiver.Balance += amount;
+ receiver.Logs.Add(new(_gameTiming.CurTime, Loc.GetString("economybanksystem-log-send-from",
+ ("amount", amount), ("currencyName", receiver.AllowedCurrency), ("accountId", sender.AccountID))));
+ return true;
+ }
+
+ public bool IsValidAccount(string accountID)
+ {
+ return _accounts.ContainsKey(accountID);
+ }
+
+ public bool TryGetAccount(string accountID, [NotNullWhen(true)] out EconomyBankAccount? account)
+ {
+ return _accounts.TryGetValue(accountID, out account);
+ }
+
+ public void AddLog(string accountID, EconomyBankAccountLogField log)
+ {
+ if (!TryGetAccount(accountID, out var account))
+ return;
+
+ account.Logs.Add(log);
+ }
+
+ public IReadOnlyDictionary GetAccounts(EconomyBankAccountMask flag = EconomyBankAccountMask.NotBlocked)
+ {
+ if (flag == EconomyBankAccountMask.All)
+ {
+ ReadOnlyDictionary all = new(_accounts);
+ return all;
+ }
+
+ Dictionary list = new();
+ var accountsEnum = _accounts.GetEnumerator();
+ while (accountsEnum.MoveNext())
+ {
+ var account = accountsEnum.Current.Value;
+ switch (flag)
+ {
+ case EconomyBankAccountMask.NotBlocked:
+ if (!account.Blocked)
+ list.Add(account.AccountID, account);
+ break;
+ case EconomyBankAccountMask.Blocked:
+ if (account.Blocked)
+ list.Add(account.AccountID, account);
+ break;
+ }
+ }
+
+ ReadOnlyDictionary result = new(list);
+ return result;
+ }
+
+ private void UpdateAccountList(INetChannel channel)
+ {
+ var msg = new MsgEconomyAccountList();
+ msg.Accounts = _accounts.ToFrozenDictionary();
+ _netManager.ServerSendMessage(msg, channel);
+ }
+
+ private void AccountListUpdateRequest(MsgEconomyAccountListRequest message)
+ {
+ UpdateAccountList(message.MsgChannel);
+ }
+
+ private void OnPlayerJoinedGame(object? sender, SessionStatusEventArgs e)
+ {
+ if (e.NewStatus != SessionStatus.InGame)
+ return;
+
+ UpdateAccountList(e.Session.Channel);
+ }
+}
\ No newline at end of file
diff --git a/Content.Server/AWS/Economy/EconomyPayDayRule.cs b/Content.Server/AWS/Economy/EconomyPayDayRule.cs
index ff0b21fd2f5..70979dfb35e 100644
--- a/Content.Server/AWS/Economy/EconomyPayDayRule.cs
+++ b/Content.Server/AWS/Economy/EconomyPayDayRule.cs
@@ -1,9 +1,4 @@
-using System.Linq;
-using Content.Shared.Dataset;
-using Content.Server.Ghost.Roles.Components;
-using Content.Server.StationEvents.Components;
using Content.Shared.GameTicking.Components;
-using Content.Shared.Random.Helpers;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Content.Shared.AWS.Economy;
@@ -11,19 +6,22 @@
using Content.Shared.Roles;
using Content.Shared.Mind.Components;
using Content.Shared.Roles.Jobs;
+using Content.Server.AWS.Economy;
namespace Content.Server.StationEvents.Events;
public sealed class EconomyPayDayRule : StationEventSystem
{
[Dependency] private readonly IEntityManager _entMan = default!;
- [Dependency] private readonly EconomyBankAccountSystemShared _bankAccountSystem = default!;
+ [Dependency] private readonly EconomyBankAccountSystem _bankAccountSystem = default!;
+ [Dependency] private readonly IEconomyManager _economyManager = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IRobustRandom _random = default!;
+
protected override void Started(EntityUid uid, EconomyPayDayRuleComponent ruleComponent, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
- var accounts = _bankAccountSystem.GetAccounts();
- if (!accounts.TryGetValue(ruleComponent.PayerAccountId, out var payerComp))
+ var accounts = _economyManager.GetAccounts();
+ if (!_economyManager.TryGetAccount(ruleComponent.PayerAccountId, out var payerAccount))
return;
if (!_prototype.TryIndex(ruleComponent.SallaryProto, out var sallariesProto))
@@ -41,17 +39,17 @@ protected override void Started(EntityUid uid, EconomyPayDayRuleComponent ruleCo
manifest.Add(mindComponent.CharacterName, jobComponent.Prototype.Value);
}
}
- List blockedAccounts = new();
+ List blockedAccounts = new();
- foreach (var (id, comp) in accounts)
+ foreach (var (id, account) in accounts)
{
- if (comp.Blocked || !comp.CanReachPayDay)
+ if (account.Blocked || !account.CanReachPayDay)
continue;
- if (comp.Blocked)
+ if (account.Blocked)
continue;
- if (!manifest.TryGetValue(comp.AccountName, out var job))
+ if (!manifest.TryGetValue(account.AccountName, out var job))
continue;
EconomySallariesJobEntry? entry = null;
@@ -71,13 +69,13 @@ protected override void Started(EntityUid uid, EconomyPayDayRuleComponent ruleCo
switch (ruleComponent.PayType)
{
case EconomyPayDayRuleType.Adding:
- _bankAccountSystem.TrySendMoney(payerComp, comp, sallary, out err);
+ _bankAccountSystem.TrySendMoney(payerAccount.AccountID, account.AccountID, sallary, out err);
break;
case EconomyPayDayRuleType.Decrementing:
- if (!_bankAccountSystem.TrySendMoney(comp, payerComp, sallary, out err))
+ if (!_bankAccountSystem.TrySendMoney(account.AccountID, payerAccount.AccountID, sallary, out err))
{
- comp.Blocked = true;
- blockedAccounts.Add(comp);
+ account.Blocked = true;
+ blockedAccounts.Add(account);
}
break;
default:
diff --git a/Content.Server/AWS/Economy/IEconomyManager.cs b/Content.Server/AWS/Economy/IEconomyManager.cs
new file mode 100644
index 00000000000..6b25890bfe3
--- /dev/null
+++ b/Content.Server/AWS/Economy/IEconomyManager.cs
@@ -0,0 +1,30 @@
+using Content.Shared.AWS.Economy;
+
+namespace Content.Server.AWS.Economy;
+
+public interface IEconomyManager : ISharedEconomyManager
+{
+ ///
+ /// Adds account to the account list.
+ ///
+ /// True if the account was successfully added, false otherwise.
+ bool TryAddAccount(EconomyBankAccount account);
+
+ ///
+ /// Changes the balance of the account.
+ ///
+ /// Whether to add or substract the given amount.
+ ///
+ bool TryChangeAccountBalance(string accountID, ulong amount, bool addition = true);
+
+ ///
+ /// Transfer money from one account to another.
+ ///
+ /// True if the transfer was successful, false otherwise.
+ bool TryTransferMoney(string senderID, string receiverID, ulong amount);
+
+ ///
+ /// Adds a log to the account.
+ ///
+ void AddLog(string accountID, EconomyBankAccountLogField log);
+}
\ No newline at end of file
diff --git a/Content.Server/Entry/EntryPoint.cs b/Content.Server/Entry/EntryPoint.cs
index 02a125bdee2..6d1af9ff297 100644
--- a/Content.Server/Entry/EntryPoint.cs
+++ b/Content.Server/Entry/EntryPoint.cs
@@ -25,6 +25,7 @@
using Content.Server.ServerInfo;
using Content.Server.ServerUpdates;
using Content.Server.Voting.Managers;
+using Content.Shared.AWS.Economy;
using Content.Shared.CCVar;
using Content.Shared.Kitchen;
using Content.Shared.Localizations;
@@ -115,6 +116,7 @@ public override void Init()
_playTimeTracking.Initialize();
IoCManager.Resolve().Initialize();
IoCManager.Resolve().Initialize();
+ IoCManager.Resolve().Initialize(); //AWS-economy
}
}
diff --git a/Content.Server/IoC/ServerContentIoC.cs b/Content.Server/IoC/ServerContentIoC.cs
index 01497efae4a..cfd4ebe7624 100644
--- a/Content.Server/IoC/ServerContentIoC.cs
+++ b/Content.Server/IoC/ServerContentIoC.cs
@@ -3,6 +3,7 @@
using Content.Server.Administration.Managers;
using Content.Server.Administration.Notes;
using Content.Server.Afk;
+using Content.Server.AWS.Economy;
using Content.Server.Chat.Managers;
using Content.Server.Connection;
using Content.Server.Corvax.TTS;
@@ -27,6 +28,7 @@
using Content.Server.Worldgen.Tools;
using Content.Shared.Administration.Logs;
using Content.Shared.Administration.Managers;
+using Content.Shared.AWS.Economy;
using Content.Shared.Kitchen;
using Content.Shared.Players.PlayTimeTracking;
@@ -71,6 +73,8 @@ public static void Register()
IoCManager.Register();
IoCManager.Register();
IoCManager.Register();
+ IoCManager.Register(); //AWS-economy
+ IoCManager.Register(); //AWS-economy
}
}
}
diff --git a/Content.Shared/AWS/Economy/BankAccountSetup.cs b/Content.Shared/AWS/Economy/BankAccountSetup.cs
new file mode 100644
index 00000000000..649a17bb014
--- /dev/null
+++ b/Content.Shared/AWS/Economy/BankAccountSetup.cs
@@ -0,0 +1,32 @@
+using Content.Shared.Store;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.AWS.Economy;
+
+[DataDefinition]
+public sealed partial class BankAccountSetup
+{
+ [DataField("accountID")]
+ public string? AccountID;
+
+ [DataField("generateAccountID")]
+ public bool GenerateAccountID = false;
+
+ [DataField("accountName")]
+ public string? AccountName;
+
+ [DataField("allowedCurrency")]
+ public ProtoId? AllowedCurrency;
+
+ [DataField("balance")]
+ public ulong? Balance;
+
+ [DataField("penalty")]
+ public ulong? Penalty;
+
+ [DataField("blocked")]
+ public bool? Blocked;
+
+ [DataField("canReachPayDay")]
+ public bool? CanReachPayDay;
+}
\ No newline at end of file
diff --git a/Content.Shared/AWS/Economy/EconomyAccountId.cs b/Content.Shared/AWS/Economy/EconomyAccountId.cs
index 93d8cab3e89..de15d7440fe 100644
--- a/Content.Shared/AWS/Economy/EconomyAccountId.cs
+++ b/Content.Shared/AWS/Economy/EconomyAccountId.cs
@@ -13,9 +13,9 @@ public sealed partial class EconomyAccountIdPrototype : IPrototype
[DataField(required: false)]
public string? Descriptior;
[DataField(required: false)]
- public uint Strik = 4;
+ public uint Streak = 4;
[DataField(required: false)]
- public uint NumbersPerStrik = 4;
+ public uint NumbersPerStreak = 4;
[DataField(required: false)]
public uint[] MinMaxSallary = {0,0};
diff --git a/Content.Shared/AWS/Economy/EconomyBankAccount.cs b/Content.Shared/AWS/Economy/EconomyBankAccount.cs
new file mode 100644
index 00000000000..2cbf310c9bd
--- /dev/null
+++ b/Content.Shared/AWS/Economy/EconomyBankAccount.cs
@@ -0,0 +1,41 @@
+using Content.Shared.Store;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.AWS.Economy;
+
+[Serializable, NetSerializable]
+public sealed class EconomyBankAccount
+{
+ public string AccountID { get; set; }
+
+ public string AccountName { get; set; }
+
+ public ProtoId AllowedCurrency { get; set; }
+
+ public ulong Balance { get; set; }
+
+ public ulong Penalty { get; set; }
+
+ public bool Blocked { get; set; }
+
+ public bool CanReachPayDay { get; set; }
+
+ public List Logs { get; set; }
+
+ public EconomyBankAccount(string accountID, string? accountName,
+ string? allowedCurrency,
+ ulong? balance, ulong? penalty,
+ bool? blocked, bool? canReachPayday,
+ List? logs = default)
+ {
+ AccountID = accountID;
+ AccountName = accountName ?? "UNEXPECTED USER";
+ AllowedCurrency = allowedCurrency ?? "Thaler";
+ Balance = balance ?? 0;
+ Penalty = penalty ?? 0;
+ Blocked = blocked ?? false;
+ CanReachPayDay = canReachPayday ?? true;
+ Logs = logs ?? [];
+ }
+}
\ No newline at end of file
diff --git a/Content.Shared/AWS/Economy/EconomyBankAccountComponent.cs b/Content.Shared/AWS/Economy/EconomyBankAccountComponent.cs
index f7f9b41fa93..1e9eac69198 100644
--- a/Content.Shared/AWS/Economy/EconomyBankAccountComponent.cs
+++ b/Content.Shared/AWS/Economy/EconomyBankAccountComponent.cs
@@ -1,53 +1,38 @@
using Robust.Shared.Prototypes;
-using Content.Shared.Store;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.AWS.Economy
{
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
- public sealed partial class EconomyBankAccountComponent : Component, IEconomyMoneyHolder
+ public sealed partial class EconomyBankAccountComponent : Component
{
- [ViewVariables(VVAccess.ReadWrite), DataField(required: true)]
- public ProtoId AllowCurrency = "Thaler";
[ViewVariables(VVAccess.ReadWrite), DataField(required: true)]
public ProtoId AccountIdByProto = "Nanotrasen";
+
[ViewVariables(VVAccess.ReadWrite), DataField(required: true)]
public EntProtoId MoneyHolderEntId = "ThalerHolder";
+ ///
+ /// Set this up in EconomyBankAccountSetup to define the account, which this card will be using (referring to).
+ ///
[ViewVariables(VVAccess.ReadWrite), DataField]
[AutoNetworkedField]
- public ulong Balance { get; set; } = 0;
- [ViewVariables(VVAccess.ReadWrite), DataField]
- [AutoNetworkedField]
- public ulong Penalty = 0;
-
- [ViewVariables(VVAccess.ReadWrite), DataField]
- [AutoNetworkedField]
- public string AccountId = "NO VALUE";
+ public string AccountID = "NO VALUE";
+ ///
+ /// Set this up in EconomyBankAccountSetup to define the name, which this card will be using.
+ ///
[ViewVariables(VVAccess.ReadWrite), DataField]
[AutoNetworkedField]
public string AccountName = "UNEXPECTED USER";
- [ViewVariables(VVAccess.ReadWrite)]
- [AutoNetworkedField]
- public bool Blocked = false;
-
+ ///
+ /// Use this in prototypes for defining the account, which this card will be using (the account will be initialized on spawn).
+ /// Also, parameters beyond AccountName can be used with IDCards (if you want to setup other currency, for example).
+ ///
[ViewVariables(VVAccess.ReadOnly), DataField]
- public bool ActivateOnSpawn = false;
-
- [ViewVariables(VVAccess.ReadWrite)]
- [AutoNetworkedField]
- public bool Activated = false;
-
- [ViewVariables(VVAccess.ReadWrite)]
- [AutoNetworkedField]
- public bool CanReachPayDay = true;
-
- [ViewVariables(VVAccess.ReadWrite)]
- [AutoNetworkedField]
- public List Logs = new();
+ public BankAccountSetup? AccountSetup;
}
[Serializable, NetSerializable]
diff --git a/Content.Shared/AWS/Economy/EconomyBankAccountSystemShared.cs b/Content.Shared/AWS/Economy/EconomyBankAccountSystemShared.cs
index de4f73d7c45..ac6bda32b91 100644
--- a/Content.Shared/AWS/Economy/EconomyBankAccountSystemShared.cs
+++ b/Content.Shared/AWS/Economy/EconomyBankAccountSystemShared.cs
@@ -1,18 +1,7 @@
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using Robust.Shared.Utility;
-using Robust.Shared.Prototypes;
-using Robust.Shared.Random;
using Content.Shared.Containers.ItemSlots;
-using Content.Shared.Access.Components;
using Content.Shared.Examine;
using Robust.Shared.Containers;
-using Robust.Shared.Map;
-using Content.Shared.Interaction;
-using Content.Shared.VendingMachines;
using Content.Shared.Popups;
-using Robust.Shared.Network;
-using Robust.Shared.Timing;
using JetBrains.Annotations;
namespace Content.Shared.AWS.Economy
@@ -20,12 +9,10 @@ namespace Content.Shared.AWS.Economy
public class EconomyBankAccountSystemShared : EntitySystem
{
[Dependency] protected readonly EntityManager _entManager = default!;
- [Dependency] private readonly IGameTiming _gameTiming = default!;
- [Dependency] private readonly INetManager _netManager = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
- [Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly SharedUserInterfaceSystem _userInterfaceSystem = default!;
+ [Dependency] private readonly ISharedEconomyManager _economyManager = default!;
public override void Initialize()
{
@@ -33,7 +20,6 @@ public override void Initialize()
SubscribeLocalEvent(OnBankTerminalExamine);
SubscribeLocalEvent(OnTerminalMessage);
- SubscribeLocalEvent(OnBankAccountComponentInit);
SubscribeLocalEvent(OnBankAccountExamine);
SubscribeLocalEvent(OnMoneyHolderExamine);
@@ -41,26 +27,18 @@ public override void Initialize()
SubscribeLocalEvent(OnATMComponentRemove);
SubscribeLocalEvent(OnATMItemSlotChanged);
SubscribeLocalEvent(OnATMItemSlotChanged);
- SubscribeLocalEvent(OnATMWithdrawMessage);
- SubscribeLocalEvent(OnATMTransferMessage);
- }
-
- private void OnBankAccountComponentInit(EntityUid uid, EconomyBankAccountComponent comp, ComponentInit args)
- {
- if (comp.ActivateOnSpawn)
- {
- comp.Activated = true;
- Dirty(uid, comp);
- }
}
private void OnBankAccountExamine(Entity entity, ref ExaminedEvent args)
{
+ if (!_economyManager.TryGetAccount(entity.Comp.AccountID, out var account))
+ return;
+
args.PushMarkup(Loc.GetString("bankaccount-component-on-examine-detailed-message",
- ("id", entity.Comp.AccountId)));
+ ("id", account.AccountID)));
args.PushMarkup(Loc.GetString("moneyholder-component-on-examine-detailed-message",
- ("moneyName", entity.Comp.AllowCurrency),
- ("balance", entity.Comp.Balance)));
+ ("moneyName", account.AllowedCurrency),
+ ("balance", account.Balance)));
}
private void OnTerminalMessage(EntityUid uid, EconomyBankTerminalComponent comp, EconomyTerminalMessage args)
@@ -110,153 +88,20 @@ private void OnATMItemSlotChanged(EntityUid uid, EconomyBankATMComponent atm, Co
UpdateATMUserInterface((uid, atm));
}
- private void OnATMWithdrawMessage(EntityUid uid, EconomyBankATMComponent atm, EconomyBankATMWithdrawMessage args)
- {
- var bankAccount = GetATMInsertedAccount(atm);
- if (bankAccount is null)
- return;
-
- string? error;
-
- TryWithdraw(bankAccount, atm, args.Amount, out error);
- UpdateATMUserInterface((uid, atm), error);
- }
-
- private void OnATMTransferMessage(EntityUid uid, EconomyBankATMComponent atm, EconomyBankATMTransferMessage args)
- {
- var bankAccount = GetATMInsertedAccount(atm);
- if (bankAccount is null)
- return;
-
- string? error;
-
- TrySendMoney(bankAccount, args.RecipientAccountId, args.Amount, out error);
- UpdateATMUserInterface((uid, atm), error);
- }
-
- [PublicAPI]
- public EconomyBankAccountComponent? FindAccountById(string id)
- {
- var accounts = GetAccounts();
- if (accounts.TryGetValue(id, out var comp))
- return comp;
-
- return null;
- }
-
- private void Withdraw(EconomyBankAccountComponent component, EconomyBankATMComponent atm, ulong sum)
- {
- component.Balance -= sum;
- var pos = Comp(atm.Owner).MapPosition;
- DropMoneyHandler(component.MoneyHolderEntId, sum, pos);
-
- component.Logs.Add(new(_gameTiming.CurTime, Loc.GetString("economybanksystem-log-withdraw",
- ("amount", sum), ("currencyName", component.AllowCurrency))));
-
- _entManager.Dirty(component);
- }
-
- [PublicAPI]
- public bool TryWithdraw(EconomyBankAccountComponent component, EconomyBankATMComponent atm, ulong sum, [NotNullWhen(false)] out string? errorMessage)
- {
- errorMessage = "";
- if (sum > 0 && component.Balance >= sum)
- {
- Withdraw(component, atm, sum);
- return true;
- }
- errorMessage = Loc.GetString("economybanksystem-transaction-error-notenoughmoney");
- return false;
- }
-
- [PublicAPI]
- public Entity DropMoneyHandler(EntProtoId entId, ulong amount, MapCoordinates pos)
- {
- var ent = Spawn(entId, pos);
-
- var moneyHolderComp = Comp(ent);
- moneyHolderComp.Balance = amount;
-
- _entManager.Dirty(moneyHolderComp);
-
- return (ent, moneyHolderComp);
- }
-
- private void SendMoney(IEconomyMoneyHolder fromAccount, EconomyBankAccountComponent toSend, ulong amount)
- {
- fromAccount.Balance -= amount;
- toSend.Balance += amount;
-
- string senderAccoutId = "UNEXPECTED";
- if (fromAccount is EconomyBankAccountComponent)
- {
- var fromAccountComponent = (fromAccount as EconomyBankAccountComponent)!;
- fromAccountComponent.Logs.Add(new(_gameTiming.CurTime, Loc.GetString("economybanksystem-log-send-to",
- ("amount", amount), ("currencyName", toSend.AllowCurrency), ("accountId", toSend.AccountId))));
-
- senderAccoutId = fromAccountComponent.AccountId;
- }
- toSend.Logs.Add(new(_gameTiming.CurTime, Loc.GetString("economybanksystem-log-send-from",
- ("amount", amount), ("currencyName", toSend.AllowCurrency), ("accountId", senderAccoutId))));
-
- _entManager.Dirty((fromAccount as Component)!);
- _entManager.Dirty(toSend);
- }
-
-/* TODO:
- public void AddLog(EconomyBankAccountComponent comp, )*/
-
- [PublicAPI]
- public bool TrySendMoney(IEconomyMoneyHolder fromAccount, EconomyBankAccountComponent? recipientAccount, ulong amount, [NotNullWhen(false)] out string? errorMessage)
- {
- errorMessage = null;
-
- if (fromAccount.Balance >= amount)
- {
- if (recipientAccount is not null)
- {
- if (fromAccount == recipientAccount)
- {
- errorMessage = "407";
- return false;
- }
- SendMoney(fromAccount, recipientAccount, amount);
- return true;
- }
-
- errorMessage = Loc.GetString("economybanksystem-transaction-error-notfoundaccout");
- return false;
- }
-
- errorMessage = Loc.GetString("economybanksystem-transaction-error-notenoughmoney");
- return false;
- }
-
- [PublicAPI]
- public bool TrySendMoney(IEconomyMoneyHolder fromAccount, string recipientAccountId, ulong amount, [NotNullWhen(false)] out string? errorMessage)
- {
- errorMessage = null;
-
- var recipientAccount = FindAccountById(recipientAccountId);
- if (recipientAccount is null)
- {
- errorMessage = Loc.GetString("economybanksystem-transaction-error-notfoundaccout", ("accountId", recipientAccountId));
- return false;
- }
-
- return TrySendMoney(fromAccount, recipientAccount, amount, out errorMessage);
- }
-
[PublicAPI]
public void UpdateATMUserInterface(Entity entity, string? error = null)
{
- var bankAccount = GetATMInsertedAccount(entity.Comp);
+ var card = GetATMInsertedAccount(entity.Comp);
+ EconomyBankAccount? bankAccount = null;
+ if (card is not null && _economyManager.TryGetAccount(card.AccountID, out var account))
+ bankAccount = account;
+
_userInterfaceSystem.SetUiState(entity.Owner, EconomyBankATMUiKey.Key, new EconomyBankATMUserInterfaceState()
{
BankAccount = bankAccount is null ? null :
new() {
Balance = bankAccount.Balance,
- AccountId = bankAccount.AccountId,
+ AccountId = bankAccount.AccountID,
AccountName = bankAccount.AccountName,
Blocked = bankAccount.Blocked,
},
@@ -282,39 +127,11 @@ public void UpdateTerminal(Entity entity, ulong am
_entManager.Dirty(entity);
}
-
- [PublicAPI]
- public Dictionary GetAccounts(EconomyBankAccountMask flag = EconomyBankAccountMask.Activated)
- {
- Dictionary list = new();
-
- var accountsEnum = AllEntityQuery();
- while (accountsEnum.MoveNext(out var comp))
- {
- switch (flag)
- {
- case EconomyBankAccountMask.Activated:
- if (comp.Activated)
- list.Add(comp.AccountId, comp);
- break;
- case EconomyBankAccountMask.ActivatedBlocked:
- if (comp.Activated && comp.Blocked)
- list.Add(comp.AccountId, comp);
- break;
- case EconomyBankAccountMask.ActivatedNotBlocked:
- if (comp.Activated && !comp.Blocked)
- list.Add(comp.AccountId, comp);
- break;
- }
- }
-
- return list;
- }
}
public enum EconomyBankAccountMask
{
- Activated,
- ActivatedBlocked,
- ActivatedNotBlocked,
+ All,
+ NotBlocked,
+ Blocked,
}
}
diff --git a/Content.Shared/AWS/Economy/IEconomyMoneyHolder.cs b/Content.Shared/AWS/Economy/IEconomyMoneyHolder.cs
index ecec51ca39e..3e706ce980c 100644
--- a/Content.Shared/AWS/Economy/IEconomyMoneyHolder.cs
+++ b/Content.Shared/AWS/Economy/IEconomyMoneyHolder.cs
@@ -1,5 +1,8 @@
namespace Content.Shared.AWS.Economy
{
+ ///
+ /// Interface for components that hold money. Not to ones that can carry a link to the account (like a card).
+ ///
public interface IEconomyMoneyHolder
{
public ulong Balance { get; set; }
diff --git a/Content.Shared/AWS/Economy/ISharedEconomyManager.cs b/Content.Shared/AWS/Economy/ISharedEconomyManager.cs
new file mode 100644
index 00000000000..4adcc8e2fa3
--- /dev/null
+++ b/Content.Shared/AWS/Economy/ISharedEconomyManager.cs
@@ -0,0 +1,26 @@
+using System.Diagnostics.CodeAnalysis;
+
+namespace Content.Shared.AWS.Economy;
+
+public interface ISharedEconomyManager
+{
+ ///
+ /// Checks if the account exists (valid).
+ ///
+ /// True if the account exists, false otherwise.
+ bool IsValidAccount(string accountID);
+
+ ///
+ /// Tries to get the account with the given ID.
+ ///
+ /// True if the fetching was successful, false otherwise.
+ bool TryGetAccount(string accountID, [NotNullWhen(true)] out EconomyBankAccount? account);
+
+ ///
+ /// Returns all currently existing accounts.
+ ///
+ /// Filter mask to fetch accounts.
+ IReadOnlyDictionary GetAccounts(EconomyBankAccountMask flag = EconomyBankAccountMask.NotBlocked);
+
+ void Initialize();
+}
\ No newline at end of file
diff --git a/Content.Shared/AWS/Economy/MsgEconomyAccountList.cs b/Content.Shared/AWS/Economy/MsgEconomyAccountList.cs
new file mode 100644
index 00000000000..c0c02f49414
--- /dev/null
+++ b/Content.Shared/AWS/Economy/MsgEconomyAccountList.cs
@@ -0,0 +1,81 @@
+using System.Collections.Frozen;
+using Lidgren.Network;
+using Robust.Shared.Network;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.AWS.Economy;
+
+public sealed class MsgEconomyAccountList : NetMessage
+{
+ public override MsgGroups MsgGroup => MsgGroups.Command;
+
+ public FrozenDictionary Accounts = default!;
+
+ public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
+ {
+ var dictionaryCount = buffer.ReadByte();
+ buffer.ReadPadBits();
+
+ Dictionary accounts = new();
+ for (var i = 0; i < dictionaryCount; i++)
+ {
+ var key = buffer.ReadString();
+
+ var id = buffer.ReadString();
+ var name = buffer.ReadString();
+ var currency = buffer.ReadString();
+ var balance = buffer.ReadUInt64();
+ var penalty = buffer.ReadUInt64();
+ var blocked = buffer.ReadBoolean();
+ var canReachPayday = buffer.ReadBoolean();
+
+ // read logs
+ var logsCount = buffer.ReadByte();
+ buffer.ReadPadBits();
+ List logs = new();
+ for (var j = 0; j < logsCount; j++)
+ {
+ var date = TimeSpan.FromTicks(buffer.ReadInt64());
+ var text = buffer.ReadString();
+ logs.Add(new EconomyBankAccountLogField(date, text));
+ }
+
+ // add entry to the dictionary
+ accounts.Add(key, new EconomyBankAccount(id, name, currency, balance, penalty, blocked, canReachPayday, logs));
+ }
+
+ Accounts = accounts.ToFrozenDictionary();
+ }
+
+ public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
+ {
+ // This shit is fucking nuts
+ buffer.Write((byte)Accounts.Count);
+ buffer.WritePadBits();
+
+ foreach (var (key, value) in Accounts)
+ {
+ buffer.Write(key);
+
+ buffer.Write(value.AccountID);
+ buffer.Write(value.AccountName);
+ buffer.Write(value.AllowedCurrency);
+ buffer.Write(value.Balance);
+ buffer.Write(value.Penalty);
+ buffer.Write(value.Blocked);
+ buffer.Write(value.CanReachPayDay);
+
+ // write logs
+ var logs = value.Logs;
+ buffer.Write((byte)logs.Count);
+ buffer.WritePadBits();
+ foreach (var log in logs)
+ {
+ buffer.Write(log.Date.Ticks);
+ buffer.Write(log.Text);
+ }
+ }
+ }
+
+ public override NetDeliveryMethod DeliveryMethod => NetDeliveryMethod.ReliableOrdered;
+}
\ No newline at end of file
diff --git a/Content.Shared/AWS/Economy/MsgEconomyAccountListRequest.cs b/Content.Shared/AWS/Economy/MsgEconomyAccountListRequest.cs
new file mode 100644
index 00000000000..7b61854834e
--- /dev/null
+++ b/Content.Shared/AWS/Economy/MsgEconomyAccountListRequest.cs
@@ -0,0 +1,22 @@
+using Lidgren.Network;
+using Robust.Shared.Network;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.AWS.Economy;
+
+public sealed class MsgEconomyAccountListRequest : NetMessage
+{
+ public override MsgGroups MsgGroup => MsgGroups.Command;
+
+ public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
+ {
+
+ }
+
+ public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
+ {
+
+ }
+
+ public override NetDeliveryMethod DeliveryMethod => NetDeliveryMethod.ReliableUnordered;
+}
\ No newline at end of file
diff --git a/Resources/Locale/ru-RU/aws/economy/logs.ftl b/Resources/Locale/ru-RU/aws/economy/logs.ftl
index 2db982e459a..bd5b9418de6 100644
--- a/Resources/Locale/ru-RU/aws/economy/logs.ftl
+++ b/Resources/Locale/ru-RU/aws/economy/logs.ftl
@@ -1,4 +1,5 @@
economybanksystem-log-withdraw = Снятие {$amount} {$currencyName}
+economybanksystem-log-insert = Пополнение на {$amount} {$currencyName}
economybanksystem-log-send-to = Перевод {$amount} {$currencyName} на {$accountId}
economybanksystem-log-send-from = Пополнение на {$amount} {$currencyName} с {$accountId}
economybanksystem-log-vending-buying = Покупка {$itemName}
diff --git a/Resources/Prototypes/AWS/Economy/nanotrasen_wallet.yml b/Resources/Prototypes/AWS/Economy/nanotrasen_wallet.yml
index 7313b58def1..2e5ebe2d65f 100644
--- a/Resources/Prototypes/AWS/Economy/nanotrasen_wallet.yml
+++ b/Resources/Prototypes/AWS/Economy/nanotrasen_wallet.yml
@@ -63,8 +63,8 @@
id: Nanotrasen
descriptior: "-"
prefix: "NT"
- strik: 1
- numbersPerStrik: 6
+ streak: 1
+ numbersPerStreak: 6
- type: entity
parent: BaseItem
@@ -82,10 +82,12 @@
heldPrefix: default
storedRotation: -90
- type: EconomyBankAccount
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 10000
+ accountSetup:
+ generateAccountID: true
+ allowedCurrency: Thaler
+ balance: 10000
# - type: entity
# parent: IDCardStandard
@@ -105,13 +107,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Command
- allowCurrency: Thaler
- accountName: Станция
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 10000
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Command
+ accountName: Станция
+ allowedCurrency: Thaler
+ balance: 10000
- type: entity
parent: BankAccountNanotrasen
@@ -120,13 +122,14 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Engineering
- allowCurrency: Thaler
- accountName: Инженерный отдел
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 1000
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Engineering
+ accountName: Инженерный отдел
+ allowedCurrency: Thaler
+ balance: 1000
+
- type: entity
parent: BankAccountNanotrasen
@@ -135,13 +138,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Service
- allowCurrency: Thaler
- accountName: Сервисный отдел
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 500
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Service
+ accountName: Сервисный отдел
+ allowedCurrency: Thaler
+ balance: 500
- type: entity
parent: BankAccountNanotrasen
@@ -150,13 +153,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Security
- allowCurrency: Thaler
- accountName: Служба безопасности
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 1000
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Security
+ allowedCurrency: Thaler
+ accountName: Служба безопасности
+ balance: 1000
- type: entity
parent: BankAccountNanotrasen
@@ -165,13 +168,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Medical
- allowCurrency: Thaler
- accountName: Медицинский отдел
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 900
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Medical
+ accountName: Медицинский отдел
+ allowedCurrency: Thaler
+ balance: 900
- type: entity
parent: BankAccountNanotrasen
@@ -180,13 +183,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Science
- allowCurrency: Thaler
- accountName: Научный отдел
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 1000
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Science
+ accountName: Научный отдел
+ allowedCurrency: Thaler
+ balance: 1000
- type: entity
parent: BankAccountNanotrasen
@@ -195,13 +198,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Cargo
- allowCurrency: Thaler
- accountName: Карго отдел
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 1000
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Cargo
+ accountName: Карго отдел
+ allowedCurrency: Thaler
+ balance: 1000
- type: entity
parent: BankAccountNanotrasen
@@ -211,13 +214,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-CentCom
- allowCurrency: Thaler
- accountName: Ценком
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 18446744073709524615
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-CentCom
+ accountName: Центком
+ allowedCurrency: Thaler
+ balance: 18446744073709524615
#Кассы
- type: entity
@@ -228,13 +231,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Service-B
- allowCurrency: Thaler
- accountName: Касса Бара
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 250
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Service-B
+ accountName: Касса Бара
+ allowedCurrency: Thaler
+ balance: 250
- type: entity
parent: BankAccountNanotrasen
@@ -244,13 +247,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Service-K
- allowCurrency: Thaler
- accountName: Касса Кухни
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 125
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Service-K
+ accountName: Касса Кухни
+ allowedCurrency: Thaler
+ balance: 125
- type: entity
parent: BankAccountNanotrasen
@@ -260,13 +263,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Service-H
- allowCurrency: Thaler
- accountName: Касса Гидропоники
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 125
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Service-H
+ accountName: Касса Гидропоники
+ allowedCurrency: Thaler
+ balance: 125
- type: entity
parent: BankAccountNanotrasen
@@ -276,13 +279,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Medical-C
- allowCurrency: Thaler
- accountName: Касса Химии
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 100
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Medical-C
+ accountName: Касса Химии
+ allowedCurrency: Thaler
+ balance: 100
- type: entity
parent: BankAccountNanotrasen
@@ -292,13 +295,13 @@
suffix: Economy
components:
- type: EconomyBankAccount
- accountId: NT-Medical-M
- allowCurrency: Thaler
- accountName: Касса Меда
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
- balance: 50
- activateOnSpawn: true
+ accountSetup:
+ accountID: NT-Medical-M
+ accountName: Касса Меда
+ allowedCurrency: Thaler
+ balance: 50
#Сейфы
- type: entity
diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
index 88f22982558..afd02c5bfbb 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
@@ -39,9 +39,10 @@
- type: PresetIdCard
job: Passenger
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: PassengerIDCard
@@ -51,9 +52,10 @@
- type: PresetIdCard
job: TechnicalAssistant
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: Sprite
layers:
- state: default
@@ -67,9 +69,10 @@
- type: PresetIdCard
job: MedicalIntern
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: Sprite
layers:
- state: default
@@ -83,9 +86,10 @@
- type: PresetIdCard
job: ResearchAssistant
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: Sprite
layers:
- state: default
@@ -99,9 +103,10 @@
- type: PresetIdCard
job: SecurityCadet
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: Sprite
layers:
- state: default
@@ -115,9 +120,10 @@
- type: PresetIdCard
job: ServiceWorker
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: Sprite
layers:
- state: default
@@ -144,9 +150,10 @@
- type: StealTarget
stealGroup: CaptainIDCard
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -160,25 +167,27 @@
- type: PresetIdCard
job: SecurityOfficer
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
id: WardenIDCard
name: warden ID card
components:
- - type: Sprite
- layers:
- - state: default
- - state: idwarden
- - type: PresetIdCard
- job: Warden
- - type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
- accountIdByProto: Nanotrasen
- moneyHolderEntId: ThalerHolder
+ - type: Sprite
+ layers:
+ - state: default
+ - state: idwarden
+ - type: PresetIdCard
+ job: Warden
+ - type: EconomyBankAccount #SS14RU
+ accountIdByProto: Nanotrasen
+ moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -192,9 +201,10 @@
- type: PresetIdCard
job: StationEngineer
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -208,9 +218,10 @@
- type: PresetIdCard
job: MedicalDoctor
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -224,9 +235,10 @@
- type: PresetIdCard
job: Paramedic
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -240,9 +252,10 @@
- type: PresetIdCard
job: Chemist
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -256,9 +269,10 @@
- type: PresetIdCard
job: CargoTechnician
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -272,27 +286,29 @@
- type: PresetIdCard
job: SalvageSpecialist
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
id: QuartermasterIDCard
name: quartermaster ID card
components:
- - type: Sprite
- layers:
- - state: silver
- - state: idquartermaster
- - type: Item
- heldPrefix: silver
- - type: PresetIdCard
- job: Quartermaster
- - type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
- accountIdByProto: Nanotrasen
- moneyHolderEntId: ThalerHolder
+ - type: Sprite
+ layers:
+ - state: silver
+ - state: idquartermaster
+ - type: Item
+ heldPrefix: silver
+ - type: PresetIdCard
+ job: Quartermaster
+ - type: EconomyBankAccount #SS14RU
+ accountIdByProto: Nanotrasen
+ moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -306,9 +322,10 @@
- type: PresetIdCard
job: Scientist
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -322,9 +339,10 @@
- type: PresetIdCard
job: Clown
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -338,25 +356,27 @@
- type: PresetIdCard
job: Mime
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
id: ChaplainIDCard
name: chaplain ID card
components:
- - type: Sprite
- layers:
- - state: default
- - state: idchaplain
- - type: PresetIdCard
- job: Chaplain
- - type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
- accountIdByProto: Nanotrasen
- moneyHolderEntId: ThalerHolder
+ - type: Sprite
+ layers:
+ - state: default
+ - state: idchaplain
+ - type: PresetIdCard
+ job: Chaplain
+ - type: EconomyBankAccount #SS14RU
+ accountIdByProto: Nanotrasen
+ moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -370,9 +390,10 @@
- type: PresetIdCard
job: Janitor
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -386,26 +407,28 @@
- type: PresetIdCard
job: Bartender
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
id: PunPunIDCard
name: pun pun ID card
components:
- - type: Sprite
- layers:
- - state: default
- - state: idbartender
- - type: PresetIdCard
- job: Bartender
- name: Pun Pun
- - type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
- accountIdByProto: Nanotrasen
- moneyHolderEntId: ThalerHolder
+ - type: Sprite
+ layers:
+ - state: default
+ - state: idbartender
+ - type: PresetIdCard
+ job: Bartender
+ name: Pun Pun
+ - type: EconomyBankAccount #SS14RU
+ accountIdByProto: Nanotrasen
+ moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -419,9 +442,10 @@
- type: PresetIdCard
job: Chef
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -435,9 +459,10 @@
- type: PresetIdCard
job: Botanist
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -451,9 +476,10 @@
- type: PresetIdCard
job: Librarian
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -467,9 +493,10 @@
- type: PresetIdCard
job: Lawyer
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -485,9 +512,10 @@
- type: PresetIdCard
job: HeadOfPersonnel
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -503,9 +531,10 @@
- type: PresetIdCard
job: ChiefEngineer
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -521,9 +550,10 @@
- type: PresetIdCard
job: ChiefMedicalOfficer
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -539,9 +569,10 @@
- type: PresetIdCard
job: ResearchDirector
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -557,9 +588,10 @@
- type: PresetIdCard
job: HeadOfSecurity
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -576,9 +608,10 @@
- type: PresetIdCard
job: Visitor
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -590,9 +623,10 @@
- state: default
- state: idbrigmedic
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -608,9 +642,10 @@
- type: PresetIdCard
job: CentralCommandOfficial
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -626,9 +661,10 @@
- type: Item
heldPrefix: gold
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -644,9 +680,10 @@
- type: Item
heldPrefix: blue
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -660,9 +697,10 @@
- type: PresetIdCard
job: ERTEngineer
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -676,9 +714,10 @@
- type: PresetIdCard
job: ERTJanitor
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -692,9 +731,10 @@
- type: PresetIdCard
job: ERTMedical
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -708,9 +748,10 @@
- type: PresetIdCard
job: ERTSecurity
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -724,9 +765,10 @@
- type: PresetIdCard
job: Musician
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -741,9 +783,10 @@
- type: PresetIdCard
job: DeathSquad
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
name: passenger ID card
@@ -817,9 +860,10 @@
- type: PresetIdCard
job: AtmosphericTechnician
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -859,9 +903,10 @@
- type: PresetIdCard
job: Psychologist
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -875,9 +920,10 @@
- type: PresetIdCard
job: Reporter
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -891,9 +937,10 @@
- type: PresetIdCard
job: Boxer
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -907,9 +954,10 @@
- type: PresetIdCard
job: Zookeeper
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard
@@ -923,9 +971,10 @@
- type: PresetIdCard
job: Detective
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: CentcomIDCard
@@ -941,9 +990,10 @@
- type: PresetIdCard
job: CBURN
- type: EconomyBankAccount #SS14RU
- allowCurrency: Thaler
accountIdByProto: Nanotrasen
moneyHolderEntId: ThalerHolder
+ accountSetup:
+ allowedCurrency: Thaler
- type: entity
parent: IDCardStandard