Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
36ed927
Змей
Autsaider-IM Jan 17, 2026
32c64b3
Первый реворк верфи
Autsaider-IM Jan 17, 2026
50c1ba2
Merge branch 'master' into TL20
Autsaider-IM Jan 18, 2026
64e800f
Флаги нексуса
Autsaider-IM Jan 18, 2026
f16a1fb
Merge branch 'TL20' of https://github.com/Autsaider-IM/Frontier into …
Autsaider-IM Jan 18, 2026
a4c7c47
Еще шаттлы на верфь
Autsaider-IM Jan 20, 2026
17c8fdf
Merge branch 'master' into TL20
Autsaider-IM Jan 21, 2026
8ee6a40
Опять верфь, стратег и фикс ошибки
Autsaider-IM Jan 21, 2026
4b561b5
research console 0.5
vsixst Jan 25, 2026
04297c2
правки маленькие
vsixst Jan 25, 2026
a6e2832
Полу нерабочая хуйня
Autsaider-IM Jan 25, 2026
1721df7
Merge branch 'TL20' of https://github.com/Autsaider-IM/Frontier into …
Autsaider-IM Jan 25, 2026
cea3615
Фух бля, новая РНД ветка
Autsaider-IM Jan 27, 2026
85c524d
Фикс верфи
Autsaider-IM Jan 28, 2026
7e6ba72
Уценка в дереве технологий и фиксы
Autsaider-IM Jan 29, 2026
d217903
Всё. С меня гладки взятки
ilivor Feb 2, 2026
44fa7f1
Микрофиксы
ilivor Feb 2, 2026
72be0fa
Update sparrow.yml
ilivor Feb 2, 2026
fddc660
Фиксы
Autsaider-IM Feb 4, 2026
b96b576
Фиксы
Autsaider-IM Feb 5, 2026
54c7514
fix
mersen-tyn Feb 7, 2026
c261be9
fix
mersen-tyn Feb 7, 2026
e789933
мммммммммммммм
mersen-tyn Feb 7, 2026
3aae852
Попытка какая-то...
mersen-tyn Feb 10, 2026
e04dee3
уэээуэуэуэ
mersen-tyn Feb 10, 2026
3a018a9
Merge branch 'master' into pr/459
mersen-tyn Feb 10, 2026
cc80462
Update furniture.yml
mersen-tyn Feb 10, 2026
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System.Linq;
using Content.Shared.Research.Components;
using Content.Shared.Research.Prototypes;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;

namespace Content.Client._Goobstation.Research.UI;

[UsedImplicitly]
public sealed class FancyResearchConsoleBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private FancyResearchConsoleMenu? _consoleMenu; // Goobstation R&D Console rework - ResearchConsoleMenu -> FancyResearchConsoleMenu

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

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

var owner = Owner;

_consoleMenu = this.CreateWindow<FancyResearchConsoleMenu>(); // Goobstation R&D Console rework - ResearchConsoleMenu -> FancyResearchConsoleMenu
_consoleMenu.SetEntity(owner);
_consoleMenu.OnClose += () => _consoleMenu = null;

_consoleMenu.OnTechnologyCardPressed += id =>
{
SendMessage(new ConsoleUnlockTechnologyMessage(id));
};

_consoleMenu.OnServerButtonPressed += () =>
{
SendMessage(new ConsoleServerSelectionMessage());
};
}

