diff --git a/Content.Client/FurryServers/FurryServersWindow.xaml b/Content.Client/FurryServers/FurryServersWindow.xaml new file mode 100644 index 00000000000..1fb63a9281d --- /dev/null +++ b/Content.Client/FurryServers/FurryServersWindow.xaml @@ -0,0 +1,16 @@ +<ui:FurryServersWindow xmlns="https://spacestation14.io" + xmlns:ui="clr-namespace:Content.Client.FurryServers" + xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls" + Title="Other Furry Servers..." + MinSize="500 300" + SetSize="500 450"> + <ScrollContainer HScrollEnabled="False" Margin="4" VerticalExpand="True" ReturnMeasure="True"> + <BoxContainer Orientation="Vertical"> + <Label Margin="8 0 0 0" StyleClasses="FurryServersSectionHeader" Align="Center" + Text="BlepStation (LRP)" Name="BlepstationHeader" /> + <RichTextLabel Margin="8 8 8 8" Name="BlepstationDescription" /> + + <Button Name="BlepstationWebsite" Text="Launch Website: BlepStation.com" /> + </BoxContainer> + </ScrollContainer> +</ui:FurryServersWindow> diff --git a/Content.Client/FurryServers/FurryServersWindow.xaml.cs b/Content.Client/FurryServers/FurryServersWindow.xaml.cs new file mode 100644 index 00000000000..29db69f967f --- /dev/null +++ b/Content.Client/FurryServers/FurryServersWindow.xaml.cs @@ -0,0 +1,59 @@ +using System.Linq; +using Content.Client.Administration.Managers; +using Content.Client.Stylesheets; +using Content.Client.UserInterface.Controls; +using Content.Client.UserInterface.Systems.EscapeMenu; +using Content.Shared.Administration; +using JetBrains.Annotations; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Console; +using Robust.Client.ResourceManagement; +using Robust.Shared.Utility; + +namespace Content.Client.FurryServers +{ + [GenerateTypedNameReferences] + public sealed partial class FurryServersWindow : FancyWindow + { + [Dependency] private readonly IResourceCache _resourceManager = default!; + [Dependency] private readonly IUriOpener _uri = default!; + + public FurryServersWindow() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSpace; + + BlepstationHeader.AddStyleClass(StyleBase.StyleClassLabelHeading); + BlepstationHeader.FontColorOverride = Color.FromHex("#7687f2"); + + var description = FormattedMessage.FromMarkup(_resourceManager.ContentFileReadAllText($"/FurryServers/Blepstation.txt")); + BlepstationDescription.SetMessage(description); + + BlepstationWebsite.OnPressed += _ => + { + _uri.OpenUri("https://blepstation.com"); + }; + } + + protected override void Opened() + { + base.Opened(); + } + } + + [UsedImplicitly, AnyCommand] + public sealed class FurryServersCommand : IConsoleCommand + { + public string Command => "furry"; + public string Description => "Shows list of furry space station 14 servers"; + public string Help => "Usage: furry"; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + IoCManager.Resolve<IUserInterfaceManager>().GetUIController<FurryServersUIController>().OpenWindow(); + } + } +} diff --git a/Content.Client/Info/LinkBanner.cs b/Content.Client/Info/LinkBanner.cs index a30aa413761..6f83fe9b5f9 100644 --- a/Content.Client/Info/LinkBanner.cs +++ b/Content.Client/Info/LinkBanner.cs @@ -43,6 +43,10 @@ public LinkBanner() }; buttons.AddChild(guidebookButton); + var furryServersButton = new Button() { Text = "More Furry Servers" }; + furryServersButton.OnPressed += args => UserInterfaceManager.GetUIController<FurryServersUIController>().ToggleWindow(); + buttons.AddChild(furryServersButton); + var changelogButton = new ChangelogButton(); changelogButton.OnPressed += args => UserInterfaceManager.GetUIController<ChangelogUIController>().ToggleWindow(); buttons.AddChild(changelogButton); diff --git a/Content.Client/MainMenu/MainMenu.cs b/Content.Client/MainMenu/MainMenu.cs index 43c5bfe5674..9c73af11583 100644 --- a/Content.Client/MainMenu/MainMenu.cs +++ b/Content.Client/MainMenu/MainMenu.cs @@ -10,6 +10,7 @@ using Robust.Shared.Network; using Robust.Shared.Utility; using UsernameHelpers = Robust.Shared.AuthLib.UsernameHelpers; +using Content.Client.UserInterface.Systems.WhitelistWindow; namespace Content.Client.MainMenu { @@ -176,7 +177,18 @@ private void ParseAddress(string address, out string ip, out ushort port) private void _onConnectFailed(object? _, NetConnectFailArgs args) { - _userInterfaceManager.Popup(Loc.GetString("main-menu-failed-to-connect",("reason", args.Reason))); + // This assumes whitelist related disconnect will contain the text 'whitelist' which is probably a fair + // assumption. More ideally, disconnect reasons would send across an enum or something, but that looks to + // be in engine code, perhaps. + if (args.Reason.ToUpper().Contains("WHITELIST")) + { + // Whitelist specialized popup that shows application link for the whitelist + _userInterfaceManager.GetUIController<WhitelistDenialUIController>().OpenWindow(args.Reason); + } else { + // Generic popup + _userInterfaceManager.Popup(Loc.GetString("main-menu-failed-to-connect",("reason", args.Reason))); + } + _netManager.ConnectFailed -= _onConnectFailed; _setConnectingState(false); } diff --git a/Content.Client/Options/UI/EscapeMenu.xaml b/Content.Client/Options/UI/EscapeMenu.xaml index 71da231f29b..f93b1a2ecd6 100644 --- a/Content.Client/Options/UI/EscapeMenu.xaml +++ b/Content.Client/Options/UI/EscapeMenu.xaml @@ -12,6 +12,7 @@ <Button Access="Public" Name="RulesButton" Text="{Loc 'ui-escape-rules'}" /> <Button Access="Public" Name="GuidebookButton" Text="{Loc 'ui-escape-guidebook'}" /> <Button Access="Public" Name="WikiButton" Text="{Loc 'ui-escape-wiki'}" /> + <Button Access="Public" Name="FurryServersButton" Text="More Furry Servers" /> <Button Access="Public" Name="DisconnectButton" Text="{Loc 'ui-escape-disconnect'}" /> <Button Access="Public" Name="QuitButton" Text="{Loc 'ui-escape-quit'}" /> </BoxContainer> diff --git a/Content.Client/Stylesheets/StyleNano.cs b/Content.Client/Stylesheets/StyleNano.cs index 13ba259dbcd..ab5ff4b2896 100644 --- a/Content.Client/Stylesheets/StyleNano.cs +++ b/Content.Client/Stylesheets/StyleNano.cs @@ -1335,6 +1335,11 @@ public StyleNano(IResourceCache resCache) : base(resCache) .Prop(Label.StylePropertyFont, notoSans10), // --- + // Furry Servers - Very Large Label for section headers + Element<Label>().Class("FurryServersSectionHeader") + .Prop(Label.StylePropertyFont, notoSansBold20), + // --- + // Different Background shapes --- Element<PanelContainer>().Class(ClassAngleRect) .Prop(PanelContainer.StylePropertyPanel, BaseAngleRect) diff --git a/Content.Client/UserInterface/Systems/EscapeMenu/EscapeUIController.cs b/Content.Client/UserInterface/Systems/EscapeMenu/EscapeUIController.cs index 85c4af76723..ad9df82c631 100644 --- a/Content.Client/UserInterface/Systems/EscapeMenu/EscapeUIController.cs +++ b/Content.Client/UserInterface/Systems/EscapeMenu/EscapeUIController.cs @@ -25,6 +25,7 @@ public sealed class EscapeUIController : UIController, IOnStateEntered<GameplayS [Dependency] private readonly InfoUIController _info = default!; [Dependency] private readonly OptionsUIController _options = default!; [Dependency] private readonly GuidebookUIController _guidebook = default!; + [Dependency] private readonly FurryServersUIController _furryServers = default!; private Options.UI.EscapeMenu? _escapeWindow; @@ -98,6 +99,12 @@ public void OnStateEntered(GameplayState state) _uri.OpenUri(_cfg.GetCVar(CCVars.InfoLinksWiki)); }; + _escapeWindow.FurryServersButton.OnPressed += _ => + { + CloseEscapeWindow(); + _furryServers.ToggleWindow(); + }; + _escapeWindow.GuidebookButton.OnPressed += _ => { _guidebook.ToggleGuidebook(); diff --git a/Content.Client/UserInterface/Systems/EscapeMenu/FurryServersUIController.cs b/Content.Client/UserInterface/Systems/EscapeMenu/FurryServersUIController.cs new file mode 100644 index 00000000000..36bd008da2d --- /dev/null +++ b/Content.Client/UserInterface/Systems/EscapeMenu/FurryServersUIController.cs @@ -0,0 +1,43 @@ +using Content.Client.FurryServers; +using JetBrains.Annotations; +using Robust.Client.State; +using Robust.Client.UserInterface.Controllers; +using Robust.Client.ResourceManagement; + +namespace Content.Client.UserInterface.Systems.EscapeMenu; + +[UsedImplicitly] +public sealed class FurryServersUIController : UIController +{ + private FurryServersWindow _furryServersWindow = default!; + + public void OpenWindow() + { + EnsureWindow(); + + _furryServersWindow.OpenCentered(); + _furryServersWindow.MoveToFront(); + } + + private void EnsureWindow() + { + if (_furryServersWindow is { Disposed: false }) + return; + + _furryServersWindow = UIManager.CreateWindow<FurryServersWindow>(); + } + + public void ToggleWindow() + { + EnsureWindow(); + + if (_furryServersWindow.IsOpen) + { + _furryServersWindow.Close(); + } + else + { + OpenWindow(); + } + } +} diff --git a/Content.Client/UserInterface/Systems/WhitelistWindow/Controls/WhitelistDenialWindow.xaml b/Content.Client/UserInterface/Systems/WhitelistWindow/Controls/WhitelistDenialWindow.xaml new file mode 100644 index 00000000000..7dce4e57d37 --- /dev/null +++ b/Content.Client/UserInterface/Systems/WhitelistWindow/Controls/WhitelistDenialWindow.xaml @@ -0,0 +1,15 @@ +<ui:WhitelistDenialWindow xmlns="https://spacestation14.io" + xmlns:ui="clr-namespace:Content.Client.UserInterface.Systems.WhitelistWindow.Controls" + xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls" + Title="Whitelist Required" + MinSize="400 170" + SetSize="400 170"> + <ScrollContainer HScrollEnabled="False" Margin="4" VerticalExpand="True" ReturnMeasure="True"> + <BoxContainer Orientation="Vertical"> + <Label Margin="8 0 0 0" Text="Whitelist Required Text Goes here" Name="DenialReason" /> + <Button Margin="8 10 0 0" Name="WhitelistApplyButton" Text="Apply for whitelist" /> + <PanelContainer Margin="8 10 0 0" StyleClasses="LowDivider" /> + <Button Margin="8 20 0 0" Name="FurryServersButton" Text="Or check out other Furry SS14 Servers" /> + </BoxContainer> + </ScrollContainer> +</ui:WhitelistDenialWindow> diff --git a/Content.Client/UserInterface/Systems/WhitelistWindow/Controls/WhitelistDenialWindow.xaml.cs b/Content.Client/UserInterface/Systems/WhitelistWindow/Controls/WhitelistDenialWindow.xaml.cs new file mode 100644 index 00000000000..afe0405921b --- /dev/null +++ b/Content.Client/UserInterface/Systems/WhitelistWindow/Controls/WhitelistDenialWindow.xaml.cs @@ -0,0 +1,52 @@ +using System.Linq; +using Content.Client.Administration.Managers; +using Content.Client.Stylesheets; +using Content.Client.UserInterface.Controls; +using Content.Client.UserInterface.Systems.EscapeMenu; +using Content.Shared.Administration; +using JetBrains.Annotations; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Console; +using Robust.Client.ResourceManagement; +using Robust.Shared.Utility; +using Content.Client.UserInterface.Systems.EscapeMenu; + +namespace Content.Client.UserInterface.Systems.WhitelistWindow.Controls +{ + [GenerateTypedNameReferences] + public sealed partial class WhitelistDenialWindow : FancyWindow + { + [Dependency] private readonly IResourceCache _resourceManager = default!; + [Dependency] private readonly IUriOpener _uri = default!; + + public WhitelistDenialWindow() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSpace; + + WhitelistApplyButton.OnPressed += _ => + { + _uri.OpenUri("https://discord.gg/ZZYNpq5KBJ"); // Floof discord link + }; + + FurryServersButton.OnPressed += _ => + { + UserInterfaceManager.GetUIController<FurryServersUIController>().ToggleWindow(); + }; + } + + + protected override void Opened() + { + base.Opened(); + } + + public void SetDenialMessage(string denial) + { + DenialReason.Text = denial; + } + } +} diff --git a/Content.Client/UserInterface/Systems/WhitelistWindow/WhitelistDenialUIController.cs b/Content.Client/UserInterface/Systems/WhitelistWindow/WhitelistDenialUIController.cs new file mode 100644 index 00000000000..849a04edbd7 --- /dev/null +++ b/Content.Client/UserInterface/Systems/WhitelistWindow/WhitelistDenialUIController.cs @@ -0,0 +1,34 @@ +using Content.Client.Options.UI; +using JetBrains.Annotations; +using Robust.Client.UserInterface.Controllers; +using Robust.Shared.Console; +using Content.Client.UserInterface.Systems.WhitelistWindow.Controls; + +namespace Content.Client.UserInterface.Systems.WhitelistWindow; + +[UsedImplicitly] +public sealed class WhitelistDenialUIController : UIController +{ + public override void Initialize() + { + } + private WhitelistDenialWindow _whitelistDenialWindow = default!; + + private void EnsureWindow() + { + if (_whitelistDenialWindow is { Disposed: false }) + return; + + _whitelistDenialWindow = UIManager.CreateWindow<WhitelistDenialWindow>(); + } + + public void OpenWindow(string denialMessage) + { + EnsureWindow(); + + _whitelistDenialWindow.SetDenialMessage(denialMessage); + + _whitelistDenialWindow.OpenCentered(); + _whitelistDenialWindow.MoveToFront(); + } +} diff --git a/Resources/FurryServers/Blepstation.txt b/Resources/FurryServers/Blepstation.txt new file mode 100644 index 00000000000..9c6001052b2 --- /dev/null +++ b/Resources/FurryServers/Blepstation.txt @@ -0,0 +1,10 @@ +Looking for faster paced rounds that are more focused on gameplay? Check out our friends at [italic]BlepStation[/italic], a furry server with unique content and features. (Adults/18+ Only) + + • Furry kinks & species. + • Shorter, [bold]gameplay-focused[/bold] rounds. + • Low role timer requirements. + • [bold]LRP[/bold] -- Simple rules, less serious vibe. + • Based on vanilla upstream (but also brings back popular removed mechanics like cloning, vehicles, list inventory, etc). + • No whitelist requirement. + +Check out the website for more information! We hope to play with you soon :)