Files
OldThink/Content.Server/_White/Economy/BankCardSystem.cs

228 lines
7.4 KiB
C#

using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Access.Systems;
using Content.Server.Cargo.Components;
using Content.Server.Cargo.Systems;
using Content.Server.CartridgeLoader;
using Content.Server.Chat.Systems;
using Content.Server.GameTicking;
using Content.Server.Roles.Jobs;
using Content.Server.Station.Systems;
using Content.Shared.CartridgeLoader;
using Content.Shared.GameTicking;
using Content.Shared.Inventory;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared._White.Economy;
using Robust.Server.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server._White.Economy;
public sealed class BankCardSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly CargoSystem _cargo = default!;
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly BankCartridgeSystem _bankCartridge = default!;
[Dependency] private readonly JobSystem _job = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly CartridgeLoaderSystem _cartridgeLoader = default!;
private const int SalaryDelay = 1200;
private SalaryPrototype _salaries = default!;
private readonly List<BankAccount> _accounts = new();
private float _salaryTimer;
public override void Initialize()
{
_salaries = _protoMan.Index<SalaryPrototype>("Salaries");
SubscribeLocalEvent<BankCardComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(OnPlayerSpawned);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
if (_gameTicker.RunLevel != GameRunLevel.InRound)
{
_salaryTimer = 0f;
return;
}
_salaryTimer += frameTime;
if (_salaryTimer <= SalaryDelay)
return;
_salaryTimer = 0f;
PaySalary();
}
private void PaySalary()
{
foreach (var account in _accounts.Where(account =>
account.Mind is {Comp.UserId: not null, Comp.CurrentEntity: not null} &&
_playerManager.TryGetSessionById(account.Mind.Value.Comp.UserId!.Value, out _) &&
!_mobState.IsDead(account.Mind.Value.Comp.CurrentEntity!.Value)))
{
account.Balance += GetSalary(account.Mind);
}
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString("salary-pay-announcement"),
colorOverride: Color.FromHex("#18abf5"));
}
private int GetSalary(EntityUid? mind)
{
if (!_job.MindTryGetJob(mind, out _, out var job) || !_salaries.Salaries.TryGetValue(job.ID, out var salary))
return 0;
return salary;
}
private void OnStartup(EntityUid uid, BankCardComponent component, ComponentStartup args)
{
if (component.CommandBudgetCard &&
TryComp(_station.GetOwningStation(uid), out StationBankAccountComponent? acc))
{
component.AccountId = acc.BankAccount.AccountId;
return;
}
if (component.AccountId.HasValue)
{
CreateAccount(component.AccountId.Value, component.StartingBalance);
return;
}
var account = CreateAccount(default, component.StartingBalance);
component.AccountId = account.AccountId;
}
private void OnRoundRestart(RoundRestartCleanupEvent ev)
{
_accounts.Clear();
}
private void OnPlayerSpawned(PlayerSpawnCompleteEvent ev)
{
if (_idCardSystem.TryFindIdCard(ev.Mob, out var id) && TryComp<MindContainerComponent>(ev.Mob, out var mind))
{
var cardEntity = id.Owner;
var bankCardComponent = EnsureComp<BankCardComponent>(cardEntity);
if (!bankCardComponent.AccountId.HasValue || !TryGetAccount(bankCardComponent.AccountId.Value, out var bankAccount))
return;
if (!TryComp(mind.Mind, out MindComponent? mindComponent))
return;
bankAccount.Balance = GetSalary(mind.Mind) + 100;
mindComponent.AddMemory(new Memory("PIN", bankAccount.AccountPin.ToString()));
mindComponent.AddMemory(new Memory(Loc.GetString("character-info-memories-account-number"),
bankAccount.AccountId.ToString()));
bankAccount.Mind = (mind.Mind.Value, mindComponent);
bankAccount.Name = Name(ev.Mob);
if (!_inventorySystem.TryGetSlotEntity(ev.Mob, "id", out var pdaUid))
return;
BankCartridgeComponent? comp = null;
var programs = _cartridgeLoader.GetInstalled(pdaUid.Value);
var program = programs.ToList().Find(program => TryComp(program, out comp));
if (comp == null)
return;
bankAccount.CartridgeUid = program;
comp.AccountId = bankAccount.AccountId;
}
}
public BankAccount CreateAccount(int accountId = default, int startingBalance = 0)
{
if (TryGetAccount(accountId, out var acc))
return acc;
BankAccount account;
if (accountId == default)
{
int accountNumber;
do
{
accountNumber = _random.Next(100000, 999999);
} while (AccountExist(accountId));
account = new BankAccount(accountNumber, startingBalance);
}
else
{
account = new BankAccount(accountId, startingBalance);
}
_accounts.Add(account);
return account;
}
public bool AccountExist(int accountId)
{
return _accounts.Any(x => x.AccountId == accountId);
}
public bool TryGetAccount(int accountId, [NotNullWhen(true)] out BankAccount? account)
{
account = _accounts.FirstOrDefault(x => x.AccountId == accountId);
return account != null;
}
public int GetBalance(int accountId)
{
if (TryGetAccount(accountId, out var account))
{
return account.Balance;
}
return 0;
}
public bool TryChangeBalance(int accountId, int amount)
{
if (!TryGetAccount(accountId, out var account) || account.Balance + amount < 0)
return false;
if (account.CommandBudgetAccount)
{
while (AllEntityQuery<StationBankAccountComponent>().MoveNext(out var uid, out var acc))
{
if (acc.BankAccount.AccountId != accountId)
continue;
_cargo.UpdateBankAccount(uid, acc, amount);
return true;
}
}
account.Balance += amount;
if (account.CartridgeUid != null)
_bankCartridge.UpdateUiState(account.CartridgeUid.Value);
return true;
}
}