public override void OnProtoReload(PrototypesReloadedEventArgs args)
{
base.OnProtoReload(args);

if (!args.WasModified<TechnologyPrototype>())
return;

if (State is not ResearchConsoleBoundInterfaceState rState)
return;

_consoleMenu?.UpdatePanels(rState.Researches);
_consoleMenu?.UpdateInformationPanel(rState.Points);
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

if (state is not ResearchConsoleBoundInterfaceState castState)
return;

// Goobstation checks added
// Thats for avoiding refresh spam when only points are updated
if (_consoleMenu == null)
return;
if (!_consoleMenu.List.SequenceEqual(castState.Researches))
_consoleMenu.UpdatePanels(castState.Researches);
if (_consoleMenu.Points != castState.Points)
_consoleMenu.UpdateInformationPanel(castState.Points);
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<LayoutContainer xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:nf="clr-namespace:Content.Client._NF.Research.UI"
xmlns:goob="clr-namespace:Content.Client._Goobstation.Research.UI"
Margin="4"
HorizontalExpand="False">
<BoxContainer Orientation="Vertical" SetSize="64 64">
HorizontalExpand="False"> <!-- Frontier: Margin="5" < Margin="4" -->
<BoxContainer Orientation="Vertical" SetSize="64 64"> <!-- Frontier: "80 80" < "64 64" -->
<PanelContainer VerticalExpand="True"
HorizontalExpand="True"
Name="Panel">
<nf:DrawButton Name="Button"
Access="Public"
ModulateSelfOverride="#00000000"
HorizontalExpand="True"/>
<goob:DrawButton Name="Button"
Access="Public"
ModulateSelfOverride="#00000000"
HorizontalExpand="True"/>
<EntityPrototypeView
Name="ResearchDisplay"
Scale="1.75 1.75"
SetSize="56 56">
</EntityPrototypeView>
</EntityPrototypeView> <!-- Frontier: "2" < "1.75", "64 64" < "56 56" -->
</PanelContainer>
</BoxContainer>
</LayoutContainer>
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
using Content.Shared._Goobstation.Research;
using Content.Shared.Research.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;

namespace Content.Client._Goobstation.Research.UI;

[GenerateTypedNameReferences]
public sealed partial class FancyResearchConsoleItem : LayoutContainer
{
[Dependency] private readonly IPrototypeManager _prototype = default!;

// Public fields
public TechnologyPrototype Prototype;
public Action<TechnologyPrototype, ResearchAvailability>? SelectAction;
public ResearchAvailability Availability;

// Some visuals
public static readonly Color DefaultColor = Color.FromHex("#2e2e2e");
public static readonly Color DefaultBorderColor = Color.FromHex("#4972A1");
public static readonly Color DefaultHoveredColor = Color.FromHex("#4972A1");

public Color BackgroundColor = DefaultColor;
public Color BorderColor = DefaultBorderColor;
public Color HoveredColor = DefaultHoveredColor;
public Color SelectedColor = DefaultHoveredColor;

// Selection state
private bool _isSelected = false;
public bool IsSelected
{
get => _isSelected;
set
{
if (_isSelected == value)
return;
_isSelected = value;
UpdateColor();
}
}

public FancyResearchConsoleItem(TechnologyPrototype proto, SpriteSystem sprite, ResearchAvailability availability)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

Availability = availability;
Prototype = proto;

// Get the discipline for background color
var discipline = _prototype.Index<TechDisciplinePrototype>(proto.Discipline);
var disciplineColor = discipline.Color;

// Handle technology icon - prioritize EntityIcon for full sprite layers
if (proto.EntityIcon.HasValue)
{
// Use EntityPrototypeView to show all sprite layers
ResearchDisplay.SetPrototype(proto.EntityIcon.Value);
}
else if (proto.Icon != null)
{
// For legacy Icon support, we need to handle this differently since EntityPrototypeView
// expects entity prototypes. For now, we'll need a fallback approach.
// TODO: Consider deprecating the Icon field in favor of EntityIcon

// We cannot directly set a SpriteSpecifier on EntityPrototypeView
// This is a limitation of the new approach - EntityIcon should be preferred
// For now, this will show no icon for legacy Icon-only technologies
ResearchDisplay.SetPrototype(null);
}
else
{
// No icon specified
ResearchDisplay.SetPrototype(null);
}

Button.OnPressed += Selected;
Button.OnDrawModeChanged += UpdateColor;

// Set colors - only border color varies by availability state
var availabilityBorderColor = availability switch
{
ResearchAvailability.Researched => Color.FromHex("#2ab043"),
ResearchAvailability.Available => Color.FromHex("#fab325"),
ResearchAvailability.PrereqsMet => Color.FromHex("#91752f"),
ResearchAvailability.Unavailable => Color.Crimson,
_ => Color.Crimson
};

// Background always uses discipline color
// Create a brighter version of the discipline color for hover by interpolating with white
HoveredColor = Color.InterpolateBetween(disciplineColor, Color.White, 0.3f);
// Create an even brighter version for selection (persistent bright highlight)
SelectedColor = Color.InterpolateBetween(disciplineColor, Color.White, 0.5f);
// Only border color varies by availability
BorderColor = availabilityBorderColor;

// Create rounded style box with 8px corner radius and thick border
var roundedStyle = new RoundedStyleBoxFlat
{
BorderColor = BorderColor,
BorderThickness = new Thickness(2.5f),
CornerRadius = 8f
};

Panel.PanelOverride = roundedStyle;
UpdateColor();
}

private void UpdateColor()
{
if (Panel.PanelOverride is RoundedStyleBoxFlat panel)
{
// Priority: Selected > Hovered > Normal
if (IsSelected)
panel.BackgroundColor = SelectedColor;
else if (Button.IsHovered)
panel.BackgroundColor = HoveredColor;
else
panel.BackgroundColor = BackgroundColor;

panel.BorderColor = BorderColor;
}
}

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

Button.OnPressed -= Selected;
}

