diff --git a/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/EconomyManagementConsoleBoundUserInterface.cs b/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/EconomyManagementConsoleBoundUserInterface.cs index 8d652e18c3..ff598699e6 100644 --- a/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/EconomyManagementConsoleBoundUserInterface.cs +++ b/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/EconomyManagementConsoleBoundUserInterface.cs @@ -41,42 +41,38 @@ protected override void UpdateState(BoundUserInterfaceState state) _menu?.UpdateState(consoleState); } - public void BlockAccountToggle(EconomyBankAccountComponent? account) + public void BlockAccountToggle(string accountId, bool blocked) { - if (account is null) - return; - - var blocked = !account.Blocked; - var msg = new EconomyManagementConsoleChangeParameterMessage(account.AccountID, EconomyBankAccountParam.Blocked, blocked); + var msg = new EconomyManagementConsoleChangeParameterMessage(accountId, EconomyBankAccountParam.Blocked, blocked); SendMessage(msg); } - public void ChangeName(EconomyBankAccountComponent? account, string newName) + public void ChangeName(string accountId, string newName) { // reeeee hardcoding - if (account is null || newName.Length > 40) + if (string.IsNullOrEmpty(accountId) || newName.Length > 40) return; - var msg = new EconomyManagementConsoleChangeParameterMessage(account.AccountID, EconomyBankAccountParam.AccountName, newName); + var msg = new EconomyManagementConsoleChangeParameterMessage(accountId, EconomyBankAccountParam.AccountName, newName); SendMessage(msg); } - public void ChangeJob(EconomyBankAccountComponent? account, string jobName) + public void ChangeJob(string accountId, string jobName) { - if (account is null) + if (string.IsNullOrEmpty(accountId)) return; - var msg = new EconomyManagementConsoleChangeParameterMessage(account.AccountID, EconomyBankAccountParam.JobName, jobName); + var msg = new EconomyManagementConsoleChangeParameterMessage(accountId, EconomyBankAccountParam.JobName, jobName); SendMessage(msg); } - public void ChangeSalary(EconomyBankAccountComponent? account, ulong salary) + public void ChangeSalary(string accountId, ulong salary) { - if (account is null) + if (string.IsNullOrEmpty(accountId)) return; - var msg = new EconomyManagementConsoleChangeParameterMessage(account.AccountID, EconomyBankAccountParam.Salary, salary); + var msg = new EconomyManagementConsoleChangeParameterMessage(accountId, EconomyBankAccountParam.Salary, salary); SendMessage(msg); } diff --git a/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/EconomyManagementConsoleMenu.xaml.cs b/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/EconomyManagementConsoleMenu.xaml.cs index b2e12e6efd..65527ef90e 100644 --- a/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/EconomyManagementConsoleMenu.xaml.cs +++ b/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/EconomyManagementConsoleMenu.xaml.cs @@ -60,16 +60,28 @@ public void UpdateState(EconomyManagementConsoleUserInterfaceState state) private void UpdateAccountManagement(EconomyManagementConsoleUserInterfaceState state) { + AccountManagementTab.ApplyConfiguration(state.DefaultJob, + state.SalaryButtonSteps, + state.AccountMask, + state.AccountTags, + state.AllowCentralCommandAccount, + state.AllowRestrictedAccounts); AccountManagementTab.Priveleged = state.Priveleged; AccountManagementTab.UpdateAccountList(); - AccountManagementTab.OnUpdateState(state.AccountID, state.AccountName, state.Balance, state.Penalty, state.Blocked, state.CanReachPayDay, state.JobName, state.Salary); + AccountManagementTab.OnUpdateState(state.AccountID, state.AccountName, state.Balance, state.Penalty, state.Blocked, state.CanReachPayDay, state.JobName, state.Salary, state.PayrollSalary, state.PayrollCanReachPayDay); } private void UpdateHolder(EconomyManagementConsoleUserInterfaceState state, Entity? holder) { + AccountHolderTab.ApplyConfiguration(state.DefaultJob, + state.SalaryButtonSteps, + state.AccountMask, + state.AccountTags, + state.AllowCentralCommandAccount, + state.AllowRestrictedAccounts); AccountHolderTab.CurrentCard = holder ?? null; AccountHolderTab.Priveleged = state.Priveleged; - AccountHolderTab.OnUpdateState(state.HolderID, state.AccountID, state.AccountName, state.Balance, state.Penalty, state.Blocked, state.CanReachPayDay, state.JobName, state.Salary); + AccountHolderTab.OnUpdateState(state.HolderID, state.AccountID, state.AccountName, state.Balance, state.Penalty, state.Blocked, state.CanReachPayDay, state.JobName, state.Salary, state.PayrollSalary, state.PayrollCanReachPayDay); } private void UpdateBonus(bool priveleged) diff --git a/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/Tabs/AccountHolderTab.xaml.cs b/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/Tabs/AccountHolderTab.xaml.cs index b57981a612..4cd33832e3 100644 --- a/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/Tabs/AccountHolderTab.xaml.cs +++ b/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/Tabs/AccountHolderTab.xaml.cs @@ -3,6 +3,8 @@ using Robust.Client.UserInterface; using Content.Shared.AWS.Economy.Bank; using Robust.Shared.Prototypes; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.Roles; using Robust.Client.UserInterface.Controls; @@ -12,21 +14,30 @@ namespace Content.Client.AWS.Economy.Bank.UI.ManagementConsole.Tabs; [GenerateTypedNameReferences] public sealed partial class AccountHolderTab : Control { - private EconomyBankAccountComponent? _currentAccount; + private string? _currentAccountId; [Dependency] private readonly EntityManager _entityManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private List _jobs = new(); - private static ProtoId _defaultJob = "Passenger"; + private readonly List _jobs = new(); + private static readonly ProtoId DefaultJobPrototype = "Passenger"; + private static readonly int[] DefaultSalaryButtons = { -10, -1, 1, 10 }; + private ProtoId _defaultJob = DefaultJobPrototype; + private EconomyBankAccountSystemShared _bankAccountSystem = default!; + private string _defaultJobName = string.Empty; + private int _defaultJobIndex = -1; + private EconomyBankAccountMask _accountMask = EconomyBankAccountMask.All; + private List? _accountTags; + private bool _allowCentralAccounts; + private bool _allowRestrictedAccounts; public Entity? CurrentCard; public bool Priveleged; - public Action? OnChangeNamePressed; - public Action? OnBlockAccountPressed; - public Action? OnChangeJob; - public Action? OnChangeSalary; + public Action? OnChangeNamePressed; + public Action? OnBlockAccountPressed; + public Action? OnChangeJob; + public Action? OnChangeSalary; public Action? OnChangeAccountPressed; public Action? OnInitializeAccountPressed; @@ -35,6 +46,9 @@ public AccountHolderTab() IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); + _bankAccountSystem = _entityManager.System(); + SetDefaultJob(null); + var jobs = _prototypeManager.EnumeratePrototypes().ToList(); jobs.Sort((x, y) => string.Compare(x.LocalizedName, y.LocalizedName, StringComparison.CurrentCulture)); foreach (var job in jobs) @@ -46,11 +60,8 @@ public AccountHolderTab() JobPresetOptionButton.AddItem(Loc.GetString(job.Name), _jobs.Count - 1); } - SalaryAmountBox.AddLeftButton(-10, "-10"); - SalaryAmountBox.AddLeftButton(-1, "-1"); - SalaryAmountBox.AddRightButton(1, "+1"); - SalaryAmountBox.AddRightButton(10, "+10"); - SalaryAmountBox.SetButtonDisabled(true); + UpdateDefaultJobIndex(); + ConfigureSalaryButtons(null); GetAccount(CurrentCard); @@ -58,50 +69,58 @@ public AccountHolderTab() ChangeNameButton.OnPressed += _ => { - if (_currentAccount is null) + if (_currentAccountId is null) return; - OnChangeNamePressed?.Invoke(_currentAccount, ChangeNamePrompt.Text); + OnChangeNamePressed?.Invoke(_currentAccountId, ChangeNamePrompt.Text); }; BlockButton.OnPressed += _ => { - if (_currentAccount is null) + if (_currentAccountId is null) return; - OnBlockAccountPressed?.Invoke(_currentAccount); + var blocked = TryGetCurrentAccount(out var account) && account.Blocked; + OnBlockAccountPressed?.Invoke(_currentAccountId, !blocked); }; JobPresetOptionButton.OnItemSelected += args => { args.Button.SelectId(args.Id); var bankAccountSystem = _entityManager.System(); - if (bankAccountSystem.TryGetSalaryJobEntry(_jobs[args.Id], "NanotrasenDefaultSallaries", out var jobEntry)) + if (bankAccountSystem.TryGetSalaryJobEntry(_jobs[args.Id], EconomyBankAccountSystemShared.DefaultSalariesPrototypeId, out var jobEntry)) SalaryAmountBox.Value = (int)jobEntry.Value.Sallary; }; ChangeSalaryInfoButton.OnPressed += _ => { - if (_currentAccount is null) + if (_currentAccountId is null || !TryGetCurrentAccount(out var account)) return; - var jobName = _currentAccount.JobName; - var salary = _currentAccount.Salary; + var jobName = account.JobName; + var salary = account.Salary; + var selectedJob = _jobs[JobPresetOptionButton.SelectedId]; if (JobPresetOptionButton.SelectedId != _jobs.IndexOf(jobName.GetValueOrDefault())) - OnChangeJob?.Invoke(_currentAccount, _jobs[JobPresetOptionButton.SelectedId]); + OnChangeJob?.Invoke(_currentAccountId, selectedJob); if (SalaryAmountBox.Value != (int)salary.GetValueOrDefault()) - OnChangeSalary?.Invoke(_currentAccount, (ulong)SalaryAmountBox.Value); + OnChangeSalary?.Invoke(_currentAccountId, (ulong)SalaryAmountBox.Value); }; ChangeAccountButton.OnPressed += _ => { if (CurrentCard is null) return; - var economySystem = _entityManager.System(); - if (!economySystem.IsValidAccount(ChangeAccountPrompt.Text)) + if (!_bankAccountSystem.TryGetAccount(ChangeAccountPrompt.Text, out var targetAccount)) { ErrorLabel.Text = Loc.GetString("economybanksystem-management-console-error-invalid-account"); return; } + if (!IsAccountAllowed(targetAccount.Value.Comp)) + { + ErrorLabel.Text = Loc.GetString("economybanksystem-management-console-error-protected-account"); + return; + } + + ErrorLabel.Text = string.Empty; var netEntity = _entityManager.GetNetEntity(CurrentCard.Value); OnChangeAccountPressed?.Invoke(netEntity, ChangeAccountPrompt.Text); }; @@ -115,18 +134,38 @@ public AccountHolderTab() }; } + public void ApplyConfiguration(ProtoId? defaultJob, + IReadOnlyList? salaryButtons, + EconomyBankAccountMask accountMask, + IReadOnlyList? accountTags, + bool allowCentralAccounts, + bool allowRestrictedAccounts) + { + _accountMask = accountMask; + _accountTags = accountTags is { Count: > 0 } tags ? new List(tags) : null; + _allowCentralAccounts = allowCentralAccounts; + _allowRestrictedAccounts = allowRestrictedAccounts; + + SetDefaultJob(defaultJob); + ConfigureSalaryButtons(salaryButtons); + + if (TryGetCurrentAccount(out var account)) + UpdateJobPreset(account, account.JobName); + else + UpdateJobPreset(null, null); + } + private void GetAccount(EconomyAccountHolderComponent? accountHolder) { - var economySystem = _entityManager.System(); - if (accountHolder is not null && economySystem.TryGetAccount(accountHolder.AccountID, out var accountEnt)) + if (accountHolder is not null && _bankAccountSystem.TryGetAccount(accountHolder.AccountID, out var accountEnt)) { - _currentAccount = accountEnt.Value.Comp; + _currentAccountId = accountEnt.Value.Comp.AccountID; FillAccount(accountEnt.Value.Comp); UpdateButtons(Priveleged); return; } - _currentAccount = null; + _currentAccountId = null; FillAccount(null); UpdateButtons(Priveleged); } @@ -146,25 +185,26 @@ private void FillAccount(EconomyBankAccountComponent? account) AccountBlockStatusLabel.Text = blocked; BlockButton.Text = blockedButton; var salary = account?.Salary ?? 0; - var paydayStatus = account is not null ? (account.CanReachPayDay ? Loc.GetString("economybanksystem-management-console-management-salary-reachable", ("salary", salary)) : Loc.GetString("economybanksystem-management-console-management-salary-not-reachable")) + var paydayStatus = account is not null ? (account.CanReachPayDay ? Loc.GetString("economybanksystem-management-console-management-salary-reachable", ("salary", salary)) : Loc.GetString("economybanksystem-management-console-management-salary-not-reachable", ("salary", salary))) : "-"; AccountPaydayStatusLabel.Text = paydayStatus; - JobPresetOptionButton.SelectId(GetJobIndex(account?.JobName)); + UpdateJobPreset(account, account?.JobName); SalaryAmountBox.Value = (int)salary; } private void UpdateButtons(bool priveleged) { - var noAccount = !priveleged || _currentAccount is null; + var noAccount = !priveleged || _currentAccountId is null; + var readOnly = TryGetCurrentAccount(out var account) && IsReadOnlyAccount(account); - ChangeNameButton.Disabled = noAccount; + ChangeNameButton.Disabled = noAccount || readOnly; BlockButton.Disabled = noAccount; - ChangeAccountButton.Disabled = !priveleged || CurrentCard is null; - InitializeAccountButton.Disabled = !priveleged || _currentAccount is not null || CurrentCard is null; - JobPresetOptionButton.Disabled = noAccount; - SalaryAmountBox.LineEditDisabled = noAccount; - SalaryAmountBox.SetButtonDisabled(noAccount); - ChangeSalaryInfoButton.Disabled = noAccount; + ChangeAccountButton.Disabled = !priveleged || CurrentCard is null || readOnly; + InitializeAccountButton.Disabled = !priveleged || _currentAccountId is not null || CurrentCard is null; + JobPresetOptionButton.Disabled = noAccount || readOnly; + SalaryAmountBox.LineEditDisabled = noAccount || readOnly; + SalaryAmountBox.SetButtonDisabled(noAccount || readOnly); + ChangeSalaryInfoButton.Disabled = noAccount || readOnly; } private void OnSalaryValueChanged(ValueChangedEventArgs args) @@ -175,10 +215,54 @@ private void OnSalaryValueChanged(ValueChangedEventArgs args) SalaryAmountBox.ValueChanged += OnSalaryValueChanged; } + private bool IsReadOnlyAccount(EconomyBankAccountComponent account) + { + if (_bankAccountSystem.IsCentralCommandAccount(account.AccountID)) + return true; + + return _bankAccountSystem.IsRestrictedDepartmentAccount(account); + } + + private string GetRestrictedJobText(EconomyBankAccountComponent account) + { + var key = _bankAccountSystem.IsDepartmentCashAccount(account) + ? "economybanksystem-management-console-management-job-placeholder-cash" + : "economybanksystem-management-console-management-job-placeholder-department"; + return Loc.GetString(key); + } + + private void UpdateJobPreset(EconomyBankAccountComponent? account, string? jobName) + { + if (_defaultJobIndex >= 0) + JobPresetOptionButton.SetItemText(_defaultJobIndex, _defaultJobName); + + if (account != null && IsReadOnlyAccount(account)) + { + if (_defaultJobIndex >= 0) + { + JobPresetOptionButton.SetItemText(_defaultJobIndex, GetRestrictedJobText(account)); + JobPresetOptionButton.SelectId(_defaultJobIndex); + } + return; + } + + JobPresetOptionButton.SelectId(GetJobIndex(jobName)); + } + private int GetJobIndex(string? jobName) { - var jobIndex = jobName is not null ? _jobs.IndexOf(jobName) : _jobs.IndexOf(_defaultJob); - return jobIndex < 0 ? _jobs.IndexOf(_defaultJob) : jobIndex; + if (jobName is not null) + { + var jobIndex = _jobs.IndexOf(jobName); + if (jobIndex >= 0) + return jobIndex; + } + + var defaultIndex = _jobs.IndexOf(_defaultJob); + if (defaultIndex >= 0) + return defaultIndex; + + return _jobs.Count > 0 ? 0 : -1; } public void OnUpdateState(string? holderID, @@ -189,23 +273,28 @@ public void OnUpdateState(string? holderID, bool? blocked, bool? canReachPayDay, string? jobName, - ulong? salary) + ulong? salary, + ulong? payrollSalary, + bool? payrollCanReach) { if (CurrentCard is null || holderID is null) { - _currentAccount = null; + _currentAccountId = null; FillAccount(null); UpdateButtons(Priveleged); return; } - if (holderID != accountID) + if (accountID is null || holderID != accountID) { - FillAccount(_currentAccount); + RefreshCurrentAccountDisplay(); UpdateButtons(Priveleged); return; } + _currentAccountId = accountID; + + var lookupAccountId = accountID; AccountInitLabel.Text = accountID is not null ? Loc.GetString("economybanksystem-management-console-management-initialized") : Loc.GetString("economybanksystem-management-console-management-not-initialized"); accountID ??= "-"; @@ -219,17 +308,116 @@ public void OnUpdateState(string? holderID, : "-"; AccountBlockStatusLabel.Text = accountBlocked; BlockButton.Text = blockedButton; - salary ??= 0; - var paydayStatus = canReachPayDay is not null ? (canReachPayDay.Value ? Loc.GetString("economybanksystem-management-console-management-salary-reachable", ("salary", salary)) : Loc.GetString("economybanksystem-management-console-management-salary-not-reachable")) + EconomyBankAccountComponent? accountComp = null; + if (lookupAccountId != null && _bankAccountSystem.TryGetAccount(lookupAccountId, out var foundAccount)) + accountComp = foundAccount.Value.Comp; + + var accountSalary = salary ?? 0; + var displaySalary = payrollSalary ?? accountSalary; + var displayReachable = payrollCanReach ?? canReachPayDay; + var paydayStatus = displayReachable is not null ? (displayReachable.Value ? Loc.GetString("economybanksystem-management-console-management-salary-reachable", ("salary", displaySalary)) : Loc.GetString("economybanksystem-management-console-management-salary-not-reachable", ("salary", displaySalary))) : "-"; AccountPaydayStatusLabel.Text = paydayStatus; - JobPresetOptionButton.SelectId(GetJobIndex(jobName)); - SalaryAmountBox.Value = (int)salary; + var salaryValue = accountComp is not null && IsReadOnlyAccount(accountComp) ? displaySalary : accountSalary; + SalaryAmountBox.Value = (int) salaryValue; - _currentAccount = null; - var economySystem = _entityManager.System(); - if (economySystem.TryGetAccount(accountID, out var foundAccount)) - _currentAccount = foundAccount.Value.Comp; + UpdateJobPreset(accountComp, jobName); UpdateButtons(Priveleged); } + + private void SetDefaultJob(ProtoId? job) + { + _defaultJob = job ?? DefaultJobPrototype; + if (_prototypeManager.TryIndex(_defaultJob, out var defaultJobPrototype)) + _defaultJobName = Loc.GetString(defaultJobPrototype.Name); + else + _defaultJobName = _defaultJob; + + UpdateDefaultJobIndex(); + } + + private void UpdateDefaultJobIndex() + { + _defaultJobIndex = GetJobIndex(null); + if (_defaultJobIndex < 0 && _jobs.Count > 0) + _defaultJobIndex = 0; + } + + private void ConfigureSalaryButtons(IReadOnlyList? buttonSteps) + { + var source = buttonSteps is { Count: > 0 } steps ? steps : DefaultSalaryButtons; + var leftButtons = new List(); + var rightButtons = new List(); + + foreach (var value in source) + { + if (value < 0) + leftButtons.Add(value); + else if (value > 0) + rightButtons.Add(value); + } + + if (leftButtons.Count == 0 && rightButtons.Count == 0) + { + foreach (var value in DefaultSalaryButtons) + { + if (value < 0) + leftButtons.Add(value); + else if (value > 0) + rightButtons.Add(value); + } + } + + SalaryAmountBox.SetButtons(leftButtons, rightButtons); + SalaryAmountBox.SetButtonDisabled(true); + } + + private void RefreshCurrentAccountDisplay() + { + if (_currentAccountId is null) + { + FillAccount(null); + return; + } + + if (_bankAccountSystem.TryGetAccount(_currentAccountId, out var account)) + { + FillAccount(account.Value.Comp); + return; + } + + _currentAccountId = null; + FillAccount(null); + } + + private bool TryGetCurrentAccount([NotNullWhen(true)] out EconomyBankAccountComponent? account) + { + account = null; + if (_currentAccountId is null) + return false; + + if (!_bankAccountSystem.TryGetAccount(_currentAccountId, out var foundAccount)) + return false; + + account = foundAccount.Value.Comp; + return true; + } + + private bool IsAccountAllowed(EconomyBankAccountComponent account) + { + if (!_allowCentralAccounts && _bankAccountSystem.IsCentralCommandAccount(account.AccountID)) + return false; + + if (!_allowRestrictedAccounts && _bankAccountSystem.IsRestrictedDepartmentAccount(account)) + return false; + + return _accountMask switch + { + EconomyBankAccountMask.All => true, + EconomyBankAccountMask.NotBlocked => !account.Blocked, + EconomyBankAccountMask.Blocked => account.Blocked, + EconomyBankAccountMask.ByTags => _accountTags != null && account.AccountTags.Any(_accountTags.Contains), + _ => true + }; + } } diff --git a/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/Tabs/AccountManagementTab.xaml.cs b/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/Tabs/AccountManagementTab.xaml.cs index a8e1ceef1b..58f338087f 100644 --- a/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/Tabs/AccountManagementTab.xaml.cs +++ b/Content.Client/AWS/Economy/Bank/UI/ManagementConsole/Tabs/AccountManagementTab.xaml.cs @@ -2,6 +2,8 @@ using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; using Robust.Client.UserInterface.Controls; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Robust.Client.UserInterface; using Robust.Shared.Prototypes; @@ -15,15 +17,24 @@ public sealed partial class AccountManagementTab : Control [Dependency] private readonly EntityManager _entityManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private IReadOnlyList> _accounts = default!; - private List _jobs = new(); - private static ProtoId _defaultJob = "Passenger"; - private EconomyBankAccountComponent? _currentAccount; - - public Action? OnBlockAccountPressed; - public Action? OnChangeNamePressed; - public Action? OnChangeJob; - public Action? OnChangeSalary; + private readonly List _accounts = new(); + private readonly List _jobs = new(); + private static readonly ProtoId DefaultJobPrototype = "Passenger"; + private static readonly int[] DefaultSalaryButtons = { -10, -1, 1, 10 }; + private ProtoId _defaultJob = DefaultJobPrototype; + private string? _currentAccountId; + private EconomyBankAccountSystemShared _bankAccountSystem = default!; + private string _defaultJobName = string.Empty; + private int _defaultJobIndex = -1; + private EconomyBankAccountMask _accountMask = EconomyBankAccountMask.All; + private List? _accountTags; + private bool _allowCentralAccounts; + private bool _allowRestrictedAccounts; + + public Action? OnBlockAccountPressed; + public Action? OnChangeNamePressed; + public Action? OnChangeJob; + public Action? OnChangeSalary; public bool Priveleged; @@ -32,6 +43,9 @@ public AccountManagementTab() IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); + _bankAccountSystem = _entityManager.System(); + SetDefaultJob(null); + var jobs = _prototypeManager.EnumeratePrototypes().ToList(); jobs.Sort((x, y) => string.Compare(x.LocalizedName, y.LocalizedName, StringComparison.CurrentCulture)); foreach (var job in jobs) @@ -43,11 +57,8 @@ public AccountManagementTab() JobPresetOptionButton.AddItem(Loc.GetString(job.Name), _jobs.Count - 1); } - SalaryAmountBox.AddLeftButton(-10, "-10"); - SalaryAmountBox.AddLeftButton(-1, "-1"); - SalaryAmountBox.AddRightButton(1, "+1"); - SalaryAmountBox.AddRightButton(10, "+10"); - SalaryAmountBox.SetButtonDisabled(true); + UpdateDefaultJobIndex(); + ConfigureSalaryButtons(null); UpdateAccountList(); @@ -56,17 +67,18 @@ public AccountManagementTab() BlockButton.OnPressed += _ => { - if (_currentAccount is null) + if (_currentAccountId is null) return; - OnBlockAccountPressed?.Invoke(_currentAccount); + var blocked = TryGetCurrentAccount(out var account) && account.Blocked; + OnBlockAccountPressed?.Invoke(_currentAccountId, !blocked); }; ChangeNameButton.OnPressed += _ => { - if (_currentAccount is null || ChangeNameBox.Text.Length <= 0) + if (_currentAccountId is null || ChangeNameBox.Text.Length <= 0) return; - OnChangeNamePressed?.Invoke(_currentAccount, ChangeNameBox.Text); + OnChangeNamePressed?.Invoke(_currentAccountId, ChangeNameBox.Text); ChangeNameBox.Clear(); }; JobPresetOptionButton.OnItemSelected += args => @@ -74,29 +86,57 @@ public AccountManagementTab() args.Button.SelectId(args.Id); var bankAccountSystem = _entityManager.System(); - if (bankAccountSystem.TryGetSalaryJobEntry(_jobs[args.Id], "NanotrasenDefaultSallaries", out var jobEntry)) + if (bankAccountSystem.TryGetSalaryJobEntry(_jobs[args.Id], EconomyBankAccountSystemShared.DefaultSalariesPrototypeId, out var jobEntry)) SalaryAmountBox.Value = (int)jobEntry.Value.Sallary; }; ChangeSalaryInfoButton.OnPressed += _ => { - if (_currentAccount is null) + if (_currentAccountId is null || !TryGetCurrentAccount(out var account)) return; - var jobName = _currentAccount.JobName; - var salary = _currentAccount.Salary; + var jobName = account.JobName; + var salary = account.Salary; + var selectedJob = _jobs[JobPresetOptionButton.SelectedId]; if (JobPresetOptionButton.SelectedId != _jobs.IndexOf(jobName.GetValueOrDefault())) - OnChangeJob?.Invoke(_currentAccount, _jobs[JobPresetOptionButton.SelectedId]); + OnChangeJob?.Invoke(_currentAccountId, selectedJob); if (SalaryAmountBox.Value != (int)salary.GetValueOrDefault()) - OnChangeSalary?.Invoke(_currentAccount, (ulong)SalaryAmountBox.Value); + OnChangeSalary?.Invoke(_currentAccountId, (ulong)SalaryAmountBox.Value); }; } + public void ApplyConfiguration(ProtoId? defaultJob, + IReadOnlyList? salaryButtons, + EconomyBankAccountMask accountMask, + IReadOnlyList? accountTags, + bool allowCentralAccounts, + bool allowRestrictedAccounts) + { + _accountMask = accountMask; + _accountTags = accountTags is { Count: > 0 } tags ? new List(tags) : null; + _allowCentralAccounts = allowCentralAccounts; + _allowRestrictedAccounts = allowRestrictedAccounts; + + SetDefaultJob(defaultJob); + ConfigureSalaryButtons(salaryButtons); + + if (TryGetCurrentAccount(out var account)) + UpdateJobPreset(account, account.JobName); + else + UpdateJobPreset(null, null); + } + public void UpdateAccountList() { AccountList.Clear(); - var bankAccountSystem = _entityManager.System(); - var accounts = bankAccountSystem.GetAccounts(EconomyBankAccountMask.All); - _accounts = accounts.Values.ToList(); + var accounts = _bankAccountSystem.GetAccounts(_accountMask, _accountTags); + _accounts.Clear(); + foreach (var (_, account) in accounts) + { + if (!IsAccountAllowed(account.Comp)) + continue; + + _accounts.Add(new AccountEntry(account.Comp.AccountID, FormFieldName(account.Comp))); + } FillList(); } @@ -108,15 +148,17 @@ public void OnUpdateState(string? accountID, bool? blocked, bool? canReachPayDay, string? jobName, - ulong? salary) + ulong? salary, + ulong? payrollSalary, + bool? payrollCanReach) { - if (accountID is null || _currentAccount?.AccountID != accountID) + if (accountID is null || _currentAccountId != accountID) { ClearCurrentAccount(); return; } - accountID ??= "-"; + var lookupAccountId = accountID; AccountIdLabel.Text = accountID; AccountOwnerLabel.Text = accountName ?? "-"; var accountBalance = balance is not null ? string.Format("{0:N0}", balance) : "-"; @@ -124,28 +166,38 @@ public void OnUpdateState(string? accountID, var accountBlocked = blocked is not null ? (blocked.Value ? Loc.GetString("economybanksystem-management-console-management-block") : Loc.GetString("economybanksystem-management-console-management-unblock")) : "-"; AccountBlockedLabel.Text = accountBlocked; - salary ??= 0; - AccountPaydayStatusLabel.Text = canReachPayDay is not null ? (canReachPayDay.Value ? Loc.GetString("economybanksystem-management-console-management-salary-reachable", ("salary", salary)) : Loc.GetString("economybanksystem-management-console-management-salary-not-reachable")) + EconomyBankAccountComponent? accountComp = null; + if (lookupAccountId != null && _bankAccountSystem.TryGetAccount(lookupAccountId, out var foundAccount)) + accountComp = foundAccount.Value.Comp; + + var accountSalary = salary ?? 0; + var displaySalary = payrollSalary ?? accountSalary; + var displayReachable = payrollCanReach ?? canReachPayDay; + AccountPaydayStatusLabel.Text = displayReachable is not null ? (displayReachable.Value ? Loc.GetString("economybanksystem-management-console-management-salary-reachable", ("salary", displaySalary)) : Loc.GetString("economybanksystem-management-console-management-salary-not-reachable", ("salary", displaySalary))) : "-"; var blockedButton = blocked is not null ? (blocked.Value ? Loc.GetString("economybanksystem-management-console-management-unblock-button") : Loc.GetString("economybanksystem-management-console-management-block-button")) : "-"; BlockButton.Text = blockedButton; - JobPresetOptionButton.SelectId(GetJobIndex(jobName)); - SalaryAmountBox.Value = (int)salary; + var salaryValue = accountComp is not null && IsReadOnlyAccount(accountComp) ? displaySalary : accountSalary; + SalaryAmountBox.Value = (int) salaryValue; - var economySystem = _entityManager.System(); - if (economySystem.TryGetAccount(accountID, out var foundAccount)) - _currentAccount = foundAccount.Value.Comp; + UpdateJobPreset(accountComp, jobName); UpdateButtons(Priveleged); } private void OnSelectAccount(ItemList.Item accountId) { - if (accountId.Metadata is not EconomyBankAccountComponent account) + if (accountId.Metadata is not string account) return; - _currentAccount = account; - FillAccountInfo(account); + _currentAccountId = account; + if (!TryGetCurrentAccount(out var accountComp)) + { + ClearCurrentAccount(); + return; + } + + FillAccountInfo(accountComp); UpdateButtons(Priveleged); } @@ -160,14 +212,13 @@ private void OnSalaryValueChanged(ValueChangedEventArgs args) private void OnTextEnteredAccount(LineEdit.LineEditEventArgs eventArgs) { AccountList.Clear(); - var upText = eventArgs.Text.ToUpper(); - foreach (var (key, value) in _accounts) + var search = eventArgs.Text; + foreach (var entry in _accounts) { - var fieldName = FormFieldName(value); - if (fieldName.Contains(upText)) + if (entry.DisplayName.Contains(search, StringComparison.CurrentCultureIgnoreCase)) { - var field = AccountList.AddItem(fieldName); - field.Metadata = value; + var field = AccountList.AddItem(entry.DisplayName); + field.Metadata = entry.AccountId; field.OnSelected += OnSelectAccount; } } @@ -181,10 +232,10 @@ private void OnTextEnteredAccount(LineEdit.LineEditEventArgs eventArgs) private void FillList() { - foreach (var (key, value) in _accounts) + foreach (var entry in _accounts) { - var field = AccountList.AddItem(FormFieldName(value)); - field.Metadata = value; + var field = AccountList.AddItem(entry.DisplayName); + field.Metadata = entry.AccountId; field.OnSelected += OnSelectAccount; } @@ -193,25 +244,70 @@ private void FillList() private string FormFieldName(EconomyBankAccountComponent account) { - return account.AccountID + " — " + account.AccountName; + return account.AccountID + " - " + account.AccountName; + } + + private bool IsReadOnlyAccount(EconomyBankAccountComponent account) + { + if (_bankAccountSystem.IsCentralCommandAccount(account.AccountID)) + return true; + + return _bankAccountSystem.IsRestrictedDepartmentAccount(account); + } + + private string GetRestrictedJobText(EconomyBankAccountComponent account) + { + var key = _bankAccountSystem.IsDepartmentCashAccount(account) + ? "economybanksystem-management-console-management-job-placeholder-cash" + : "economybanksystem-management-console-management-job-placeholder-department"; + return Loc.GetString(key); + } + + private void UpdateJobPreset(EconomyBankAccountComponent? account, string? jobName) + { + if (_defaultJobIndex >= 0) + JobPresetOptionButton.SetItemText(_defaultJobIndex, _defaultJobName); + + if (account != null && IsReadOnlyAccount(account)) + { + if (_defaultJobIndex >= 0) + { + JobPresetOptionButton.SetItemText(_defaultJobIndex, GetRestrictedJobText(account)); + JobPresetOptionButton.SelectId(_defaultJobIndex); + } + return; + } + + JobPresetOptionButton.SelectId(GetJobIndex(jobName)); } private int GetJobIndex(string? jobName) { - var jobIndex = jobName is not null ? _jobs.IndexOf(jobName) : _jobs.IndexOf(_defaultJob); - return jobIndex < 0 ? _jobs.IndexOf(_defaultJob) : jobIndex; + if (jobName is not null) + { + var jobIndex = _jobs.IndexOf(jobName); + if (jobIndex >= 0) + return jobIndex; + } + + var defaultIndex = _jobs.IndexOf(_defaultJob); + if (defaultIndex >= 0) + return defaultIndex; + + return _jobs.Count > 0 ? 0 : -1; } private void UpdateButtons(bool priveleged) { - var disabled = _currentAccount is null || !priveleged; + var disabled = _currentAccountId is null || !priveleged; + var readOnly = TryGetCurrentAccount(out var account) && IsReadOnlyAccount(account); BlockButton.Disabled = disabled; - ChangeNameButton.Disabled = disabled; - JobPresetOptionButton.Disabled = disabled; - SalaryAmountBox.LineEditDisabled = disabled; - SalaryAmountBox.SetButtonDisabled(disabled); - ChangeSalaryInfoButton.Disabled = disabled; + ChangeNameButton.Disabled = disabled || readOnly; + JobPresetOptionButton.Disabled = disabled || readOnly; + SalaryAmountBox.LineEditDisabled = disabled || readOnly; + SalaryAmountBox.SetButtonDisabled(disabled || readOnly); + ChangeSalaryInfoButton.Disabled = disabled || readOnly; } private void ClearCurrentAccount() @@ -224,7 +320,8 @@ private void ClearCurrentAccount() BlockButton.Text = "-"; SalaryAmountBox.Value = 0; - _currentAccount = null; + _currentAccountId = null; + UpdateJobPreset(null, null); UpdateButtons(Priveleged); } @@ -237,11 +334,99 @@ private void FillAccountInfo(EconomyBankAccountComponent account) AccountBlockedLabel.Text = account.Blocked ? Loc.GetString("economybanksystem-management-console-management-block") : Loc.GetString("economybanksystem-management-console-management-unblock"); var salary = account.Salary ?? 0; - AccountPaydayStatusLabel.Text = account.CanReachPayDay ? Loc.GetString("economybanksystem-management-console-management-salary-reachable", ("salary", salary)) : - Loc.GetString("economybanksystem-management-console-management-salary-not-reachable"); + var reachable = account.CanReachPayDay; + var readOnly = IsReadOnlyAccount(account); + if (readOnly && _bankAccountSystem.TryGetAssignedPayroll(account, out var payroll, out var payrollCanReach)) + { + salary = payroll; + reachable = payrollCanReach; + } + AccountPaydayStatusLabel.Text = reachable + ? Loc.GetString("economybanksystem-management-console-management-salary-reachable", ("salary", salary)) + : Loc.GetString("economybanksystem-management-console-management-salary-not-reachable", ("salary", salary)); BlockButton.Text = account.Blocked ? Loc.GetString("economybanksystem-management-console-management-unblock-button") : Loc.GetString("economybanksystem-management-console-management-block-button"); - JobPresetOptionButton.SelectId(GetJobIndex(account.JobName)); - SalaryAmountBox.Value = (int)salary; + UpdateJobPreset(account, account.JobName); + SalaryAmountBox.Value = (int) salary; + } + + private void SetDefaultJob(ProtoId? job) + { + _defaultJob = job ?? DefaultJobPrototype; + if (_prototypeManager.TryIndex(_defaultJob, out var defaultJobPrototype)) + _defaultJobName = Loc.GetString(defaultJobPrototype.Name); + else + _defaultJobName = _defaultJob; + + UpdateDefaultJobIndex(); + } + + private void UpdateDefaultJobIndex() + { + _defaultJobIndex = GetJobIndex(null); + if (_defaultJobIndex < 0 && _jobs.Count > 0) + _defaultJobIndex = 0; + } + + private void ConfigureSalaryButtons(IReadOnlyList? buttonSteps) + { + var source = buttonSteps is { Count: > 0 } steps ? steps : DefaultSalaryButtons; + var leftButtons = new List(); + var rightButtons = new List(); + + foreach (var value in source) + { + if (value < 0) + leftButtons.Add(value); + else if (value > 0) + rightButtons.Add(value); + } + + if (leftButtons.Count == 0 && rightButtons.Count == 0) + { + foreach (var value in DefaultSalaryButtons) + { + if (value < 0) + leftButtons.Add(value); + else if (value > 0) + rightButtons.Add(value); + } + } + + SalaryAmountBox.SetButtons(leftButtons, rightButtons); + SalaryAmountBox.SetButtonDisabled(true); + } + + private bool TryGetCurrentAccount([NotNullWhen(true)] out EconomyBankAccountComponent? account) + { + account = null; + if (_currentAccountId is null) + return false; + + if (!_bankAccountSystem.TryGetAccount(_currentAccountId, out var foundAccount)) + return false; + + account = foundAccount.Value.Comp; + return true; + } + + private readonly record struct AccountEntry(string AccountId, string DisplayName); + + private bool IsAccountAllowed(EconomyBankAccountComponent account) + { + if (!_allowCentralAccounts && _bankAccountSystem.IsCentralCommandAccount(account.AccountID)) + return false; + + if (!_allowRestrictedAccounts && _bankAccountSystem.IsRestrictedDepartmentAccount(account)) + return false; + + return _accountMask switch + { + EconomyBankAccountMask.All => true, + EconomyBankAccountMask.NotBlocked => !account.Blocked, + EconomyBankAccountMask.Blocked => account.Blocked, + EconomyBankAccountMask.ByTags => _accountTags != null && account.AccountTags.Any(_accountTags.Contains), + _ => true + }; } } diff --git a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs index 2a8b88d526..17efea133b 100644 --- a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs +++ b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs @@ -4,7 +4,6 @@ using Robust.Client.UserInterface; using Robust.Shared.Input; using System.Linq; -using Content.Shared.Emag.Components; namespace Content.Client.VendingMachines { @@ -81,20 +80,6 @@ protected override void Dispose(bool disposing) _menu.Dispose(); } - //SS14-RU - private VendingMachineInventoryEntry? GetEntry(EntityUid uid, VendingMachineComponent component) - { - string selectedId = component.SelectedItemId!; - if (component.SelectedItemInventoryType == InventoryType.Emagged && EntMan.HasComponent(uid)) - return component.EmaggedInventory.GetValueOrDefault(selectedId); - - if (component.SelectedItemInventoryType == InventoryType.Contraband && component.Contraband) - return component.ContrabandInventory.GetValueOrDefault(selectedId); - - return component.Inventory.GetValueOrDefault(selectedId); - } - //SS14-RU - private void OnSearchChanged(string? filter) { _menu?.Populate(_cachedInventory); diff --git a/Content.Server/AWS/Economy/Bank/EconomyBankAccountSystem.cs b/Content.Server/AWS/Economy/Bank/EconomyBankAccountSystem.cs index d6e97fe48b..e14ee3e5a2 100644 --- a/Content.Server/AWS/Economy/Bank/EconomyBankAccountSystem.cs +++ b/Content.Server/AWS/Economy/Bank/EconomyBankAccountSystem.cs @@ -14,6 +14,7 @@ using Content.Server.Access.Components; using JetBrains.Annotations; using Robust.Server.GameObjects; +using Robust.Shared.GameObjects; using Robust.Shared.Map; using Robust.Shared.Timing; using System.Diagnostics.CodeAnalysis; @@ -27,13 +28,13 @@ using System.Security.Principal; using Robust.Shared; using Content.Server.GameTicking; -using Content.Shared.Mind.Components; -using Content.Shared.Mind; -using Content.Shared.Roles.Jobs; using Robust.Shared.Toolshed.TypeParsers; using System; using System.Collections.ObjectModel; using Content.Shared.NameIdentifier; +using Robust.Shared.Log; +using Content.Server.Roles.Jobs; +using Robust.Server.Player; namespace Content.Server.AWS.Economy.Bank { @@ -52,6 +53,10 @@ public sealed class EconomyBankAccountSystem : EconomyBankAccountSystemShared [Dependency] private readonly MetaDataSystem _metaDataSystem = default!; [Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!; + private static readonly TimeSpan ManagementConsoleActionCooldown = TimeSpan.FromSeconds(0.5); + private readonly Dictionary _consoleCooldowns = new(); + private ISawmill _sawmill = default!; + private double _salaryMultiplier = 1.0; public double SalaryMultiplier => _salaryMultiplier; @@ -59,7 +64,8 @@ public sealed class EconomyBankAccountSystem : EconomyBankAccountSystemShared #pragma warning disable RA0028 public override void Initialize() { - SubscribeLocalEvent(OnAccountComponentInit); + _sawmill = Logger.GetSawmill("economy.accounts"); + SubscribeLocalEvent(OnAccountComponentMapInit); SubscribeLocalEvent(OnBankComponentRemove); SubscribeLocalEvent(OnTerminalInteracted); @@ -156,9 +162,15 @@ public bool TryCreateAccount(string accountID, /// Enables a card or a bank account (described in setup) for usage. /// [PublicAPI] - public bool TryActivate(Entity entity, [NotNullWhen(true)] out Entity? activatedAccount) + public bool TryActivate(Entity entity, + [NotNullWhen(true)] out Entity? activatedAccount, + bool skipIfIdCard = false) { activatedAccount = null; + + if (skipIfIdCard && HasComp(entity.Owner)) + return false; + if (!_prototypeManager.TryIndex(entity.Comp.AccountIdByProto, out EconomyAccountIdPrototype? proto)) return false; @@ -198,7 +210,7 @@ presetIdCardComponent.JobName is { } job && accountName = accountSetup.AccountName ?? accountName; balance = accountSetup.Balance ?? balance; - TryCreateAccount( + var created = TryCreateAccount( accountID, accountName, accountSetup.AllowedCurrency ?? "Thaler", @@ -212,6 +224,16 @@ presetIdCardComponent.JobName is { } job && cords, out var account); + if (created) + { + var holderName = MetaData(entity.Owner).EntityName; + var stationTag = station?.ToString() ?? "null"; + var salaryText = salary?.ToString() ?? "null"; + _sawmill.Info( + $"Created account '{accountID}' ('{accountName}') for holder '{holderName}' ({entity.Owner}). " + + $"Job={jobName?.ToString() ?? "null"}, Balance={balance}, Salary={salaryText}, Station={stationTag}, Coords={cords}."); + } + activatedAccount = account; entity.Comp.AccountID = accountID; entity.Comp.AccountName = accountName; @@ -230,10 +252,13 @@ public bool TrySetAccountParameter(string accountID, EconomyBankAccountParam par if (!TryGetAccount(accountID, out var entity)) return false; - if (accountID == "NT-CentCom") + if (IsCentralCommandAccount(accountID)) return false; var account = entity.Value.Comp; + if (IsRestrictedDepartmentAccount(account) && param != EconomyBankAccountParam.Blocked) + return false; + switch (param) { case EconomyBankAccountParam.AccountName: @@ -641,13 +666,13 @@ private string GenerateAccountId(string prefix, uint strik, uint numbersPerStrik return res; } - private void OnAccountComponentInit(Entity entity, ref ComponentInit args) + private void OnAccountComponentMapInit(Entity entity, ref MapInitEvent args) { // if has id card comp, then it will be initialized in the other place. - if (entity.Comp.AccountSetup is null || HasComp(entity)) + if (entity.Comp.AccountSetup is null || HasComp(entity.Owner)) return; - TryActivate(entity, out _); + TryActivate(entity, out _, skipIfIdCard: true); } private void OnBankComponentRemove(Entity entity, ref ComponentRemove args) @@ -773,7 +798,7 @@ private void OnTerminalInteracted(EntityUid uid, EconomyBankTerminalComponent co if (TryComp(uid, out var machineComponent)) { vendingMachineComponent = machineComponent; - if (!TryBuildVendingPurchaseReason(uid, machineComponent, out purchaseReason, out var vendingError)) + if (!TryBuildVendingPurchaseReason(uid, component, machineComponent, out purchaseReason, out var vendingError)) { var error = vendingError ?? Loc.GetString("economyBankTerminal-component-vending-error"); _popupSystem.PopupEntity(error, uid, type: PopupType.MediumCaution); @@ -808,7 +833,7 @@ private void OnTerminalInteracted(EntityUid uid, EconomyBankTerminalComponent co if (vendingMachineComponent is not null) { - if (!TryTransactionFromVendingMachine(uid, args.User, vendingMachineComponent, out _)) + if (!TryTransactionFromVendingMachine(uid, args.User, component, vendingMachineComponent, out _)) { Withdraw(receiverAccount.Value.Comp.AccountID, uid, amount); var error = Loc.GetString("economyBankTerminal-component-vending-error"); @@ -831,18 +856,20 @@ private void TriggerVendingPaymentFailEffect(EntityUid uid, VendingMachineCompon //SS14RU - end - private bool TryBuildVendingPurchaseReason(EntityUid uid, VendingMachineComponent vendingMachine, [NotNullWhen(true)] out string? reason, out string? error) + private bool TryBuildVendingPurchaseReason(EntityUid uid, EconomyBankTerminalComponent terminal, + VendingMachineComponent vendingMachine, [NotNullWhen(true)] out string? reason, out string? error) { reason = null; error = null; - if (vendingMachine.SelectedItemId is not { } selectedItemId) + if (terminal.PendingItemId is not { } selectedItemId) { error = Loc.GetString("economyBankTerminal-component-vending-error"); return false; } - if (!vendingMachine.Inventory.TryGetValue(selectedItemId, out var entry) || entry.Price <= 0) + var entry = GetPendingEntry(uid, terminal, vendingMachine); + if (entry == null || entry.Price <= 0) { error = Loc.GetString("economyBankTerminal-component-vending-error"); return false; @@ -868,23 +895,47 @@ private bool TryBuildVendingPurchaseReason(EntityUid uid, VendingMachineComponen return true; } - private bool TryTransactionFromVendingMachine(EntityUid uid, EntityUid user, VendingMachineComponent vendingMachine, [NotNullWhen(true)] out string? itemName) + private bool TryTransactionFromVendingMachine(EntityUid uid, EntityUid user, EconomyBankTerminalComponent terminal, + VendingMachineComponent vendingMachine, [NotNullWhen(true)] out string? itemName) { itemName = null; - if (vendingMachine.SelectedItemId is not { } selectedItemID) + if (terminal.PendingItemId is not { } selectedItemID) return false; - if (!vendingMachine.Inventory.TryGetValue(selectedItemID, out var entry) || entry.Price <= 0) + var entry = GetPendingEntry(uid, terminal, vendingMachine); + if (entry == null || entry.Price <= 0) return false; - itemName = vendingMachine.SelectedItemId; - vendingMachine.SelectedItemId = null; - _vendingMachine.AuthorizedVend(uid, user, vendingMachine.SelectedItemInventoryType, selectedItemID, vendingMachine); + itemName = selectedItemID; + var inventoryType = terminal.PendingInventoryType; + terminal.PendingItemId = null; + terminal.PendingInventoryType = InventoryType.Regular; + _vendingMachine.AuthorizedVend(uid, user, inventoryType, selectedItemID, vendingMachine); return !vendingMachine.Denying; } + private VendingMachineInventoryEntry? GetPendingEntry(EntityUid uid, EconomyBankTerminalComponent terminal, + VendingMachineComponent vendingMachine) + { + var selectedItemId = terminal.PendingItemId; + if (selectedItemId == null) + return null; + + return terminal.PendingInventoryType switch + { + InventoryType.Emagged when HasComp(uid) => + vendingMachine.EmaggedInventory.GetValueOrDefault(selectedItemId), + InventoryType.Contraband when vendingMachine.Contraband => + vendingMachine.ContrabandInventory.GetValueOrDefault(selectedItemId), + _ => vendingMachine.Inventory.GetValueOrDefault(selectedItemId) + }; + } + private void OnManagementConsoleChangeHolderIDMessage(Entity ent, ref EconomyManagementConsoleChangeHolderIDMessage args) { + if (!TryThrottleManagementConsole(ent.Owner)) + return; + if (!TryComp(ent, out var accessReader) || ent.Comp.CardSlot.Item is not { } idCard) return; @@ -900,6 +951,9 @@ private void OnManagementConsoleChangeHolderIDMessage(Entity ent, ref EconomyManagementConsoleInitAccountOnHolderMessage args) { + if (!TryThrottleManagementConsole(ent.Owner)) + return; + if (!TryComp(ent, out var accessReader) || ent.Comp.CardSlot.Item is not { } idCard) return; @@ -929,6 +986,9 @@ private void OnManagementConsoleInitAccountOnHolderMessage(Entity ent, ref EconomyManagementConsoleChangeParameterMessage args) { + if (!TryThrottleManagementConsole(ent.Owner)) + return; + if (!TryComp(ent, out var accessReader) || ent.Comp.CardSlot.Item is not { } idCard) return; @@ -939,12 +999,18 @@ private void OnManagementConsoleParameterMessage(Entity ent, ref EconomyManagementConsolePayBonusMessage args) { + if (!TryThrottleManagementConsole(ent.Owner)) + return; + // Check for priveleges if (!TryComp(ent, out var accessReader) || ent.Comp.CardSlot.Item is not { } idCard) return; @@ -956,6 +1022,9 @@ private void OnManagementConsolePayBonusMessage(Entity { BankAccountTag.Personal }); var accountList = args.Accounts; var intersectedAccounts = accounts.Where(account => accountList.Contains(account.Value.Comp.AccountID)).GetEnumerator(); @@ -968,6 +1037,9 @@ private void OnManagementConsolePayBonusMessage(Entity ent, + EconomyBankAccountComponent? bankAccount, + EconomyManagementConsoleUserInterfaceState state) + { + base.AdjustManagementConsoleState(ent, bankAccount, state); + + if (bankAccount is null) + return; + + if (!IsRestrictedDepartmentAccount(bankAccount)) + return; + + if (!TryGetAssignedPayroll(bankAccount, out var payroll, out var canReach)) + return; + + state.PayrollSalary = payroll; + state.PayrollCanReachPayDay = canReach; + } + + private bool TryThrottleManagementConsole(EntityUid console) + { + var curTime = _gameTiming.CurTime; + + if (_consoleCooldowns.TryGetValue(console, out var nextAvailable) && nextAvailable > curTime) + return false; + + _consoleCooldowns[console] = curTime + ManagementConsoleActionCooldown; + return true; + } + [PublicAPI] private EconomySallaryInfo? PaySalaries(ProtoId salaryProto, EconomyPayDayRuleType type = EconomyPayDayRuleType.Adding) diff --git a/Content.Server/AWS/Economy/Bank/EconomyBankVendingSystem.cs b/Content.Server/AWS/Economy/Bank/EconomyBankVendingSystem.cs index fb45496c9e..d48a76a830 100644 --- a/Content.Server/AWS/Economy/Bank/EconomyBankVendingSystem.cs +++ b/Content.Server/AWS/Economy/Bank/EconomyBankVendingSystem.cs @@ -55,8 +55,8 @@ private void OnVendingSelect(EntityUid uid, VendingMachineComponent component, V entry.Price, Loc.GetString("economyBankTerminal-component-vending-reason", ("itemName", itemName))); - component.SelectedItemInventoryType = args.Type; - component.SelectedItemId = args.ID; + terminal.PendingItemId = args.ID; + terminal.PendingInventoryType = args.Type; args.Handled = true; } diff --git a/Content.Server/AWS/Gravity/AwsGravityGeneratorFieldSystem.cs b/Content.Server/AWS/Gravity/AwsGravityGeneratorFieldSystem.cs index b479aafe6d..e930b5f3e3 100644 --- a/Content.Server/AWS/Gravity/AwsGravityGeneratorFieldSystem.cs +++ b/Content.Server/AWS/Gravity/AwsGravityGeneratorFieldSystem.cs @@ -159,7 +159,6 @@ private bool TryGetParentGrid(EntityUid uid, out EntityUid gridUid) private void ApplyGridEffects(EntityUid gridUid, GridGravityWellComponent well) { UpdateGridMass(gridUid, well); - Dirty(gridUid, well); } private void UpdateGridMass(EntityUid gridUid, GridGravityWellComponent well) diff --git a/Content.Server/Station/Systems/StationSpawningSystem.cs b/Content.Server/Station/Systems/StationSpawningSystem.cs index d5389a8acd..55583b76d4 100644 --- a/Content.Server/Station/Systems/StationSpawningSystem.cs +++ b/Content.Server/Station/Systems/StationSpawningSystem.cs @@ -1,5 +1,8 @@ +using Content.Server._Lavaland.Procedural.Components; +using Content.Server.Access.Components; using Content.Server.Access.Systems; using Content.Server.DetailExaminable; +using Content.Server.GameTicking; using Content.Server.Humanoid; using Content.Server.IdentityManagement; using Content.Server.Mind.Commands; @@ -24,6 +27,7 @@ using Content.Shared.Station; using JetBrains.Annotations; using Robust.Shared.Configuration; +using Robust.Shared.GameObjects; using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -51,6 +55,8 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem [Dependency] private readonly MetaDataSystem _metaSystem = default!; [Dependency] private readonly InternalEncryptionKeySpawner _internalEncryption = default!; [Dependency] private readonly EconomyBankAccountSystem _bankAccountSystem = default!; + [Dependency] private readonly StationSystem _stationSystem = default!; + [Dependency] private readonly GameTicker _gameTicker = default!; private bool _randomizeCharacters; @@ -213,11 +219,52 @@ public void SetPdaAndIdCardData(EntityUid entity, string characterName, JobProto if (pdaComponent != null) _pdaSystem.SetOwner(idUid.Value, pdaComponent, entity, characterName); + //IH - Start + var preset = EnsureComp(cardId); + preset.JobName = jobPrototype.ID; - // SS14RU if (TryComp(cardId, out var economyAccountHolder)) - _bankAccountSystem.TryActivate((cardId, economyAccountHolder), out _); - // SS14RU + { + economyAccountHolder.AccountName = characterName; + Dirty(cardId, economyAccountHolder); + + if (ShouldAssignBankAccount(entity, station)) + _bankAccountSystem.TryActivate((cardId, economyAccountHolder), out _); + } + } + + private bool ShouldAssignBankAccount(EntityUid entity, EntityUid? station, TransformComponent? xform = null) + { + if (!Resolve(entity, ref xform, logMissing: false)) + return false; + + if (station != null && IsEligibleMainStation(station.Value)) + return true; + + if (xform.GridUid is EntityUid grid && HasComp(grid)) + return true; + + var defaultMap = _gameTicker.DefaultMap; + if (defaultMap == MapId.Nullspace) + return false; + + var mainStation = _stationSystem.GetStationInMap(defaultMap); + if (mainStation == null) + return false; + + var owningStation = _stationSystem.GetOwningStation(entity, xform); + return owningStation == mainStation; + } + + private bool IsEligibleMainStation(EntityUid station) + { + var defaultMap = _gameTicker.DefaultMap; + if (defaultMap == MapId.Nullspace) + return false; + + var mainStation = _stationSystem.GetStationInMap(defaultMap); + return mainStation == station; + //IH - end } diff --git a/Content.Server/VendingMachines/VendingMachineSystem.cs b/Content.Server/VendingMachines/VendingMachineSystem.cs index 86e823cf31..fb63c7a908 100644 --- a/Content.Server/VendingMachines/VendingMachineSystem.cs +++ b/Content.Server/VendingMachines/VendingMachineSystem.cs @@ -1,15 +1,16 @@ -//SS14RU - start using System; using System.Collections.Generic; -//SS14RU - end using System.Linq; using System.Numerics; +using Content.Server._Lavaland.Procedural.Components; using Content.Server.Advertise; using Content.Server.Advertise.Components; using Content.Server.Cargo.Systems; using Content.Server.Emp; +using Content.Server.GameTicking; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; +using Content.Server.Station.Systems; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Actions; @@ -19,14 +20,10 @@ using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.Emp; -//SS14RU - start using Content.Shared.Cargo.Prototypes; -//SS14RU - end using Content.Shared.Popups; using Content.Shared.Power; -//SS14RU - start using Content.Shared.Storage.Components; -//SS14RU - end using Content.Shared.Throwing; using Content.Shared.UserInterface; using Content.Shared.VendingMachines; @@ -35,6 +32,7 @@ using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Robust.Shared.Map; using Robust.Shared.Timing; namespace Content.Server.VendingMachines @@ -52,6 +50,8 @@ public sealed class VendingMachineSystem : SharedVendingMachineSystem [Dependency] private readonly SharedPointLightSystem _light = default!; [Dependency] private readonly EmagSystem _emag = default!; + [Dependency] private readonly StationSystem _stations = default!; + [Dependency] private readonly GameTicker _ticker = default!; private const float WallVendEjectDistanceFromWall = 1f; @@ -81,15 +81,22 @@ public override void Initialize() SubscribeLocalEvent(OnPriceCalculation); } - //SS14RU - start + //IH - start protected override void RecalculateEntriesPrice(EntityUid uid, VendingMachineComponent component) { + if (!component.PriceEligible) + { + if (ResetInventoryPrices(component)) + Dirty(uid, component); + return; + } + base.RecalculateEntriesPrice(uid, component); var ev = new VendingMachineRecalculatePriceEvent(uid, component); RaiseLocalEvent(uid, ev); } - //SS14RU - end + //IH - end private void OnSelectMessage(EntityUid uid, VendingMachineComponent component, VendingMachineSelectMessage args) { @@ -110,8 +117,17 @@ private void OnSelectMessage(EntityUid uid, VendingMachineComponent component, V protected override void OnMapInit(EntityUid uid, VendingMachineComponent component, MapInitEvent args) { + //IH - Start + var eligible = HasPriceEligibility(uid); + var changed = component.PriceEligible != eligible; + component.PriceEligible = eligible; + //IH - End base.OnMapInit(uid, component, args); + //IH - Start + if (changed) + Dirty(uid, component); + //IH - End if (HasComp(uid)) { TryUpdateVisualState(uid, component); @@ -120,6 +136,10 @@ protected override void OnMapInit(EntityUid uid, VendingMachineComponent compone private void OnVendingPrice(EntityUid uid, VendingMachineComponent component, ref PriceCalculationEvent args) { + //IH - Start + if (!component.PriceEligible) + return; + //IH - End var price = 0.0; foreach (var entry in component.Inventory.Values) @@ -601,5 +621,50 @@ private void OnPriceCalculation(EntityUid uid, VendingMachineRestockComponent co args.Price += priceSets.Max(); } + //IH - Start + private static bool ResetInventoryPrices(VendingMachineComponent component) + { + var dirty = false; + dirty |= ResetInventoryPrices(component.Inventory); + dirty |= ResetInventoryPrices(component.EmaggedInventory); + dirty |= ResetInventoryPrices(component.ContrabandInventory); + return dirty; + } + + private static bool ResetInventoryPrices(Dictionary inventory) + { + var dirty = false; + foreach (var entry in inventory.Values) + { + if (entry.Price == 0) + continue; + + entry.Price = 0; + dirty = true; + } + + return dirty; + } + + private bool HasPriceEligibility(EntityUid uid, TransformComponent? xform = null) + { + if (!Resolve(uid, ref xform, logMissing:false)) + return false; + + if (xform.GridUid is EntityUid gridUid && HasComp(gridUid)) + return true; + + var defaultMap = _ticker.DefaultMap; + if (defaultMap == MapId.Nullspace) + return false; + + var mainStation = _stations.GetStationInMap(defaultMap); + if (mainStation == null) + return false; + + var owningStation = _stations.GetOwningStation(uid, xform); + return owningStation == mainStation; + } + //IH - End } } diff --git a/Content.Shared/AWS/Economy/Bank/BankAccountTag.cs b/Content.Shared/AWS/Economy/Bank/BankAccountTag.cs index d0a46e0aea..0edb4b9f77 100644 --- a/Content.Shared/AWS/Economy/Bank/BankAccountTag.cs +++ b/Content.Shared/AWS/Economy/Bank/BankAccountTag.cs @@ -7,5 +7,6 @@ public enum BankAccountTag { Department, Station, - Personal + Personal, + CashRegister } diff --git a/Content.Shared/AWS/Economy/Bank/EconomyBankAccountComponent.cs b/Content.Shared/AWS/Economy/Bank/EconomyBankAccountComponent.cs index 7f9b6160f2..f4987ba961 100644 --- a/Content.Shared/AWS/Economy/Bank/EconomyBankAccountComponent.cs +++ b/Content.Shared/AWS/Economy/Bank/EconomyBankAccountComponent.cs @@ -55,6 +55,7 @@ public sealed partial class EconomyBankAccountComponent : Component [ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] public List AccountTags = new(); + } [Serializable, NetSerializable] diff --git a/Content.Shared/AWS/Economy/Bank/EconomyBankAccountSystemShared.cs b/Content.Shared/AWS/Economy/Bank/EconomyBankAccountSystemShared.cs index e18862a32a..6e763981c1 100644 --- a/Content.Shared/AWS/Economy/Bank/EconomyBankAccountSystemShared.cs +++ b/Content.Shared/AWS/Economy/Bank/EconomyBankAccountSystemShared.cs @@ -16,6 +16,7 @@ using Content.Shared.Movement.Pulling.Components; using Content.Shared.Mind.Components; using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; namespace Content.Shared.AWS.Economy.Bank { @@ -30,6 +31,8 @@ public class EconomyBankAccountSystemShared : EntitySystem [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private const int MaxAtmHistoryEntries = 10; + public const string CentralCommandAccountId = "NT-CentCom"; + public const string DefaultSalariesPrototypeId = "NanotrasenDefaultSallaries"; private EntityQuery _containerQuery; private bool _containerQueryInitialized; @@ -56,6 +59,7 @@ public override void Initialize() SubscribeLocalEvent(OnManagementConsoleRemove); SubscribeLocalEvent(OnManagementConsoleSlotChanged); SubscribeLocalEvent(OnManagementConsoleEntRemoved); + SubscribeLocalEvent(OnManagementConsoleBoundUiOpened); } /// @@ -115,6 +119,89 @@ public IReadOnlyDictionary> GetAccou return result; } + [PublicAPI] + public bool IsCentralCommandAccount(string accountID) + { + return accountID == CentralCommandAccountId; + } + + [PublicAPI] + public bool IsDepartmentCashAccount(EconomyBankAccountComponent account) + { + return account.AccountTags.Contains(BankAccountTag.CashRegister); + } + + [PublicAPI] + public bool IsDepartmentAccount(EconomyBankAccountComponent account) + { + if (!account.AccountTags.Contains(BankAccountTag.Department)) + return false; + + if (account.AccountTags.Contains(BankAccountTag.Personal)) + return false; + + return !IsDepartmentCashAccount(account); + } + + [PublicAPI] + public bool IsRestrictedDepartmentAccount(EconomyBankAccountComponent account) + { + return IsDepartmentAccount(account) || IsDepartmentCashAccount(account); + } + + protected bool IsAccountAllowedForConsole(EconomyManagementConsoleComponent console, EconomyBankAccountComponent account) + { + if (!console.AllowCentralCommandAccount && IsCentralCommandAccount(account.AccountID)) + return false; + + if (!console.AllowRestrictedAccounts && IsRestrictedDepartmentAccount(account)) + return false; + + return console.AllowedAccountMask switch + { + EconomyBankAccountMask.All => true, + EconomyBankAccountMask.NotBlocked => !account.Blocked, + EconomyBankAccountMask.Blocked => account.Blocked, + EconomyBankAccountMask.ByTags => console.AllowedAccountTags != null && account.AccountTags.Any(console.AllowedAccountTags.Contains), + _ => true + }; + } + + protected virtual void AdjustManagementConsoleState(Entity ent, + EconomyBankAccountComponent? bankAccount, + EconomyManagementConsoleUserInterfaceState state) + { + } + + [PublicAPI] + public bool TryGetAssignedPayroll(EconomyBankAccountComponent account, out ulong payroll, out bool canReach) + { + payroll = 0; + canReach = false; + + var accounts = GetAccounts(EconomyBankAccountMask.All); + var found = false; + foreach (var (_, entity) in accounts) + { + var comp = entity.Comp; + if (comp.JobName is not { } jobId) + continue; + + if (!TryGetSalaryJobEntry(jobId, DefaultSalariesPrototypeId, out var jobEntry)) + continue; + + if (jobEntry.Value.AccountId != account.AccountID) + continue; + + var salary = comp.Salary ?? jobEntry.Value.Sallary; + payroll += salary; + found = true; + } + + canReach = payroll == 0 || account.Balance >= payroll; + return found || payroll == 0; + } + /// /// Returns JobEntry from salaries prototype. /// @@ -327,6 +414,21 @@ private void OnManagementConsoleEntRemoved(Entity ent, ref BoundUIOpenedEvent args) + { + if (args.UiKey is not EconomyManagementConsoleUiKey.Key) + return; + + EconomyBankAccountComponent? account = null; + if (TryComp(ent.Comp.TargetCardSlot.Item, out EconomyAccountHolderComponent? holder) && + TryGetAccount(holder.AccountID, out var accountEnt)) + { + account = accountEnt.Value.Comp; + } + + UpdateManagementConsoleUserInterface(ent, account); + } + [PublicAPI] public (bool, string?, Entity?) GetManagementConsoleInsertedCardsStateInfo(Entity ent) { @@ -352,6 +454,9 @@ private void OnManagementConsoleEntRemoved(Entity ent, EconomyBankAccountComponent? bankAccount) { + if (bankAccount is not null && !IsAccountAllowedForConsole(ent.Comp, bankAccount)) + bankAccount = null; + var stateInfo = GetManagementConsoleInsertedCardsStateInfo(ent); var netHolder = GetNetEntity(stateInfo.Item3); var uiState = new EconomyManagementConsoleUserInterfaceState() @@ -360,6 +465,12 @@ public void UpdateManagementConsoleUserInterface(Entity(ent.Comp.SalaryButtonSteps), + AccountMask = ent.Comp.AllowedAccountMask, + AccountTags = ent.Comp.AllowedAccountTags != null ? new List(ent.Comp.AllowedAccountTags) : null, + AllowCentralCommandAccount = ent.Comp.AllowCentralCommandAccount, + AllowRestrictedAccounts = ent.Comp.AllowRestrictedAccounts, AccountID = bankAccount?.AccountID, AccountName = bankAccount?.AccountName, Balance = bankAccount?.Balance, @@ -369,6 +480,8 @@ public void UpdateManagementConsoleUserInterface(Entity + /// Stores data about the selected vending item while the terminal processes the purchase. + /// + [ViewVariables(VVAccess.ReadWrite)] + public string? PendingItemId; + + [ViewVariables(VVAccess.ReadWrite)] + public InventoryType PendingInventoryType = InventoryType.Regular; } } diff --git a/Content.Shared/AWS/Economy/Bank/EconomyManagementConsoleComponent.cs b/Content.Shared/AWS/Economy/Bank/EconomyManagementConsoleComponent.cs index a99f63d931..2c8cda47a6 100644 --- a/Content.Shared/AWS/Economy/Bank/EconomyManagementConsoleComponent.cs +++ b/Content.Shared/AWS/Economy/Bank/EconomyManagementConsoleComponent.cs @@ -1,6 +1,9 @@ using Content.Shared.Containers.ItemSlots; +using Content.Shared.Roles; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; +using System.Collections.Generic; namespace Content.Shared.AWS.Economy.Bank; @@ -15,6 +18,24 @@ public sealed partial class EconomyManagementConsoleComponent : Component [DataField("targetCardSlot"), AutoNetworkedField] public ItemSlot TargetCardSlot = new(); + + [DataField("defaultJob")] + public ProtoId DefaultJob = "Passenger"; + + [DataField("salaryButtonSteps")] + public List SalaryButtonSteps { get; set; } = new() { -10, -1, 1, 10 }; + + [DataField("allowCentralCommandAccount")] + public bool AllowCentralCommandAccount = false; + + [DataField("allowRestrictedAccounts")] + public bool AllowRestrictedAccounts = false; + + [DataField("allowedAccountMask")] + public EconomyBankAccountMask AllowedAccountMask = EconomyBankAccountMask.All; + + [DataField("allowedAccountTags")] + public List? AllowedAccountTags; } [Serializable, NetSerializable] diff --git a/Content.Shared/AWS/Economy/Bank/EconomyManagementConsoleMessages.cs b/Content.Shared/AWS/Economy/Bank/EconomyManagementConsoleMessages.cs index ee1b7ba70e..17cf18a357 100644 --- a/Content.Shared/AWS/Economy/Bank/EconomyManagementConsoleMessages.cs +++ b/Content.Shared/AWS/Economy/Bank/EconomyManagementConsoleMessages.cs @@ -1,4 +1,7 @@ +using Content.Shared.Roles; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; +using System.Collections.Generic; namespace Content.Shared.AWS.Economy.Bank; @@ -30,6 +33,12 @@ public sealed class EconomyManagementConsoleUserInterfaceState : BoundUserInterf public string? IDCardName; public NetEntity? AccountHolder; public string? HolderID; + public ProtoId? DefaultJob; + public List? SalaryButtonSteps; + public EconomyBankAccountMask AccountMask = EconomyBankAccountMask.All; + public List? AccountTags; + public bool AllowCentralCommandAccount; + public bool AllowRestrictedAccounts; // Account that has been selected when performing the last action (this is kinda dumb yeah) public string? AccountID; @@ -40,6 +49,8 @@ public sealed class EconomyManagementConsoleUserInterfaceState : BoundUserInterf public bool? CanReachPayDay; public string? JobName; public ulong? Salary; + public ulong? PayrollSalary; + public bool? PayrollCanReachPayDay; } [Serializable, NetSerializable] diff --git a/Content.Shared/VendingMachines/VendingMachineComponent.cs b/Content.Shared/VendingMachines/VendingMachineComponent.cs index 507dfd4d01..904989518b 100644 --- a/Content.Shared/VendingMachines/VendingMachineComponent.cs +++ b/Content.Shared/VendingMachines/VendingMachineComponent.cs @@ -55,6 +55,12 @@ public sealed partial class VendingMachineComponent : Component public bool Broken; + /// + /// IH: фиксирует, можно ли вычислять цену вендинга (например, для продажи). + /// + [DataField, AutoNetworkedField] + public bool PriceEligible; + /// /// When true, will forcefully throw any object it dispenses /// @@ -206,14 +212,6 @@ public sealed partial class VendingMachineComponent : Component public bool LoopDenyAnimation = true; #endregion - /// - /// SS14RU - /// - public string? SelectedItemId; - /// - /// SS14RU - /// - public InventoryType SelectedItemInventoryType; } [Serializable, NetSerializable] diff --git a/Resources/Locale/ru-RU/aws/economy/accountmanagement.ftl b/Resources/Locale/ru-RU/aws/economy/accountmanagement.ftl index d39ac637e4..5bd986ada6 100644 --- a/Resources/Locale/ru-RU/aws/economy/accountmanagement.ftl +++ b/Resources/Locale/ru-RU/aws/economy/accountmanagement.ftl @@ -5,11 +5,13 @@ economybanksystem-management-console-management-block = Заблокирован economybanksystem-management-console-management-unblock = Разблокирован economybanksystem-management-console-management-salary = Зарплата economybanksystem-management-console-management-salary-reachable = Возможна ({$salary}) -economybanksystem-management-console-management-salary-not-reachable = Невозможна +economybanksystem-management-console-management-salary-not-reachable = Невозможна ({$salary}) economybanksystem-management-console-management-initialized-title = Счёт на носителе economybanksystem-management-console-management-initialized = Действителен economybanksystem-management-console-management-not-initialized = Не действителен economybanksystem-management-console-management-job-preset = Должность +economybanksystem-management-console-management-job-placeholder-department = Счёт отдела +economybanksystem-management-console-management-job-placeholder-cash = Касса отдела economybanksystem-management-console-bonus-payer-account = Счёт выплаты economybanksystem-management-console-bonus-total-bonus = Итого к выплате economybanksystem-management-console-bonus-percent = Множитель премии, % @@ -29,7 +31,8 @@ economybanksystem-management-console-bonus-pay-button = Выплатить пр economybanksystem-management-console-bonus-clear-selected-button = Очистить выбранные счета economybanksystem-management-console-error-invalid-account = Счёт не найден! +economybanksystem-management-console-error-protected-account = Этот счёт нельзя использовать на консоли economybanksystem-management-console-management-tab = Управление счетами economybanksystem-management-console-account-holder-tab = Счёт целевой карты -economybanksystem-management-console-bonus-tab = Выдача премий \ No newline at end of file +economybanksystem-management-console-bonus-tab = Выдача премий diff --git a/Resources/Prototypes/AWS/Economy/console.yml b/Resources/Prototypes/AWS/Economy/console.yml index 252d6b74b8..30ecb820a2 100644 --- a/Resources/Prototypes/AWS/Economy/console.yml +++ b/Resources/Prototypes/AWS/Economy/console.yml @@ -52,6 +52,9 @@ suffix: Economy components: - type: EconomyManagementConsole + defaultJob: Passenger + allowCentralCommandAccount: false + allowRestrictedAccounts: true cardSlot: ejectSound: /Audio/Machines/id_swipe.ogg insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg diff --git a/Resources/Prototypes/AWS/Economy/nanotrasen_wallet.yml b/Resources/Prototypes/AWS/Economy/nanotrasen_wallet.yml index b571889097..815e9ae03e 100644 --- a/Resources/Prototypes/AWS/Economy/nanotrasen_wallet.yml +++ b/Resources/Prototypes/AWS/Economy/nanotrasen_wallet.yml @@ -338,6 +338,7 @@ balance: 250 accountTags: - Department + - CashRegister - type: entity parent: BankAccountNanotrasen @@ -365,6 +366,7 @@ balance: 125 accountTags: - Department + - CashRegister - type: entity parent: BankAccountNanotrasen @@ -392,6 +394,7 @@ balance: 125 accountTags: - Department + - CashRegister - type: entity parent: BankAccountNanotrasen @@ -419,6 +422,7 @@ balance: 100 accountTags: - Department + - CashRegister - type: entity parent: BankAccountNanotrasen @@ -446,6 +450,7 @@ balance: 50 accountTags: - Department + - CashRegister #Сейфы - type: entity