Skip to content

Commit

Permalink
Merge branch 'ValidPrinter' of https://github.com/Smugman/Delta-v int…
Browse files Browse the repository at this point in the history
…o ValidPrinter
  • Loading branch information
Smugman committed Dec 28, 2024
2 parents 517a9a0 + a17966b commit 6a1af0d
Show file tree
Hide file tree
Showing 48 changed files with 1,048 additions and 62 deletions.
11 changes: 11 additions & 0 deletions Content.Client/Crayon/CrayonSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ protected override void FrameUpdate(FrameEventArgs args)
}

_parent.UIUpdateNeeded = false;

// Frontier: unlimited crayon, Delta V Port
if (_parent.Capacity == int.MaxValue)
{
_label.SetMarkup(Robust.Shared.Localization.Loc.GetString("crayon-drawing-label-unlimited",
("color", _parent.Color),
("state", _parent.SelectedState)));
return;
}
// End Frontier, Delta V Port

_label.SetMarkup(Robust.Shared.Localization.Loc.GetString("crayon-drawing-label",
("color",_parent.Color),
("state",_parent.SelectedState),
Expand Down
123 changes: 123 additions & 0 deletions Content.Client/DeltaV/VendingMachines/ShopVendorSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
using Content.Shared.DeltaV.VendingMachines;
using Content.Shared.VendingMachines;
using Robust.Client.Animations;
using Robust.Client.GameObjects;

namespace Content.Client.DeltaV.VendingMachines;

public sealed class ShopVendorSystem : SharedShopVendorSystem
{
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ShopVendorComponent, AppearanceChangeEvent>(OnAppearanceChange);
SubscribeLocalEvent<ShopVendorComponent, AnimationCompletedEvent>(OnAnimationCompleted);
}

// copied from vending machines because its not reusable in other systems :)
private void OnAnimationCompleted(Entity<ShopVendorComponent> ent, ref AnimationCompletedEvent args)
{
UpdateAppearance((ent, ent.Comp));
}

private void OnAppearanceChange(Entity<ShopVendorComponent> ent, ref AppearanceChangeEvent args)
{
UpdateAppearance((ent, ent.Comp, args.Sprite));
}

private void UpdateAppearance(Entity<ShopVendorComponent, SpriteComponent?> ent)
{
if (!Resolve(ent, ref ent.Comp2))
return;

if (!_appearance.TryGetData<VendingMachineVisualState>(ent, VendingMachineVisuals.VisualState, out var state))
state = VendingMachineVisualState.Normal;

var sprite = ent.Comp2;
SetLayerState(VendingMachineVisualLayers.Base, ent.Comp1.OffState, sprite);
SetLayerState(VendingMachineVisualLayers.Screen, ent.Comp1.ScreenState, sprite);
switch (state)
{
case VendingMachineVisualState.Normal:
SetLayerState(VendingMachineVisualLayers.BaseUnshaded, ent.Comp1.NormalState, sprite);
break;

case VendingMachineVisualState.Deny:
if (ent.Comp1.LoopDenyAnimation)
SetLayerState(VendingMachineVisualLayers.BaseUnshaded, ent.Comp1.DenyState, sprite);
else
PlayAnimation(ent, VendingMachineVisualLayers.BaseUnshaded, ent.Comp1.DenyState, ent.Comp1.DenyDelay, sprite);
break;

case VendingMachineVisualState.Eject:
PlayAnimation(ent, VendingMachineVisualLayers.BaseUnshaded, ent.Comp1.EjectState, ent.Comp1.EjectDelay, sprite);
break;

case VendingMachineVisualState.Broken:
HideLayers(sprite);
SetLayerState(VendingMachineVisualLayers.Base, ent.Comp1.BrokenState, sprite);
break;

case VendingMachineVisualState.Off:
HideLayers(sprite);
break;
}
}

private static void SetLayerState(VendingMachineVisualLayers layer, string? state, SpriteComponent sprite)
{
if (state == null)
return;

sprite.LayerSetVisible(layer, true);
sprite.LayerSetAutoAnimated(layer, true);
sprite.LayerSetState(layer, state);
}

private void PlayAnimation(EntityUid uid, VendingMachineVisualLayers layer, string? state, TimeSpan time, SpriteComponent sprite)
{
if (state == null || _animationPlayer.HasRunningAnimation(uid, state))
return;

var animation = GetAnimation(layer, state, time);
sprite.LayerSetVisible(layer, true);
_animationPlayer.Play(uid, animation, state);
}

private static Animation GetAnimation(VendingMachineVisualLayers layer, string state, TimeSpan time)
{
return new Animation
{
Length = time,
AnimationTracks =
{
new AnimationTrackSpriteFlick
{
LayerKey = layer,
KeyFrames =
{
new AnimationTrackSpriteFlick.KeyFrame(state, 0f)
}
}
}
};
}

private static void HideLayers(SpriteComponent sprite)
{
HideLayer(VendingMachineVisualLayers.BaseUnshaded, sprite);
HideLayer(VendingMachineVisualLayers.Screen, sprite);
}

private static void HideLayer(VendingMachineVisualLayers layer, SpriteComponent sprite)
{
if (!sprite.LayerMapTryGet(layer, out var actualLayer))
return;

sprite.LayerSetVisible(actualLayer, false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Content.Shared.DeltaV.VendingMachines;
using Robust.Client.UserInterface;

namespace Content.Client.DeltaV.VendingMachines.UI;

public sealed class ShopVendorBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private ShopVendorWindow? _window;

public ShopVendorBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}

protected override void Open()
{
base.Open();

_window = this.CreateWindow<ShopVendorWindow>();
_window.SetEntity(Owner);
_window.OpenCenteredLeft();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
_window.OnItemSelected += index => SendMessage(new ShopVendorPurchaseMessage(index));
}
}
13 changes: 13 additions & 0 deletions Content.Client/DeltaV/VendingMachines/UI/ShopVendorItem.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<BoxContainer xmlns="https://spacestation14.io"
Orientation="Horizontal"
HorizontalExpand="True"
SeparationOverride="4">
<EntityPrototypeView
Name="ItemPrototype"
Margin="4 0 0 0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MinSize="32 32"/>
<Label Name="NameLabel" SizeFlagsStretchRatio="3" HorizontalExpand="True" ClipText="True"/>
<Label Name="CostLabel" SizeFlagsStretchRatio="3" HorizontalAlignment="Right" Margin="8 0"/>
</BoxContainer>
21 changes: 21 additions & 0 deletions Content.Client/DeltaV/VendingMachines/UI/ShopVendorItem.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;

namespace Content.Client.DeltaV.VendingMachines.UI;

[GenerateTypedNameReferences]
public sealed partial class ShopVendorItem : BoxContainer
{
public ShopVendorItem(EntProtoId entProto, string text, uint cost)
{
RobustXamlLoader.Load(this);

ItemPrototype.SetPrototype(entProto);

NameLabel.Text = text;

CostLabel.Text = cost.ToString();
}
}
24 changes: 24 additions & 0 deletions Content.Client/DeltaV/VendingMachines/UI/ShopVendorWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MinHeight="210">
<BoxContainer Name="MainContainer" Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin="4 4"/>
<Label Name="BalanceLabel" Margin="4 4"/>
</BoxContainer>
<controls:SearchListContainer Name="VendingContents" VerticalExpand="True" Margin="4 4"/>
<!-- Footer -->
<BoxContainer Orientation="Vertical">
<PanelContainer StyleClasses="LowDivider" />
<BoxContainer Orientation="Horizontal" Margin="10 2 5 0" VerticalAlignment="Bottom">
<Label Text="{Loc 'shop-vendor-flavor-left'}" StyleClasses="WindowFooterText" />
<Label Text="{Loc 'shop-vendor-flavor-right'}" StyleClasses="WindowFooterText"
HorizontalAlignment="Right" HorizontalExpand="True" Margin="0 0 5 0" />
<TextureRect StyleClasses="NTLogoDark" Stretch="KeepAspectCentered"
VerticalAlignment="Center" HorizontalAlignment="Right" SetSize="19 19"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
147 changes: 147 additions & 0 deletions Content.Client/DeltaV/VendingMachines/UI/ShopVendorWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.DeltaV.VendingMachines;
using Content.Shared.Stacks;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System.Numerics;

namespace Content.Client.DeltaV.VendingMachines.UI;

[GenerateTypedNameReferences]
public sealed partial class ShopVendorWindow : FancyWindow
{
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
private readonly ShopVendorSystem _vendor;

/// <summary>
/// Event fired with the listing index to purchase.
/// </summary>
public event Action<int>? OnItemSelected;

private EntityUid _owner;
private readonly StyleBoxFlat _style = new() { BackgroundColor = new Color(70, 73, 102) };
private readonly StyleBoxFlat _styleBroke = new() { BackgroundColor = Color.FromHex("#303133") };
private readonly List<ListContainerButton> _buttons = new();
private uint _balance = 1;

public ShopVendorWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

_vendor = _entMan.System<ShopVendorSystem>();

VendingContents.SearchBar = SearchBar;
VendingContents.DataFilterCondition += DataFilterCondition;
VendingContents.GenerateItem += GenerateButton;
VendingContents.ItemKeyBindDown += (args, data) => OnItemSelected?.Invoke(((ShopVendorListingData) data).Index);
}

public void SetEntity(EntityUid owner)
{
_owner = owner;

if (!_entMan.TryGetComponent<ShopVendorComponent>(owner, out var comp))
return;

var pack = _proto.Index(comp.Pack);
Populate(pack.Listings);

UpdateBalance();
}

private void UpdateBalance(uint balance)
{
if (_balance == balance)
return;

_balance = balance;

BalanceLabel.Text = Loc.GetString("shop-vendor-balance", ("points", balance));

// disable items that are too expensive to buy
foreach (var button in _buttons)
{
if (button.Data is ShopVendorListingData data)
button.Disabled = data.Cost > balance;

button.StyleBoxOverride = button.Disabled ? _styleBroke : _style;
}
}

private void UpdateBalance()
{
if (_player.LocalEntity is {} user)
UpdateBalance(_vendor.GetBalance(_owner, user));
}

private bool DataFilterCondition(string filter, ListData data)
{
if (data is not ShopVendorListingData { Text: var text })
return false;

if (string.IsNullOrEmpty(filter))
return true;

return text.Contains(filter, StringComparison.CurrentCultureIgnoreCase);
}

private void GenerateButton(ListData data, ListContainerButton button)
{
if (data is not ShopVendorListingData cast)
return;

_buttons.Add(button);
button.AddChild(new ShopVendorItem(cast.ItemId, cast.Text, cast.Cost));

button.ToolTip = cast.Text;
button.Disabled = cast.Cost > _balance;
button.StyleBoxOverride = button.Disabled ? _styleBroke : _style;
}

public void Populate(List<ShopListing> listings)
{
var longestEntry = string.Empty;
var listData = new List<ShopVendorListingData>();
for (var i = 0; i < listings.Count; i++)
{
var listing = listings[i];
var proto = _proto.Index(listing.Id);
var text = proto.Name;
if (proto.TryGetComponent<StackComponent>(out var stack, _factory) && stack.Count > 1)
{
text += " ";
text += Loc.GetString("shop-vendor-stack-suffix", ("count", stack.Count));
}
listData.Add(new ShopVendorListingData(i, listing.Id, text, listing.Cost));
}

_buttons.Clear();
VendingContents.PopulateList(listData);
SetSizeAfterUpdate(longestEntry.Length, listings.Count);
}

private void SetSizeAfterUpdate(int longestEntryLength, int contentCount)
{
SetSize = new Vector2(Math.Clamp((longestEntryLength + 2) * 12, 250, 400),
Math.Clamp(contentCount * 50, 150, 350));
}

protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);

UpdateBalance();
}
}

public record ShopVendorListingData(int Index, EntProtoId ItemId, string Text, uint Cost) : ListData;
11 changes: 8 additions & 3 deletions Content.Server/Crayon/CrayonSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,14 @@ private void OnCrayonAfterInteract(EntityUid uid, CrayonComponent component, Aft
if (component.UseSound != null)
_audio.PlayPvs(component.UseSound, uid, AudioParams.Default.WithVariation(0.125f));

// Decrease "Ammo"
component.Charges--;
Dirty(uid, component);
// Frontier: check if crayon is infinite, Delta V Port
if (component.Charges != int.MaxValue)
{
// Decrease "Ammo"
component.Charges--;
Dirty(uid, component);
}
// End Frontier, Delta V Port

_adminLogger.Add(LogType.CrayonDraw, LogImpact.Low, $"{EntityManager.ToPrettyString(args.User):user} drew a {component.Color:color} {component.SelectedState}");
args.Handled = true;
Expand Down
Loading

0 comments on commit 6a1af0d

Please sign in to comment.