Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smart fridge #555

Merged
merged 29 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b79907f
Переписываю с 0
SkaldetSkaeg Nov 2, 2023
743b485
3 попытки совмещения ужа и ежа, на этот раз полностью по предложению …
SkaldetSkaeg Nov 5, 2023
0b9544d
Merge branch 'SmartFridge' of https://github.com/SkaldetSkaeg/space-s…
SkaldetSkaeg Nov 5, 2023
668eb52
Первые потуги третьей попытки совместить ужа Storage и Dtictionary Ve…
SkaldetSkaeg Nov 12, 2023
669fd94
Адекватное отображение в новом интерфейсе
SkaldetSkaeg Nov 19, 2023
b4f3cd4
Merge branch 'SerbiaStrong-220:master' into SmartFridge
SkaldetSkaeg Nov 28, 2023
ee8cd24
Добработки работы интерфейса с Storage (черновой вариант)
SkaldetSkaeg Nov 28, 2023
850975c
Merge branch 'SmartFridge' of https://github.com/SkaldetSkaeg/space-s…
SkaldetSkaeg Nov 28, 2023
28b789e
Function of getting items adjusted
SkaldetSkaeg Nov 28, 2023
7f9a43f
Pre-PR state
SkaldetSkaeg Dec 1, 2023
4f2491c
done
SkaldetSkaeg Dec 2, 2023
2b219d8
Merge branch 'SerbiaStrong-220:master' into SmartFridge
SkaldetSkaeg Dec 2, 2023
8afe5a2
Merge branch 'SerbiaStrong-220:master' into SmartFridge
SkaldetSkaeg Dec 3, 2023
8de211a
Поправил файл миграции
SkaldetSkaeg Dec 3, 2023
1b15a2a
Merge branch 'SmartFridge' of https://github.com/SkaldetSkaeg/space-s…
SkaldetSkaeg Dec 3, 2023
ddc4108
Откат
SkaldetSkaeg Dec 3, 2023
550bf5a
Поправлено id, добавлена локализация, добавлена ent вайл миграции
SkaldetSkaeg Dec 3, 2023
e062627
Поправлены тэги (очень странно работает со Storage, так как предмет п…
SkaldetSkaeg Dec 3, 2023
5638862
Перенес функции отображения инвентаря в Shared
SkaldetSkaeg Dec 5, 2023
cbe545c
Нашел, что потерял анимацию консольки, пытаюсь вернуть + заделки на с…
SkaldetSkaeg Dec 5, 2023
3a6a3e9
Получилось починить анимацию, но картинка слабо отличается от не вклю…
SkaldetSkaeg Dec 5, 2023
7bdcaa4
Прикрутил спрайты заполнения.
SkaldetSkaeg Dec 5, 2023
52f7132
Поправлена моделька
SkaldetSkaeg Dec 7, 2023
fe8126e
Допили всё до финала + оставил заделку для допиливания до уровня оффов
SkaldetSkaeg Dec 10, 2023
d5b2d61
Merge branch 'master' into SmartFridge
SkaldetSkaeg Dec 10, 2023
b114310
Убрал параметр maxSlots
SkaldetSkaeg Dec 10, 2023
a8cd827
Merge branch 'SmartFridge' of https://github.com/SkaldetSkaeg/space-s…
SkaldetSkaeg Dec 10, 2023
bcc219f
Merge branch 'SerbiaStrong-220:master' into SmartFridge
SkaldetSkaeg Dec 10, 2023
cc3ab45
Правки под новый grid storage
SkaldetSkaeg Dec 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions Content.Client/SS220/SmartFridge/SmartFridgeBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt

using Content.Client.SS220.SmartFridge.UI;
using Content.Shared.SS220.SmartFridge;
using Content.Shared.VendingMachines;
using Robust.Client.UserInterface.Controls;
using System.Linq;

namespace Content.Client.SS220.SmartFridge
{
public sealed class SmartFridgeBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private SmartFridgeMenu? _menu;

[ViewVariables]
private List<VendingMachineInventoryEntry> _cachedInventory = new();

[ViewVariables]
private List<int> _cachedFilteredIndex = new();

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

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

_menu = new SmartFridgeMenu { Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName };

_menu.OnClose += Close;
_menu.OnItemSelected += OnItemSelected;
_menu.OnSearchChanged += OnSearchChanged;

UpdateUI();

_menu.OpenCentered();
}

private void OnItemSelected(ItemList.ItemListSelectedEventArgs args)
{

if (_cachedInventory.Count == 0)
return;

var selectedItem = _cachedInventory.ElementAtOrDefault(_cachedFilteredIndex.ElementAtOrDefault(args.ItemIndex));

if (selectedItem == null)
return;

SendPredictedMessage(new SmartFridgeInteractWithItemEvent(selectedItem.EntityUids[0]));

UpdateUI();
}

public void UpdateUI()
{
var smartFridgeSys = EntMan.System<SharedSmartFridgeSystem>();
_cachedInventory = smartFridgeSys.GetAllInventory(Owner);
_menu?.Populate(_cachedInventory, out _cachedFilteredIndex);
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;

if (_menu == null)
return;

_menu.OnItemSelected -= OnItemSelected;
_menu.OnClose -= Close;
_menu.Dispose();
}

private void OnSearchChanged(string? filter)
{
_menu?.Populate(_cachedInventory, out _cachedFilteredIndex, filter);
}
}

}
136 changes: 136 additions & 0 deletions Content.Client/SS220/SmartFridge/SmartFridgeSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt

