_menu = this.CreateWindow<FundingAllocationMenu>();
- _menu.OnSavePressed += d =>
+ _menu.OnSavePressed += (dicts, primary, lockbox) =>
{
- SendMessage(new SetFundingAllocationBuiMessage(d));
+ SendMessage(new SetFundingAllocationBuiMessage(dicts, primary, lockbox));
};
}
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
- Title="{Loc 'cargo-funding-alloc-console-menu-title'}"
- SetSize="680 310"
- MinSize="680 310">
+ Title="{Loc 'cargo-funding-alloc-console-menu-title'}">
<BoxContainer Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True"
Margin="10 5 10 10">
- <Label Name="HelpLabel" HorizontalAlignment="Center" StyleClasses="LabelSubText"/>
- <Control MinHeight="10"/>
+ <controls:TableContainer Columns="2" HorizontalExpand="True" VerticalExpand="True">
+ <RichTextLabel Name="PrimaryCutLabel" Text="{Loc 'cargo-funding-alloc-console-label-primary-cut'}"/>
+ <SpinBox Name="PrimaryCut"/>
+ <RichTextLabel Name="LockboxCutLabel" Text="{Loc 'cargo-funding-alloc-console-label-lockbox-cut'}"/>
+ <SpinBox Name="LockboxCut"/>
+ </controls:TableContainer>
+ <Label Name="HelpLabel" HorizontalAlignment="Center" StyleClasses="LabelSubText" Margin="0 10"/>
<PanelContainer VerticalExpand="True" HorizontalExpand="True" VerticalAlignment="Top" MaxHeight="250">
<PanelContainer.PanelOverride>
<graphics:StyleBoxFlat BackgroundColor="#1B1B1E"/>
+using System.Collections.Generic;
using System.Linq;
using Content.Client.Message;
using Content.Client.UserInterface.Controls;
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Prototypes;
+using Content.Shared.CCVar;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
[GenerateTypedNameReferences]
public sealed partial class FundingAllocationMenu : FancyWindow
{
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private readonly EntityQuery<StationBankAccountComponent> _bankQuery;
- public event Action<Dictionary<ProtoId<CargoAccountPrototype>, int>>? OnSavePressed;
+ public event Action<Dictionary<ProtoId<CargoAccountPrototype>, int>, double, double>? OnSavePressed;
private EntityUid? _station;
+ private bool _allowPrimaryAccountAllocation;
+ private bool _allowPrimaryCutAdjustment;
+ private bool _lockboxCutEnabled;
+
+ private double _primaryCut;
+ private double _lockboxCut;
private readonly HashSet<Control> _addedControls = new();
private readonly List<SpinBox> _spinBoxes = new();
_bankQuery = _entityManager.GetEntityQuery<StationBankAccountComponent>();
+ PrimaryCut.ValueChanged += args =>
+ {
+ _primaryCut = (double)args.Value / 100.0;
+ UpdateButtonDisabled();
+ };
+
+ LockboxCut.ValueChanged += args =>
+ {
+ _lockboxCut = 1.0 - (double)args.Value / 100.0;
+ UpdateButtonDisabled();
+ };
+
SaveButton.OnPressed += _ =>
{
if (!_entityManager.TryGetComponent<StationBankAccountComponent>(_station, out var bank))
return;
- var accounts = bank.Accounts.Keys.OrderBy(p => p.Id).ToList();
+ var accounts = EditableAccounts(bank).OrderBy(p => p.Key).Select(p => p.Key).ToList();
var dicts = new Dictionary<ProtoId<CargoAccountPrototype>, int>();
for (var i = 0; i< accounts.Count; i++)
{
dicts.Add(accounts[i], _spinBoxes[i].Value);
}
- OnSavePressed?.Invoke(dicts);
+ OnSavePressed?.Invoke(dicts, _primaryCut, _lockboxCut);
SaveButton.Disabled = true;
};
+ _cfg.OnValueChanged(CCVars.AllowPrimaryAccountAllocation, enabled => { _allowPrimaryAccountAllocation = enabled; }, true);
+ _cfg.OnValueChanged(CCVars.AllowPrimaryCutAdjustment, enabled => { _allowPrimaryCutAdjustment = enabled; }, true);
+ _cfg.OnValueChanged(CCVars.LockboxCutEnabled, enabled => { _lockboxCutEnabled = enabled; }, true);
+
BuildEntries();
}
+ private IEnumerable<KeyValuePair<ProtoId<CargoAccountPrototype>, int>> EditableAccounts(StationBankAccountComponent bank)
+ {
+ foreach (var kvp in bank.Accounts)
+ {
+ if (_allowPrimaryAccountAllocation || kvp.Key != bank.PrimaryAccount)
+ {
+ yield return kvp;
+ }
+ }
+ }
+
private void BuildEntries()
{
if (!_entityManager.TryGetComponent<StationBankAccountComponent>(_station, out var bank))
return;
- HelpLabel.Text = Loc.GetString("cargo-funding-alloc-console-label-help",
- ("percent", (int) (bank.PrimaryCut * 100)));
+
+ if (_allowPrimaryCutAdjustment)
+ {
+ HelpLabel.Text = Loc.GetString("cargo-funding-alloc-console-label-help-adjustible");
+ }
+ else
+ {
+ HelpLabel.Text = Loc.GetString("cargo-funding-alloc-console-label-help-non-adjustible",
+ ("percent", (int) (bank.PrimaryCut * 100)));
+ }
foreach (var ctrl in _addedControls)
{
_spinBoxes.Clear();
_balanceLabels.Clear();
- var accounts = bank.Accounts.ToList().OrderBy(p => p.Key);
+ _primaryCut = bank.PrimaryCut;
+ _lockboxCut = bank.LockboxCut;
+
+ LockboxCut.OverrideValue(100 - (int)(_lockboxCut * 100));
+ PrimaryCut.OverrideValue((int)(_primaryCut * 100));
+
+ LockboxCut.IsValid = val => val is >= 0 and <= 100;
+ PrimaryCut.IsValid = val => val is >= 0 and <= 100;
+
+ LockboxCut.Visible = _lockboxCutEnabled;
+ LockboxCutLabel.Visible = _lockboxCutEnabled;
+ PrimaryCut.Visible = _allowPrimaryCutAdjustment;
+ PrimaryCutLabel.Visible = _allowPrimaryCutAdjustment;
+
+ var accounts = EditableAccounts(bank).OrderBy(p => p.Key);
foreach (var (account, balance) in accounts)
{
var accountProto = _prototypeManager.Index(account);
var incorrectSum = sum != 100;
var differs = false;
- var accounts = bank.Accounts.Keys.OrderBy(p => p.Id).ToList();
+ var accounts = EditableAccounts(bank).OrderBy(p => p.Key).Select(p => p.Key).ToList();
for (var i = 0; i < accounts.Count; i++)
{
var percent = _spinBoxes[i].Value;
break;
}
}
+ differs = differs || _primaryCut != bank.PrimaryCut || _lockboxCut != bank.LockboxCut;
SaveButton.Disabled = !differs || incorrectSum;
using System.Linq;
using Content.Shared.Cargo.Components;
+using Content.Shared.CCVar;
using Content.Shared.Database;
using Content.Shared.Emag.Systems;
using Content.Shared.IdentityManagement;
public sealed partial class CargoSystem
{
+ private bool _allowPrimaryAccountAllocation;
+ private bool _allowPrimaryCutAdjustment;
+
public void InitializeFunds()
{
SubscribeLocalEvent<CargoOrderConsoleComponent, CargoConsoleWithdrawFundsMessage>(OnWithdrawFunds);
SubscribeLocalEvent<CargoOrderConsoleComponent, CargoConsoleToggleLimitMessage>(OnToggleLimit);
SubscribeLocalEvent<FundingAllocationConsoleComponent, SetFundingAllocationBuiMessage>(OnSetFundingAllocation);
SubscribeLocalEvent<FundingAllocationConsoleComponent, BeforeActivatableUIOpenEvent>(OnFundAllocationBuiOpen);
+
+ _cfg.OnValueChanged(CCVars.AllowPrimaryAccountAllocation, enabled => { _allowPrimaryAccountAllocation = enabled; }, true);
+ _cfg.OnValueChanged(CCVars.AllowPrimaryCutAdjustment, enabled => { _allowPrimaryCutAdjustment = enabled; }, true);
}
private void OnWithdrawFunds(Entity<CargoOrderConsoleComponent> ent, ref CargoConsoleWithdrawFundsMessage args)
!TryComp<StationBankAccountComponent>(station, out var bank))
return;
- if (args.Percents.Count != bank.RevenueDistribution.Count)
+ var expectedCount = _allowPrimaryAccountAllocation ? bank.RevenueDistribution.Count : bank.RevenueDistribution.Count - 1;
+ if (args.Percents.Count != expectedCount)
return;
var differs = false;
break;
}
}
+ differs = differs || args.PrimaryCut != bank.PrimaryCut || args.LockboxCut != bank.LockboxCut;
if (!differs)
return;
if (args.Percents.Values.Sum() != 100)
return;
+ var primaryCut = bank.RevenueDistribution[bank.PrimaryAccount];
bank.RevenueDistribution.Clear();
foreach (var (account, percent )in args.Percents)
{
bank.RevenueDistribution.Add(account, percent / 100.0);
}
+ if (!_allowPrimaryAccountAllocation)
+ {
+ bank.RevenueDistribution.Add(bank.PrimaryAccount, 0);
+ }
+
+ if (_allowPrimaryCutAdjustment && args.PrimaryCut is >= 0.0 and <= 1.0)
+ {
+ bank.PrimaryCut = args.PrimaryCut;
+ }
+ if (_lockboxCutEnabled && args.LockboxCut is >= 0.0 and <= 1.0)
+ {
+ bank.LockboxCut = args.LockboxCut;
+ }
+
Dirty(station, bank);
_audio.PlayPvs(ent.Comp.SetDistributionSound, ent);
_adminLogger.Add(
LogType.Action,
LogImpact.Medium,
- $"{ToPrettyString(args.Actor):player} set station {ToPrettyString(station)} fund distribution: {string.Join(',', bank.RevenueDistribution.Select(p => $"{p.Key}: {p.Value}").ToList())}");
+ $"{ToPrettyString(args.Actor):player} set station {ToPrettyString(station)} fund distribution: {string.Join(',', bank.RevenueDistribution.Select(p => $"{p.Key}: {p.Value}").ToList())}, primary cut: {bank.PrimaryCut}, lockbox cut: {bank.LockboxCut}");
}
private void OnFundAllocationBuiOpen(Entity<FundingAllocationConsoleComponent> ent, ref BeforeActivatableUIOpenEvent args)
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Events;
using Content.Shared.Cargo.Prototypes;
+using Content.Shared.CCVar;
using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
*/
private static readonly SoundPathSpecifier ApproveSound = new("/Audio/Effects/Cargo/ping.ogg");
+ private bool _lockboxCutEnabled;
private void InitializeShuttle()
{
SubscribeLocalEvent<CargoPalletConsoleComponent, CargoPalletSellMessage>(OnPalletSale);
SubscribeLocalEvent<CargoPalletConsoleComponent, CargoPalletAppraiseMessage>(OnPalletAppraise);
SubscribeLocalEvent<CargoPalletConsoleComponent, BoundUIOpenedEvent>(OnPalletUIOpen);
+
+ _cfg.OnValueChanged(CCVars.LockboxCutEnabled, (enabled) => { _lockboxCutEnabled = enabled; }, true);
}
#region Console
Dictionary<ProtoId<CargoAccountPrototype>, double> distribution;
if (sellComponent != null)
{
+ var cut = _lockboxCutEnabled ? bankAccount.LockboxCut : bankAccount.PrimaryCut;
distribution = new Dictionary<ProtoId<CargoAccountPrototype>, double>
{
- { sellComponent.OverrideAccount, sellComponent.OverrideCut },
- { bankAccount.PrimaryAccount, 1.0 - sellComponent.OverrideCut },
+ { sellComponent.OverrideAccount, cut },
+ { bankAccount.PrimaryAccount, 1.0 - cut },
};
}
else
using Content.Shared.Cargo;
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Prototypes;
+using Content.Shared.CCVar;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Mobs.Components;
using Content.Shared.Paper;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
+using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
public sealed partial class CargoSystem : SharedCargoSystem
{
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
--- /dev/null
+using Robust.Shared.Configuration;
+
+namespace Content.Shared.CCVar;
+
+public sealed partial class CCVars
+{
+ /// <summary>
+ /// Whether or not the primary account of a bank should be listed
+ /// in the funding allocation console
+ /// </summary>
+ public static readonly CVarDef<bool> AllowPrimaryAccountAllocation =
+ CVarDef.Create("cargo.allow_primary_account_allocation", false, CVar.REPLICATED);
+
+ /// <summary>
+ /// Whether or not the primary cut of a bank should be manipulable
+ /// in the funding allocation console
+ /// </summary>
+ public static readonly CVarDef<bool> AllowPrimaryCutAdjustment =
+ CVarDef.Create("cargo.allow_primary_cut_adjustment", true, CVar.REPLICATED);
+
+ /// <summary>
+ /// Whether or not the separate lockbox cut is enabled
+ /// </summary>
+ public static readonly CVarDef<bool> LockboxCutEnabled =
+ CVarDef.Create("cargo.enable_lockbox_cut", true, CVar.REPLICATED);
+}
public sealed class SetFundingAllocationBuiMessage : BoundUserInterfaceMessage
{
public Dictionary<ProtoId<CargoAccountPrototype>, int> Percents;
+ public double PrimaryCut;
+ public double LockboxCut;
- public SetFundingAllocationBuiMessage(Dictionary<ProtoId<CargoAccountPrototype>, int> percents)
+ public SetFundingAllocationBuiMessage(Dictionary<ProtoId<CargoAccountPrototype>, int> percents, double primaryCut, double lockboxCut)
{
Percents = percents;
+ PrimaryCut = primaryCut;
+ LockboxCut = lockboxCut;
}
}
/// </summary>
[DataField(required: true)]
public ProtoId<CargoAccountPrototype> OverrideAccount;
-
- /// <summary>
- /// The cut that the OverrideAccount will get from the price. The rest is given to the primary station account.
- /// </summary>
- [DataField]
- public float OverrideCut = 0.75f;
}
[DataField, AutoNetworkedField]
public double PrimaryCut = 0.50;
+ /// <summary>
+ /// When giving funds to a particular account from an override sell, the proportion of funds they should receive compared to remaining accounts.
+ /// </summary>
+ [DataField, AutoNetworkedField]
+ public double LockboxCut = 0.75;
+
/// <summary>
/// A dictionary corresponding to the money held by each cargo account.
/// </summary>
cargo-funding-alloc-console-label-balance = [bold] Balance [/bold]
cargo-funding-alloc-console-label-cut = [bold] Revenue Division (%) [/bold]
-cargo-funding-alloc-console-label-help = Cargo receives {$percent}% of all profits. The rest is split as specified below:
+cargo-funding-alloc-console-label-primary-cut = Cargo's cut of funds from non-lockbox sources (%):
+cargo-funding-alloc-console-label-lockbox-cut = Cargo's cut of funds from lockbox sales (%):
+
+cargo-funding-alloc-console-label-help-non-adjustible = Cargo receives {$percent}% of profits from non-lockbox sales. The rest is split as specified below:
+cargo-funding-alloc-console-label-help-adjustible = Remaining funds from non-lockbox sources are distributed as specified below:
cargo-funding-alloc-console-button-save = Save Changes
cargo-funding-alloc-console-label-save-fail = [bold]Revenue Divisions Invalid![/bold] [color=red]({$pos ->
[1] +