Economy (#403)
* nasrano * Add station budget & salary * Initial balance * Vending machine UI * Pricing for vending machines * Finish economy * Eftpos * Finish eftpos * Put eftpos into lockers * Vending machine prices * Small fixes * Fix atm UI * Add atms to maps * fix * reset * Add PDA program * Maps again --------- Co-authored-by: Mona Hmiza <> Co-authored-by: rhailrake <49613070+rhailrake@users.noreply.github.com>
This commit is contained in:
@@ -32,7 +32,7 @@ public sealed class CharacterInfoSystem : EntitySystem
|
||||
private void OnCharacterInfoEvent(CharacterInfoEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
var entity = GetEntity(msg.NetEntity);
|
||||
var data = new CharacterData(entity, msg.JobTitle, msg.Objectives, msg.Briefing, Name(entity));
|
||||
var data = new CharacterData(entity, msg.JobTitle, msg.Objectives, msg.Briefing, Name(entity), msg.Memory);
|
||||
|
||||
OnCharacterUpdate?.Invoke(data);
|
||||
}
|
||||
@@ -49,7 +49,8 @@ public sealed class CharacterInfoSystem : EntitySystem
|
||||
string Job,
|
||||
Dictionary<string, List<ObjectiveInfo>> Objectives,
|
||||
string? Briefing,
|
||||
string EntityName
|
||||
string EntityName,
|
||||
Dictionary<string, string> Memory
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -105,12 +105,13 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
|
||||
return;
|
||||
}
|
||||
|
||||
var (entity, job, objectives, briefing, entityName) = data;
|
||||
var (entity, job, objectives, briefing, entityName, memories) = data;
|
||||
|
||||
_window.SpriteView.SetEntity(entity);
|
||||
_window.NameLabel.Text = entityName;
|
||||
_window.SubText.Text = job;
|
||||
_window.Objectives.RemoveAllChildren();
|
||||
_window.Memories.RemoveAllChildren();
|
||||
_window.ObjectivesLabel.Visible = objectives.Any();
|
||||
|
||||
foreach (var (groupId, conditions) in objectives)
|
||||
@@ -146,6 +147,26 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
|
||||
_window.Objectives.AddChild(objectiveControl);
|
||||
}
|
||||
|
||||
//WD EDIT
|
||||
foreach (var (memoryName, memoryValue) in memories)
|
||||
{
|
||||
var memoryControl = new BoxContainer()
|
||||
{
|
||||
Orientation = BoxContainer.LayoutOrientation.Vertical,
|
||||
Modulate = Color.Gray
|
||||
};
|
||||
var text = Loc.TryGetString(memoryName, out var t, ("value", memoryValue))
|
||||
? t
|
||||
: $"{memoryName}: {memoryValue}";
|
||||
|
||||
memoryControl.AddChild(new Label
|
||||
{
|
||||
Text = text,
|
||||
});
|
||||
_window.Memories.AddChild(memoryControl);
|
||||
}
|
||||
//WD EDIT END
|
||||
|
||||
if (briefing != null)
|
||||
{
|
||||
var briefingControl = new ObjectiveBriefingControl();
|
||||
|
||||
@@ -14,6 +14,13 @@
|
||||
<Label Name="SubText" VerticalAlignment="Top" StyleClasses="LabelSubText" Access="Public"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<!-- WD EDIT -->
|
||||
<Label Text="{Loc 'character-info-memories-label'}" HorizontalAlignment="Center"/>
|
||||
<BoxContainer Orientation="Vertical" Name="Memories" Access="Public"/>
|
||||
<cc:Placeholder PlaceholderText="{Loc 'character-info-memories-placeholder-text'}"/>
|
||||
<!-- WD EDIT END -->
|
||||
|
||||
<Label Name="ObjectivesLabel" Access="Public" Text="{Loc 'character-info-objectives-label'}" HorizontalAlignment="Center"/>
|
||||
<BoxContainer Orientation="Vertical" Name="Objectives" Access="Public"/>
|
||||
<cc:Placeholder Name="RolePlaceholder" Access="Public" PlaceholderText="{Loc 'character-info-roles-antagonist-text'}"/>
|
||||
|
||||
@@ -2,13 +2,14 @@ using Content.Client.VendingMachines.UI;
|
||||
using Content.Shared.VendingMachines;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using System.Linq;
|
||||
using Content.Client.White.Economy.Ui;
|
||||
|
||||
namespace Content.Client.VendingMachines
|
||||
{
|
||||
public sealed class VendingMachineBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[ViewVariables]
|
||||
private VendingMachineMenu? _menu;
|
||||
private VendingMenu? _menu; // WD EDIT
|
||||
|
||||
[ViewVariables]
|
||||
private List<VendingMachineInventoryEntry> _cachedInventory = new();
|
||||
@@ -26,15 +27,18 @@ namespace Content.Client.VendingMachines
|
||||
|
||||
var vendingMachineSys = EntMan.System<VendingMachineSystem>();
|
||||
|
||||
_cachedInventory = vendingMachineSys.GetAllInventory(Owner);
|
||||
// WD EDIT START
|
||||
var component = EntMan.GetComponent<VendingMachineComponent>(Owner);
|
||||
_cachedInventory = vendingMachineSys.GetAllInventory(Owner, component);
|
||||
|
||||
_menu = new VendingMachineMenu { Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName };
|
||||
_menu = new VendingMenu { Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName };
|
||||
|
||||
_menu.OnClose += Close;
|
||||
_menu.OnItemSelected += OnItemSelected;
|
||||
_menu.OnSearchChanged += OnSearchChanged;
|
||||
_menu.OnWithdraw += SendMessage;
|
||||
// WD EDIT END
|
||||
|
||||
_menu.Populate(_cachedInventory, out _cachedFilteredIndex);
|
||||
_menu.Populate(_cachedInventory, component.PriceMultiplier, component.Credits);
|
||||
|
||||
_menu.OpenCentered();
|
||||
}
|
||||
@@ -48,21 +52,23 @@ namespace Content.Client.VendingMachines
|
||||
|
||||
_cachedInventory = newState.Inventory;
|
||||
|
||||
_menu?.Populate(_cachedInventory, out _cachedFilteredIndex, _menu.SearchBar.Text);
|
||||
_menu?.Populate(_cachedInventory, newState.PriceMultiplier, newState.Credits);
|
||||
}
|
||||
|
||||
private void OnItemSelected(ItemList.ItemListSelectedEventArgs args)
|
||||
// WD EDIT START
|
||||
private void OnItemSelected(int index)
|
||||
{
|
||||
if (_cachedInventory.Count == 0)
|
||||
return;
|
||||
|
||||
var selectedItem = _cachedInventory.ElementAtOrDefault(_cachedFilteredIndex.ElementAtOrDefault(args.ItemIndex));
|
||||
var selectedItem = _cachedInventory.ElementAtOrDefault(index);
|
||||
|
||||
if (selectedItem == null)
|
||||
return;
|
||||
|
||||
SendMessage(new VendingMachineEjectMessage(selectedItem.Type, selectedItem.ID));
|
||||
}
|
||||
// WD EDIT END
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
@@ -80,7 +86,7 @@ namespace Content.Client.VendingMachines
|
||||
|
||||
private void OnSearchChanged(string? filter)
|
||||
{
|
||||
_menu?.Populate(_cachedInventory, out _cachedFilteredIndex, filter);
|
||||
//_menu?.Populate(_cachedInventory, out _cachedFilteredIndex, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
Content.Client/White/Economy/ATMVisualLayers.cs
Normal file
8
Content.Client/White/Economy/ATMVisualLayers.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Content.Client.White.Economy;
|
||||
|
||||
public enum ATMVisualLayers : byte
|
||||
{
|
||||
Base,
|
||||
BaseUnshaded
|
||||
}
|
||||
|
||||
43
Content.Client/White/Economy/Ui/ATMBui.cs
Normal file
43
Content.Client/White/Economy/Ui/ATMBui.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.White.Economy.Ui;
|
||||
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class ATMBui : BoundUserInterface
|
||||
{
|
||||
private AtmWindow _window;
|
||||
|
||||
public ATMBui(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
_window = new AtmWindow();
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
_window.OnClose += Close;
|
||||
_window.OnWithdrawAttempt += SendMessage;
|
||||
|
||||
if (State != null)
|
||||
{
|
||||
UpdateState(State);
|
||||
}
|
||||
|
||||
_window.OpenCentered();
|
||||
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
_window?.UpdateState(state);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_window?.Close();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
20
Content.Client/White/Economy/Ui/AtmWindow.xaml
Normal file
20
Content.Client/White/Economy/Ui/AtmWindow.xaml
Normal file
@@ -0,0 +1,20 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="ATM"
|
||||
SetSize="400 220"
|
||||
Resizable="False">
|
||||
|
||||
<BoxContainer Name="AuthorizationPage" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer HorizontalAlignment="Center" HorizontalExpand="True" VerticalAlignment="Center" Orientation="Vertical" MinSize="325 160">
|
||||
<Label Text="NANOTRASEN ATM"/>
|
||||
<Label Name="BalanceLabel" Visible="False"/>
|
||||
<controls:HighDivider Name="Divider" Visible="False"/>
|
||||
<Label Name="StatusLabel"/>
|
||||
<SliderIntInput Name="WithdrawSlider"/>
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True" VerticalAlignment="Bottom" Orientation="Horizontal">
|
||||
<LineEdit Name="PinLineEdit" HorizontalExpand="True" Text="Enter PIN"/>
|
||||
<Button Name="WithdrawButton" Text="{Loc 'store-ui-default-withdraw-text'}"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
79
Content.Client/White/Economy/Ui/AtmWindow.xaml.cs
Normal file
79
Content.Client/White/Economy/Ui/AtmWindow.xaml.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Content.Shared.White.Economy;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.White.Economy.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AtmWindow : DefaultWindow
|
||||
{
|
||||
public Action<ATMRequestWithdrawMessage>? OnWithdrawAttempt;
|
||||
|
||||
private readonly string _pinPattern = "[^0-9]";
|
||||
public AtmWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
|
||||
WithdrawButton.OnButtonDown += args =>
|
||||
{
|
||||
if(PinLineEdit.Text.Length != 4) return;
|
||||
OnWithdrawAttempt?.Invoke(new ATMRequestWithdrawMessage(WithdrawSlider.Value, int.Parse(PinLineEdit.Text)));
|
||||
};
|
||||
|
||||
PinLineEdit.OnTextChanged += _ =>
|
||||
{
|
||||
ValidatePin();
|
||||
};
|
||||
}
|
||||
|
||||
public void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
if(state is not ATMBuiState cast) return;
|
||||
|
||||
if (!cast.HasCard)
|
||||
{
|
||||
StatusLabel.Text = cast.InfoMessage;
|
||||
BalanceLabel.Visible = false;
|
||||
Divider.Visible = false;
|
||||
WithdrawSlider.Visible = false;
|
||||
PinLineEdit.Visible = false;
|
||||
WithdrawButton.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
StatusLabel.Text = cast.InfoMessage;
|
||||
|
||||
BalanceLabel.Text = Loc.GetString("atm-ui-balance", ("balance", cast.AccountBalance));
|
||||
BalanceLabel.Visible = true;
|
||||
Divider.Visible = true;
|
||||
WithdrawSlider.Visible = true;
|
||||
PinLineEdit.Visible = true;
|
||||
WithdrawButton.Visible = true;
|
||||
|
||||
WithdrawSlider.MaxValue = cast.AccountBalance;
|
||||
WithdrawSlider.Value = Math.Min(WithdrawSlider.Value, cast.AccountBalance);
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
WithdrawButton.Disabled = PinLineEdit.Text.Length != 4;
|
||||
}
|
||||
|
||||
private void ValidatePin()
|
||||
{
|
||||
var pinText = Regex.Replace(PinLineEdit.Text, _pinPattern, string.Empty);
|
||||
|
||||
if (pinText.Length > 4)
|
||||
{
|
||||
pinText = pinText[..4];
|
||||
}
|
||||
|
||||
PinLineEdit.Text = pinText;
|
||||
}
|
||||
}
|
||||
29
Content.Client/White/Economy/Ui/BankUi.cs
Normal file
29
Content.Client/White/Economy/Ui/BankUi.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Content.Client.UserInterface.Fragments;
|
||||
using Content.Shared.White.Economy;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.White.Economy.Ui;
|
||||
|
||||
public sealed partial class BankUi : UIFragment
|
||||
{
|
||||
private BankUiFragment? _fragment;
|
||||
|
||||
public override Control GetUIFragmentRoot()
|
||||
{
|
||||
return _fragment!;
|
||||
}
|
||||
|
||||
public override void Setup(BoundUserInterface userInterface, EntityUid? fragmentOwner)
|
||||
{
|
||||
_fragment = new BankUiFragment();
|
||||
}
|
||||
|
||||
public override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
if (state is not BankCartridgeUiState bankState)
|
||||
return;
|
||||
|
||||
_fragment?.UpdateState(bankState);
|
||||
}
|
||||
}
|
||||
12
Content.Client/White/Economy/Ui/BankUiFragment.xaml
Normal file
12
Content.Client/White/Economy/Ui/BankUiFragment.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<ui:BankUiFragment xmlns="https://spacestation14.io"
|
||||
xmlns:ui="clr-namespace:Content.Client.White.Economy.Ui">
|
||||
|
||||
<PanelContainer StyleClasses="BackgroundDark"></PanelContainer>
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Margin="8">
|
||||
<BoxContainer Name="LinkedAccount" Orientation="Vertical" Visible="False">
|
||||
<RichTextLabel Name="LinkedAccountNameLabel"/>
|
||||
<RichTextLabel Name="LinkedAccountBalanceLabel"/>
|
||||
</BoxContainer>
|
||||
<RichTextLabel Name="NoLinkedAccountLabel" Visible="False"/>
|
||||
</BoxContainer>
|
||||
</ui:BankUiFragment>
|
||||
30
Content.Client/White/Economy/Ui/BankUiFragment.xaml.cs
Normal file
30
Content.Client/White/Economy/Ui/BankUiFragment.xaml.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Content.Client.Message;
|
||||
using Content.Shared.White.Economy;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.White.Economy.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class BankUiFragment : BoxContainer
|
||||
{
|
||||
public BankUiFragment()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
public void UpdateState(BankCartridgeUiState state)
|
||||
{
|
||||
LinkedAccount.Visible = state.AccountLinked;
|
||||
NoLinkedAccountLabel.Visible = !state.AccountLinked;
|
||||
|
||||
if (state.AccountLinked)
|
||||
{
|
||||
LinkedAccountNameLabel.SetMarkup(Loc.GetString("eftpos-ui-account-text", ("owner", state.OwnerName)));
|
||||
LinkedAccountBalanceLabel.SetMarkup(Loc.GetString("atm-ui-balance", ("balance", state.Balance)));
|
||||
return;
|
||||
}
|
||||
|
||||
NoLinkedAccountLabel.SetMarkup(Loc.GetString("bank-program-ui-no-account"));
|
||||
}
|
||||
}
|
||||
41
Content.Client/White/Economy/Ui/EftposBui.cs
Normal file
41
Content.Client/White/Economy/Ui/EftposBui.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.White.Economy.Ui;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class EftposBui : BoundUserInterface
|
||||
{
|
||||
private readonly EftposWindow _window;
|
||||
|
||||
public EftposBui(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
_window = new EftposWindow();
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
_window.OnClose += Close;
|
||||
_window.OnCardButtonPressed += SendMessage;
|
||||
|
||||
if (State != null)
|
||||
{
|
||||
UpdateState(State);
|
||||
}
|
||||
|
||||
_window.OpenCentered();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
_window.UpdateState(state);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_window.Close();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
30
Content.Client/White/Economy/Ui/EftposWindow.xaml
Normal file
30
Content.Client/White/Economy/Ui/EftposWindow.xaml
Normal file
@@ -0,0 +1,30 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
Title="{Loc 'eftpos-ui-title'}"
|
||||
Resizable="False"
|
||||
SetSize="380 120">
|
||||
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label
|
||||
Name="AmountLabel"
|
||||
Text="{Loc 'eftpos-ui-amount-text'}" />
|
||||
<LineEdit
|
||||
Name="AmountLineEdit"
|
||||
PlaceHolder="0"
|
||||
MinWidth="60"
|
||||
Access="Public" />
|
||||
<Button
|
||||
Name="CardButton"
|
||||
Access="Public"
|
||||
HorizontalExpand="True"
|
||||
HorizontalAlignment="Right"
|
||||
ToolTip="{Loc 'eftpos-ui-card-lock-desc'}"
|
||||
Text="{Loc 'eftpos-ui-card-lock-text'}" />
|
||||
</BoxContainer>
|
||||
<Label
|
||||
Name="AccountLabel"
|
||||
VerticalExpand="True"
|
||||
VerticalAlignment="Bottom"
|
||||
Access="Public" />
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
58
Content.Client/White/Economy/Ui/EftposWindow.xaml.cs
Normal file
58
Content.Client/White/Economy/Ui/EftposWindow.xaml.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Content.Shared.White.Economy;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.White.Economy.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class EftposWindow : DefaultWindow
|
||||
{
|
||||
public Action<EftposLockMessage>? OnCardButtonPressed;
|
||||
|
||||
public EftposWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
AmountLineEdit.OnTextChanged += _ =>
|
||||
{
|
||||
if (!int.TryParse(AmountLineEdit.Text, out var result) || result <= 0)
|
||||
AmountLineEdit.Text = string.Empty;
|
||||
|
||||
AmountLineEdit.Text = result.ToString();
|
||||
};
|
||||
|
||||
CardButton.OnPressed += _ =>
|
||||
{
|
||||
if (!int.TryParse(AmountLineEdit.Text, out var result) || result < 0)
|
||||
result = 0;
|
||||
|
||||
OnCardButtonPressed?.Invoke(new EftposLockMessage(result));
|
||||
};
|
||||
}
|
||||
|
||||
public void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
if(state is not EftposBuiState eftState)
|
||||
return;
|
||||
|
||||
AmountLineEdit.Text = eftState.Amount == 0 ? string.Empty : eftState.Amount.ToString();
|
||||
if (eftState.Locked)
|
||||
{
|
||||
CardButton.Text = Loc.GetString("eftpos-ui-card-unlock-text");
|
||||
CardButton.ToolTip = Loc.GetString("eftpos-ui-card-unlock-desc");
|
||||
AmountLineEdit.Editable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CardButton.Text = Loc.GetString("eftpos-ui-card-lock-text");
|
||||
CardButton.ToolTip = Loc.GetString("eftpos-ui-card-lock-desc");
|
||||
AmountLineEdit.Editable = true;
|
||||
}
|
||||
|
||||
AccountLabel.Text = eftState.Owner == string.Empty
|
||||
? string.Empty
|
||||
: Loc.GetString("eftpos-ui-account-text", ("owner", eftState.Owner));
|
||||
}
|
||||
}
|
||||
13
Content.Client/White/Economy/Ui/VendingItem.xaml
Normal file
13
Content.Client/White/Economy/Ui/VendingItem.xaml
Normal file
@@ -0,0 +1,13 @@
|
||||
<Control xmlns="https://spacestation14.io">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<TextureRect
|
||||
Name="VendingItemTexture"
|
||||
Stretch="KeepAspectCentered" />
|
||||
<Label Name="VendingItemName" HorizontalExpand="True" />
|
||||
<Button
|
||||
Name="VendingItemBuyButton"
|
||||
MinWidth="80"
|
||||
HorizontalAlignment="Right"
|
||||
Access="Public" />
|
||||
</BoxContainer>
|
||||
</Control>
|
||||
22
Content.Client/White/Economy/Ui/VendingItem.xaml.cs
Normal file
22
Content.Client/White/Economy/Ui/VendingItem.xaml.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.White.Economy.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class VendingItem : Control
|
||||
{
|
||||
public VendingItem(string itemName, string price, Texture? texture = null)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
VendingItemName.Text = itemName;
|
||||
|
||||
VendingItemBuyButton.Text = price;
|
||||
// VendingItemBuyButton.Disabled = !canBuy;
|
||||
|
||||
VendingItemTexture.Texture = texture;
|
||||
}
|
||||
}
|
||||
26
Content.Client/White/Economy/Ui/VendingMenu.xaml
Normal file
26
Content.Client/White/Economy/Ui/VendingMenu.xaml
Normal file
@@ -0,0 +1,26 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<Label Name="CreditsLabel" HorizontalExpand="True"/>
|
||||
<Button
|
||||
Name="WithdrawButton"
|
||||
Text="{Loc 'store-ui-default-withdraw-text'}"
|
||||
HorizontalAlignment="Right"/>
|
||||
</BoxContainer>
|
||||
<PanelContainer StyleClasses="HighDivider" />
|
||||
<Label
|
||||
Name="OutOfStockLabel"
|
||||
Visible="False"
|
||||
Text="{Loc 'vending-machine-component-try-eject-out-of-stock'}"/>
|
||||
<ScrollContainer
|
||||
HScrollEnabled="False"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<BoxContainer
|
||||
Name="VendingContents"
|
||||
Orientation="Vertical"
|
||||
VerticalExpand="True">
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
88
Content.Client/White/Economy/Ui/VendingMenu.xaml.cs
Normal file
88
Content.Client/White/Economy/Ui/VendingMenu.xaml.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.VendingMachines;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.White.Economy.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class VendingMenu : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public event Action<int>? OnItemSelected;
|
||||
public Action<VendingMachineWithdrawMessage>? OnWithdraw;
|
||||
|
||||
public VendingMenu()
|
||||
{
|
||||
MinSize = SetSize = new Vector2(250, 150);
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the list of available items on the vending machine interface
|
||||
/// and sets icons based on their prototypes
|
||||
/// </summary>
|
||||
public void Populate(List<VendingMachineInventoryEntry> inventory, double priceMultiplier, int credits)
|
||||
{
|
||||
CreditsLabel.Text = Loc.GetString("vending-ui-credits-amount", ("credits", credits));
|
||||
WithdrawButton.Disabled = credits == 0;
|
||||
WithdrawButton.OnPressed += _ =>
|
||||
{
|
||||
if (credits == 0)
|
||||
return;
|
||||
OnWithdraw?.Invoke(new VendingMachineWithdrawMessage());
|
||||
};
|
||||
VendingContents.RemoveAllChildren();
|
||||
if (inventory.Count == 0)
|
||||
{
|
||||
OutOfStockLabel.Visible = true;
|
||||
SetSizeAfterUpdate(OutOfStockLabel.Text?.Length ?? 0);
|
||||
return;
|
||||
}
|
||||
OutOfStockLabel.Visible = false;
|
||||
|
||||
var longestEntry = string.Empty;
|
||||
var spriteSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>();
|
||||
|
||||
for (var i = 0; i < inventory.Count; i++)
|
||||
{
|
||||
var entry = inventory[i];
|
||||
|
||||
var itemName = entry.ID;
|
||||
Texture? icon = null;
|
||||
if (_prototypeManager.TryIndex<EntityPrototype>(entry.ID, out var prototype))
|
||||
{
|
||||
itemName = prototype.Name;
|
||||
icon = spriteSystem.GetPrototypeIcon(prototype).Default;
|
||||
}
|
||||
|
||||
if (itemName.Length > longestEntry.Length)
|
||||
longestEntry = itemName;
|
||||
|
||||
var price = (int) (entry.Price * priceMultiplier);
|
||||
var vendingItem = new VendingItem($"{itemName} [{entry.Amount}]", $"{price} ¢", icon);
|
||||
|
||||
var j = i;
|
||||
vendingItem.VendingItemBuyButton.OnPressed += _ =>
|
||||
{
|
||||
OnItemSelected?.Invoke(j);
|
||||
};
|
||||
|
||||
VendingContents.AddChild(vendingItem);
|
||||
}
|
||||
|
||||
SetSizeAfterUpdate(longestEntry.Length);
|
||||
}
|
||||
|
||||
private void SetSizeAfterUpdate(int longestEntryLength)
|
||||
{
|
||||
SetSize = new Vector2(Math.Clamp((longestEntryLength + 10) * 12, 250, 700),
|
||||
Math.Clamp(VendingContents.ChildCount * 50, 150, 400));
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Server.White.Economy;
|
||||
using Content.Shared.Cargo;
|
||||
|
||||
namespace Content.Server.Cargo.Components;
|
||||
@@ -8,8 +9,17 @@ namespace Content.Server.Cargo.Components;
|
||||
[RegisterComponent, Access(typeof(SharedCargoSystem))]
|
||||
public sealed partial class StationBankAccountComponent : Component
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("balance")]
|
||||
public int Balance = 2000;
|
||||
// WD EDIT START
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public int Balance
|
||||
{
|
||||
get => BankAccount.Balance;
|
||||
set => BankAccount.Balance = value;
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
public BankAccount BankAccount = default!;
|
||||
// WD EDIT END
|
||||
|
||||
/// <summary>
|
||||
/// How much the bank balance goes up per second, every Delay period. Rounded down when multiplied.
|
||||
|
||||
@@ -6,6 +6,7 @@ using Content.Server.Popups;
|
||||
using Content.Server.Shuttles.Systems;
|
||||
using Content.Server.Stack;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.White.Economy;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Cargo;
|
||||
@@ -46,6 +47,7 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
|
||||
[Dependency] private readonly BankCardSystem _bankCard = default!; // WD
|
||||
|
||||
private EntityQuery<TransformComponent> _xformQuery;
|
||||
private EntityQuery<CargoSellBlacklistComponent> _blacklistQuery;
|
||||
@@ -63,6 +65,15 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
||||
InitializeShuttle();
|
||||
InitializeTelepad();
|
||||
InitializeBounty();
|
||||
|
||||
SubscribeLocalEvent<StationBankAccountComponent, ComponentInit>(OnInit); // WD
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, StationBankAccountComponent component, ComponentInit args)
|
||||
{
|
||||
component.BankAccount = _bankCard.CreateAccount(default, 2000);
|
||||
component.BankAccount.CommandBudgetAccount = true;
|
||||
component.BankAccount.Name = Loc.GetString("command-budget");
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
|
||||
@@ -32,6 +32,7 @@ public sealed class CharacterInfoSystem : EntitySystem
|
||||
|
||||
var objectives = new Dictionary<string, List<ObjectiveInfo>>();
|
||||
var jobTitle = "No Profession";
|
||||
var memories = new Dictionary<string, string>(); //WD EDIT
|
||||
string? briefing = null;
|
||||
if (_minds.TryGetMind(entity, out var mindId, out var mind))
|
||||
{
|
||||
@@ -54,8 +55,14 @@ public sealed class CharacterInfoSystem : EntitySystem
|
||||
|
||||
// Get briefing
|
||||
briefing = _roles.MindGetBriefing(mindId);
|
||||
|
||||
// WD EDIT Get memories
|
||||
foreach (var memory in mind.AllMemories)
|
||||
{
|
||||
memories[memory.Name] = memory.Value;
|
||||
}
|
||||
}
|
||||
|
||||
RaiseNetworkEvent(new CharacterInfoEvent(GetNetEntity(entity), jobTitle, objectives, briefing), args.SenderSession);
|
||||
RaiseNetworkEvent(new CharacterInfoEvent(GetNetEntity(entity), jobTitle, objectives, briefing, memories), args.SenderSession);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@ using Content.Server.Chat.Systems;
|
||||
using Content.Server.Emp;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Stack;
|
||||
using Content.Server.Storage.Components;
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Server.UserInterface;
|
||||
using Content.Server.White.Economy;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Actions;
|
||||
@@ -15,9 +19,14 @@ using Content.Shared.DoAfter;
|
||||
using Content.Shared.Emag.Components;
|
||||
using Content.Shared.Emag.Systems;
|
||||
using Content.Shared.Emp;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Throwing;
|
||||
using Content.Shared.VendingMachines;
|
||||
using Content.Shared.White.Economy;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -37,9 +46,16 @@ namespace Content.Server.VendingMachines
|
||||
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
// WD START
|
||||
[Dependency] private readonly BankCardSystem _bankCard = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly StackSystem _stackSystem = default!;
|
||||
// WD END
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
private double _priceMultiplier = 1.0; // WD
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -60,6 +76,12 @@ namespace Content.Server.VendingMachines
|
||||
SubscribeLocalEvent<VendingMachineComponent, VendingMachineSelfDispenseEvent>(OnSelfDispense);
|
||||
|
||||
SubscribeLocalEvent<VendingMachineComponent, RestockDoAfterEvent>(OnDoAfter);
|
||||
//WD EDIT
|
||||
|
||||
SubscribeLocalEvent<VendingMachineComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
SubscribeLocalEvent<VendingMachineComponent, VendingMachineWithdrawMessage>(OnWithdrawMessage);
|
||||
|
||||
//WD EDIT END
|
||||
|
||||
SubscribeLocalEvent<VendingMachineRestockComponent, PriceCalculationEvent>(OnPriceCalculation);
|
||||
}
|
||||
@@ -111,7 +133,8 @@ namespace Content.Server.VendingMachines
|
||||
|
||||
private void UpdateVendingMachineInterfaceState(EntityUid uid, VendingMachineComponent component)
|
||||
{
|
||||
var state = new VendingMachineInterfaceState(GetAllInventory(uid, component));
|
||||
var state = new VendingMachineInterfaceState(GetAllInventory(uid, component), GetPriceMultiplier(component),
|
||||
component.Credits); // WD EDIT
|
||||
|
||||
_userInterfaceSystem.TrySetUiState(uid, VendingMachineUiKey.Key, state);
|
||||
}
|
||||
@@ -190,6 +213,54 @@ namespace Content.Server.VendingMachines
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
//WD EDIT
|
||||
|
||||
private void OnInteractUsing(EntityUid uid, VendingMachineComponent component, InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (component.Broken || !this.IsPowered(uid, EntityManager))
|
||||
return;
|
||||
|
||||
if (!TryComp<CurrencyComponent>(args.Used, out var currency) ||
|
||||
!currency.Price.Keys.Contains(component.CurrencyType))
|
||||
return;
|
||||
|
||||
var stack = Comp<StackComponent>(args.Used);
|
||||
component.Credits += stack.Count;
|
||||
Del(args.Used);
|
||||
UpdateVendingMachineInterfaceState(uid, component);
|
||||
Audio.PlayPvs(component.SoundInsertCurrency, uid);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
protected override int GetEntryPrice(EntityPrototype proto)
|
||||
{
|
||||
return (int) _pricing.GetEstimatedPrice(proto);
|
||||
}
|
||||
|
||||
private int GetPrice(VendingMachineInventoryEntry entry, VendingMachineComponent comp)
|
||||
{
|
||||
return (int) (entry.Price * GetPriceMultiplier(comp));
|
||||
}
|
||||
|
||||
private double GetPriceMultiplier(VendingMachineComponent comp)
|
||||
{
|
||||
return comp.PriceMultiplier * _priceMultiplier;
|
||||
}
|
||||
|
||||
private void OnWithdrawMessage(EntityUid uid, VendingMachineComponent component, VendingMachineWithdrawMessage args)
|
||||
{
|
||||
_stackSystem.Spawn(component.Credits,
|
||||
PrototypeManager.Index<StackPrototype>(component.CreditStackPrototype), Transform(uid).Coordinates);
|
||||
component.Credits = 0;
|
||||
Audio.PlayPvs(component.SoundWithdrawCurrency, uid);
|
||||
|
||||
UpdateVendingMachineInterfaceState(uid, component);
|
||||
}
|
||||
//WD EDIT END
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="VendingMachineComponent.CanShoot"/> property of the vending machine.
|
||||
/// </summary>
|
||||
@@ -245,7 +316,7 @@ namespace Content.Server.VendingMachines
|
||||
/// <param name="itemId">The prototype ID of the item</param>
|
||||
/// <param name="throwItem">Whether the item should be thrown in a random direction after ejection</param>
|
||||
/// <param name="vendComponent"></param>
|
||||
public void TryEjectVendorItem(EntityUid uid, InventoryType type, string itemId, bool throwItem, VendingMachineComponent? vendComponent = null)
|
||||
public void TryEjectVendorItem(EntityUid uid, InventoryType type, string itemId, bool throwItem, VendingMachineComponent? vendComponent = null, EntityUid? sender = null) // WD EDIT
|
||||
{
|
||||
if (!Resolve(uid, ref vendComponent))
|
||||
return;
|
||||
@@ -274,6 +345,44 @@ namespace Content.Server.VendingMachines
|
||||
if (string.IsNullOrEmpty(entry.ID))
|
||||
return;
|
||||
|
||||
// WD START
|
||||
var price = GetPrice(entry, vendComponent);
|
||||
if (price > 0 && sender.HasValue && !_tag.HasTag(sender.Value, "IgnoreBalanceChecks"))
|
||||
{
|
||||
var success = false;
|
||||
if (vendComponent.Credits >= price)
|
||||
{
|
||||
vendComponent.Credits -= price;
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var items = _accessReader.FindPotentialAccessItems(sender.Value);
|
||||
foreach (var item in items)
|
||||
{
|
||||
var nextItem = item;
|
||||
if (TryComp(item, out PdaComponent? pda) && pda.ContainedId is { Valid: true } id)
|
||||
nextItem = id;
|
||||
|
||||
if (!TryComp<BankCardComponent>(nextItem, out var bankCard) || !bankCard.BankAccountId.HasValue
|
||||
|| !_bankCard.TryGetAccount(bankCard.BankAccountId.Value, out var account)
|
||||
|| account.Balance < price)
|
||||
continue;
|
||||
|
||||
_bankCard.TryChangeBalance(bankCard.BankAccountId.Value, -price);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
Popup.PopupEntity(Loc.GetString("vending-machine-component-no-balance"), uid);
|
||||
Deny(uid, vendComponent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// WD END
|
||||
|
||||
// Start Ejecting, and prevent users from ordering while anim playing
|
||||
vendComponent.Ejecting = true;
|
||||
@@ -297,7 +406,7 @@ namespace Content.Server.VendingMachines
|
||||
{
|
||||
if (IsAuthorized(uid, sender, component))
|
||||
{
|
||||
TryEjectVendorItem(uid, type, itemId, component.CanShoot, component);
|
||||
TryEjectVendorItem(uid, type, itemId, component.CanShoot, component, sender);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
124
Content.Server/White/Economy/ATMSystem.cs
Normal file
124
Content.Server/White/Economy/ATMSystem.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Stack;
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.White.Economy;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.White.Economy;
|
||||
|
||||
public sealed class ATMSystem : SharedATMSystem
|
||||
{
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
[Dependency] private readonly BankCardSystem _bankCardSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly StackSystem _stackSystem = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly ContainerSystem _container = default!;
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<ATMComponent, EntInsertedIntoContainerMessage>(OnCardInserted);
|
||||
SubscribeLocalEvent<ATMComponent, EntRemovedFromContainerMessage>(OnCardRemoved);
|
||||
SubscribeLocalEvent<ATMComponent, ATMRequestWithdrawMessage>(OnWithdrawRequest);
|
||||
SubscribeLocalEvent<ATMComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
SubscribeLocalEvent<ATMComponent, ComponentStartup>(OnComponentStartup);
|
||||
}
|
||||
|
||||
private void OnComponentStartup(EntityUid uid, ATMComponent component, ComponentStartup args)
|
||||
{
|
||||
UpdateUiState(uid, -1, false, Loc.GetString("atm-ui-insert-card"));
|
||||
}
|
||||
|
||||
private void OnInteractUsing(EntityUid uid, ATMComponent component, InteractUsingEvent args)
|
||||
{
|
||||
if (!TryComp<CurrencyComponent>(args.Used, out var currency) || !currency.Price.Keys.Contains(component.CurrencyType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!component.CardSlot.Item.HasValue)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("atm-trying-insert-cash-error"), args.Target, args.User, PopupType.Medium);
|
||||
_audioSystem.PlayPvs(component.SoundDeny, uid);
|
||||
return;
|
||||
}
|
||||
|
||||
var stack = Comp<StackComponent>(args.Used);
|
||||
var bankCard = Comp<BankCardComponent>(component.CardSlot.Item.Value);
|
||||
var amount = stack.Count;
|
||||
|
||||
_bankCardSystem.TryChangeBalance(bankCard.BankAccountId!.Value, amount);
|
||||
Del(args.Used);
|
||||
|
||||
_audioSystem.PlayPvs(component.SoundInsertCurrency, uid);
|
||||
UpdateUiState(uid, _bankCardSystem.GetBalance(bankCard.BankAccountId.Value), true, Loc.GetString("atm-ui-select-withdraw-amount"));
|
||||
}
|
||||
|
||||
private void OnCardInserted(EntityUid uid, ATMComponent component, EntInsertedIntoContainerMessage args)
|
||||
{
|
||||
if (!TryComp<BankCardComponent>(args.Entity, out var bankCard) || !bankCard.BankAccountId.HasValue)
|
||||
{
|
||||
_container.EmptyContainer(args.Container);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateUiState(uid, _bankCardSystem.GetBalance(bankCard.BankAccountId.Value), true, Loc.GetString("atm-ui-select-withdraw-amount"));
|
||||
}
|
||||
|
||||
private void OnCardRemoved(EntityUid uid, ATMComponent component, EntRemovedFromContainerMessage args)
|
||||
{
|
||||
UpdateUiState(uid, -1, false, Loc.GetString("atm-ui-insert-card"));
|
||||
}
|
||||
|
||||
private void OnWithdrawRequest(EntityUid uid, ATMComponent component, ATMRequestWithdrawMessage args)
|
||||
{
|
||||
if (!TryComp<BankCardComponent>(component.CardSlot.Item, out var bankCard) || !bankCard.BankAccountId.HasValue)
|
||||
{
|
||||
if (component.CardSlot.ContainerSlot != null)
|
||||
_container.EmptyContainer(component.CardSlot.ContainerSlot);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_bankCardSystem.TryGetAccount(bankCard.BankAccountId.Value, out var account) || account.AccountPin != args.Pin)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("atm-wrong-pin"), uid);
|
||||
_audioSystem.PlayPvs(component.SoundDeny, uid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_bankCardSystem.TryChangeBalance(account.AccountId, -args.Amount))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("atm-not-enough-cash"), uid);
|
||||
_audioSystem.PlayPvs(component.SoundDeny, uid);
|
||||
return;
|
||||
}
|
||||
|
||||
_stackSystem.Spawn(args.Amount, _prototypeManager.Index<StackPrototype>(component.CreditStackPrototype), Transform(uid).Coordinates);
|
||||
_audioSystem.PlayPvs(component.SoundWithdrawCurrency, uid);
|
||||
|
||||
UpdateUiState(uid, account.Balance, true, Loc.GetString("atm-ui-select-withdraw-amount"));
|
||||
}
|
||||
|
||||
private void UpdateUiState(EntityUid uid, int balance, bool hasCard, string infoMessage)
|
||||
{
|
||||
var state = new ATMBuiState
|
||||
{
|
||||
AccountBalance = balance,
|
||||
HasCard = hasCard,
|
||||
InfoMessage = infoMessage
|
||||
};
|
||||
|
||||
|
||||
_ui.TrySetUiState(uid, ATMUiKey.Key, state);
|
||||
}
|
||||
}
|
||||
24
Content.Server/White/Economy/BankAccount.cs
Normal file
24
Content.Server/White/Economy/BankAccount.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Content.Shared.Mind;
|
||||
|
||||
namespace Content.Server.White.Economy;
|
||||
|
||||
public sealed class BankAccount
|
||||
{
|
||||
public readonly int AccountId;
|
||||
public readonly int AccountPin;
|
||||
public int Balance;
|
||||
public bool CommandBudgetAccount;
|
||||
public Entity<MindComponent>? Mind;
|
||||
public string Name = string.Empty;
|
||||
|
||||
public EntityUid? CartridgeUid;
|
||||
public EntityUid? LoaderUid;
|
||||
|
||||
public BankAccount(int accountId, int balance)
|
||||
{
|
||||
AccountId = accountId;
|
||||
Balance = balance;
|
||||
AccountPin = Random.Shared.Next(1000, 10000);
|
||||
}
|
||||
}
|
||||
|
||||
221
Content.Server/White/Economy/BankCardSystem.cs
Normal file
221
Content.Server/White/Economy/BankCardSystem.cs
Normal file
@@ -0,0 +1,221 @@
|
||||
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.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!;
|
||||
|
||||
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);
|
||||
|
||||
_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.BankAccountId = acc.BankAccount.AccountId;
|
||||
return;
|
||||
}
|
||||
|
||||
if (component.BankAccountId.HasValue)
|
||||
{
|
||||
CreateAccount(component.BankAccountId.Value, component.StartingBalance);
|
||||
return;
|
||||
}
|
||||
|
||||
var account = CreateAccount(default, component.StartingBalance);
|
||||
component.BankAccountId = 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.BankAccountId.HasValue || !TryGetAccount(bankCardComponent.BankAccountId.Value, out var bankAccount))
|
||||
return;
|
||||
|
||||
if (!TryComp(mind.Mind, out MindComponent? mindComponent))
|
||||
return;
|
||||
|
||||
bankAccount.Balance = GetSalary(mind.Mind) * 3;
|
||||
mindComponent.AddMemory(new Memory("PIN", bankAccount.AccountPin.ToString()));
|
||||
bankAccount.Mind = (mind.Mind.Value, mindComponent);
|
||||
bankAccount.Name = Name(ev.Mob);
|
||||
|
||||
if (!_inventorySystem.TryGetSlotEntity(ev.Mob, "id", out var pdaUid) ||
|
||||
!TryComp(pdaUid, out CartridgeLoaderComponent? cartridgeLoader))
|
||||
return;
|
||||
|
||||
BankCartridgeComponent? comp = null;
|
||||
|
||||
var programs = new List<EntityUid>(cartridgeLoader.BackgroundPrograms);
|
||||
if (cartridgeLoader.ActiveProgram != null)
|
||||
programs.Add(cartridgeLoader.ActiveProgram.Value);
|
||||
|
||||
var program = programs.Find(program => TryComp(program, out comp));
|
||||
if (comp == null)
|
||||
return;
|
||||
|
||||
bankAccount.CartridgeUid = program;
|
||||
bankAccount.LoaderUid = pdaUid;
|
||||
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 is {CartridgeUid: not null, LoaderUid: not null})
|
||||
_bankCartridge.UpdateUiState(account.CartridgeUid.Value, account.LoaderUid.Value);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
8
Content.Server/White/Economy/BankCartridgeComponent.cs
Normal file
8
Content.Server/White/Economy/BankCartridgeComponent.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Content.Server.White.Economy;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class BankCartridgeComponent : Component
|
||||
{
|
||||
[ViewVariables]
|
||||
public int? AccountId;
|
||||
}
|
||||
46
Content.Server/White/Economy/BankCartridgeSystem.cs
Normal file
46
Content.Server/White/Economy/BankCartridgeSystem.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Content.Server.CartridgeLoader;
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.White.Economy;
|
||||
|
||||
namespace Content.Server.White.Economy;
|
||||
|
||||
public sealed class BankCartridgeSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly CartridgeLoaderSystem? _cartridgeLoaderSystem = default!;
|
||||
[Dependency] private readonly BankCardSystem _bankCardSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<BankCartridgeComponent, CartridgeMessageEvent>(OnUiMessage);
|
||||
SubscribeLocalEvent<BankCartridgeComponent, CartridgeUiReadyEvent>(OnUiReady);
|
||||
}
|
||||
|
||||
private void OnUiReady(EntityUid uid, BankCartridgeComponent component, CartridgeUiReadyEvent args)
|
||||
{
|
||||
UpdateUiState(uid, args.Loader, component);
|
||||
}
|
||||
|
||||
private void OnUiMessage(EntityUid uid, BankCartridgeComponent component, CartridgeMessageEvent args)
|
||||
{
|
||||
UpdateUiState(uid, GetEntity(args.LoaderUid), component);
|
||||
}
|
||||
|
||||
public void UpdateUiState(EntityUid cartridgeUid, EntityUid loaderUid, BankCartridgeComponent? component = null)
|
||||
{
|
||||
if (!Resolve(cartridgeUid, ref component))
|
||||
return;
|
||||
|
||||
var state = new BankCartridgeUiState
|
||||
{
|
||||
AccountLinked = component.AccountId != null
|
||||
};
|
||||
|
||||
if (component.AccountId != null && _bankCardSystem.TryGetAccount(component.AccountId.Value, out var account))
|
||||
{
|
||||
state.Balance = account.Balance;
|
||||
state.OwnerName = account.Name;
|
||||
}
|
||||
_cartridgeLoaderSystem?.UpdateCartridgeUiState(loaderUid, state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Content.Server.White.Economy;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class CommandBudgetPinPaperComponent : Component
|
||||
{
|
||||
}
|
||||
27
Content.Server/White/Economy/CommandBudgetSystem.cs
Normal file
27
Content.Server/White/Economy/CommandBudgetSystem.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Paper;
|
||||
using Content.Server.Station.Systems;
|
||||
|
||||
namespace Content.Server.White.Economy;
|
||||
|
||||
public sealed class CommandBudgetSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly PaperSystem _paper = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CommandBudgetPinPaperComponent, MapInitEvent>(OnMapInit);
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, CommandBudgetPinPaperComponent component, MapInitEvent args)
|
||||
{
|
||||
if (!TryComp(_station.GetOwningStation(uid), out StationBankAccountComponent? account))
|
||||
return;
|
||||
|
||||
var pin = account.BankAccount.AccountPin;
|
||||
_paper.SetContent(uid,Loc. GetString("command-budget-pin-message", ("pin", pin)));
|
||||
}
|
||||
}
|
||||
88
Content.Server/White/Economy/EftposSystem.cs
Normal file
88
Content.Server/White/Economy/EftposSystem.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.White.Economy;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
|
||||
namespace Content.Server.White.Economy;
|
||||
|
||||
public sealed class EftposSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
[Dependency] private readonly BankCardSystem _bankCardSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<EftposComponent, EftposLockMessage>(OnLock);
|
||||
SubscribeLocalEvent<EftposComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
}
|
||||
|
||||
private void OnInteractUsing(EntityUid uid, EftposComponent component, InteractUsingEvent args)
|
||||
{
|
||||
if (component.BankAccountId == null || !TryComp(args.Used, out BankCardComponent? bankCard) ||
|
||||
bankCard.BankAccountId == component.BankAccountId || component.Amount <= 0)
|
||||
return;
|
||||
|
||||
if (_bankCardSystem.TryChangeBalance(bankCard.BankAccountId!.Value, -component.Amount) &&
|
||||
_bankCardSystem.TryChangeBalance(component.BankAccountId.Value, component.Amount))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("eftpos-transaction-success"), uid);
|
||||
_audioSystem.PlayPvs(component.SoundApply, uid);
|
||||
}
|
||||
else
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("eftpos-transaction-error"), uid);
|
||||
_audioSystem.PlayPvs(component.SoundDeny, uid);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLock(EntityUid uid, EftposComponent component, EftposLockMessage args)
|
||||
{
|
||||
if (!TryComp(args.Session.AttachedEntity, out HandsComponent? hands) ||
|
||||
!TryComp(hands.ActiveHandEntity, out BankCardComponent? bankCard))
|
||||
return;
|
||||
|
||||
if (component.BankAccountId == null)
|
||||
{
|
||||
component.BankAccountId = bankCard.BankAccountId;
|
||||
component.Amount = args.Amount;
|
||||
}
|
||||
else if (component.BankAccountId == bankCard.BankAccountId)
|
||||
{
|
||||
component.BankAccountId = null;
|
||||
component.Amount = 0;
|
||||
}
|
||||
|
||||
UpdateUiState(uid, component.BankAccountId != null, component.Amount,
|
||||
GetOwner(hands.ActiveHandEntity.Value, component.BankAccountId));
|
||||
}
|
||||
|
||||
private string GetOwner(EntityUid uid, int? bankAccountId)
|
||||
{
|
||||
if (bankAccountId == null || !_bankCardSystem.TryGetAccount(bankAccountId.Value, out var account))
|
||||
return string.Empty;
|
||||
|
||||
if (TryComp(uid, out IdCardComponent? idCard) && idCard.FullName != null)
|
||||
return idCard.FullName;
|
||||
|
||||
return account.Name == string.Empty ? account.AccountId.ToString() : account.Name;
|
||||
}
|
||||
|
||||
private void UpdateUiState(EntityUid uid, bool locked, int amount, string owner)
|
||||
{
|
||||
var state = new EftposBuiState
|
||||
{
|
||||
Locked = locked,
|
||||
Amount = amount,
|
||||
Owner = owner
|
||||
};
|
||||
|
||||
_ui.TrySetUiState(uid, EftposKey.Key, state);
|
||||
}
|
||||
}
|
||||
@@ -21,12 +21,14 @@ public sealed class CharacterInfoEvent : EntityEventArgs
|
||||
public readonly string JobTitle;
|
||||
public readonly Dictionary<string, List<ObjectiveInfo>> Objectives;
|
||||
public readonly string? Briefing;
|
||||
public readonly Dictionary<string, string> Memory;
|
||||
|
||||
public CharacterInfoEvent(NetEntity netEntity, string jobTitle, Dictionary<string, List<ObjectiveInfo>> objectives, string? briefing)
|
||||
public CharacterInfoEvent(NetEntity netEntity, string jobTitle, Dictionary<string, List<ObjectiveInfo>> objectives, string? briefing, Dictionary<string,string> memory)
|
||||
{
|
||||
NetEntity = netEntity;
|
||||
JobTitle = jobTitle;
|
||||
Objectives = objectives;
|
||||
Briefing = briefing;
|
||||
Memory = memory;
|
||||
}
|
||||
}
|
||||
|
||||
16
Content.Shared/Mind/Memory.cs
Normal file
16
Content.Shared/Mind/Memory.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace Content.Shared.Mind;
|
||||
|
||||
public sealed class Memory
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string Value { get; set; }
|
||||
|
||||
public Memory(string name, string value)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,8 @@ namespace Content.Shared.Mind
|
||||
[DataField, AutoNetworkedField]
|
||||
public List<EntityUid> Objectives = new();
|
||||
|
||||
internal readonly List<Memory> _memories = new();
|
||||
|
||||
/// <summary>
|
||||
/// The session ID of the player owning this mind.
|
||||
/// </summary>
|
||||
@@ -73,6 +75,21 @@ namespace Content.Shared.Mind
|
||||
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? BorgName { get; set; }
|
||||
|
||||
[ViewVariables]
|
||||
public IEnumerable<Memory> AllMemories => _memories;
|
||||
|
||||
//WD EDIT
|
||||
public void AddMemory(Memory memory)
|
||||
{
|
||||
if (_memories.Contains(memory))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_memories.Add(memory);
|
||||
}
|
||||
//WD EDIT END
|
||||
|
||||
/// <summary>
|
||||
/// The time of death for this Mind.
|
||||
/// Can be null - will be null if the Mind is not considered "dead".
|
||||
|
||||
@@ -105,7 +105,7 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem
|
||||
|
||||
foreach (var (id, amount) in entries)
|
||||
{
|
||||
if (PrototypeManager.HasIndex<EntityPrototype>(id))
|
||||
if (PrototypeManager.TryIndex<EntityPrototype>(id, out var proto)) // WD EDIT
|
||||
{
|
||||
if (inventory.TryGetValue(id, out var entry))
|
||||
// Prevent a machine's stock from going over three times
|
||||
@@ -115,9 +115,14 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem
|
||||
// all the items just to restock one empty slot without
|
||||
// losing the rest of the restock.
|
||||
entry.Amount = Math.Min(entry.Amount + amount, 3 * amount);
|
||||
else
|
||||
inventory.Add(id, new VendingMachineInventoryEntry(type, id, amount));
|
||||
else // WD EDIT START
|
||||
{
|
||||
var price = GetEntryPrice(proto);
|
||||
inventory.Add(id, new VendingMachineInventoryEntry(type, id, amount, price));
|
||||
} // WD EDIT END
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual int GetEntryPrice(EntityPrototype proto) { return 0; } // WD
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -179,6 +181,27 @@ namespace Content.Shared.VendingMachines
|
||||
[DataField("loopDeny")]
|
||||
public bool LoopDenyAnimation = true;
|
||||
#endregion
|
||||
|
||||
//WD EDIT
|
||||
|
||||
[DataField("priceMultiplier")]
|
||||
public double PriceMultiplier;
|
||||
|
||||
[ValidatePrototypeId<StackPrototype>]
|
||||
public string CreditStackPrototype = "Credit";
|
||||
|
||||
[DataField("currencyType")]
|
||||
public string CurrencyType = "SpaceCash";
|
||||
|
||||
[DataField("soundInsertCurrency")]
|
||||
public SoundSpecifier SoundInsertCurrency = new SoundPathSpecifier("/Audio/White/Machines/polaroid2.ogg");
|
||||
|
||||
[DataField("soundWithdrawCurrency")]
|
||||
public SoundSpecifier SoundWithdrawCurrency = new SoundPathSpecifier("/Audio/White/Machines/polaroid1.ogg");
|
||||
|
||||
[ViewVariables]
|
||||
public int Credits;
|
||||
//WD EDIT END
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
@@ -190,11 +213,14 @@ namespace Content.Shared.VendingMachines
|
||||
public string ID;
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public uint Amount;
|
||||
public VendingMachineInventoryEntry(InventoryType type, string id, uint amount)
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public int Price; // WD
|
||||
public VendingMachineInventoryEntry(InventoryType type, string id, uint amount, int price)
|
||||
{
|
||||
Type = type;
|
||||
ID = id;
|
||||
Amount = amount;
|
||||
Price = price; // WD
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,19 +6,31 @@ namespace Content.Shared.VendingMachines
|
||||
public sealed class VendingMachineInterfaceState : BoundUserInterfaceState
|
||||
{
|
||||
public List<VendingMachineInventoryEntry> Inventory;
|
||||
// WD EDIT START
|
||||
public double PriceMultiplier;
|
||||
public int Credits;
|
||||
|
||||
public VendingMachineInterfaceState(List<VendingMachineInventoryEntry> inventory)
|
||||
public VendingMachineInterfaceState(List<VendingMachineInventoryEntry> inventory, double priceMultiplier,
|
||||
int credits)
|
||||
{
|
||||
Inventory = inventory;
|
||||
PriceMultiplier = priceMultiplier;
|
||||
Credits = credits;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class VendingMachineWithdrawMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
}
|
||||
// WD EDIT END
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class VendingMachineEjectMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly InventoryType Type;
|
||||
public readonly string ID;
|
||||
public VendingMachineEjectMessage(InventoryType type, string id)
|
||||
public VendingMachineEjectMessage(InventoryType type, string id) // WD EDIT
|
||||
{
|
||||
Type = type;
|
||||
ID = id;
|
||||
|
||||
40
Content.Shared/White/Economy/ATMComponent.cs
Normal file
40
Content.Shared/White/Economy/ATMComponent.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Stacks;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.White.Economy;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class ATMComponent : Component
|
||||
{
|
||||
[DataField("idCardSlot")]
|
||||
public ItemSlot CardSlot = default!;
|
||||
|
||||
[DataField("currencyType")]
|
||||
public string CurrencyType = "SpaceCash";
|
||||
|
||||
public string SlotId = "card-slot";
|
||||
|
||||
[ValidatePrototypeId<StackPrototype>]
|
||||
public string CreditStackPrototype = "Credit";
|
||||
|
||||
[DataField("soundInsertCurrency")]
|
||||
public SoundSpecifier SoundInsertCurrency = new SoundPathSpecifier("/Audio/White/Machines/polaroid2.ogg");
|
||||
|
||||
[DataField("soundWithdrawCurrency")]
|
||||
public SoundSpecifier SoundWithdrawCurrency = new SoundPathSpecifier("/Audio/White/Machines/polaroid1.ogg");
|
||||
|
||||
[DataField("soundApply")]
|
||||
public SoundSpecifier SoundApply = new SoundPathSpecifier("/Audio/White/Machines/chime.ogg");
|
||||
|
||||
[DataField("soundDeny")]
|
||||
public SoundSpecifier SoundDeny = new SoundPathSpecifier("/Audio/White/Machines/buzz-sigh.ogg");
|
||||
}
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum ATMUiKey
|
||||
{
|
||||
Key
|
||||
}
|
||||
24
Content.Shared/White/Economy/ATMMessages.cs
Normal file
24
Content.Shared/White/Economy/ATMMessages.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.White.Economy;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ATMRequestWithdrawMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public int Amount;
|
||||
public int Pin;
|
||||
|
||||
public ATMRequestWithdrawMessage(int amount, int pin)
|
||||
{
|
||||
Amount = amount;
|
||||
Pin = pin;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ATMBuiState : BoundUserInterfaceState
|
||||
{
|
||||
public bool HasCard;
|
||||
public string InfoMessage = string.Empty;
|
||||
public int AccountBalance;
|
||||
}
|
||||
16
Content.Shared/White/Economy/BankCardComponent.cs
Normal file
16
Content.Shared/White/Economy/BankCardComponent.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.White.Economy;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class BankCardComponent : Component
|
||||
{
|
||||
[DataField("accountId")]
|
||||
public int? BankAccountId;
|
||||
|
||||
[DataField("startingBalance")]
|
||||
public int StartingBalance = 0;
|
||||
|
||||
[DataField("commandBudgetCard")]
|
||||
public bool CommandBudgetCard;
|
||||
}
|
||||
11
Content.Shared/White/Economy/BankCartridgeUiState.cs
Normal file
11
Content.Shared/White/Economy/BankCartridgeUiState.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.White.Economy;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BankCartridgeUiState : BoundUserInterfaceState
|
||||
{
|
||||
public int Balance;
|
||||
public string OwnerName = string.Empty;
|
||||
public bool AccountLinked;
|
||||
}
|
||||
26
Content.Shared/White/Economy/EftposComponent.cs
Normal file
26
Content.Shared/White/Economy/EftposComponent.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.White.Economy;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class EftposComponent : Component
|
||||
{
|
||||
[ViewVariables]
|
||||
public int? BankAccountId;
|
||||
|
||||
[ViewVariables]
|
||||
public int Amount;
|
||||
|
||||
[DataField("soundApply")]
|
||||
public SoundSpecifier SoundApply = new SoundPathSpecifier("/Audio/White/Machines/chime.ogg");
|
||||
|
||||
[DataField("soundDeny")]
|
||||
public SoundSpecifier SoundDeny = new SoundPathSpecifier("/Audio/White/Machines/buzz-sigh.ogg");
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum EftposKey
|
||||
{
|
||||
Key
|
||||
}
|
||||
22
Content.Shared/White/Economy/EftposMessages.cs
Normal file
22
Content.Shared/White/Economy/EftposMessages.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.White.Economy;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class EftposBuiState : BoundUserInterfaceState
|
||||
{
|
||||
public bool Locked;
|
||||
public int Amount;
|
||||
public string Owner = string.Empty;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class EftposLockMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public int Amount;
|
||||
|
||||
public EftposLockMessage(int amount)
|
||||
{
|
||||
Amount = amount;
|
||||
}
|
||||
}
|
||||
13
Content.Shared/White/Economy/SalaryPrototype.cs
Normal file
13
Content.Shared/White/Economy/SalaryPrototype.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.White.Economy;
|
||||
|
||||
[Prototype("salary")]
|
||||
public sealed class SalaryPrototype : IPrototype
|
||||
{
|
||||
[IdDataField]
|
||||
public string ID { get; } = default!;
|
||||
|
||||
[DataField("salaries")]
|
||||
public Dictionary<string, int> Salaries = new();
|
||||
}
|
||||
28
Content.Shared/White/Economy/SharedATMSystem.cs
Normal file
28
Content.Shared/White/Economy/SharedATMSystem.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Shared.White.Economy;
|
||||
|
||||
public abstract class SharedATMSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<ATMComponent, ComponentInit>(OnATMInit);
|
||||
SubscribeLocalEvent<ATMComponent, ComponentRemove>(OnATMRemoved);
|
||||
}
|
||||
|
||||
protected virtual void OnATMInit(EntityUid uid, ATMComponent component, ComponentInit args)
|
||||
{
|
||||
_itemSlotsSystem.AddItemSlot(uid, component.SlotId, component.CardSlot);
|
||||
}
|
||||
|
||||
private void OnATMRemoved(EntityUid uid, ATMComponent component, ComponentRemove args)
|
||||
{
|
||||
_itemSlotsSystem.TryEject(uid, component.CardSlot, null!, out _);
|
||||
_itemSlotsSystem.RemoveItemSlot(uid, component.CardSlot);
|
||||
}
|
||||
}
|
||||
BIN
Resources/Audio/White/Machines/buzz-sigh.ogg
Normal file
BIN
Resources/Audio/White/Machines/buzz-sigh.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/White/Machines/buzz-two.ogg
Normal file
BIN
Resources/Audio/White/Machines/buzz-two.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/White/Machines/chime.ogg
Normal file
BIN
Resources/Audio/White/Machines/chime.ogg
Normal file
Binary file not shown.
6
Resources/Audio/White/Machines/license.txt
Normal file
6
Resources/Audio/White/Machines/license.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
buzz-sigh.ogg taken from: https://github.com/Baystation12/Baystation12 at commit 662c08272acd7be79531550919f56f846726eabb
|
||||
buzz-two.ogg taken from: https://github.com/Baystation12/Baystation12 at commit 662c08272acd7be79531550919f56f846726eabb
|
||||
chime.ogg taken from: https://github.com/Baystation12/Baystation12 at commit 662c08272acd7be79531550919f56f846726eabb
|
||||
polaroid1.ogg taken from: https://github.com/Baystation12/Baystation12 at commit 662c08272acd7be79531550919f56f846726eabb and edited (stereo to mono)
|
||||
polaroid2.ogg taken from: https://github.com/Baystation12/Baystation12 at commit 662c08272acd7be79531550919f56f846726eabb and edited (stereo to mono)
|
||||
twobeep.ogg taken from: https://github.com/Baystation12/Baystation12 at commit 662c08272acd7be79531550919f56f846726eabb
|
||||
BIN
Resources/Audio/White/Machines/polaroid1.ogg
Normal file
BIN
Resources/Audio/White/Machines/polaroid1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/White/Machines/polaroid2.ogg
Normal file
BIN
Resources/Audio/White/Machines/polaroid2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/White/Machines/twobeep.ogg
Normal file
BIN
Resources/Audio/White/Machines/twobeep.ogg
Normal file
Binary file not shown.
@@ -9,3 +9,8 @@ store-currency-display-debugdollar = {$amount ->
|
||||
}
|
||||
store-currency-display-telecrystal = TC
|
||||
store-currency-display-stolen-essence = Stolen Essence
|
||||
|
||||
store-currency-display-space-cash = {$amount ->
|
||||
[one] One Dollar
|
||||
*[other] Dollars
|
||||
}
|
||||
|
||||
@@ -9,3 +9,10 @@ store-currency-display-debugdollar =
|
||||
}
|
||||
store-currency-display-telecrystal = ТК
|
||||
store-currency-display-stolen-essence = Украденная эссенция
|
||||
|
||||
store-currency-display-space-cash =
|
||||
{ $amount ->
|
||||
[one] { $amount } доллар
|
||||
[few] { $amount } доллара
|
||||
*[other] { $amount } долларов
|
||||
}
|
||||
|
||||
1
Resources/Locale/ru-RU/white/economy/announcemets.ftl
Normal file
1
Resources/Locale/ru-RU/white/economy/announcemets.ftl
Normal file
@@ -0,0 +1 @@
|
||||
salary-pay-announcement = Внимание! Экипажу станции была выплачена заработная плата.
|
||||
12
Resources/Locale/ru-RU/white/economy/atm.ftl
Normal file
12
Resources/Locale/ru-RU/white/economy/atm.ftl
Normal file
@@ -0,0 +1,12 @@
|
||||
atm-trying-insert-cash-error = Купюроприемник закрыт.
|
||||
atm-wrong-pin = Неверный PIN-код.
|
||||
atm-not-enough-cash = Недостаточно средств.
|
||||
|
||||
|
||||
atm-ui-select-withdraw-amount = Выберите сумму вывода.
|
||||
atm-ui-insert-card = Вставьте карту.
|
||||
atm-ui-balance = Баланс: { $balance } ¢
|
||||
|
||||
ent-ATM = Банкомат
|
||||
.desc = Для всех ваших денежных нужд!
|
||||
.suffix = { "" }
|
||||
6
Resources/Locale/ru-RU/white/economy/bank.ftl
Normal file
6
Resources/Locale/ru-RU/white/economy/bank.ftl
Normal file
@@ -0,0 +1,6 @@
|
||||
bank-program-ui-no-account = [color=red]Аккаунт не привязан.[/color]
|
||||
bank-program-name = Банк
|
||||
|
||||
ent-BankCartridge = Картридж банка
|
||||
.desc = Программа для управления банковским аккаунтом.
|
||||
.suffix = { "" }
|
||||
32
Resources/Locale/ru-RU/white/economy/cards.ftl
Normal file
32
Resources/Locale/ru-RU/white/economy/cards.ftl
Normal file
@@ -0,0 +1,32 @@
|
||||
ent-CommandBudgetCard = Ведомственная карточка (Станционный бюджет).
|
||||
.desc = Предоставляет доступ к бюджету станции!
|
||||
.suffix = { "" }
|
||||
|
||||
ent-CargoBudgetCard = Ведомственная карточка (Бюджет снабжения).
|
||||
.desc = Предоставляет доступ к бюджету снабжения!
|
||||
.suffix = { "" }
|
||||
|
||||
ent-CivilianBudgetCard = Ведомственная карточка (Гражданский бюджет).
|
||||
.desc = Предоставляет доступ к гражданскому бюджету!
|
||||
.suffix = { "" }
|
||||
|
||||
ent-EngineeringBudgetCard = Ведомственная карточка (Инженерный бюджет).
|
||||
.desc = Предоставляет доступ к инженерному бюджету!
|
||||
.suffix = { "" }
|
||||
|
||||
ent-MedicalBudgetCard = Ведомственная карточка (Медицинский бюджет).
|
||||
.desc = Предоставляет доступ к медицинскому бюджету!
|
||||
.suffix = { "" }
|
||||
|
||||
ent-ScienceBudgetCard = Ведомственная карточка (Научный бюджет).
|
||||
.desc = Предоставляет доступ к научному бюджету!
|
||||
.suffix = { "" }
|
||||
|
||||
ent-SecurityBudgetCard = Ведомственная карточка (Оборонный бюджет).
|
||||
.desc = Предоставляет доступ к оборонному бюджету!
|
||||
.suffix = { "" }
|
||||
|
||||
ent-CommandBudgetPinPaper = PIN-код станционного бюджета.
|
||||
.suffix = { "" }
|
||||
|
||||
command-budget-pin-message = PIN-код станционного бюджета: { $pin }
|
||||
16
Resources/Locale/ru-RU/white/economy/eftpos.ftl
Normal file
16
Resources/Locale/ru-RU/white/economy/eftpos.ftl
Normal file
@@ -0,0 +1,16 @@
|
||||
eftpos-ui-title = Терминал безналичной оплаты
|
||||
eftpos-ui-amount-text = Сумма кредитов:
|
||||
eftpos-ui-card-lock-text = Заблокировать
|
||||
eftpos-ui-card-unlock-text = Разблокировать
|
||||
eftpos-ui-card-lock-desc = Проведите картой для блокировки
|
||||
eftpos-ui-card-unlock-desc = Проведите картой для разблокировки
|
||||
eftpos-ui-account-text = Аккаунт: { $owner }
|
||||
|
||||
eftpos-transaction-success = Транзакция успешна
|
||||
eftpos-transaction-error = Ошибка транзакции
|
||||
|
||||
command-budget = Командный бюджет
|
||||
|
||||
ent-Eftpos = Терминал безналичной оплаты
|
||||
.desc = Проведите картой для совершения покупок без использования наличных.
|
||||
.suffix = { "" }
|
||||
2
Resources/Locale/ru-RU/white/economy/memory.ftl
Normal file
2
Resources/Locale/ru-RU/white/economy/memory.ftl
Normal file
@@ -0,0 +1,2 @@
|
||||
character-info-memories-label = Память
|
||||
character-info-memories-placeholder-text = Воспоминания
|
||||
1
Resources/Locale/ru-RU/white/economy/vending.ftl
Normal file
1
Resources/Locale/ru-RU/white/economy/vending.ftl
Normal file
@@ -0,0 +1 @@
|
||||
vending-ui-credits-amount = Кредитов в автомате: { $credits }
|
||||
@@ -34,7 +34,6 @@
|
||||
- id: WeaponEgun
|
||||
- id: CommsComputerCircuitboard
|
||||
- id: ClothingHeadsetAltCommand
|
||||
- id: SpaceCash1000
|
||||
- id: PlushieNuke
|
||||
prob: 0.1
|
||||
- id: CigarGoldCase
|
||||
@@ -45,6 +44,8 @@
|
||||
- id: WeaponAntiqueLaser
|
||||
- id: JetpackCaptainFilled
|
||||
- id: MedalCase
|
||||
- id: CommandBudgetCard
|
||||
- id: CommandBudgetPinPaper
|
||||
|
||||
- type: entity
|
||||
id: LockerCaptainFilled
|
||||
@@ -60,7 +61,6 @@
|
||||
- id: WeaponDisabler
|
||||
- id: CommsComputerCircuitboard
|
||||
- id: ClothingHeadsetAltCommand
|
||||
- id: SpaceCash1000
|
||||
- id: PlushieNuke
|
||||
prob: 0.1
|
||||
- id: CigarGoldCase
|
||||
@@ -71,6 +71,8 @@
|
||||
- id: WeaponAntiqueLaser
|
||||
- id: JetpackCaptainFilled
|
||||
- id: MedalCase
|
||||
- id: CommandBudgetCard
|
||||
- id: CommandBudgetPinPaper
|
||||
|
||||
- type: entity
|
||||
id: LockerHeadOfPersonnelFilled
|
||||
@@ -168,6 +170,7 @@
|
||||
- id: RubberStampCMO
|
||||
- id: MedicalTechFabCircuitboard
|
||||
- id: BoxEncryptionKeyMedical
|
||||
- id: Eftpos
|
||||
|
||||
- type: entity
|
||||
id: LockerChiefMedicalOfficerFilled
|
||||
@@ -188,6 +191,7 @@
|
||||
- id: RubberStampCMO
|
||||
- id: MedicalTechFabCircuitboard
|
||||
- id: BoxEncryptionKeyMedical
|
||||
- id: Eftpos
|
||||
|
||||
- type: entity
|
||||
id: LockerResearchDirectorFilledHardsuit
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
prob: 0.05
|
||||
orGroup: Surgshrubs
|
||||
- id: ClothingMaskSterile
|
||||
- id: Eftpos
|
||||
|
||||
- type: entity
|
||||
id: LockerChemistryFilled
|
||||
@@ -123,6 +124,7 @@
|
||||
- id: ClothingMaskSterile
|
||||
- id: HandLabeler
|
||||
prob: 0.5
|
||||
- id: Eftpos
|
||||
|
||||
- type: entity
|
||||
id: LockerParamedicFilled
|
||||
@@ -144,3 +146,4 @@
|
||||
- id: ClothingMaskSterile
|
||||
- id: MedkitFilled
|
||||
prob: 0.3
|
||||
- id: Eftpos
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
amount: 2
|
||||
- id: RagItem
|
||||
amount: 2
|
||||
- id: Eftpos
|
||||
|
||||
#- type: entity
|
||||
# id: LockerFormalFilled
|
||||
@@ -50,6 +51,7 @@
|
||||
- id: DrinkMilkCarton
|
||||
amount: 2
|
||||
- id: DrinkSoyMilkCarton
|
||||
- id: Eftpos
|
||||
|
||||
- type: entity
|
||||
id: ClosetJanitorFilled
|
||||
@@ -106,6 +108,7 @@
|
||||
- id: ClothingUniformOveralls
|
||||
- id: ClothingHeadHatTrucker
|
||||
prob: 0.1
|
||||
- id: Eftpos
|
||||
|
||||
- type: entity
|
||||
id: LockerBotanistLoot
|
||||
|
||||
@@ -34,3 +34,4 @@
|
||||
DrinkWhiskeyBottleFull: 5
|
||||
DrinkWineBottleFull: 5
|
||||
DrinkChampagneBottleFull: 2 #because the premium drink
|
||||
Eftpos: 4
|
||||
|
||||
@@ -19,3 +19,4 @@
|
||||
FoodButter: 4
|
||||
FoodCheese: 1
|
||||
FoodMeat: 6
|
||||
Eftpos: 4
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
Bloodpack: 5
|
||||
EpinephrineChemistryBottle: 3
|
||||
Syringe: 5
|
||||
Eftpos: 2 #WD edit
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
EZNutrientChemistryBottle: 3
|
||||
Bucket: 3
|
||||
DiseaseSwab: 20
|
||||
Eftpos: 4 #WD edit
|
||||
#TO DO:
|
||||
#plant analyzer
|
||||
emaggedInventory:
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
- key: enum.StorageUiKey.Key
|
||||
type: StorageBoundUserInterface
|
||||
- type: StaticPrice
|
||||
price: 80
|
||||
price: 20
|
||||
# WD edit sounds start
|
||||
- type: EmitSoundOnPickup
|
||||
sound:
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
- BypassInteractionRangeChecks
|
||||
- BypassDropChecks
|
||||
- SMImmune
|
||||
- IgnoreBalanceChecks
|
||||
- type: Input
|
||||
context: "aghost"
|
||||
- type: Ghost
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
interfaces:
|
||||
- key: enum.TransferAmountUiKey.Key
|
||||
type: TransferAmountBoundUserInterface
|
||||
- type: StaticPrice
|
||||
price: 30
|
||||
|
||||
- type: entity
|
||||
parent: DrinkBase
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
- type: Tag
|
||||
tags:
|
||||
- DrinkCan
|
||||
- type: StaticPrice
|
||||
price: 20
|
||||
|
||||
- type: entity
|
||||
parent: DrinkCanBaseFull
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
damage:
|
||||
types:
|
||||
Blunt: 0
|
||||
- type: StaticPrice
|
||||
price: 20
|
||||
|
||||
- type: entity
|
||||
parent: DrinkBaseCup
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
- type: Item
|
||||
sprite: Objects/Consumable/Food/Baked/donut.rsi
|
||||
size: Tiny
|
||||
- type: StaticPrice
|
||||
price: 10
|
||||
# Tastes like donut.
|
||||
|
||||
# The sprinkles are now an overlay, so you can put them on any donut! If we really
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
solution: food
|
||||
- type: SpaceGarbage
|
||||
- type: StaticPrice
|
||||
price: 0
|
||||
price: 5
|
||||
|
||||
# Packets
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
sprite: Objects/Consumable/Food/snacks.rsi
|
||||
heldPrefix: packet
|
||||
size: Tiny
|
||||
- type: StaticPrice
|
||||
price: 10
|
||||
# Snacks
|
||||
|
||||
# "Snacks" means food in a packet. Down the line this stuff can have multiple
|
||||
@@ -112,6 +114,8 @@
|
||||
- id: FoodSnackChocolateBar
|
||||
sound:
|
||||
path: /Audio/Effects/unwrap.ogg
|
||||
- type: StaticPrice
|
||||
price: 20
|
||||
|
||||
- type: entity
|
||||
name: chocolate bar
|
||||
|
||||
@@ -64,7 +64,9 @@
|
||||
- cig4
|
||||
- cig5
|
||||
- cig6
|
||||
- type: Appearance
|
||||
- type: Appearance
|
||||
- type: StaticPrice
|
||||
price: 10
|
||||
|
||||
- type: entity
|
||||
id: CigPackMixedBase
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
- cigar7
|
||||
- cigar8
|
||||
- type: Appearance
|
||||
- type: StaticPrice
|
||||
price: 40
|
||||
|
||||
- type: entity
|
||||
id: CigarGoldCase
|
||||
@@ -72,3 +74,5 @@
|
||||
contents:
|
||||
- id: CigarGold
|
||||
amount: 8
|
||||
- type: StaticPrice
|
||||
price: 80
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
equippedPrefix: unlit
|
||||
- type: Item
|
||||
size: Tiny
|
||||
- type: StaticPrice
|
||||
price: 10
|
||||
|
||||
- type: entity
|
||||
id: CigarGoldSpent
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
solutions:
|
||||
smokable:
|
||||
maxVol: 30
|
||||
- type: StaticPrice
|
||||
price: 20
|
||||
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
@@ -80,3 +82,5 @@
|
||||
solution: smokable
|
||||
- type: ExaminableSolution
|
||||
solution: smokable
|
||||
- type: StaticPrice
|
||||
price: 20
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
- CrewManifestCartridge
|
||||
- NotekeeperCartridge
|
||||
- NewsReadCartridge
|
||||
- BankCartridge
|
||||
cartridgeSlot:
|
||||
priority: -1
|
||||
name: Cartridge
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
Credit: 1
|
||||
- type: StaticPrice
|
||||
price: 0
|
||||
- type: StackPrice
|
||||
price: 1
|
||||
- type: Stack
|
||||
stackType: Credit
|
||||
count: 1
|
||||
@@ -39,6 +41,9 @@
|
||||
mask:
|
||||
- ItemMask
|
||||
- type: Appearance
|
||||
- type: Currency
|
||||
price:
|
||||
SpaceCash: 1
|
||||
|
||||
- type: material
|
||||
id: Credit
|
||||
|
||||
@@ -86,6 +86,9 @@
|
||||
netsync: false
|
||||
radius: 1.1 #smallest possible
|
||||
color: orange
|
||||
- type: StaticPrice
|
||||
price: 10
|
||||
|
||||
|
||||
- type: entity
|
||||
name: cheap lighter
|
||||
@@ -115,6 +118,8 @@
|
||||
- ReagentId: WeldingFuel
|
||||
Quantity: 4
|
||||
maxVol: 4 #uses less fuel than a welder, so this isnt as bad as it looks
|
||||
- type: StaticPrice
|
||||
price: 5
|
||||
|
||||
- type: entity
|
||||
name: flippo lighter
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
- type: VendingMachine
|
||||
pack: CondimentInventory
|
||||
offState: off
|
||||
priceMultiplier: 1.0
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/condiments.rsi
|
||||
drawdepth: SmallObjects
|
||||
@@ -265,6 +266,7 @@
|
||||
normalState: normal-unshaded
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: CigaretteMachineAds
|
||||
- type: Speech
|
||||
@@ -291,6 +293,7 @@
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
denyState: deny-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: ClothesMateAds
|
||||
- type: Speech
|
||||
@@ -324,6 +327,7 @@
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
denyState: deny-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: ClothesMateAds
|
||||
- type: Speech
|
||||
@@ -363,6 +367,7 @@
|
||||
screenState: screen
|
||||
ejectDelay: 5
|
||||
soundVend: /Audio/Machines/machine_vend_hot_drink.ogg
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: HotDrinksMachineAds
|
||||
- type: Speech
|
||||
@@ -400,6 +405,7 @@
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
ejectDelay: 1.9
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: RobustSoftdrinksAds
|
||||
- type: Speech
|
||||
@@ -467,6 +473,7 @@
|
||||
components:
|
||||
- type: VendingMachine
|
||||
pack: SpaceUpInventory
|
||||
priceMultiplier: 1.0
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/spaceup.rsi
|
||||
layers:
|
||||
@@ -489,6 +496,7 @@
|
||||
components:
|
||||
- type: VendingMachine
|
||||
pack: SodaInventory
|
||||
priceMultiplier: 1.0
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/soda.rsi
|
||||
layers:
|
||||
@@ -512,6 +520,7 @@
|
||||
components:
|
||||
- type: VendingMachine
|
||||
pack: StarkistInventory
|
||||
priceMultiplier: 1.0
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/starkist.rsi
|
||||
layers:
|
||||
@@ -543,6 +552,7 @@
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
ejectDelay: 1.9
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: RobustSoftdrinksAds
|
||||
- type: Speech
|
||||
@@ -577,6 +587,7 @@
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
ejectDelay: 1.9
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: RobustSoftdrinksAds
|
||||
- type: Speech
|
||||
@@ -701,6 +712,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: DiscountDansAds
|
||||
- type: Speech
|
||||
@@ -906,6 +918,7 @@
|
||||
normalState: normal-unshaded
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: GetmoreChocolateCorpAds
|
||||
- type: Speech
|
||||
@@ -939,6 +952,7 @@
|
||||
normalState: normal-unshaded
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/sustenance.rsi
|
||||
layers:
|
||||
@@ -1049,6 +1063,7 @@
|
||||
normalState: normal-unshaded
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: BodaAds
|
||||
- type: Speech
|
||||
@@ -1081,6 +1096,7 @@
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
screenState: screen
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: AutoDrobeAds
|
||||
- type: Speech
|
||||
@@ -1246,6 +1262,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: ChangAds
|
||||
- type: Speech
|
||||
@@ -1309,6 +1326,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: DonutAds
|
||||
- type: Speech
|
||||
@@ -1384,6 +1402,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: HyDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1410,6 +1429,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: LawDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1436,6 +1456,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: SecDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1462,6 +1483,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: BarDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1488,6 +1510,7 @@
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
denyState: deny-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/chapdrobe.rsi
|
||||
layers:
|
||||
@@ -1516,6 +1539,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: CargoDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1542,6 +1566,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: MediDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1568,6 +1593,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: ChemDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1620,6 +1646,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: AtmosDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1646,6 +1673,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: EngiDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1672,6 +1700,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: ChefDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1698,6 +1727,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: DetDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1724,6 +1754,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: JaniDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1750,6 +1781,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: SciDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1802,6 +1834,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: RoboDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1828,6 +1861,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: GeneDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1854,6 +1888,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Advertise
|
||||
pack: ViroDrobeAds
|
||||
- type: Sprite
|
||||
@@ -1880,6 +1915,7 @@
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
priceMultiplier: 1.0
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/centdrobe.rsi
|
||||
layers:
|
||||
@@ -1913,6 +1949,7 @@
|
||||
denyState: deny-unshaded
|
||||
ejectDelay: 1.9
|
||||
soundVend: /Audio/Items/bikehorn.ogg
|
||||
priceMultiplier: 1.0
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/happyhonk.rsi
|
||||
layers:
|
||||
|
||||
@@ -100,6 +100,11 @@
|
||||
kind: source
|
||||
path: "/Textures/Shaders/cataracts.swsl"
|
||||
|
||||
- type: shader
|
||||
id: Gradient
|
||||
kind: source
|
||||
path: "/Textures/Shaders/White/gradient.swsl"
|
||||
|
||||
- type: shader
|
||||
id: SaturationScale
|
||||
kind: source
|
||||
|
||||
@@ -19,3 +19,9 @@
|
||||
- type: currency
|
||||
id: DebugDollar
|
||||
displayName: store-currency-display-debugdollar
|
||||
|
||||
- type: currency
|
||||
id: SpaceCash
|
||||
cash :
|
||||
1: SpaceCash
|
||||
displayName: store-currency-display-space-cash
|
||||
|
||||
95
Resources/Prototypes/White/Economy/card.yml
Normal file
95
Resources/Prototypes/White/Economy/card.yml
Normal file
@@ -0,0 +1,95 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: BaseDepartmentBudgetCard
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: BankCard
|
||||
startingBalance: 5000
|
||||
- type: Sprite
|
||||
sprite: White/Misc/cards.rsi
|
||||
scale: 0.8, 0.8
|
||||
|
||||
- type: entity
|
||||
parent: BaseDepartmentBudgetCard
|
||||
id: CommandBudgetCard
|
||||
name: Command budget card
|
||||
components:
|
||||
- type: Sprite
|
||||
state: budgetcard
|
||||
- type: BankCard
|
||||
commandBudgetCard: true
|
||||
|
||||
- type: entity
|
||||
parent: Paper
|
||||
id: CommandBudgetPinPaper
|
||||
name: command budget pin
|
||||
components:
|
||||
- type: CommandBudgetPinPaper
|
||||
- type: Paper
|
||||
|
||||
- type: entity
|
||||
parent: BaseDepartmentBudgetCard
|
||||
id: CargoBudgetCard
|
||||
noSpawn: true
|
||||
name: Cargo budget card
|
||||
components:
|
||||
- type: Sprite
|
||||
state: car_budget
|
||||
- type: BankCard
|
||||
accountId: 1315
|
||||
|
||||
- type: entity
|
||||
parent: BaseDepartmentBudgetCard
|
||||
id: CivilianBudgetCard
|
||||
name: Civilian budget card
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: Sprite
|
||||
state: srv_budget
|
||||
- type: BankCard
|
||||
accountId: 1316
|
||||
|
||||
- type: entity
|
||||
parent: BaseDepartmentBudgetCard
|
||||
id: EngineeringBudgetCard
|
||||
name: Engineering budget card
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: Sprite
|
||||
state: eng_budget
|
||||
- type: BankCard
|
||||
accountId: 1318
|
||||
|
||||
- type: entity
|
||||
parent: BaseDepartmentBudgetCard
|
||||
id: MedicalBudgetCard
|
||||
name: Medical budget card
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: Sprite
|
||||
state: med_budget
|
||||
- type: BankCard
|
||||
accountId: 1319
|
||||
|
||||
- type: entity
|
||||
parent: BaseDepartmentBudgetCard
|
||||
id: ScienceBudgetCard
|
||||
name: Science budget card
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: Sprite
|
||||
state: sci_budget
|
||||
- type: BankCard
|
||||
accountId: 1321
|
||||
|
||||
- type: entity
|
||||
parent: BaseDepartmentBudgetCard
|
||||
id: SecurityBudgetCard
|
||||
name: Security budget card
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: Sprite
|
||||
state: sec_budget
|
||||
- type: BankCard
|
||||
accountId: 1320
|
||||
|
||||
27
Resources/Prototypes/White/Economy/eftpos.yml
Normal file
27
Resources/Prototypes/White/Economy/eftpos.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: Eftpos
|
||||
name: EFTPOS
|
||||
description: Swipe your ID card to make purchases electronically.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Objects/Devices/eftpos.rsi
|
||||
state:
|
||||
layers:
|
||||
- state: eftpos
|
||||
- state: eftpos-screen
|
||||
shader: unshaded
|
||||
netsync: false
|
||||
- type: Eftpos
|
||||
- type: ActivatableUI
|
||||
key: enum.EftposKey.Key
|
||||
singleUser: true
|
||||
closeOnHandDeselect: false
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
- key: enum.EftposKey.Key
|
||||
type: EftposBui
|
||||
- type: Clothing
|
||||
quickEquip: false
|
||||
slots:
|
||||
- Belt
|
||||
42
Resources/Prototypes/White/Economy/salary.yml
Normal file
42
Resources/Prototypes/White/Economy/salary.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
- type: salary
|
||||
id: Salaries
|
||||
salaries:
|
||||
Captain: 800
|
||||
CentralCommandOfficial: 800
|
||||
ChiefEngineer: 600
|
||||
ChiefMedicalOfficer: 600
|
||||
HeadOfPersonnel: 600
|
||||
HeadOfSecurity: 600
|
||||
ResearchDirector: 600
|
||||
Quartermaster: 600
|
||||
CargoTechnician: 200
|
||||
SalvageSpecialist: 300
|
||||
Bartender: 200
|
||||
Botanist: 200
|
||||
Boxer: 150
|
||||
Chaplain: 150
|
||||
Chef: 200
|
||||
Clown: 150
|
||||
Janitor: 200
|
||||
Lawyer: 150
|
||||
Librarian: 150
|
||||
Mime: 150
|
||||
Musician: 150
|
||||
Passenger: 100
|
||||
Reporter: 150
|
||||
Zookeeper: 150
|
||||
ServiceWorker: 150
|
||||
AtmosphericTechnician: 400
|
||||
StationEngineer: 300
|
||||
TechnicalAssistant: 200
|
||||
Chemist: 400
|
||||
MedicalDoctor: 300
|
||||
MedicalIntern: 200
|
||||
Psychologist: 200
|
||||
Paramedic: 400
|
||||
SecurityCadet: 200
|
||||
SecurityOfficer: 300
|
||||
Detective: 400
|
||||
Warden: 500
|
||||
Scientist: 300
|
||||
ResearchAssistant: 200
|
||||
@@ -0,0 +1,21 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: BankCartridge
|
||||
name: bank cartridge
|
||||
description: A program for managing bank account
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Devices/cartridge.rsi
|
||||
state: cart-y
|
||||
netsync: false
|
||||
- type: Icon
|
||||
sprite: Objects/Devices/cartridge.rsi
|
||||
state: cart-y
|
||||
- type: UIFragment
|
||||
ui: !type:BankUi
|
||||
- type: Cartridge
|
||||
programName: bank-program-name
|
||||
icon:
|
||||
sprite: White/Structures/Machines/atm.rsi
|
||||
state: off
|
||||
- type: BankCartridge
|
||||
75
Resources/Prototypes/White/Structures/Machines/atm.yml
Normal file
75
Resources/Prototypes/White/Structures/Machines/atm.yml
Normal file
@@ -0,0 +1,75 @@
|
||||
- type: entity
|
||||
id: ATM
|
||||
name: ATM
|
||||
description: For all your monetary needs!
|
||||
placement:
|
||||
mode: SnapgridCenter
|
||||
snap:
|
||||
- Wallmount
|
||||
components:
|
||||
- type: WallMount
|
||||
arc: 360
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Clickable
|
||||
- type: InteractionOutline
|
||||
- type: Sprite
|
||||
sprite: White/Structures/Machines/atm.rsi
|
||||
snapCardinals: true
|
||||
state:
|
||||
layers:
|
||||
- state: "off"
|
||||
map: ["enum.ATMVisualLayers.Base"]
|
||||
- state: "on"
|
||||
map: ["enum.ATMVisualLayers.BaseUnshaded"]
|
||||
shader: unshaded
|
||||
- type: ATM
|
||||
idCardSlot:
|
||||
ejectSound: /Audio/Machines/id_swipe.ogg
|
||||
insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
|
||||
ejectOnBreak: true
|
||||
swap: false
|
||||
whitelist:
|
||||
components:
|
||||
- BankCard
|
||||
- type: ItemSlots
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
IdCardSlot: !type:ContainerSlot
|
||||
- type: Appearance
|
||||
- type: AmbientOnPowered
|
||||
- type: AmbientSound
|
||||
volume: -9
|
||||
range: 3
|
||||
enabled: false
|
||||
sound:
|
||||
path: /Audio/Ambience/Objects/vending_machine_hum.ogg
|
||||
# - type: Destructible
|
||||
# thresholds:
|
||||
# - trigger:
|
||||
# !type:DamageTrigger
|
||||
# damage: 100
|
||||
# behaviors:
|
||||
# - !type:DoActsBehavior
|
||||
# acts: ["Breakage"]
|
||||
# - !type:EjectVendorItems
|
||||
- type: ActivatableUI
|
||||
key: enum.ATMUiKey.Key
|
||||
singleUser: true
|
||||
- type: ActivatableUIRequiresPower
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
- key: enum.ATMUiKey.Key
|
||||
type: ATMBui
|
||||
- type: PointLight
|
||||
enabled: false
|
||||
castShadows: false
|
||||
radius: 1.5
|
||||
- type: LitOnPowered
|
||||
- type: ApcPowerReceiver
|
||||
powerLoad: 200
|
||||
priority: Low
|
||||
- type: ExtensionCableReceiver
|
||||
- type: EmitSoundOnUIOpen
|
||||
sound:
|
||||
collection: Keyboard
|
||||
@@ -9,3 +9,6 @@
|
||||
|
||||
- type: Tag
|
||||
id: SMImmune
|
||||
|
||||
- type: Tag
|
||||
id: IgnoreBalanceChecks
|
||||
|
||||
@@ -1199,4 +1199,6 @@
|
||||
- type: Tag
|
||||
id: ZombifyableByMelee
|
||||
|
||||
- type: Tag
|
||||
id: SpaceCash
|
||||
# WHITE END
|
||||
|
||||
20
Resources/Textures/Shaders/White/gradient.swsl
Normal file
20
Resources/Textures/Shaders/White/gradient.swsl
Normal file
@@ -0,0 +1,20 @@
|
||||
uniform sampler2D SCREEN_TEXTURE;
|
||||
|
||||
uniform highp vec4 first_color = vec4(1.0);
|
||||
uniform highp vec4 second_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
uniform highp float position = 0.0;
|
||||
uniform highp float size = 1.0;
|
||||
uniform highp float angle = 90.0;
|
||||
|
||||
void fragment() {
|
||||
|
||||
highp float pivot = position + 0.5;
|
||||
|
||||
highp vec2 uv = UV - pivot;
|
||||
|
||||
highp float rotated = uv.x * cos(radians(angle)) - uv.y * sin(radians(angle));
|
||||
|
||||
highp float pos = smoothstep((1.0 - size) + position, size + 0.0001 + position, rotated + pivot);
|
||||
|
||||
COLOR = mix(first_color, second_color, pos);
|
||||
}
|
||||
BIN
Resources/Textures/White/Misc/cards.rsi/budgetcard.png
Normal file
BIN
Resources/Textures/White/Misc/cards.rsi/budgetcard.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 336 B |
BIN
Resources/Textures/White/Misc/cards.rsi/car_budget.png
Normal file
BIN
Resources/Textures/White/Misc/cards.rsi/car_budget.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 328 B |
BIN
Resources/Textures/White/Misc/cards.rsi/civ_budget.png
Normal file
BIN
Resources/Textures/White/Misc/cards.rsi/civ_budget.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 315 B |
BIN
Resources/Textures/White/Misc/cards.rsi/eng_budget.png
Normal file
BIN
Resources/Textures/White/Misc/cards.rsi/eng_budget.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 349 B |
BIN
Resources/Textures/White/Misc/cards.rsi/med_budget.png
Normal file
BIN
Resources/Textures/White/Misc/cards.rsi/med_budget.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 316 B |
35
Resources/Textures/White/Misc/cards.rsi/meta.json
Normal file
35
Resources/Textures/White/Misc/cards.rsi/meta.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "da poxuy",
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "budgetcard"
|
||||
},
|
||||
{
|
||||
"name": "car_budget"
|
||||
},
|
||||
{
|
||||
"name": "srv_budget"
|
||||
},
|
||||
{
|
||||
"name": "civ_budget"
|
||||
},
|
||||
{
|
||||
"name": "sec_budget"
|
||||
},
|
||||
{
|
||||
"name": "med_budget"
|
||||
},
|
||||
{
|
||||
"name": "sci_budget"
|
||||
},
|
||||
{
|
||||
"name": "eng_budget"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/White/Misc/cards.rsi/sci_budget.png
Normal file
BIN
Resources/Textures/White/Misc/cards.rsi/sci_budget.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 312 B |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user