forked from space-wizards/space-station-14
-
Notifications
You must be signed in to change notification settings - Fork 156
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Переписываю с 0 * 3 попытки совмещения ужа и ежа, на этот раз полностью по предложению Артура * Первые потуги третьей попытки совместить ужа Storage и Dtictionary Vending * Адекватное отображение в новом интерфейсе * Добработки работы интерфейса с Storage (черновой вариант) * Function of getting items adjusted * Pre-PR state * done * Поправил файл миграции * Откат * Поправлено id, добавлена локализация, добавлена ent вайл миграции * Поправлены тэги (очень странно работает со Storage, так как предмет проверяется и по тэгу, и по компонентам, в результате предмет может вставиться, написав ошибку вайтлиста) * Перенес функции отображения инвентаря в Shared * Нашел, что потерял анимацию консольки, пытаюсь вернуть + заделки на сломанность и возможность отказа. * Получилось починить анимацию, но картинка слабо отличается от не включенного. * Прикрутил спрайты заполнения. * Поправлена моделька * Допили всё до финала + оставил заделку для допиливания до уровня оффов * Убрал параметр maxSlots * Правки под новый grid storage
- Loading branch information
1 parent
e25756f
commit 598e8f6
Showing
10 changed files
with
768 additions
and
0 deletions.
There are no files selected for viewing
84 changes: 84 additions & 0 deletions
84
Content.Client/SS220/SmartFridge/SmartFridgeBoundUserInterface.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
112
Content.Client/SS220/SmartFridge/UI/SmartFridgeMenu.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
} | ||
} |
Oops, something went wrong.