private void Selected(BaseButton.ButtonEventArgs args)
{
SelectAction?.Invoke(Prototype, Availability);
}
}

public sealed class DrawButton : Button
{
public event Action? OnDrawModeChanged;

public DrawButton()
{
}

protected override void DrawModeChanged()
{
OnDrawModeChanged?.Invoke();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls;assembly=Content.Client"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls;assembly=Content.Client"
xmlns:nf="clr-namespace:Content.Client._NF.Research.UI"
xmlns:goob="clr-namespace:Content.Client._Goobstation.Research.UI"
Title="{Loc 'research-console-menu-title'}"
SetSize="1000 600"
MinSize="800 400">
Expand Down Expand Up @@ -30,48 +30,37 @@
<BoxContainer Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True"
SizeFlagsStretchRatio="3"
SizeFlagsStretchRatio="6"
Margin="0 0 0 10">
<PanelContainer Name="ResearchesContainer" VerticalExpand="True" HorizontalExpand="True">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#0F1419" />
<gfx:StyleBoxFlat BackgroundColor="#222226FF" />
</PanelContainer.PanelOverride>
<!-- Add ScrollContainer - vertical only -->
<ScrollContainer
Name="TechScrollContainer"
Access="Public"
<goob:ResearchesContainerPanel
HorizontalExpand="True"
VerticalExpand="True"
HScrollEnabled="False"
VScrollEnabled="True"
ReserveScrollbarSpace="True"
StyleClasses="PdaScrollContainer">
<nf:ResearchesContainerPanel
HorizontalExpand="True"
VerticalExpand="True"
Name="DragContainer"
MouseFilter="Pass"
RectClipContent="True"
HorizontalAlignment="Left">
<!-- There lives all of technologies -->
</nf:ResearchesContainerPanel>
</ScrollContainer>
Name="DragContainer"
MouseFilter="Pass"
RectClipContent="True">
<!-- There lives all of technologies -->
</goob:ResearchesContainerPanel>
<Button Name="RecenterButton" Text="{Loc 'research-console-menu-recenter-button'}" MinHeight="40" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="5 -5"/>
</PanelContainer>
</BoxContainer>
<PanelContainer SizeFlagsStretchRatio="2">
<PanelContainer SizeFlagsStretchRatio="4">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1B1E" />
</PanelContainer.PanelOverride>
<BoxContainer Name="InfoContainer"
Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True"
SizeFlagsStretchRatio="1"
SizeFlagsStretchRatio="2"
Margin="0">
<!-- Frontier: add a placeholder so the scrollable interface doesn't immediately shrink, matches InfoPanel size -->
<Control
Margin="5"
MinWidth="350"
MinWidth="450"
VerticalExpand="True"
HorizontalExpand="True"/>
</BoxContainer>
Expand Down
Loading
Loading