RND Rework [Death to Techweb] (#16370)

* Techweb rework

* more ui work

* finishing ui

* Finish all the C# logic

* the techs + lathes

* remove old-tech

* mirror-review
This commit is contained in:
Nemanja
2023-05-15 16:17:30 -04:00
committed by GitHub
parent a71d9c8eff
commit 9efc727fe1
51 changed files with 1732 additions and 1401 deletions

View File

@@ -1,195 +1,167 @@
using System.Collections.Generic;
using Content.Client.UserInterface.Controls;
using Content.Shared.Research.Components;
using Content.Shared.Research.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Utility;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Client.Research.UI
namespace Content.Client.Research.UI;
[GenerateTypedNameReferences]
public sealed partial class ResearchConsoleMenu : FancyWindow
{
[GenerateTypedNameReferences]
public sealed partial class ResearchConsoleMenu : DefaultWindow
public Action<string>? OnTechnologyCardPressed;
public Action? OnServerButtonPressed;
public Action? OnSyncButtonPressed;
[Dependency] private readonly IEntityManager _entity = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
private readonly TechnologyDatabaseComponent? _technologyDatabase;
private readonly ResearchSystem _research;
private readonly SpriteSystem _sprite;
public readonly EntityUid Entity;
public ResearchConsoleMenu(EntityUid entity)
{
public ResearchConsoleBoundUserInterface Owner { get; }
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
private readonly List<TechnologyPrototype> _unlockedTechnologyPrototypes = new();
private readonly List<TechnologyPrototype> _unlockableTechnologyPrototypes = new();
private readonly List<TechnologyPrototype> _futureTechnologyPrototypes = new();
_research = _entity.System<ResearchSystem>();
_sprite = _entity.System<SpriteSystem>();
Entity = entity;
public TechnologyPrototype? TechnologySelected;
ServerButton.OnPressed += _ => OnServerButtonPressed?.Invoke();
SyncButton.OnPressed += _ => OnSyncButtonPressed?.Invoke();
public ResearchConsoleMenu(ResearchConsoleBoundUserInterface owner)
_entity.TryGetComponent(entity, out _technologyDatabase);
}
public void UpdatePanels(ResearchConsoleBoundInterfaceState state)
{
var allTech = _research.GetAvailableTechnologies(Entity);
AvailableCardsContainer.Children.Clear();
TechnologyCardsContainer.Children.Clear();
UnlockedCardsContainer.Children.Clear();
foreach (var tech in allTech)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
var mini = new MiniTechnologyCardControl(tech, _prototype, _sprite, GetTechnologyDescription(tech, false));
AvailableCardsContainer.AddChild(mini);
}
Owner = owner;
if (_technologyDatabase == null)
return;
UnlockedTechnologies.OnItemSelected += UnlockedTechnologySelected;
UnlockableTechnologies.OnItemSelected += UnlockableTechnologySelected;
FutureTechnologies.OnItemSelected += FutureTechnologySelected;
// i can't figure out the spacing so here you go
TechnologyCardsContainer.AddChild(new Control
{
MinHeight = 10
});
foreach (var techId in _technologyDatabase.CurrentTechnologyCards)
{
var tech = _prototype.Index<TechnologyPrototype>(techId);
var cardControl = new TechnologyCardControl(tech, _prototype, _sprite, GetTechnologyDescription(tech), state.Points);
cardControl.OnPressed += () => OnTechnologyCardPressed?.Invoke(techId);
TechnologyCardsContainer.AddChild(cardControl);
}
PointLabel.Text = Loc.GetString("research-console-menu-research-points-text", ("points", 0));
PointsPerSecondLabel.Text = Loc.GetString("research-console-menu-points-per-second-text", ("pointsPerSecond", 0));
foreach (var unlocked in _technologyDatabase.UnlockedTechnologies)
{
var tech = _prototype.Index<TechnologyPrototype>(unlocked);
var cardControl = new MiniTechnologyCardControl(tech, _prototype, _sprite, GetTechnologyDescription(tech, false));
UnlockedCardsContainer.AddChild(cardControl);
}
}
UnlockButton.Text = Loc.GetString("research-console-menu-server-unlock-button");
public FormattedMessage GetTechnologyDescription(TechnologyPrototype technology, bool includeCost = true)
{
var description = new FormattedMessage();
if (includeCost)
{
description.AddMarkup(Loc.GetString("research-console-cost", ("amount", technology.Cost)));
description.PushNewline();
}
description.AddMarkup(Loc.GetString("research-console-unlocks-list-start"));
foreach (var recipe in technology.RecipeUnlocks)
{
var recipeProto = _prototype.Index<LatheRecipePrototype>(recipe);
description.PushNewline();
description.AddMarkup(Loc.GetString("research-console-unlocks-list-entry",
("name",recipeProto.Name)));
}
foreach (var generic in technology.GenericUnlocks)
{
description.PushNewline();
description.AddMarkup(Loc.GetString("research-console-unlocks-list-entry-generic",
("name", Loc.GetString(generic.UnlockDescription))));
}
UnlockButton.OnPressed += _ =>
return description;
}
public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state)
{
var amountMsg = new FormattedMessage();
amountMsg.AddMarkup(Loc.GetString("research-console-menu-research-points-text",
("points", state.Points)));
ResearchAmountLabel.SetMessage(amountMsg);
if (_technologyDatabase == null)
return;
var disciplineText = Loc.GetString("research-discipline-none");
var disciplineColor = Color.Gray;
if (_technologyDatabase.MainDiscipline != null)
{
var discipline = _prototype.Index<TechDisciplinePrototype>(_technologyDatabase.MainDiscipline);
disciplineText = Loc.GetString(discipline.Name);
disciplineColor = discipline.Color;
}
var msg = new FormattedMessage();
msg.AddMarkup(Loc.GetString("research-console-menu-main-discipline",
("name", disciplineText), ("color", disciplineColor)));
MainDisciplineLabel.SetMessage(msg);
TierDisplayContainer.Children.Clear();
foreach (var disciplineId in _technologyDatabase.SupportedDisciplines)
{
var discipline = _prototype.Index<TechDisciplinePrototype>(disciplineId);
var tier = _research.GetHighestDisciplineTier(_technologyDatabase, discipline);
// don't show tiers with no available tech
if (tier == 0)
continue;
// i'm building the small-ass control here to spare me some mild annoyance in making a new file
var texture = new TextureRect
{
CleanSelectedTechnology();
TextureScale = ( 2, 2 ),
VerticalAlignment = VAlignment.Center
};
var label = new RichTextLabel();
texture.Texture = _sprite.Frame0(discipline.Icon);
label.SetMessage(Loc.GetString("research-console-tier-info-small", ("tier", tier)));
Populate();
}
/// <summary>
/// Cleans the selected technology controls to blank.
/// </summary>
private void CleanSelectedTechnology()
{
UnlockButton.Disabled = true;
TechnologyIcon.Texture = Texture.Transparent;
TechnologyName.Text = string.Empty;
TechnologyDescription.Text = string.Empty;
TechnologyRequirements.Text = string.Empty;
}
/// <summary>
/// Called when an unlocked technology is selected.
/// </summary>
private void UnlockedTechnologySelected(ItemList.ItemListSelectedEventArgs obj)
{
TechnologySelected = _unlockedTechnologyPrototypes[obj.ItemIndex];
UnlockButton.Disabled = true;
PopulateSelectedTechnology();
}
/// <summary>
/// Called when an unlockable technology is selected.
/// </summary>
private void UnlockableTechnologySelected(ItemList.ItemListSelectedEventArgs obj)
{
TechnologySelected = _unlockableTechnologyPrototypes[obj.ItemIndex];
UnlockButton.Disabled = Owner.Points < TechnologySelected.RequiredPoints;
PopulateSelectedTechnology();
}
/// <summary>
/// Called when a future technology is selected
/// </summary>
private void FutureTechnologySelected(ItemList.ItemListSelectedEventArgs obj)
{
TechnologySelected = _futureTechnologyPrototypes[obj.ItemIndex];
UnlockButton.Disabled = true;
PopulateSelectedTechnology();
}
/// <summary>
/// Populate all technologies in the ItemLists.
/// </summary>
public void PopulateItemLists()
{
UnlockedTechnologies.Clear();
UnlockableTechnologies.Clear();
FutureTechnologies.Clear();
_unlockedTechnologyPrototypes.Clear();
_unlockableTechnologyPrototypes.Clear();
_futureTechnologyPrototypes.Clear();
var prototypeMan = IoCManager.Resolve<IPrototypeManager>();
// For now, we retrieve all technologies. In the future, this should be changed.
foreach (var tech in prototypeMan.EnumeratePrototypes<TechnologyPrototype>())
var control = new BoxContainer
{
var techName = GetTechName(tech);
if (Owner.IsTechnologyUnlocked(tech))
Children =
{
UnlockedTechnologies.AddItem(techName, tech.Icon.Frame0());
_unlockedTechnologyPrototypes.Add(tech);
texture,
label,
new Control
{
MinWidth = 10
}
}
else if (Owner.CanUnlockTechnology(tech))
{
UnlockableTechnologies.AddItem(techName, tech.Icon.Frame0());
_unlockableTechnologyPrototypes.Add(tech);
}
else
{
FutureTechnologies.AddItem(techName, tech.Icon.Frame0());
_futureTechnologyPrototypes.Add(tech);
}
}
}
private string GetTechName(TechnologyPrototype prototype)
{
if (prototype.Name is { } name)
return Loc.GetString(name);
return prototype.ID;
}
/// <summary>
/// Fills the selected technology controls with details.
/// </summary>
public void PopulateSelectedTechnology()
{
if (TechnologySelected == null)
{
TechnologyName.Text = string.Empty;
TechnologyDescription.Text = string.Empty;
TechnologyRequirements.Text = string.Empty;
return;
}
TechnologyIcon.Texture = TechnologySelected.Icon.Frame0();
TechnologyName.Text = GetTechName(TechnologySelected);
var desc = Loc.GetString(TechnologySelected.Description);
TechnologyDescription.Text = desc + $"\n{TechnologySelected.RequiredPoints} " + Loc.GetString("research-console-menu-research-points-text" ,("points", Owner.Points)).ToLowerInvariant();
TechnologyRequirements.Text = Loc.GetString("research-console-tech-requirements-none");
var prototypeMan = IoCManager.Resolve<IPrototypeManager>();
for (var i = 0; i < TechnologySelected.RequiredTechnologies.Count; i++)
{
var requiredId = TechnologySelected.RequiredTechnologies[i];
if (!prototypeMan.TryIndex(requiredId, out TechnologyPrototype? prototype)) continue;
var protoName = GetTechName(prototype);
if (i == 0)
TechnologyRequirements.Text = Loc.GetString("research-console-tech-requirements-prototype-name", ("prototypeName", protoName));
else
TechnologyRequirements.Text += $", {protoName}";
}
}
/// <summary>
/// Updates the research point labels.
/// </summary>
public void PopulatePoints()
{
PointLabel.Text = Loc.GetString("research-console-menu-research-points-text", ("points", Owner.Points));
PointsPerSecondLabel.Text = Loc.GetString("research-console-menu-points-per-second-text", ("pointsPerSecond", Owner.PointsPerSecond));
}
/// <summary>
/// Updates the whole user interface.
/// </summary>
public void Populate()
{
PopulatePoints();
PopulateSelectedTechnology();
PopulateItemLists();
};
TierDisplayContainer.AddChild(control);
}
}
}