using Content.Shared.SS220.SmartFridge;
using Robust.Client.Animations;
using Robust.Client.GameObjects;

namespace Content.Client.SS220.SmartFridge;

public sealed class SmartFridgeSystem : SharedSmartFridgeSystem
{
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;

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

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

private void OnAnimationCompleted(EntityUid uid, SmartFridgeComponent component, AnimationCompletedEvent args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;

if (!TryComp<AppearanceComponent>(uid, out var appearance) ||
!_appearanceSystem.TryGetData<SmartFridgeVisualState>(uid, SmartFridgeVisuals.VisualState, out var visualState, appearance))
{
visualState = SmartFridgeVisualState.Normal;
}

UpdateAppearance(uid, visualState, component, sprite);
}

private void OnAppearanceChange(EntityUid uid, SmartFridgeComponent component, ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
return;

if (!args.AppearanceData.TryGetValue(SmartFridgeVisuals.VisualState, out var visualStateObject) ||
visualStateObject is not SmartFridgeVisualState visualState)
{
visualState = SmartFridgeVisualState.Normal;
}

UpdateAppearance(uid, visualState, component, args.Sprite);
}

private void UpdateAppearance(EntityUid uid, SmartFridgeVisualState visualState, SmartFridgeComponent component, SpriteComponent sprite)
{
SetLayerState(SmartFridgeVisualLayers.Base, component.OffState, sprite);

switch (visualState)
{
case SmartFridgeVisualState.Normal:
SetLayerState(SmartFridgeVisualLayers.BaseUnshaded, component.NormalState, sprite);
SetLayerState(SmartFridgeVisualLayers.Screen, component.ScreenState, sprite);
break;

case SmartFridgeVisualState.Deny:
if (component.LoopDenyAnimation)
SetLayerState(SmartFridgeVisualLayers.BaseUnshaded, component.DenyState, sprite);
else
PlayAnimation(uid, SmartFridgeVisualLayers.BaseUnshaded, component.DenyState, component.DenyDelay, sprite);

SetLayerState(SmartFridgeVisualLayers.Screen, component.ScreenState, sprite);
break;

case SmartFridgeVisualState.Broken:
HideLayers(sprite);
SetLayerState(SmartFridgeVisualLayers.Base, component.BrokenState, sprite);
break;

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

private static void SetLayerState(SmartFridgeVisualLayers layer, string? state, SpriteComponent sprite)
{
if (string.IsNullOrEmpty(state))
return;

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

private void PlayAnimation(EntityUid uid, SmartFridgeVisualLayers layer, string? state, float animationTime, SpriteComponent sprite)
{
if (string.IsNullOrEmpty(state))
return;

if (!_animationPlayer.HasRunningAnimation(uid, state))
{
var animation = GetAnimation(layer, state, animationTime);
sprite.LayerSetVisible(layer, true);
_animationPlayer.Play(uid, animation, state);
}
}

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

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

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

sprite.LayerSetVisible(actualLayer, false);
}
}
11 changes: 11 additions & 0 deletions Content.Client/SS220/SmartFridge/UI/SmartFridgeMenu.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt -->

<DefaultWindow xmlns="https://spacestation14.io">
<BoxContainer Orientation="Vertical">
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin ="0 4" Access="Public"/>
<ItemList Name="SmartFridgeContents"
SizeFlagsStretchRatio="8"
VerticalExpand="True">
</ItemList>
</BoxContainer>
</DefaultWindow>
112 changes: 112 additions & 0 deletions Content.Client/SS220/SmartFridge/UI/SmartFridgeMenu.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt

using System.Numerics;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Content.Shared.VendingMachines;

namespace Content.Client.SS220.SmartFridge.UI
{
[GenerateTypedNameReferences]
public sealed partial class SmartFridgeMenu : DefaultWindow
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;

public event Action<ItemList.ItemListSelectedEventArgs>? OnItemSelected;
public event Action<string>? OnSearchChanged;

public SmartFridgeMenu()
{
MinSize = new Vector2(250, 150); // Corvax-Resize
SetSize = new Vector2(450, 150); // Corvax-Resize
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

SearchBar.OnTextChanged += _ =>
{
OnSearchChanged?.Invoke(SearchBar.Text);
};

SmartFridgeContents.OnItemSelected += args =>
{
OnItemSelected?.Invoke(args);
};
}

/// <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, out List<int> filteredInventory, string? filter = null)
{

filteredInventory = new();

if (inventory.Count == 0)
{
SmartFridgeContents.Clear();
var outOfStockText = Loc.GetString("vending-machine-component-try-eject-out-of-stock");
SmartFridgeContents.AddItem(outOfStockText);
SetSizeAfterUpdate(outOfStockText.Length, SmartFridgeContents.Count);
return;
}

while (inventory.Count != SmartFridgeContents.Count)
{
if (inventory.Count > SmartFridgeContents.Count)
SmartFridgeContents.AddItem(string.Empty);
else
SmartFridgeContents.RemoveAt(SmartFridgeContents.Count - 1);
}

var longestEntry = string.Empty;
var spriteSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>();

var filterCount = 0;
for (var i = 0; i < inventory.Count; i++)
{
var entry = inventory[i];
var smartFridgeItem = SmartFridgeContents[i - filterCount];
smartFridgeItem.Text = string.Empty;
smartFridgeItem.Icon = null;

var itemName = entry.ID;
Texture? icon = null;
if (_prototypeManager.TryIndex<EntityPrototype>(entry.ID, out var prototype))
{
itemName = prototype.Name;
icon = spriteSystem.GetPrototypeIcon(prototype).Default;
}

// search filter
if (!string.IsNullOrEmpty(filter) &&
!itemName.ToLowerInvariant().Contains(filter.Trim().ToLowerInvariant()))
{
SmartFridgeContents.Remove(smartFridgeItem);
filterCount++;
continue;
}

if (itemName.Length > longestEntry.Length)
longestEntry = itemName;

smartFridgeItem.Text = $"{itemName} [{entry.Amount}]";
smartFridgeItem.Icon = icon;
filteredInventory.Add(i);
}

SetSizeAfterUpdate(longestEntry.Length, inventory.Count);
}

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