Compare commits
2 Commits
v0.2.0
...
archive/3d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
609c718ca3 | ||
|
|
7e5acf8e45 |
@@ -1,24 +0,0 @@
|
|||||||
version: 1.0.{build}
|
|
||||||
image: Visual Studio 2017
|
|
||||||
|
|
||||||
platform: x64
|
|
||||||
configuration: Debug
|
|
||||||
|
|
||||||
build:
|
|
||||||
project: SpaceStation.sln
|
|
||||||
parallel: false
|
|
||||||
verbosity: minimal
|
|
||||||
|
|
||||||
before_build:
|
|
||||||
- cmd: py -3 -m pip install --user requests
|
|
||||||
- cmd: py -3 RUN_THIS.py --no-prompt
|
|
||||||
- cmd: nuget restore SpaceStation14.sln
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- ps: msbuild SpaceStation14.sln /v:m /nologo /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /p:Platform=x64 /p:Configuration=Debug /p:AppVeyor=yes
|
|
||||||
|
|
||||||
test:
|
|
||||||
assemblies:
|
|
||||||
only:
|
|
||||||
- bin/Content.IntegrationTests/Content.IntegrationTests.dll
|
|
||||||
- bin/Content.Tests/Content.Tests.dll
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -268,8 +268,6 @@ release/
|
|||||||
|
|
||||||
# Apple please go.
|
# Apple please go.
|
||||||
.DS_Store
|
.DS_Store
|
||||||
# KDE, come in.
|
|
||||||
.directory
|
|
||||||
|
|
||||||
BuildFiles/Mac/Space Station 14.app/Contents/MacOS/Godot
|
BuildFiles/Mac/Space Station 14.app/Contents/MacOS/Godot
|
||||||
BuildFiles/Mac/Space Station 14.app/Contents/MacOS/GodotSharpTools.dll
|
BuildFiles/Mac/Space Station 14.app/Contents/MacOS/GodotSharpTools.dll
|
||||||
|
|||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,4 +1,4 @@
|
|||||||
[submodule "RobustToolbox"]
|
[submodule "engine"]
|
||||||
path = RobustToolbox
|
path = engine
|
||||||
url = https://github.com/space-wizards/RobustToolbox.git
|
url = https://github.com/space-wizards/space-station-14.git
|
||||||
branch = master
|
branch = master
|
||||||
23
.travis.yml
23
.travis.yml
@@ -9,30 +9,29 @@ os:
|
|||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
#sources:
|
sources:
|
||||||
#- deadsnakes
|
- deadsnakes
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- python3.5
|
- python3.6
|
||||||
- python3-pip
|
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- packages/
|
- packages/
|
||||||
- RobustToolbox/Dependencies/
|
- engine/Dependencies/
|
||||||
- RobustToolbox/SS14.Client.Godot/.mono/assemblies/
|
- engine/SS14.Client.Godot/.mono/assemblies/
|
||||||
|
|
||||||
#before_install:
|
#before_install:
|
||||||
# - if [ $TRAVIS_OS_NAME = osx ]; then brew update && brew upgrade python; fi
|
# - if [ $TRAVIS_OS_NAME = osx ]; then brew update && brew upgrade python; fi
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
#- "if [ $TRAVIS_OS_NAME = linux ]; then pyenv shell 3.6; fi"
|
- "if [ $TRAVIS_OS_NAME = linux ]; then pyenv shell 3.6; fi"
|
||||||
- "python3.5 -m pip install --user requests"
|
- "pip3 install --user requests"
|
||||||
- "nuget restore SpaceStation14.sln"
|
- "nuget restore SpaceStation14Content.sln"
|
||||||
- "python3.5 RUN_THIS.py --no-prompt"
|
- "python3.6 RUN_THIS.py --no-prompt"
|
||||||
|
- "engine/Tools/download_godotsharp.py"
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- "msbuild /p:Configuration=Debug /p:Platform=x64 /nologo /m SpaceStation14.sln /p:Python=python3.5"
|
- "msbuild /p:Configuration=Debug /p:Platform=x64 /p:HEADLESS=1 /p:Configuratio=Debug /nologo /m /p:AllowMissingMacNatives=yes SpaceStation14Content.sln /p:Python=python3.6"
|
||||||
- "mono packages/nunit.consolerunner/3.10.0/tools/nunit3-console.exe bin/Content.Tests/Content.Tests.dll bin/Content.IntegrationTests/Content.IntegrationTests.dll"
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild
|
|||||||
<Python>python3</Python>
|
<Python>python3</Python>
|
||||||
<Python Condition="'$(OS)'=='Windows_NT' Or '$(OS)'=='Windows'">py -3</Python>
|
<Python Condition="'$(OS)'=='Windows_NT' Or '$(OS)'=='Windows'">py -3</Python>
|
||||||
<ProjectGuid>{C899FCA4-7037-4E49-ABC2-44DE72487110}</ProjectGuid>
|
<ProjectGuid>{C899FCA4-7037-4E49-ABC2-44DE72487110}</ProjectGuid>
|
||||||
<TargetFrameworkMoniker>.NETFramework, Version=v4.7.1</TargetFrameworkMoniker>
|
<TargetFrameworkMoniker>.NETFramework, Version=v4.5.1</TargetFrameworkMoniker>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
@@ -25,9 +25,6 @@ https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Target Name="Build">
|
<Target Name="Build">
|
||||||
<Exec Command="$(Python) git_helper.py" CustomErrorRegularExpression="^Error" />
|
<Exec Command="$(Python) git_helper.py" CustomErrorRegularExpression="^Error" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import shutil
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
SOLUTION_PATH = Path("..") / "SpaceStation14.sln"
|
SOLUTION_PATH = Path("..") / "SpaceStation14Content.sln"
|
||||||
# If this doesn't match the saved version we overwrite them all.
|
# If this doesn't match the saved version we overwrite them all.
|
||||||
CURRENT_HOOKS_VERSION = "2"
|
CURRENT_HOOKS_VERSION = "2"
|
||||||
QUIET = len(sys.argv) == 2 and sys.argv[1] == "--quiet"
|
QUIET = len(sys.argv) == 2 and sys.argv[1] == "--quiet"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
exec mono bin/SS14.Launcher.exe
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>SS14L</string>
|
|
||||||
<key>CFBundleDisplayName</key>
|
|
||||||
<string>Space Station 14 Launcher</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>SS14</string>
|
|
||||||
<!--
|
|
||||||
Just a note about this icon.
|
|
||||||
MacOS seems REALLY iffy about this and even when the file is correct,
|
|
||||||
it can take forever before it decides to actually update it and display it.
|
|
||||||
TL;DR Apple is stupid.
|
|
||||||
-->
|
|
||||||
<key>CFBundleIconFile</key>
|
|
||||||
<string>ss14</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# cd to file containing script or something?
|
|
||||||
BASEDIR=$(dirname "$0")
|
|
||||||
echo "$BASEDIR"
|
|
||||||
cd "$BASEDIR"
|
|
||||||
|
|
||||||
exec /Library/Frameworks/Mono.framework/Versions/Current/Commands/mono ../Resources/SS14.Launcher.exe
|
|
||||||
Binary file not shown.
@@ -1,8 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/usr/bin/env -i bash
|
||||||
|
|
||||||
# cd to file containing script or something?
|
# cd to file containing script or something?
|
||||||
BASEDIR=$(dirname "$0")
|
BASEDIR=$(dirname "$0")
|
||||||
echo "$BASEDIR"
|
echo "$BASEDIR"
|
||||||
cd "$BASEDIR"
|
cd "$BASEDIR"
|
||||||
|
|
||||||
exec /Library/Frameworks/Mono.framework/Versions/Current/Commands/mono ../Resources/Robust.Client.exe
|
./Godot --path ./SS14.Client.Godot
|
||||||
|
|||||||
1
BuildFiles/Windows/launch.bat
Normal file
1
BuildFiles/Windows/launch.bat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
call Godot\godot.windows.tools.64.mono.exe --path SS14.Client.Godot
|
||||||
@@ -1 +0,0 @@
|
|||||||
call bin\SS14.Launcher.exe
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using BenchmarkDotNet.Attributes;
|
|
||||||
using Moq;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Benchmarks
|
|
||||||
{
|
|
||||||
public class ComponentManagerGetAllComponents
|
|
||||||
{
|
|
||||||
private readonly List<IEntity> _entities = new List<IEntity>();
|
|
||||||
|
|
||||||
private IComponentManager _componentManager;
|
|
||||||
|
|
||||||
[Params(500, 1000, 5000)] public int N { get; set; }
|
|
||||||
|
|
||||||
[GlobalSetup]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
// Initialize component manager.
|
|
||||||
IoCManager.InitThread();
|
|
||||||
|
|
||||||
IoCManager.Register<IComponentManager, ComponentManager>();
|
|
||||||
|
|
||||||
var dummyReg = new Mock<IComponentRegistration>();
|
|
||||||
dummyReg.SetupGet(p => p.Name).Returns("Dummy");
|
|
||||||
dummyReg.SetupGet(p => p.Type).Returns(typeof(DummyComponent));
|
|
||||||
dummyReg.SetupGet(p => p.NetID).Returns((uint?) null);
|
|
||||||
dummyReg.SetupGet(p => p.NetworkSynchronizeExistence).Returns(false);
|
|
||||||
dummyReg.SetupGet(p => p.References).Returns(new Type[] {typeof(DummyComponent)});
|
|
||||||
|
|
||||||
var componentFactory = new Mock<IComponentFactory>();
|
|
||||||
componentFactory.Setup(p => p.GetComponent<DummyComponent>()).Returns(new DummyComponent());
|
|
||||||
componentFactory.Setup(p => p.GetRegistration(It.IsAny<DummyComponent>())).Returns(dummyReg.Object);
|
|
||||||
|
|
||||||
IoCManager.RegisterInstance<IComponentFactory>(componentFactory.Object);
|
|
||||||
|
|
||||||
IoCManager.BuildGraph();
|
|
||||||
|
|
||||||
_componentManager = IoCManager.Resolve<IComponentManager>();
|
|
||||||
|
|
||||||
// Initialize N entities with one component.
|
|
||||||
for (var i = 0; i < N; i++)
|
|
||||||
{
|
|
||||||
var entity = new Entity();
|
|
||||||
entity.SetUid(new EntityUid(i + 1));
|
|
||||||
_entities.Add(entity);
|
|
||||||
|
|
||||||
_componentManager.AddComponent<DummyComponent>(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Benchmark]
|
|
||||||
public int Run()
|
|
||||||
{
|
|
||||||
var count = 0;
|
|
||||||
|
|
||||||
foreach (var _ in _componentManager.GetAllComponents<DummyComponent>())
|
|
||||||
{
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DummyComponent : Component
|
|
||||||
{
|
|
||||||
public override string Name => "Dummy";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net472</TargetFramework>
|
|
||||||
<OutputPath>..\bin\Content.Benchmarks\</OutputPath>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
|
||||||
<Platforms>x86;x64</Platforms>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Content.Client\Content.Client.csproj" />
|
|
||||||
<ProjectReference Include="..\Content.Server\Content.Server.csproj" />
|
|
||||||
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj" />
|
|
||||||
<ProjectReference Include="..\Content.Tests\Content.Tests.csproj" />
|
|
||||||
<ProjectReference Include="..\Content.IntegrationTests\Content.IntegrationTests.csproj" />
|
|
||||||
<ProjectReference Include="..\RobustToolbox\Robust.Client\Robust.Client.csproj" />
|
|
||||||
<ProjectReference Include="..\RobustToolbox\Robust.Server\Robust.Server.csproj" />
|
|
||||||
<ProjectReference Include="..\RobustToolbox\Robust.Shared.Maths\Robust.Shared.Maths.csproj" />
|
|
||||||
<ProjectReference Include="..\RobustToolbox\Robust.Shared\Robust.Shared.csproj" />
|
|
||||||
<ProjectReference Include="..\RobustToolbox\Robust.UnitTesting\Robust.UnitTesting.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using BenchmarkDotNet.Configs;
|
|
||||||
using BenchmarkDotNet.Running;
|
|
||||||
|
|
||||||
namespace Content.Benchmarks
|
|
||||||
{
|
|
||||||
internal class Program
|
|
||||||
{
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
BenchmarkRunner.Run<ComponentManagerGetAllComponents>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,232 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Shared.Chat;
|
|
||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Input;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.Chat
|
|
||||||
{
|
|
||||||
public class ChatBox : MarginContainer
|
|
||||||
{
|
|
||||||
public delegate void TextSubmitHandler(ChatBox chatBox, string text);
|
|
||||||
|
|
||||||
public delegate void FilterToggledHandler(ChatBox chatBox, BaseButton.ButtonToggledEventArgs e);
|
|
||||||
|
|
||||||
private const int MaxLinePixelLength = 500;
|
|
||||||
|
|
||||||
private readonly IList<string> _inputHistory = new List<string>();
|
|
||||||
|
|
||||||
private ILocalizationManager localize = IoCManager.Resolve<ILocalizationManager>();
|
|
||||||
|
|
||||||
public LineEdit Input { get; private set; }
|
|
||||||
public OutputPanel contents;
|
|
||||||
|
|
||||||
// Buttons for filtering
|
|
||||||
public Button AllButton;
|
|
||||||
public Button LocalButton;
|
|
||||||
public Button OOCButton;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Index while cycling through the input history. -1 means not going through history.
|
|
||||||
/// </summary>
|
|
||||||
private int _inputIndex = -1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Message that WAS being input before going through history began.
|
|
||||||
/// </summary>
|
|
||||||
private string _inputTemp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default formatting string for the ClientChatConsole.
|
|
||||||
/// </summary>
|
|
||||||
public string DefaultChatFormat { get; set; }
|
|
||||||
|
|
||||||
public bool ReleaseFocusOnEnter { get; set; } = true;
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
MarginLeft = -475.0f;
|
|
||||||
MarginTop = 10.0f;
|
|
||||||
MarginRight = -10.0f;
|
|
||||||
MarginBottom = 235.0f;
|
|
||||||
|
|
||||||
AnchorLeft = 1.0f;
|
|
||||||
AnchorRight = 1.0f;
|
|
||||||
|
|
||||||
var outerVBox = new VBoxContainer();
|
|
||||||
|
|
||||||
var panelContainer = new PanelContainer
|
|
||||||
{
|
|
||||||
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#25252aaa")},
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand
|
|
||||||
};
|
|
||||||
var vBox = new VBoxContainer();
|
|
||||||
panelContainer.AddChild(vBox);
|
|
||||||
var hBox = new HBoxContainer();
|
|
||||||
|
|
||||||
outerVBox.AddChild(panelContainer);
|
|
||||||
outerVBox.AddChild(hBox);
|
|
||||||
|
|
||||||
var contentMargin = new MarginContainer
|
|
||||||
{
|
|
||||||
MarginLeftOverride = 4, MarginRightOverride = 4,
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand
|
|
||||||
};
|
|
||||||
contents = new OutputPanel();
|
|
||||||
contentMargin.AddChild(contents);
|
|
||||||
vBox.AddChild(contentMargin);
|
|
||||||
|
|
||||||
Input = new LineEdit();
|
|
||||||
Input.OnKeyDown += InputKeyDown;
|
|
||||||
Input.OnTextEntered += Input_OnTextEntered;
|
|
||||||
vBox.AddChild(Input);
|
|
||||||
|
|
||||||
AllButton = new Button
|
|
||||||
{
|
|
||||||
Text = localize.GetString("All"),
|
|
||||||
Name = "ALL",
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Expand,
|
|
||||||
ToggleMode = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalButton = new Button
|
|
||||||
{
|
|
||||||
Text = localize.GetString("Local"),
|
|
||||||
Name = "Local",
|
|
||||||
ToggleMode = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
OOCButton = new Button
|
|
||||||
{
|
|
||||||
Text = localize.GetString("OOC"),
|
|
||||||
Name = "OOC",
|
|
||||||
ToggleMode = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
AllButton.OnToggled += OnFilterToggled;
|
|
||||||
LocalButton.OnToggled += OnFilterToggled;
|
|
||||||
OOCButton.OnToggled += OnFilterToggled;
|
|
||||||
|
|
||||||
hBox.AddChild(AllButton);
|
|
||||||
hBox.AddChild(LocalButton);
|
|
||||||
hBox.AddChild(OOCButton);
|
|
||||||
|
|
||||||
AddChild(outerVBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void MouseDown(GUIMouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
base.MouseDown(e);
|
|
||||||
|
|
||||||
Input.GrabKeyboardFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InputKeyDown(GUIKeyEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Key == Keyboard.Key.Escape)
|
|
||||||
{
|
|
||||||
Input.ReleaseKeyboardFocus();
|
|
||||||
e.Handle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.Key == Keyboard.Key.Up)
|
|
||||||
{
|
|
||||||
if (_inputIndex == -1 && _inputHistory.Count != 0)
|
|
||||||
{
|
|
||||||
_inputTemp = Input.Text;
|
|
||||||
_inputIndex++;
|
|
||||||
}
|
|
||||||
else if (_inputIndex + 1 < _inputHistory.Count)
|
|
||||||
{
|
|
||||||
_inputIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_inputIndex != -1)
|
|
||||||
{
|
|
||||||
Input.Text = _inputHistory[_inputIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Handle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.Key == Keyboard.Key.Down)
|
|
||||||
{
|
|
||||||
if (_inputIndex == 0)
|
|
||||||
{
|
|
||||||
Input.Text = _inputTemp;
|
|
||||||
_inputTemp = "";
|
|
||||||
_inputIndex--;
|
|
||||||
}
|
|
||||||
else if (_inputIndex != -1)
|
|
||||||
{
|
|
||||||
_inputIndex--;
|
|
||||||
Input.Text = _inputHistory[_inputIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
base.Dispose(disposing);
|
|
||||||
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
TextSubmitted = null;
|
|
||||||
Input = null;
|
|
||||||
contents = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public event TextSubmitHandler TextSubmitted;
|
|
||||||
|
|
||||||
public event FilterToggledHandler FilterToggled;
|
|
||||||
|
|
||||||
public void AddLine(string message, ChatChannel channel, Color color)
|
|
||||||
{
|
|
||||||
if (Disposed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var formatted = new FormattedMessage(3);
|
|
||||||
formatted.PushColor(color);
|
|
||||||
formatted.AddText(message);
|
|
||||||
formatted.Pop();
|
|
||||||
contents.AddMessage(formatted);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Input_OnTextEntered(LineEdit.LineEditEventArgs args)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(args.Text))
|
|
||||||
{
|
|
||||||
TextSubmitted?.Invoke(this, args.Text);
|
|
||||||
_inputHistory.Insert(0, args.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
_inputIndex = -1;
|
|
||||||
|
|
||||||
Input.Clear();
|
|
||||||
|
|
||||||
if (ReleaseFocusOnEnter)
|
|
||||||
{
|
|
||||||
Input.ReleaseKeyboardFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnFilterToggled(BaseButton.ButtonToggledEventArgs args)
|
|
||||||
{
|
|
||||||
FilterToggled?.Invoke(this, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,408 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.Interfaces.Chat;
|
|
||||||
using Content.Shared.Chat;
|
|
||||||
using Robust.Client;
|
|
||||||
using Robust.Client.Console;
|
|
||||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
|
||||||
using Robust.Client.Interfaces.UserInterface;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client.Chat
|
|
||||||
{
|
|
||||||
internal sealed class ChatManager : IChatManager
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The max amount of chars allowed to fit in a single speech bubble.
|
|
||||||
/// </summary>
|
|
||||||
private const int SingleBubbleCharLimit = 100;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Base queue delay each speech bubble has.
|
|
||||||
/// </summary>
|
|
||||||
private const float BubbleDelayBase = 0.2f;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Factor multiplied by speech bubble char length to add to delay.
|
|
||||||
/// </summary>
|
|
||||||
private const float BubbleDelayFactor = 0.8f / SingleBubbleCharLimit;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The max amount of speech bubbles over a single entity at once.
|
|
||||||
/// </summary>
|
|
||||||
private const int SpeechBubbleCap = 4;
|
|
||||||
|
|
||||||
private const char ConCmdSlash = '/';
|
|
||||||
private const char OOCAlias = '[';
|
|
||||||
private const char MeAlias = '@';
|
|
||||||
|
|
||||||
private readonly List<StoredChatMessage> filteredHistory = new List<StoredChatMessage>();
|
|
||||||
|
|
||||||
// Filter Button States
|
|
||||||
private bool _allState;
|
|
||||||
private bool _localState;
|
|
||||||
private bool _oocState;
|
|
||||||
|
|
||||||
// Flag Enums for holding filtered channels
|
|
||||||
private ChatChannel _filteredChannels;
|
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IClientNetManager _netManager;
|
|
||||||
[Dependency] private readonly IClientConsole _console;
|
|
||||||
[Dependency] private readonly IEntityManager _entityManager;
|
|
||||||
[Dependency] private readonly IEyeManager _eyeManager;
|
|
||||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private ChatBox _currentChatBox;
|
|
||||||
private Control _speechBubbleRoot;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Speech bubbles that are currently visible on screen.
|
|
||||||
/// We track them to push them up when new ones get added.
|
|
||||||
/// </summary>
|
|
||||||
private readonly Dictionary<EntityUid, List<SpeechBubble>> _activeSpeechBubbles =
|
|
||||||
new Dictionary<EntityUid, List<SpeechBubble>>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Speech bubbles that are to-be-sent because of the "rate limit" they have.
|
|
||||||
/// </summary>
|
|
||||||
private readonly Dictionary<EntityUid, SpeechBubbleQueueData> _queuedSpeechBubbles
|
|
||||||
= new Dictionary<EntityUid, SpeechBubbleQueueData>();
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
_netManager.RegisterNetMessage<MsgChatMessage>(MsgChatMessage.NAME, _onChatMessage);
|
|
||||||
|
|
||||||
_speechBubbleRoot = new Control();
|
|
||||||
_speechBubbleRoot.SetAnchorPreset(Control.LayoutPreset.Wide);
|
|
||||||
_userInterfaceManager.StateRoot.AddChild(_speechBubbleRoot);
|
|
||||||
_speechBubbleRoot.SetPositionFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FrameUpdate(RenderFrameEventArgs delta)
|
|
||||||
{
|
|
||||||
// Update queued speech bubbles.
|
|
||||||
if (_queuedSpeechBubbles.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var (entityUid, queueData) in _queuedSpeechBubbles.ShallowClone())
|
|
||||||
{
|
|
||||||
if (!_entityManager.TryGetEntity(entityUid, out var entity))
|
|
||||||
{
|
|
||||||
_queuedSpeechBubbles.Remove(entityUid);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
queueData.TimeLeft -= delta.Elapsed;
|
|
||||||
if (queueData.TimeLeft > 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queueData.MessageQueue.Count == 0)
|
|
||||||
{
|
|
||||||
_queuedSpeechBubbles.Remove(entityUid);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var msg = queueData.MessageQueue.Dequeue();
|
|
||||||
|
|
||||||
queueData.TimeLeft += BubbleDelayBase + msg.Length * BubbleDelayFactor;
|
|
||||||
|
|
||||||
// We keep the queue around while it has 0 items. This allows us to keep the timer.
|
|
||||||
// When the timer hits 0 and there's no messages left, THEN we can clear it up.
|
|
||||||
CreateSpeechBubble(entity, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetChatBox(ChatBox chatBox)
|
|
||||||
{
|
|
||||||
if (_currentChatBox != null)
|
|
||||||
{
|
|
||||||
_currentChatBox.TextSubmitted -= _onChatBoxTextSubmitted;
|
|
||||||
_currentChatBox.FilterToggled -= _onFilterButtonToggled;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentChatBox = chatBox;
|
|
||||||
if (_currentChatBox != null)
|
|
||||||
{
|
|
||||||
_currentChatBox.TextSubmitted += _onChatBoxTextSubmitted;
|
|
||||||
_currentChatBox.FilterToggled += _onFilterButtonToggled;
|
|
||||||
}
|
|
||||||
|
|
||||||
RepopulateChat(filteredHistory);
|
|
||||||
_currentChatBox.AllButton.Pressed = !_allState;
|
|
||||||
_currentChatBox.LocalButton.Pressed = !_localState;
|
|
||||||
_currentChatBox.OOCButton.Pressed = !_oocState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveSpeechBubble(EntityUid entityUid, SpeechBubble bubble)
|
|
||||||
{
|
|
||||||
bubble.Dispose();
|
|
||||||
|
|
||||||
var list = _activeSpeechBubbles[entityUid];
|
|
||||||
list.Remove(bubble);
|
|
||||||
|
|
||||||
if (list.Count == 0)
|
|
||||||
{
|
|
||||||
_activeSpeechBubbles.Remove(entityUid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteChatMessage(StoredChatMessage message)
|
|
||||||
{
|
|
||||||
Logger.Debug($"{message.Channel}: {message.Message}");
|
|
||||||
|
|
||||||
if (IsFiltered(message.Channel))
|
|
||||||
{
|
|
||||||
Logger.Debug($"Message filtered: {message.Channel}: {message.Message}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var color = Color.DarkGray;
|
|
||||||
var messageText = message.Message;
|
|
||||||
if (!string.IsNullOrEmpty(message.MessageWrap))
|
|
||||||
{
|
|
||||||
messageText = string.Format(message.MessageWrap, messageText);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (message.Channel)
|
|
||||||
{
|
|
||||||
case ChatChannel.Server:
|
|
||||||
color = Color.Orange;
|
|
||||||
break;
|
|
||||||
case ChatChannel.OOC:
|
|
||||||
color = Color.LightSkyBlue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentChatBox?.AddLine(messageText, message.Channel, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _onChatBoxTextSubmitted(ChatBox chatBox, string text)
|
|
||||||
{
|
|
||||||
DebugTools.Assert(chatBox == _currentChatBox);
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (text[0])
|
|
||||||
{
|
|
||||||
case ConCmdSlash:
|
|
||||||
{
|
|
||||||
// run locally
|
|
||||||
var conInput = text.Substring(1);
|
|
||||||
_console.ProcessCommand(conInput);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OOCAlias:
|
|
||||||
{
|
|
||||||
var conInput = text.Substring(1);
|
|
||||||
_console.ProcessCommand($"ooc \"{conInput}\"");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MeAlias:
|
|
||||||
{
|
|
||||||
var conInput = text.Substring(1);
|
|
||||||
_console.ProcessCommand($"me \"{conInput}\"");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
var conInput = _currentChatBox.DefaultChatFormat != null
|
|
||||||
? string.Format(_currentChatBox.DefaultChatFormat, text)
|
|
||||||
: text;
|
|
||||||
_console.ProcessCommand(conInput);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _onFilterButtonToggled(ChatBox chatBox, BaseButton.ButtonToggledEventArgs e)
|
|
||||||
{
|
|
||||||
switch (e.Button.Name)
|
|
||||||
{
|
|
||||||
case "Local":
|
|
||||||
_localState = !_localState;
|
|
||||||
if (_localState)
|
|
||||||
{
|
|
||||||
_filteredChannels |= ChatChannel.Local;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_filteredChannels &= ~ChatChannel.Local;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "OOC":
|
|
||||||
_oocState = !_oocState;
|
|
||||||
if (_oocState)
|
|
||||||
{
|
|
||||||
_filteredChannels |= ChatChannel.OOC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_filteredChannels &= ~ChatChannel.OOC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "ALL":
|
|
||||||
chatBox.LocalButton.Pressed ^= true;
|
|
||||||
chatBox.OOCButton.Pressed ^= true;
|
|
||||||
_allState = !_allState;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RepopulateChat(filteredHistory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RepopulateChat(IEnumerable<StoredChatMessage> filteredMessages)
|
|
||||||
{
|
|
||||||
_currentChatBox.contents.Clear();
|
|
||||||
|
|
||||||
foreach (var msg in filteredMessages)
|
|
||||||
{
|
|
||||||
WriteChatMessage(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _onChatMessage(MsgChatMessage msg)
|
|
||||||
{
|
|
||||||
Logger.Debug($"{msg.Channel}: {msg.Message}");
|
|
||||||
|
|
||||||
// Log all incoming chat to repopulate when filter is un-toggled
|
|
||||||
var storedMessage = new StoredChatMessage(msg);
|
|
||||||
filteredHistory.Add(storedMessage);
|
|
||||||
WriteChatMessage(storedMessage);
|
|
||||||
|
|
||||||
// Local messages that have an entity attached get a speech bubble.
|
|
||||||
if (msg.Channel == ChatChannel.Local && msg.SenderEntity != default)
|
|
||||||
{
|
|
||||||
AddSpeechBubble(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddSpeechBubble(MsgChatMessage msg)
|
|
||||||
{
|
|
||||||
if (!_entityManager.TryGetEntity(msg.SenderEntity, out var entity))
|
|
||||||
{
|
|
||||||
Logger.WarningS("chat", "Got local chat message with invalid sender entity: {0}", msg.SenderEntity);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split message into words separated by spaces.
|
|
||||||
var words = msg.Message.Split(' ');
|
|
||||||
var messages = new List<string>();
|
|
||||||
var currentBuffer = new List<string>();
|
|
||||||
|
|
||||||
// Really shoddy way to approximate word length.
|
|
||||||
// Yes, I am aware of all the crimes here.
|
|
||||||
// TODO: Improve this to use actual glyph width etc..
|
|
||||||
var currentWordLength = 0;
|
|
||||||
foreach (var word in words)
|
|
||||||
{
|
|
||||||
// +1 for the space.
|
|
||||||
currentWordLength += word.Length + 1;
|
|
||||||
|
|
||||||
if (currentWordLength > SingleBubbleCharLimit)
|
|
||||||
{
|
|
||||||
// Too long for the current speech bubble, flush it.
|
|
||||||
messages.Add(string.Join(" ", currentBuffer));
|
|
||||||
currentBuffer.Clear();
|
|
||||||
|
|
||||||
currentWordLength = word.Length;
|
|
||||||
|
|
||||||
if (currentWordLength > SingleBubbleCharLimit)
|
|
||||||
{
|
|
||||||
// Word is STILL too long.
|
|
||||||
// Truncate it with an ellipse.
|
|
||||||
messages.Add($"{word.Substring(0, SingleBubbleCharLimit-3)}...");
|
|
||||||
currentWordLength = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentBuffer.Add(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentBuffer.Count != 0)
|
|
||||||
{
|
|
||||||
// Don't forget the last bubble.
|
|
||||||
messages.Add(string.Join(" ", currentBuffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var message in messages)
|
|
||||||
{
|
|
||||||
EnqueueSpeechBubble(entity, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnqueueSpeechBubble(IEntity entity, string contents)
|
|
||||||
{
|
|
||||||
if (!_queuedSpeechBubbles.TryGetValue(entity.Uid, out var queueData))
|
|
||||||
{
|
|
||||||
queueData = new SpeechBubbleQueueData();
|
|
||||||
_queuedSpeechBubbles.Add(entity.Uid, queueData);
|
|
||||||
}
|
|
||||||
|
|
||||||
queueData.MessageQueue.Enqueue(contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateSpeechBubble(IEntity entity, string contents)
|
|
||||||
{
|
|
||||||
var bubble = new SpeechBubble(contents, entity, _eyeManager, this);
|
|
||||||
|
|
||||||
if (_activeSpeechBubbles.TryGetValue(entity.Uid, out var existing))
|
|
||||||
{
|
|
||||||
// Push up existing bubbles above the mob's head.
|
|
||||||
foreach (var existingBubble in existing)
|
|
||||||
{
|
|
||||||
existingBubble.VerticalOffset += bubble.ContentHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
existing = new List<SpeechBubble>();
|
|
||||||
_activeSpeechBubbles.Add(entity.Uid, existing);
|
|
||||||
}
|
|
||||||
|
|
||||||
existing.Add(bubble);
|
|
||||||
_speechBubbleRoot.AddChild(bubble);
|
|
||||||
|
|
||||||
if (existing.Count > SpeechBubbleCap)
|
|
||||||
{
|
|
||||||
// Get the oldest to start fading fast.
|
|
||||||
var last = existing[0];
|
|
||||||
last.FadeNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsFiltered(ChatChannel channel)
|
|
||||||
{
|
|
||||||
// _allState works as inverter.
|
|
||||||
return _allState ^ _filteredChannels.HasFlag(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class SpeechBubbleQueueData
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Time left until the next speech bubble can appear.
|
|
||||||
/// </summary>
|
|
||||||
public float TimeLeft { get; set; }
|
|
||||||
|
|
||||||
public Queue<string> MessageQueue { get; } = new Queue<string>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
using Content.Client.Interfaces.Chat;
|
|
||||||
using Robust.Client;
|
|
||||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Timers;
|
|
||||||
|
|
||||||
namespace Content.Client.Chat
|
|
||||||
{
|
|
||||||
public class SpeechBubble : Control
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The total time a speech bubble stays on screen.
|
|
||||||
/// </summary>
|
|
||||||
private const float TotalTime = 4;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of time at the end of the bubble's life at which it starts fading.
|
|
||||||
/// </summary>
|
|
||||||
private const float FadeTime = 0.25f;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The distance in world space to offset the speech bubble from the center of the entity.
|
|
||||||
/// i.e. greater -> higher above the mob's head.
|
|
||||||
/// </summary>
|
|
||||||
private const float EntityVerticalOffset = 0.5f;
|
|
||||||
|
|
||||||
private readonly IEyeManager _eyeManager;
|
|
||||||
private readonly IEntity _senderEntity;
|
|
||||||
private readonly IChatManager _chatManager;
|
|
||||||
|
|
||||||
private Control _panel;
|
|
||||||
|
|
||||||
private float _timeLeft = TotalTime;
|
|
||||||
|
|
||||||
public float VerticalOffset { get; set; }
|
|
||||||
private float _verticalOffsetAchieved;
|
|
||||||
|
|
||||||
public float ContentHeight { get; }
|
|
||||||
|
|
||||||
public SpeechBubble(string text, IEntity senderEntity, IEyeManager eyeManager, IChatManager chatManager)
|
|
||||||
{
|
|
||||||
_chatManager = chatManager;
|
|
||||||
_senderEntity = senderEntity;
|
|
||||||
_eyeManager = eyeManager;
|
|
||||||
|
|
||||||
MouseFilter = MouseFilterMode.Ignore;
|
|
||||||
// Use text clipping so new messages don't overlap old ones being pushed up.
|
|
||||||
RectClipContent = true;
|
|
||||||
|
|
||||||
var label = new RichTextLabel
|
|
||||||
{
|
|
||||||
MaxWidth = 256,
|
|
||||||
MouseFilter = MouseFilterMode.Ignore
|
|
||||||
};
|
|
||||||
label.SetMessage(text);
|
|
||||||
|
|
||||||
_panel = new PanelContainer
|
|
||||||
{
|
|
||||||
StyleClasses = { "tooltipBox" },
|
|
||||||
Children = { label },
|
|
||||||
MouseFilter = MouseFilterMode.Ignore,
|
|
||||||
ModulateSelfOverride = Color.White.WithAlpha(0.75f)
|
|
||||||
};
|
|
||||||
|
|
||||||
AddChild(_panel);
|
|
||||||
|
|
||||||
_panel.Size = _panel.CombinedMinimumSize;
|
|
||||||
ContentHeight = _panel.Height;
|
|
||||||
Size = (_panel.Width, 0);
|
|
||||||
_verticalOffsetAchieved = -ContentHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void FrameUpdate(RenderFrameEventArgs args)
|
|
||||||
{
|
|
||||||
base.FrameUpdate(args);
|
|
||||||
|
|
||||||
_timeLeft -= args.Elapsed;
|
|
||||||
|
|
||||||
if (_timeLeft <= FadeTime)
|
|
||||||
{
|
|
||||||
// Update alpha if we're fading.
|
|
||||||
Modulate = Color.White.WithAlpha(_timeLeft / FadeTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_senderEntity.Deleted || _timeLeft <= 0)
|
|
||||||
{
|
|
||||||
// Timer spawn to prevent concurrent modification exception.
|
|
||||||
Timer.Spawn(0, Die);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lerp to our new vertical offset if it's been modified.
|
|
||||||
if (FloatMath.CloseTo(_verticalOffsetAchieved - VerticalOffset, 0, 0.1))
|
|
||||||
{
|
|
||||||
_verticalOffsetAchieved = VerticalOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_verticalOffsetAchieved = FloatMath.Lerp(_verticalOffsetAchieved, VerticalOffset, 10 * args.Elapsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
var worldPos = _senderEntity.Transform.WorldPosition;
|
|
||||||
worldPos += (0, EntityVerticalOffset);
|
|
||||||
|
|
||||||
var lowerCenter = _eyeManager.WorldToScreen(worldPos) / UIScale;
|
|
||||||
var screenPos = lowerCenter - (Width / 2, ContentHeight + _verticalOffsetAchieved);
|
|
||||||
Position = screenPos;
|
|
||||||
|
|
||||||
var height = (lowerCenter.Y - screenPos.Y).Clamp(0, ContentHeight);
|
|
||||||
Size = (Size.X, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Die()
|
|
||||||
{
|
|
||||||
if (Disposed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_chatManager.RemoveSpeechBubble(_senderEntity.Uid, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Causes the speech bubble to start fading IMMEDIATELY.
|
|
||||||
/// </summary>
|
|
||||||
public void FadeNow()
|
|
||||||
{
|
|
||||||
if (_timeLeft > FadeTime)
|
|
||||||
{
|
|
||||||
_timeLeft = FadeTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
using Content.Shared.Chat;
|
|
||||||
|
|
||||||
namespace Content.Client.Chat
|
|
||||||
{
|
|
||||||
public class StoredChatMessage
|
|
||||||
{
|
|
||||||
// TODO Make me reflected with respect to MsgChatMessage
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Client's own copies of chat messages used in filtering locally
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Actual Message contents, i.e. words
|
|
||||||
/// </summary>
|
|
||||||
public string Message { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Message channel, used for filtering
|
|
||||||
/// </summary>
|
|
||||||
public ChatChannel Channel { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// What to "wrap" the message contents with. Example is stuff like 'Joe says: "{0}"'
|
|
||||||
/// </summary>
|
|
||||||
public string MessageWrap { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor to copy a net message into stored client variety
|
|
||||||
/// </summary>
|
|
||||||
public StoredChatMessage(MsgChatMessage netMsg)
|
|
||||||
{
|
|
||||||
Message = netMsg.Message;
|
|
||||||
Channel = netMsg.Channel;
|
|
||||||
MessageWrap = netMsg.MessageWrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared;
|
|
||||||
|
|
||||||
namespace Content.Client
|
|
||||||
{
|
|
||||||
public sealed class ClientModuleTestingCallbacks : SharedModuleTestingCallbacks
|
|
||||||
{
|
|
||||||
public Action ClientBeforeIoC { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.Interfaces;
|
|
||||||
using Content.Shared;
|
|
||||||
using Robust.Client;
|
|
||||||
using Robust.Client.Interfaces.Console;
|
|
||||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.Interfaces.UserInterface;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client
|
|
||||||
{
|
|
||||||
public class ClientNotifyManager : SharedNotifyManager, IClientNotifyManager
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private IPlayerManager _playerManager;
|
|
||||||
[Dependency] private IUserInterfaceManager _userInterfaceManager;
|
|
||||||
[Dependency] private IInputManager _inputManager;
|
|
||||||
[Dependency] private IEyeManager _eyeManager;
|
|
||||||
[Dependency] private IClientNetManager _netManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private readonly List<PopupLabel> _aliveLabels = new List<PopupLabel>();
|
|
||||||
private bool _initialized;
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
DebugTools.Assert(!_initialized);
|
|
||||||
|
|
||||||
_netManager.RegisterNetMessage<MsgDoNotify>(nameof(MsgDoNotify), DoNotifyMessage);
|
|
||||||
|
|
||||||
_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DoNotifyMessage(MsgDoNotify message)
|
|
||||||
{
|
|
||||||
PopupMessage(_eyeManager.WorldToScreen(message.Coordinates), message.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PopupMessage(GridCoordinates coordinates, IEntity viewer, string message)
|
|
||||||
{
|
|
||||||
if (viewer != _playerManager.LocalPlayer.ControlledEntity)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PopupMessage(_eyeManager.WorldToScreen(coordinates), message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PopupMessage(ScreenCoordinates coordinates, string message)
|
|
||||||
{
|
|
||||||
var label = new PopupLabel {Text = message};
|
|
||||||
var minimumSize = label.CombinedMinimumSize;
|
|
||||||
label.InitialPos = label.Position = coordinates.Position - minimumSize / 2;
|
|
||||||
_userInterfaceManager.StateRoot.AddChild(label);
|
|
||||||
_aliveLabels.Add(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PopupMessage(string message)
|
|
||||||
{
|
|
||||||
PopupMessage(new ScreenCoordinates(_inputManager.MouseScreenPosition), message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FrameUpdate(RenderFrameEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
foreach (var label in _aliveLabels)
|
|
||||||
{
|
|
||||||
label.Update(eventArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
_aliveLabels.RemoveAll(l => l.Disposed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PopupLabel : Label
|
|
||||||
{
|
|
||||||
private float _timeLeft;
|
|
||||||
public Vector2 InitialPos { get; set; }
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
ShadowOffsetXOverride = 1;
|
|
||||||
ShadowOffsetYOverride = 1;
|
|
||||||
FontColorShadowOverride = Color.Black;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(RenderFrameEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
_timeLeft += eventArgs.Elapsed;
|
|
||||||
Position = InitialPos - new Vector2(0, 20 * (_timeLeft * _timeLeft + _timeLeft));
|
|
||||||
if (_timeLeft > 0.5f)
|
|
||||||
{
|
|
||||||
Modulate = Color.White.WithAlpha(1f - 0.2f * (float)Math.Pow(_timeLeft - 0.5f, 3f));
|
|
||||||
if (_timeLeft > 3f)
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PopupMessageCommand : IConsoleCommand
|
|
||||||
{
|
|
||||||
public string Command => "popupmsg";
|
|
||||||
public string Description => "";
|
|
||||||
public string Help => "";
|
|
||||||
|
|
||||||
public bool Execute(IDebugConsole console, params string[] args)
|
|
||||||
{
|
|
||||||
var arg = args[0];
|
|
||||||
var mgr = IoCManager.Resolve<IClientNotifyManager>();
|
|
||||||
mgr.PopupMessage(arg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
using Content.Client.Interfaces;
|
|
||||||
using Content.Shared.GameObjects.Components.Markers;
|
|
||||||
using Robust.Client.Interfaces.Console;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.Commands
|
|
||||||
{
|
|
||||||
internal sealed class ShowMarkersCommand : IConsoleCommand
|
|
||||||
{
|
|
||||||
// ReSharper disable once StringLiteralTypo
|
|
||||||
public string Command => "togglemarkers";
|
|
||||||
public string Description => "Toggles visibility of markers such as spawn points.";
|
|
||||||
public string Help => "";
|
|
||||||
|
|
||||||
public bool Execute(IDebugConsole console, params string[] args)
|
|
||||||
{
|
|
||||||
bool? whichToSet = null;
|
|
||||||
foreach (var entity in IoCManager.Resolve<IEntityManager>()
|
|
||||||
.GetEntities(new TypeEntityQuery(typeof(SharedSpawnPointComponent))))
|
|
||||||
{
|
|
||||||
if (!entity.TryGetComponent(out ISpriteComponent sprite))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!whichToSet.HasValue)
|
|
||||||
{
|
|
||||||
whichToSet = !sprite.Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite.Visible = whichToSet.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class NotifyCommand : IConsoleCommand
|
|
||||||
{
|
|
||||||
public string Command => "notify";
|
|
||||||
public string Description => "Send a notify client side.";
|
|
||||||
public string Help => "notify <message>";
|
|
||||||
|
|
||||||
public bool Execute(IDebugConsole console, params string[] args)
|
|
||||||
{
|
|
||||||
var message = args[0];
|
|
||||||
|
|
||||||
var notifyManager = IoCManager.Resolve<IClientNotifyManager>();
|
|
||||||
notifyManager.PopupMessage(message);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,391 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Client.GameObjects.Components.Construction;
|
|
||||||
using Content.Shared.Construction;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.Interfaces.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.Graphics;
|
|
||||||
using Robust.Client.Interfaces.Placement;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.Placement;
|
|
||||||
using Robust.Client.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Client.Utility;
|
|
||||||
using Robust.Shared.Enums;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client.Construction
|
|
||||||
{
|
|
||||||
public class ConstructionMenu : SS14Window
|
|
||||||
{
|
|
||||||
|
|
||||||
#pragma warning disable CS0649
|
|
||||||
[Dependency]
|
|
||||||
readonly IPrototypeManager PrototypeManager;
|
|
||||||
[Dependency]
|
|
||||||
readonly IResourceCache ResourceCache;
|
|
||||||
#pragma warning restore
|
|
||||||
|
|
||||||
public ConstructorComponent Owner { get; set; }
|
|
||||||
Button BuildButton;
|
|
||||||
Button EraseButton;
|
|
||||||
LineEdit SearchBar;
|
|
||||||
Tree RecipeList;
|
|
||||||
TextureRect InfoIcon;
|
|
||||||
Label InfoLabel;
|
|
||||||
ItemList StepList;
|
|
||||||
|
|
||||||
CategoryNode RootCategory;
|
|
||||||
// This list is flattened in such a way that the top most deepest category is first.
|
|
||||||
List<CategoryNode> FlattenedCategories;
|
|
||||||
PlacementManager Placement;
|
|
||||||
|
|
||||||
public ConstructionMenu()
|
|
||||||
{
|
|
||||||
Size = new Vector2(500.0f, 350.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
Placement = (PlacementManager)IoCManager.Resolve<IPlacementManager>();
|
|
||||||
Placement.PlacementCanceled += OnPlacementCanceled;
|
|
||||||
|
|
||||||
Title = "Construction";
|
|
||||||
|
|
||||||
var hSplitContainer = new HSplitContainer();
|
|
||||||
|
|
||||||
// Left side
|
|
||||||
var recipes = new VBoxContainer("Recipes") {CustomMinimumSize = new Vector2(150.0f, 0.0f)};
|
|
||||||
SearchBar = new LineEdit("Search") {PlaceHolder = "Search"};
|
|
||||||
RecipeList = new Tree("Tree") {SizeFlagsVertical = SizeFlags.FillExpand, HideRoot = true};
|
|
||||||
recipes.AddChild(SearchBar);
|
|
||||||
recipes.AddChild(RecipeList);
|
|
||||||
hSplitContainer.AddChild(recipes);
|
|
||||||
|
|
||||||
// Right side
|
|
||||||
var guide = new VBoxContainer("Guide");
|
|
||||||
var info = new HBoxContainer("Info");
|
|
||||||
InfoIcon = new TextureRect("TextureRect");
|
|
||||||
InfoLabel = new Label("Label")
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand, SizeFlagsVertical = SizeFlags.ShrinkCenter
|
|
||||||
};
|
|
||||||
info.AddChild(InfoIcon);
|
|
||||||
info.AddChild(InfoLabel);
|
|
||||||
guide.AddChild(info);
|
|
||||||
|
|
||||||
var stepsLabel = new Label("Label")
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
|
||||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
|
||||||
Text = "Steps"
|
|
||||||
};
|
|
||||||
guide.AddChild(stepsLabel);
|
|
||||||
|
|
||||||
StepList = new ItemList("StepsList")
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand, SelectMode = ItemList.ItemListSelectMode.None
|
|
||||||
};
|
|
||||||
guide.AddChild(StepList);
|
|
||||||
|
|
||||||
var buttonsContainer = new HBoxContainer("Buttons");
|
|
||||||
BuildButton = new Button("BuildButton")
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
TextAlign = Button.AlignMode.Center,
|
|
||||||
Text = "Build!",
|
|
||||||
Disabled = true,
|
|
||||||
ToggleMode = false
|
|
||||||
};
|
|
||||||
EraseButton = new Button("EraseButton")
|
|
||||||
{
|
|
||||||
TextAlign = Button.AlignMode.Center, Text = "Clear Ghosts", ToggleMode = true
|
|
||||||
};
|
|
||||||
buttonsContainer.AddChild(BuildButton);
|
|
||||||
buttonsContainer.AddChild(EraseButton);
|
|
||||||
guide.AddChild(buttonsContainer);
|
|
||||||
|
|
||||||
hSplitContainer.AddChild(guide);
|
|
||||||
Contents.AddChild(hSplitContainer);
|
|
||||||
|
|
||||||
BuildButton.OnPressed += OnBuildPressed;
|
|
||||||
EraseButton.OnToggled += OnEraseToggled;
|
|
||||||
SearchBar.OnTextChanged += OnTextEntered;
|
|
||||||
RecipeList.OnItemSelected += OnItemSelected;
|
|
||||||
|
|
||||||
PopulatePrototypeList();
|
|
||||||
PopulateTree();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
base.Dispose(disposing);
|
|
||||||
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
Placement.PlacementCanceled -= OnPlacementCanceled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnItemSelected()
|
|
||||||
{
|
|
||||||
var prototype = (ConstructionPrototype)RecipeList.Selected.Metadata;
|
|
||||||
|
|
||||||
if (prototype == null)
|
|
||||||
{
|
|
||||||
InfoLabel.Text = "";
|
|
||||||
InfoIcon.Texture = null;
|
|
||||||
StepList.Clear();
|
|
||||||
BuildButton.Disabled = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BuildButton.Disabled = false;
|
|
||||||
InfoLabel.Text = prototype.Description;
|
|
||||||
InfoIcon.Texture = prototype.Icon.Frame0();
|
|
||||||
|
|
||||||
StepList.Clear();
|
|
||||||
|
|
||||||
foreach (var forward in prototype.Stages.Select(a => a.Forward))
|
|
||||||
{
|
|
||||||
if (forward == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Texture icon;
|
|
||||||
string text;
|
|
||||||
switch (forward)
|
|
||||||
{
|
|
||||||
case ConstructionStepMaterial mat:
|
|
||||||
switch (mat.Material)
|
|
||||||
{
|
|
||||||
case ConstructionStepMaterial.MaterialType.Metal:
|
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/sheet_metal.png");
|
|
||||||
text = $"Metal x{mat.Amount}";
|
|
||||||
break;
|
|
||||||
case ConstructionStepMaterial.MaterialType.Glass:
|
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/sheet_glass.png");
|
|
||||||
text = $"Glass x{mat.Amount}";
|
|
||||||
break;
|
|
||||||
case ConstructionStepMaterial.MaterialType.Cable:
|
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/cable_coil.png");
|
|
||||||
text = $"Cable Coil x{mat.Amount}";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ConstructionStepTool tool:
|
|
||||||
switch (tool.Tool)
|
|
||||||
{
|
|
||||||
case ConstructionStepTool.ToolType.Wrench:
|
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/wrench.png");
|
|
||||||
text = "Wrench";
|
|
||||||
break;
|
|
||||||
case ConstructionStepTool.ToolType.Crowbar:
|
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/crowbar.png");
|
|
||||||
text = "Crowbar";
|
|
||||||
break;
|
|
||||||
case ConstructionStepTool.ToolType.Screwdriver:
|
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/screwdriver.png");
|
|
||||||
text = "Screwdriver";
|
|
||||||
break;
|
|
||||||
case ConstructionStepTool.ToolType.Welder:
|
|
||||||
icon = ResourceCache.GetResource<RSIResource>("/Textures/Objects/tools.rsi").RSI["welder"].Frame0;
|
|
||||||
text = $"Welding tool ({tool.Amount} fuel)";
|
|
||||||
break;
|
|
||||||
case ConstructionStepTool.ToolType.Wirecutters:
|
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/wirecutter.png");
|
|
||||||
text = "Wirecutters";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
StepList.AddItem(text, icon, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnTextEntered(LineEdit.LineEditEventArgs args)
|
|
||||||
{
|
|
||||||
var str = args.Text;
|
|
||||||
PopulateTree(string.IsNullOrWhiteSpace(str) ? null : str.ToLowerInvariant());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnBuildPressed(Button.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
var prototype = (ConstructionPrototype)RecipeList.Selected.Metadata;
|
|
||||||
if (prototype == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prototype.Type != ConstructionType.Structure)
|
|
||||||
{
|
|
||||||
// In-hand attackby doesn't exist so this is the best alternative.
|
|
||||||
var loc = Owner.Owner.GetComponent<ITransformComponent>().GridPosition;
|
|
||||||
Owner.SpawnGhost(prototype, loc, Direction.North);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var hijack = new ConstructionPlacementHijack(prototype, Owner);
|
|
||||||
var info = new PlacementInformation
|
|
||||||
{
|
|
||||||
IsTile = false,
|
|
||||||
PlacementOption = prototype.PlacementMode,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Placement.BeginHijackedPlacing(info, hijack);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEraseToggled(BaseButton.ButtonToggledEventArgs args)
|
|
||||||
{
|
|
||||||
var hijack = new ConstructionPlacementHijack(null, Owner);
|
|
||||||
Placement.ToggleEraserHijacked(hijack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PopulatePrototypeList()
|
|
||||||
{
|
|
||||||
RootCategory = new CategoryNode("", null);
|
|
||||||
int count = 1;
|
|
||||||
|
|
||||||
foreach (var prototype in PrototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
|
||||||
{
|
|
||||||
var currentNode = RootCategory;
|
|
||||||
|
|
||||||
foreach (var category in prototype.CategorySegments)
|
|
||||||
{
|
|
||||||
if (!currentNode.ChildCategories.TryGetValue(category, out var subNode))
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
subNode = new CategoryNode(category, currentNode);
|
|
||||||
currentNode.ChildCategories.Add(category, subNode);
|
|
||||||
}
|
|
||||||
currentNode = subNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentNode.Prototypes.Add(prototype);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do a pass to sort the prototype lists and flatten the hierarchy.
|
|
||||||
void Recurse(CategoryNode node)
|
|
||||||
{
|
|
||||||
// I give up we're using recursion to flatten this.
|
|
||||||
// There probably IS a way to do it.
|
|
||||||
// I'm too stupid to think of what that way is.
|
|
||||||
foreach (var child in node.ChildCategories.Values)
|
|
||||||
{
|
|
||||||
Recurse(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
node.Prototypes.Sort(ComparePrototype);
|
|
||||||
FlattenedCategories.Add(node);
|
|
||||||
node.FlattenedIndex = FlattenedCategories.Count - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlattenedCategories = new List<CategoryNode>(count);
|
|
||||||
Recurse(RootCategory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PopulateTree(string searchTerm = null)
|
|
||||||
{
|
|
||||||
RecipeList.Clear();
|
|
||||||
|
|
||||||
var categoryItems = new Tree.Item[FlattenedCategories.Count];
|
|
||||||
categoryItems[RootCategory.FlattenedIndex] = RecipeList.CreateItem();
|
|
||||||
|
|
||||||
// Yay more recursion.
|
|
||||||
Tree.Item ItemForNode(CategoryNode node)
|
|
||||||
{
|
|
||||||
if (categoryItems[node.FlattenedIndex] != null)
|
|
||||||
{
|
|
||||||
return categoryItems[node.FlattenedIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
var item = RecipeList.CreateItem(ItemForNode(node.Parent));
|
|
||||||
item.Text = node.Name;
|
|
||||||
item.Selectable = false;
|
|
||||||
categoryItems[node.FlattenedIndex] = item;
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var node in FlattenedCategories)
|
|
||||||
{
|
|
||||||
foreach (var prototype in node.Prototypes)
|
|
||||||
{
|
|
||||||
if (searchTerm != null)
|
|
||||||
{
|
|
||||||
var found = false;
|
|
||||||
// TODO: don't run ToLowerInvariant() constantly.
|
|
||||||
if (prototype.Name.ToLowerInvariant().IndexOf(searchTerm) != -1)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var keyw in prototype.Keywords.Concat(prototype.CategorySegments))
|
|
||||||
{
|
|
||||||
// TODO: don't run ToLowerInvariant() constantly.
|
|
||||||
if (keyw.ToLowerInvariant().IndexOf(searchTerm) != -1)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var subItem = RecipeList.CreateItem(ItemForNode(node));
|
|
||||||
subItem.Text = prototype.Name;
|
|
||||||
subItem.Metadata = prototype;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPlacementCanceled(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
EraseButton.Pressed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int ComparePrototype(ConstructionPrototype x, ConstructionPrototype y)
|
|
||||||
{
|
|
||||||
return x.Name.CompareTo(y.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
class CategoryNode
|
|
||||||
{
|
|
||||||
public readonly string Name;
|
|
||||||
public readonly CategoryNode Parent;
|
|
||||||
public SortedDictionary<string, CategoryNode> ChildCategories = new SortedDictionary<string, CategoryNode>();
|
|
||||||
public List<ConstructionPrototype> Prototypes = new List<ConstructionPrototype>();
|
|
||||||
public int FlattenedIndex = -1;
|
|
||||||
|
|
||||||
public CategoryNode(string name, CategoryNode parent)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
Parent = parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
using Content.Client.GameObjects.Components.Construction;
|
|
||||||
using Content.Shared.Construction;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.Placement;
|
|
||||||
using Robust.Client.ResourceManagement;
|
|
||||||
using Robust.Client.Utility;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.Construction
|
|
||||||
{
|
|
||||||
public class ConstructionPlacementHijack : PlacementHijack
|
|
||||||
{
|
|
||||||
private readonly ConstructionPrototype Prototype;
|
|
||||||
private readonly ConstructorComponent Owner;
|
|
||||||
|
|
||||||
public ConstructionPlacementHijack(ConstructionPrototype prototype, ConstructorComponent owner)
|
|
||||||
{
|
|
||||||
Prototype = prototype;
|
|
||||||
Owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HijackPlacementRequest(GridCoordinates coords)
|
|
||||||
{
|
|
||||||
if (Prototype != null)
|
|
||||||
{
|
|
||||||
var dir = Manager.Direction;
|
|
||||||
Owner.SpawnGhost(Prototype, coords, dir);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HijackDeletion(IEntity entity)
|
|
||||||
{
|
|
||||||
if (entity.TryGetComponent(out ConstructionGhostComponent ghost))
|
|
||||||
{
|
|
||||||
Owner.ClearGhost(ghost.GhostID);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void StartHijack(PlacementManager manager)
|
|
||||||
{
|
|
||||||
base.StartHijack(manager);
|
|
||||||
|
|
||||||
var res = IoCManager.Resolve<IResourceCache>();
|
|
||||||
manager.CurrentBaseSprite = Prototype.Icon.DirFrame0();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +1,112 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Import Project="..\RobustToolbox\MSBuild\Robust.Properties.targets" />
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<LangVersion>7.3</LangVersion>
|
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
|
||||||
<IsPackable>false</IsPackable>
|
<ProjectGuid>{A2E5F175-78AF-4DDD-8F97-E2D2552372ED}</ProjectGuid>
|
||||||
<Platforms>x64;x86</Platforms>
|
<OutputType>Library</OutputType>
|
||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Content.Client</RootNamespace>
|
||||||
|
<AssemblyName>Content.Client</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ContentAssemblyTarget>..\engine\bin\Client\Resources\Assemblies\</ContentAssemblyTarget>
|
||||||
|
<!--
|
||||||
|
This copies all dependencies,
|
||||||
|
but on the plus side it's automatically located in the right place.
|
||||||
|
-->
|
||||||
<OutputPath>..\bin\Content.Client\</OutputPath>
|
<OutputPath>..\bin\Content.Client\</OutputPath>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(ActualOS)' == 'Windows'">MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>portable</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<DefineConstants>TRACE;RELEASE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>portable</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<DefineConstants>TRACE;RELEASE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DefineConstants>TRACE;RELEASE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>portable</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="..\RobustToolbox\MSBuild\Robust.DefineConstants.targets" />
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Nett" Version="0.11.0" />
|
<Reference Include="System" />
|
||||||
<PackageReference Include="SixLabors.Core" Version="1.0.0-beta0007" />
|
<Reference Include="System.Core" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0006" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<PackageReference Include="YamlDotNet" Version="6.0.0" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.1.0" />
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||||
|
<HintPath>$(SolutionDir)packages\OpenTK.3.0.0-pre\lib\net20\OpenTK.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="YamlDotNet, Version=4.3.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>$(SolutionDir)packages\YamlDotNet.4.3.1\lib\net45\YamlDotNet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\RobustToolbox\Lidgren.Network\Lidgren.Network.csproj" />
|
<Compile Include="EntryPoint.cs" />
|
||||||
<ProjectReference Include="..\RobustToolbox\Robust.Shared.Maths\Robust.Shared.Maths.csproj" />
|
<Compile Include="GameObjects\Components\Inventory\ClientInventoryComponent.cs" />
|
||||||
<ProjectReference Include="..\RobustToolbox\Robust.Shared\Robust.Shared.csproj" />
|
<Compile Include="GameObjects\Components\Storage\ClientStorageComponent.cs" />
|
||||||
<ProjectReference Include="..\RobustToolbox\Robust.Client\Robust.Client.csproj" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj" />
|
<Compile Include="GameObjects\Components\Items\ClientHandsComponent.cs" />
|
||||||
|
<Compile Include="Interfaces\GameObjects\Components\Items\IHandsComponent.cs" />
|
||||||
|
<Compile Include="UserInterface\HandsGui.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\PowerDebugTool.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj">
|
||||||
|
<Project>{26aeebb3-dde7-443a-9f43-7bc7f4acf6b5}</Project>
|
||||||
|
<Name>Content.Shared</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\engine\Lidgren.Network\Lidgren.Network.csproj">
|
||||||
|
<Project>{59250baf-0000-0000-0000-000000000000}</Project>
|
||||||
|
<Name>Lidgren.Network</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\engine\SS14.Client\SS14.Client.csproj">
|
||||||
|
<Project>{83429BD6-6358-4B18-BE51-401DF8EA2673}</Project>
|
||||||
|
<Name>SS14.Client</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\engine\SS14.Shared\SS14.Shared.csproj">
|
||||||
|
<Project>{0529f740-0000-0000-0000-000000000000}</Project>
|
||||||
|
<Name>SS14.Shared</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="..\SS14.Content.targets" />
|
||||||
|
<Target Name="AfterBuild" DependsOnTargets="CopyContentAssemblies" />
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- Files to be copied into Client/Assemblies -->
|
||||||
|
<ContentAssemblies Include="$(OutputPath)Content.Client.dll" />
|
||||||
|
<ContentAssemblies Include="$(OutputPath)Content.Shared.dll" />
|
||||||
|
<ContentAssemblies Include="$(OutputPath)Content.Client.pdb" Condition="'$(Configuration)' == 'Debug'" />
|
||||||
|
<ContentAssemblies Include="$(OutputPath)Content.Shared.pdb" Condition="'$(Configuration)' == 'Debug'" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="app.config" />
|
||||||
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,194 +1,50 @@
|
|||||||
using System;
|
using Content.Client.GameObjects;
|
||||||
using Content.Client.Chat;
|
using Content.Client.GameObjects.Components.Power;
|
||||||
using Content.Client.GameObjects.Components.Actor;
|
using Content.Client.GameObjects.Components.Storage;
|
||||||
using Content.Client.GameTicking;
|
using Content.Client.Interfaces.GameObjects;
|
||||||
using Content.Client.Input;
|
using SS14.Shared.ContentPack;
|
||||||
using Content.Client.Interfaces;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using Content.Client.Interfaces.Chat;
|
using SS14.Shared.IoC;
|
||||||
using Content.Client.Interfaces.Parallax;
|
|
||||||
using Content.Client.Parallax;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.GameObjects.Components.Chemistry;
|
|
||||||
using Content.Shared.GameObjects.Components.Markers;
|
|
||||||
using Content.Shared.GameObjects.Components.Research;
|
|
||||||
using Content.Shared.Interfaces;
|
|
||||||
using Robust.Client;
|
|
||||||
using Robust.Client.Interfaces;
|
|
||||||
using Robust.Client.Interfaces.Graphics.Overlays;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.Interfaces.UserInterface;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Shared.ContentPack;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client
|
namespace Content.Client
|
||||||
{
|
{
|
||||||
public class EntryPoint : GameClient
|
public class EntryPoint : GameClient
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
|
||||||
[Dependency] private readonly IEscapeMenuOwner _escapeMenuOwner;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
var factory = IoCManager.Resolve<IComponentFactory>();
|
var factory = IoCManager.Resolve<IComponentFactory>();
|
||||||
var prototypes = IoCManager.Resolve<IPrototypeManager>();
|
|
||||||
|
|
||||||
factory.DoAutoRegistrations();
|
factory.RegisterIgnore("Item");
|
||||||
|
factory.RegisterIgnore("Interactable");
|
||||||
|
factory.RegisterIgnore("Damageable");
|
||||||
|
factory.RegisterIgnore("Destructible");
|
||||||
|
factory.RegisterIgnore("Temperature");
|
||||||
|
factory.RegisterIgnore("PowerTransfer");
|
||||||
|
factory.RegisterIgnore("PowerNode");
|
||||||
|
factory.RegisterIgnore("PowerProvider");
|
||||||
|
factory.RegisterIgnore("PowerDevice");
|
||||||
|
factory.RegisterIgnore("PowerStorage");
|
||||||
|
factory.RegisterIgnore("PowerGenerator");
|
||||||
|
|
||||||
var registerIgnore = new[]
|
factory.RegisterIgnore("Wirecutter");
|
||||||
{
|
factory.RegisterIgnore("Screwdriver");
|
||||||
"Interactable",
|
factory.RegisterIgnore("Multitool");
|
||||||
"Destructible",
|
factory.RegisterIgnore("Welder");
|
||||||
"Temperature",
|
factory.RegisterIgnore("Wrench");
|
||||||
"PowerTransfer",
|
factory.RegisterIgnore("Crowbar");
|
||||||
"PowerNode",
|
factory.RegisterIgnore("HitscanWeapon");
|
||||||
"PowerProvider",
|
factory.RegisterIgnore("ProjectileWeapon");
|
||||||
"PowerDevice",
|
factory.RegisterIgnore("Projectile");
|
||||||
"PowerStorage",
|
factory.RegisterIgnore("MeleeWeapon");
|
||||||
"PowerGenerator",
|
|
||||||
"Explosive",
|
|
||||||
"OnUseTimerTrigger",
|
|
||||||
"ToolboxElectricalFill",
|
|
||||||
"ToolLockerFill",
|
|
||||||
"EmitSoundOnUse",
|
|
||||||
"FootstepModifier",
|
|
||||||
"HeatResistance",
|
|
||||||
"CombatMode",
|
|
||||||
"Teleportable",
|
|
||||||
"ItemTeleporter",
|
|
||||||
"Portal",
|
|
||||||
"EntityStorage",
|
|
||||||
"PlaceableSurface",
|
|
||||||
"Wirecutter",
|
|
||||||
"Screwdriver",
|
|
||||||
"Multitool",
|
|
||||||
"Welder",
|
|
||||||
"Wrench",
|
|
||||||
"Crowbar",
|
|
||||||
"HitscanWeapon",
|
|
||||||
"ProjectileWeapon",
|
|
||||||
"Projectile",
|
|
||||||
"MeleeWeapon",
|
|
||||||
"Storeable",
|
|
||||||
"Stack",
|
|
||||||
"Dice",
|
|
||||||
"Construction",
|
|
||||||
"Apc",
|
|
||||||
"Door",
|
|
||||||
"PoweredLight",
|
|
||||||
"Smes",
|
|
||||||
"Powercell",
|
|
||||||
"HandheldLight",
|
|
||||||
"LightBulb",
|
|
||||||
"Healing",
|
|
||||||
"Catwalk",
|
|
||||||
"BallisticMagazine",
|
|
||||||
"BallisticMagazineWeapon",
|
|
||||||
"BallisticBullet",
|
|
||||||
"HitscanWeaponCapacitor",
|
|
||||||
"PowerCell",
|
|
||||||
"AiController",
|
|
||||||
"PlayerInputMover",
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var ignoreName in registerIgnore)
|
factory.RegisterIgnore("Storeable");
|
||||||
{
|
factory.RegisterIgnore("Clothing");
|
||||||
factory.RegisterIgnore(ignoreName);
|
|
||||||
}
|
|
||||||
|
|
||||||
factory.Register<SharedLatheComponent>();
|
factory.Register<HandsComponent>();
|
||||||
factory.Register<SharedSpawnPointComponent>();
|
factory.RegisterReference<HandsComponent, IHandsComponent>();
|
||||||
factory.Register<SolutionComponent>();
|
factory.Register<ClientStorageComponent>();
|
||||||
|
factory.Register<ClientInventoryComponent>();
|
||||||
prototypes.RegisterIgnore("material");
|
factory.Register<PowerDebugTool>();
|
||||||
|
|
||||||
IoCManager.Register<IGameHud, GameHud>();
|
|
||||||
IoCManager.Register<IClientNotifyManager, ClientNotifyManager>();
|
|
||||||
IoCManager.Register<ISharedNotifyManager, ClientNotifyManager>();
|
|
||||||
IoCManager.Register<IClientGameTicker, ClientGameTicker>();
|
|
||||||
IoCManager.Register<IParallaxManager, ParallaxManager>();
|
|
||||||
IoCManager.Register<IChatManager, ChatManager>();
|
|
||||||
IoCManager.Register<IEscapeMenuOwner, EscapeMenuOwner>();
|
|
||||||
if (TestingCallbacks != null)
|
|
||||||
{
|
|
||||||
var cast = (ClientModuleTestingCallbacks) TestingCallbacks;
|
|
||||||
cast.ClientBeforeIoC?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
IoCManager.BuildGraph();
|
|
||||||
|
|
||||||
IoCManager.Resolve<IParallaxManager>().LoadParallax();
|
|
||||||
IoCManager.Resolve<IBaseClient>().PlayerJoinedServer += SubscribePlayerAttachmentEvents;
|
|
||||||
|
|
||||||
var stylesheet = new NanoStyle();
|
|
||||||
|
|
||||||
IoCManager.Resolve<IUserInterfaceManager>().Stylesheet = stylesheet.Stylesheet;
|
|
||||||
IoCManager.Resolve<IUserInterfaceManager>().Stylesheet = stylesheet.Stylesheet;
|
|
||||||
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
_escapeMenuOwner.Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Subscribe events to the player manager after the player manager is set up
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="args"></param>
|
|
||||||
public void SubscribePlayerAttachmentEvents(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
_playerManager.LocalPlayer.EntityAttached += AttachPlayerToEntity;
|
|
||||||
_playerManager.LocalPlayer.EntityDetached += DetachPlayerFromEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add the character interface master which combines all character interfaces into one window
|
|
||||||
/// </summary>
|
|
||||||
public static void AttachPlayerToEntity(EntityAttachedEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
eventArgs.NewEntity.AddComponent<CharacterInterface>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Remove the character interface master from this entity now that we have detached ourselves from it
|
|
||||||
/// </summary>
|
|
||||||
public static void DetachPlayerFromEntity(EntityDetachedEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
eventArgs.OldEntity.RemoveComponent<CharacterInterface>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostInit()
|
|
||||||
{
|
|
||||||
base.PostInit();
|
|
||||||
|
|
||||||
// Setup key contexts
|
|
||||||
var inputMan = IoCManager.Resolve<IInputManager>();
|
|
||||||
ContentContexts.SetupContexts(inputMan.Contexts);
|
|
||||||
|
|
||||||
IoCManager.Resolve<IGameHud>().Initialize();
|
|
||||||
IoCManager.Resolve<IClientNotifyManager>().Initialize();
|
|
||||||
IoCManager.Resolve<IClientGameTicker>().Initialize();
|
|
||||||
IoCManager.Resolve<IOverlayManager>().AddOverlay(new ParallaxOverlay());
|
|
||||||
IoCManager.Resolve<IChatManager>().Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(ModUpdateLevel level, float frameTime)
|
|
||||||
{
|
|
||||||
base.Update(level, frameTime);
|
|
||||||
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case ModUpdateLevel.FramePreEngine:
|
|
||||||
var renderFrameEventArgs = new RenderFrameEventArgs(frameTime);
|
|
||||||
IoCManager.Resolve<IClientNotifyManager>().FrameUpdate(renderFrameEventArgs);
|
|
||||||
IoCManager.Resolve<IClientGameTicker>().FrameUpdate(renderFrameEventArgs);
|
|
||||||
IoCManager.Resolve<IChatManager>().FrameUpdate(renderFrameEventArgs);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
using Content.Client.UserInterface;
|
|
||||||
using Robust.Client.Console;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.Interfaces.Placement;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.Interfaces.State;
|
|
||||||
using Robust.Client.State.States;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.Interfaces.Configuration;
|
|
||||||
using Robust.Shared.Interfaces.Map;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Players;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client
|
|
||||||
{
|
|
||||||
internal sealed class EscapeMenuOwner : IEscapeMenuOwner
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IClientConsole _clientConsole;
|
|
||||||
[Dependency] private readonly IConfigurationManager _configurationManager;
|
|
||||||
[Dependency] private readonly IInputManager _inputManager;
|
|
||||||
[Dependency] private readonly IPlacementManager _placementManager;
|
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
|
||||||
[Dependency] private readonly IStateManager _stateManager;
|
|
||||||
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager;
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private EscapeMenu _escapeMenu;
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
_stateManager.OnStateChanged += StateManagerOnOnStateChanged;
|
|
||||||
|
|
||||||
_gameHud.EscapeButtonToggled += _setOpenValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StateManagerOnOnStateChanged(StateChangedEventArgs obj)
|
|
||||||
{
|
|
||||||
if (obj.NewState is GameScreen)
|
|
||||||
{
|
|
||||||
// Switched TO GameScreen.
|
|
||||||
_escapeMenu = new EscapeMenu(_clientConsole, _tileDefinitionManager, _placementManager,
|
|
||||||
_prototypeManager, _resourceCache, _configurationManager, _localizationManager);
|
|
||||||
|
|
||||||
_escapeMenu.OnClose += () => _gameHud.EscapeButtonDown = false;
|
|
||||||
|
|
||||||
var escapeMenuCommand = InputCmdHandler.FromDelegate(Enabled);
|
|
||||||
|
|
||||||
_inputManager.SetInputCommand(EngineKeyFunctions.EscapeMenu, escapeMenuCommand);
|
|
||||||
}
|
|
||||||
else if (obj.OldState is GameScreen)
|
|
||||||
{
|
|
||||||
// Switched FROM GameScreen.
|
|
||||||
_escapeMenu.Dispose();
|
|
||||||
_escapeMenu = null;
|
|
||||||
|
|
||||||
_inputManager.SetInputCommand(EngineKeyFunctions.EscapeMenu, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Enabled(ICommonSession session)
|
|
||||||
{
|
|
||||||
if (_escapeMenu.IsOpen)
|
|
||||||
{
|
|
||||||
if (_escapeMenu.IsAtFront())
|
|
||||||
{
|
|
||||||
_setOpenValue(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_escapeMenu.MoveToFront();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_setOpenValue(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _setOpenValue(bool value)
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
_gameHud.EscapeButtonDown = true;
|
|
||||||
_escapeMenu.OpenCentered();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gameHud.EscapeButtonDown = false;
|
|
||||||
_escapeMenu.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IEscapeMenuOwner
|
|
||||||
{
|
|
||||||
void Initialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
using Content.Client.GameObjects.Components.Mobs;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Actor
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed class CharacterInfoComponent : Component, ICharacterUI
|
|
||||||
{
|
|
||||||
private CharacterInfoControl _control;
|
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly ILocalizationManager _loc;
|
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override string Name => "CharacterInfo";
|
|
||||||
|
|
||||||
public Control Scene { get; private set; }
|
|
||||||
public UIPriority Priority => UIPriority.Info;
|
|
||||||
|
|
||||||
public override void OnAdd()
|
|
||||||
{
|
|
||||||
base.OnAdd();
|
|
||||||
|
|
||||||
Scene = _control = new CharacterInfoControl(_resourceCache, _loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
if (Owner.TryGetComponent(out ISpriteComponent spriteComponent))
|
|
||||||
{
|
|
||||||
_control.SpriteView.Sprite = spriteComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
_control.NameLabel.Text = Owner.Name;
|
|
||||||
// ReSharper disable once StringLiteralTypo
|
|
||||||
_control.SubText.Text = _loc.GetString("Professional Greyshirt");
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class CharacterInfoControl : VBoxContainer
|
|
||||||
{
|
|
||||||
public SpriteView SpriteView { get; }
|
|
||||||
public Label NameLabel { get; }
|
|
||||||
public Label SubText { get; }
|
|
||||||
|
|
||||||
public CharacterInfoControl(IResourceCache resourceCache, ILocalizationManager loc)
|
|
||||||
{
|
|
||||||
AddChild(new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
(SpriteView = new SpriteView { Scale = (2, 2)}),
|
|
||||||
new VBoxContainer
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.None,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
(NameLabel = new Label()),
|
|
||||||
(SubText = new Label
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.None,
|
|
||||||
StyleClasses = {NanoStyle.StyleClassLabelSubText}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AddChild(new Placeholder(resourceCache)
|
|
||||||
{
|
|
||||||
PlaceholderText = loc.GetString("Health & status effects")
|
|
||||||
});
|
|
||||||
|
|
||||||
AddChild(new Placeholder(resourceCache)
|
|
||||||
{
|
|
||||||
PlaceholderText = loc.GetString("Objectives")
|
|
||||||
});
|
|
||||||
|
|
||||||
AddChild(new Placeholder(resourceCache)
|
|
||||||
{
|
|
||||||
PlaceholderText = loc.GetString("Antagonist Roles")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Client.GameObjects.Components.Mobs;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Actor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A semi-abstract component which gets added to entities upon attachment and collects all character
|
|
||||||
/// user interfaces into a single window and keybind for the user
|
|
||||||
/// </summary>
|
|
||||||
[RegisterComponent]
|
|
||||||
public class CharacterInterface : Component
|
|
||||||
{
|
|
||||||
public override string Name => "Character Interface Component";
|
|
||||||
|
|
||||||
[Dependency]
|
|
||||||
#pragma warning disable 649
|
|
||||||
private readonly IGameHud _gameHud;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Window to hold each of the character interfaces
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Null if it would otherwise be empty.
|
|
||||||
/// </remarks>
|
|
||||||
public SS14Window Window { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create the window with all character UIs and bind it to a keypress
|
|
||||||
/// </summary>
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
//Use all the character ui interfaced components to create the character window
|
|
||||||
var uiComponents = Owner.GetAllComponents<ICharacterUI>().ToList();
|
|
||||||
if (uiComponents.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Window = new CharacterWindow(uiComponents);
|
|
||||||
Window.OnClose += () => _gameHud.CharacterButtonDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dispose of window and the keypress binding
|
|
||||||
/// </summary>
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
base.OnRemove();
|
|
||||||
|
|
||||||
Window?.Dispose();
|
|
||||||
Window = null;
|
|
||||||
|
|
||||||
var inputMgr = IoCManager.Resolve<IInputManager>();
|
|
||||||
inputMgr.SetInputCommand(ContentKeyFunctions.OpenCharacterMenu, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
|
|
||||||
IComponent component = null)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, netChannel, component);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case PlayerAttachedMsg _:
|
|
||||||
if (Window != null)
|
|
||||||
{
|
|
||||||
_gameHud.CharacterButtonVisible = true;
|
|
||||||
_gameHud.CharacterButtonToggled = b =>
|
|
||||||
{
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
Window.Open();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Window.Close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PlayerDetachedMsg _:
|
|
||||||
if (Window != null)
|
|
||||||
{
|
|
||||||
_gameHud.CharacterButtonVisible = false;
|
|
||||||
Window.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A window that collects and shows all the individual character user interfaces
|
|
||||||
/// </summary>
|
|
||||||
public class CharacterWindow : SS14Window
|
|
||||||
{
|
|
||||||
private readonly VBoxContainer _contentsVBox;
|
|
||||||
|
|
||||||
public CharacterWindow(List<ICharacterUI> windowComponents)
|
|
||||||
{
|
|
||||||
Title = "Character";
|
|
||||||
|
|
||||||
_contentsVBox = new VBoxContainer();
|
|
||||||
Contents.AddChild(_contentsVBox);
|
|
||||||
|
|
||||||
windowComponents.Sort((a, b) => ((int) a.Priority).CompareTo((int) b.Priority));
|
|
||||||
foreach (var element in windowComponents)
|
|
||||||
{
|
|
||||||
_contentsVBox.AddChild(element.Scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
Size = CombinedMinimumSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines ordering of the character user interface, small values come sooner
|
|
||||||
/// </summary>
|
|
||||||
public enum UIPriority
|
|
||||||
{
|
|
||||||
First = 0,
|
|
||||||
Info = 5,
|
|
||||||
Species = 100,
|
|
||||||
Last = 99999
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.GameObjects;
|
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
|
||||||
using Content.Shared.GameObjects.Components.Items;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Clothing
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
[ComponentReference(typeof(ItemComponent))]
|
|
||||||
public class ClothingComponent : ItemComponent
|
|
||||||
{
|
|
||||||
public override string Name => "Clothing";
|
|
||||||
public override uint? NetID => ContentNetIDs.CLOTHING;
|
|
||||||
public override Type StateType => typeof(ClothingComponentState);
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public string ClothingEquippedPrefix { get; set; }
|
|
||||||
|
|
||||||
public (RSI rsi, RSI.StateId stateId)? GetEquippedStateInfo(EquipmentSlotDefines.SlotFlags slot)
|
|
||||||
{
|
|
||||||
if (RsiPath == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var rsi = GetRSI();
|
|
||||||
var prefix = ClothingEquippedPrefix ?? EquippedPrefix;
|
|
||||||
var stateId = prefix != null ? $"{prefix}-equipped-{slot}" : $"equipped-{slot}";
|
|
||||||
if (rsi.TryGetState(stateId, out _))
|
|
||||||
{
|
|
||||||
return (rsi, stateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
||||||
{
|
|
||||||
if (curState == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var clothingComponentState = (ClothingComponentState)curState;
|
|
||||||
ClothingEquippedPrefix = clothingComponentState.ClothingEquippedPrefix;
|
|
||||||
EquippedPrefix = clothingComponentState.EquippedPrefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using Content.Shared.Construction;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Construction
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public class ConstructionGhostComponent : Component
|
|
||||||
{
|
|
||||||
public override string Name => "ConstructionGhost";
|
|
||||||
|
|
||||||
[ViewVariables] public ConstructionPrototype Prototype { get; set; }
|
|
||||||
[ViewVariables] public ConstructorComponent Master { get; set; }
|
|
||||||
[ViewVariables] public int GhostID { get; set; }
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
|
|
||||||
IComponent component = null)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, netChannel, component);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case ClientEntityClickMsg clickMsg:
|
|
||||||
Master.TryStartConstruction(GhostID);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.Construction;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.Construction;
|
|
||||||
using Content.Shared.GameObjects.Components.Construction;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Construction
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public class ConstructorComponent : SharedConstructorComponent
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private int nextId;
|
|
||||||
private readonly Dictionary<int, ConstructionGhostComponent> Ghosts = new Dictionary<int, ConstructionGhostComponent>();
|
|
||||||
public ConstructionMenu ConstructionMenu { get; private set; }
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
Owner.GetComponent<ITransformComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, netChannel, component);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case PlayerAttachedMsg _:
|
|
||||||
if (ConstructionMenu == null)
|
|
||||||
{
|
|
||||||
ConstructionMenu = new ConstructionMenu {Owner = this};
|
|
||||||
ConstructionMenu.OnClose += () => _gameHud.CraftingButtonDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gameHud.CraftingButtonVisible = true;
|
|
||||||
_gameHud.CraftingButtonToggled = b =>
|
|
||||||
{
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
ConstructionMenu.Open();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConstructionMenu.Close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PlayerDetachedMsg _:
|
|
||||||
_gameHud.CraftingButtonVisible = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AckStructureConstructionMessage ackMsg:
|
|
||||||
ClearGhost(ackMsg.Ack);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
ConstructionMenu?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SpawnGhost(ConstructionPrototype prototype, GridCoordinates loc, Direction dir)
|
|
||||||
{
|
|
||||||
var entMgr = IoCManager.Resolve<IClientEntityManager>();
|
|
||||||
var ghost = entMgr.SpawnEntityAt("constructionghost", loc);
|
|
||||||
var comp = ghost.GetComponent<ConstructionGhostComponent>();
|
|
||||||
comp.Prototype = prototype;
|
|
||||||
comp.Master = this;
|
|
||||||
comp.GhostID = nextId++;
|
|
||||||
ghost.GetComponent<ITransformComponent>().LocalRotation = dir.ToAngle();
|
|
||||||
var sprite = ghost.GetComponent<SpriteComponent>();
|
|
||||||
sprite.LayerSetSprite(0, prototype.Icon);
|
|
||||||
sprite.LayerSetVisible(0, true);
|
|
||||||
|
|
||||||
Ghosts.Add(comp.GhostID, comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TryStartConstruction(int ghostId)
|
|
||||||
{
|
|
||||||
var ghost = Ghosts[ghostId];
|
|
||||||
var transform = ghost.Owner.GetComponent<ITransformComponent>();
|
|
||||||
var msg = new TryStartStructureConstructionMessage(transform.GridPosition, ghost.Prototype.ID, transform.LocalRotation, ghostId);
|
|
||||||
SendNetworkMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearGhost(int ghostId)
|
|
||||||
{
|
|
||||||
if (Ghosts.TryGetValue(ghostId, out var ghost))
|
|
||||||
{
|
|
||||||
ghost.Owner.Delete();
|
|
||||||
Ghosts.Remove(ghostId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Fuck I really hate doing this
|
|
||||||
/// TODO: make sure the client only gets damageable component on the clientside entity for its player mob
|
|
||||||
/// </summary>
|
|
||||||
[RegisterComponent]
|
|
||||||
public class DamageableComponent : SharedDamageableComponent
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override string Name => "Damageable";
|
|
||||||
|
|
||||||
public Dictionary<DamageType, int> CurrentDamage = new Dictionary<DamageType, int>();
|
|
||||||
|
|
||||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
||||||
{
|
|
||||||
base.HandleComponentState(curState, nextState);
|
|
||||||
|
|
||||||
if(curState is DamageComponentState)
|
|
||||||
{
|
|
||||||
var damagestate = (DamageComponentState)curState;
|
|
||||||
CurrentDamage = damagestate.CurrentDamage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.GameObjects.Components.Doors;
|
|
||||||
using Robust.Client.Animations;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.GameObjects.Components.Animations;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Doors
|
|
||||||
{
|
|
||||||
public class AirlockVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
private const string AnimationKey = "airlock_animation";
|
|
||||||
|
|
||||||
private Animation CloseAnimation;
|
|
||||||
private Animation OpenAnimation;
|
|
||||||
|
|
||||||
public override void LoadData(YamlMappingNode node)
|
|
||||||
{
|
|
||||||
base.LoadData(node);
|
|
||||||
|
|
||||||
var openSound = node.GetNode("open_sound").AsString();
|
|
||||||
var closeSound = node.GetNode("close_sound").AsString();
|
|
||||||
|
|
||||||
CloseAnimation = new Animation {Length = TimeSpan.FromSeconds(1.2f)};
|
|
||||||
{
|
|
||||||
var flick = new AnimationTrackSpriteFlick();
|
|
||||||
CloseAnimation.AnimationTracks.Add(flick);
|
|
||||||
flick.LayerKey = DoorVisualLayers.Base;
|
|
||||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("closing", 0f));
|
|
||||||
|
|
||||||
var flickUnlit = new AnimationTrackSpriteFlick();
|
|
||||||
CloseAnimation.AnimationTracks.Add(flickUnlit);
|
|
||||||
flickUnlit.LayerKey = DoorVisualLayers.BaseUnlit;
|
|
||||||
flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("closing_unlit", 0f));
|
|
||||||
|
|
||||||
var sound = new AnimationTrackPlaySound();
|
|
||||||
CloseAnimation.AnimationTracks.Add(sound);
|
|
||||||
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(closeSound, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(1.2f)};
|
|
||||||
{
|
|
||||||
var flick = new AnimationTrackSpriteFlick();
|
|
||||||
OpenAnimation.AnimationTracks.Add(flick);
|
|
||||||
flick.LayerKey = DoorVisualLayers.Base;
|
|
||||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("opening", 0f));
|
|
||||||
|
|
||||||
var flickUnlit = new AnimationTrackSpriteFlick();
|
|
||||||
OpenAnimation.AnimationTracks.Add(flickUnlit);
|
|
||||||
flickUnlit.LayerKey = DoorVisualLayers.BaseUnlit;
|
|
||||||
flickUnlit.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("opening_unlit", 0f));
|
|
||||||
|
|
||||||
var sound = new AnimationTrackPlaySound();
|
|
||||||
OpenAnimation.AnimationTracks.Add(sound);
|
|
||||||
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(openSound, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void InitializeEntity(IEntity entity)
|
|
||||||
{
|
|
||||||
if (!entity.HasComponent<AnimationPlayerComponent>())
|
|
||||||
{
|
|
||||||
entity.AddComponent<AnimationPlayerComponent>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
var animPlayer = component.Owner.GetComponent<AnimationPlayerComponent>();
|
|
||||||
if (!component.TryGetData(DoorVisuals.VisualState, out DoorVisualState state))
|
|
||||||
{
|
|
||||||
state = DoorVisualState.Closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case DoorVisualState.Closed:
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.Base, "closed");
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.BaseUnlit, "closed_unlit");
|
|
||||||
sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, true);
|
|
||||||
break;
|
|
||||||
case DoorVisualState.Closing:
|
|
||||||
sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, true);
|
|
||||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
|
||||||
{
|
|
||||||
animPlayer.Play(CloseAnimation, AnimationKey);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DoorVisualState.Opening:
|
|
||||||
sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, true);
|
|
||||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
|
||||||
{
|
|
||||||
animPlayer.Play(OpenAnimation, AnimationKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case DoorVisualState.Open:
|
|
||||||
sprite.LayerSetState(DoorVisualLayers.Base, "open");
|
|
||||||
sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, false);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum DoorVisualLayers
|
|
||||||
{
|
|
||||||
Base,
|
|
||||||
BaseUnlit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Client.GameObjects.Components.Clothing;
|
|
||||||
using Content.Shared.GameObjects;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
|
||||||
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A character UI which shows items the user has equipped within his inventory
|
|
||||||
/// </summary>
|
|
||||||
[RegisterComponent]
|
|
||||||
public class ClientInventoryComponent : SharedInventoryComponent
|
|
||||||
{
|
|
||||||
private readonly Dictionary<Slots, IEntity> _slots = new Dictionary<Slots, IEntity>();
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public InventoryInterfaceController InterfaceController { get; private set; }
|
|
||||||
|
|
||||||
private ISpriteComponent _sprite;
|
|
||||||
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
base.OnRemove();
|
|
||||||
|
|
||||||
InterfaceController?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
var controllerType = ReflectionManager.LooseGetType(InventoryInstance.InterfaceControllerTypeName);
|
|
||||||
var args = new object[] {this};
|
|
||||||
InterfaceController = DynamicTypeFactory.CreateInstance<InventoryInterfaceController>(controllerType, args);
|
|
||||||
InterfaceController.Initialize();
|
|
||||||
|
|
||||||
if (Owner.TryGetComponent(out _sprite))
|
|
||||||
{
|
|
||||||
foreach (var mask in InventoryInstance.SlotMasks.OrderBy(s => InventoryInstance.SlotDrawingOrder(s)))
|
|
||||||
{
|
|
||||||
if (mask == Slots.NONE)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_sprite.LayerMapReserveBlank(mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Component state already came in but we couldn't set anything visually because, well, we didn't initialize yet.
|
|
||||||
foreach (var (slot, entity) in _slots)
|
|
||||||
{
|
|
||||||
_setSlot(slot, entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
||||||
{
|
|
||||||
base.HandleComponentState(curState, nextState);
|
|
||||||
|
|
||||||
if (curState == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var cast = (InventoryComponentState) curState;
|
|
||||||
|
|
||||||
var doneSlots = new HashSet<Slots>();
|
|
||||||
|
|
||||||
foreach (var (slot, entityUid) in cast.Entities)
|
|
||||||
{
|
|
||||||
if (_slots.ContainsKey(slot))
|
|
||||||
{
|
|
||||||
_slots.Remove(slot);
|
|
||||||
_clearSlot(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
var entity = Owner.EntityManager.GetEntity(entityUid);
|
|
||||||
_slots[slot] = entity;
|
|
||||||
_setSlot(slot, entity);
|
|
||||||
doneSlots.Add(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var slot in _slots.Keys.ToList())
|
|
||||||
{
|
|
||||||
if (!doneSlots.Contains(slot))
|
|
||||||
{
|
|
||||||
_clearSlot(slot);
|
|
||||||
_slots.Remove(slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _setSlot(Slots slot, IEntity entity)
|
|
||||||
{
|
|
||||||
if (_sprite != null && entity.TryGetComponent(out ClothingComponent clothing))
|
|
||||||
{
|
|
||||||
var flag = SlotMasks[slot];
|
|
||||||
var data = clothing.GetEquippedStateInfo(flag);
|
|
||||||
if (data == null)
|
|
||||||
{
|
|
||||||
_sprite.LayerSetVisible(slot, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var (rsi, state) = data.Value;
|
|
||||||
_sprite.LayerSetVisible(slot, true);
|
|
||||||
_sprite.LayerSetRSI(slot, rsi);
|
|
||||||
_sprite.LayerSetState(slot, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceController?.AddToSlot(slot, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _clearSlot(Slots slot)
|
|
||||||
{
|
|
||||||
InterfaceController?.RemoveFromSlot(slot);
|
|
||||||
_sprite?.LayerSetVisible(slot, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendUnequipMessage(Slots slot)
|
|
||||||
{
|
|
||||||
var unequipmessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Unequip);
|
|
||||||
SendNetworkMessage(unequipmessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendEquipMessage(Slots slot)
|
|
||||||
{
|
|
||||||
var equipmessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Equip);
|
|
||||||
SendNetworkMessage(equipmessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
|
|
||||||
IComponent component = null)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, netChannel, component);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case PlayerAttachedMsg _:
|
|
||||||
InterfaceController.PlayerAttached();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PlayerDetachedMsg _:
|
|
||||||
InterfaceController.PlayerDetached();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.Utility;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
|
||||||
{
|
|
||||||
// Dynamically instantiated by ClientInventoryComponent.
|
|
||||||
[UsedImplicitly]
|
|
||||||
public class HumanInventoryInterfaceController : InventoryInterfaceController
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly ILocalizationManager _loc;
|
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private readonly Dictionary<Slots, List<InventoryButton>> _inventoryButtons
|
|
||||||
= new Dictionary<Slots, List<InventoryButton>>();
|
|
||||||
|
|
||||||
private InventoryButton _hudButtonPocket1;
|
|
||||||
private InventoryButton _hudButtonPocket2;
|
|
||||||
private InventoryButton _hudButtonBelt;
|
|
||||||
private InventoryButton _hudButtonBack;
|
|
||||||
private Control _quickButtonsContainer;
|
|
||||||
|
|
||||||
public HumanInventoryInterfaceController(ClientInventoryComponent owner) : base(owner)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
_window = new HumanInventoryWindow(_loc, _resourceCache);
|
|
||||||
|
|
||||||
foreach (var (slot, button) in _window.Buttons)
|
|
||||||
{
|
|
||||||
button.OnPressed = AddToInventory;
|
|
||||||
_inventoryButtons.Add(slot, new List<InventoryButton> {button});
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddButton(out InventoryButton variable, Slots slot, string textureName)
|
|
||||||
{
|
|
||||||
var texture = _resourceCache.GetTexture($"/Textures/UserInterface/Inventory/{textureName}.png");
|
|
||||||
variable = new InventoryButton(slot, texture)
|
|
||||||
{
|
|
||||||
OnPressed = AddToInventory
|
|
||||||
};
|
|
||||||
_inventoryButtons[slot].Add(variable);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddButton(out _hudButtonPocket1, Slots.POCKET1, "pocket");
|
|
||||||
AddButton(out _hudButtonPocket2, Slots.POCKET2, "pocket");
|
|
||||||
AddButton(out _hudButtonBack, Slots.BACKPACK, "back");
|
|
||||||
AddButton(out _hudButtonBelt, Slots.BELT, "belt");
|
|
||||||
|
|
||||||
_quickButtonsContainer = new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
_hudButtonBelt,
|
|
||||||
_hudButtonBack,
|
|
||||||
_hudButtonPocket1,
|
|
||||||
_hudButtonPocket2,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override SS14Window Window => _window;
|
|
||||||
private HumanInventoryWindow _window;
|
|
||||||
|
|
||||||
public override void AddToSlot(Slots slot, IEntity entity)
|
|
||||||
{
|
|
||||||
base.AddToSlot(slot, entity);
|
|
||||||
|
|
||||||
if (!_inventoryButtons.TryGetValue(slot, out var buttons))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.TryGetComponent(out ISpriteComponent sprite);
|
|
||||||
|
|
||||||
foreach (var button in buttons)
|
|
||||||
{
|
|
||||||
button.SpriteView.Sprite = sprite;
|
|
||||||
button.OnPressed = RemoveFromInventory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RemoveFromSlot(Slots slot)
|
|
||||||
{
|
|
||||||
base.RemoveFromSlot(slot);
|
|
||||||
|
|
||||||
if (!_inventoryButtons.TryGetValue(slot, out var buttons))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var button in buttons)
|
|
||||||
{
|
|
||||||
button.SpriteView.Sprite = null;
|
|
||||||
button.OnPressed = AddToInventory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PlayerAttached()
|
|
||||||
{
|
|
||||||
base.PlayerAttached();
|
|
||||||
|
|
||||||
GameHud.InventoryQuickButtonContainer.AddChild(_quickButtonsContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PlayerDetached()
|
|
||||||
{
|
|
||||||
base.PlayerDetached();
|
|
||||||
|
|
||||||
GameHud.InventoryQuickButtonContainer.RemoveChild(_quickButtonsContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class HumanInventoryWindow : SS14Window
|
|
||||||
{
|
|
||||||
private const int ButtonSize = 64;
|
|
||||||
private const int ButtonSeparation = 2;
|
|
||||||
private const int RightSeparation = 2;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<Slots, InventoryButton> Buttons { get; }
|
|
||||||
|
|
||||||
public HumanInventoryWindow(ILocalizationManager loc, IResourceCache resourceCache)
|
|
||||||
{
|
|
||||||
Title = loc.GetString("Your Inventory");
|
|
||||||
Resizable = false;
|
|
||||||
|
|
||||||
var buttonDict = new Dictionary<Slots, InventoryButton>();
|
|
||||||
Buttons = buttonDict;
|
|
||||||
|
|
||||||
const int width = ButtonSize * 4 + ButtonSeparation * 3 + RightSeparation;
|
|
||||||
const int height = ButtonSize * 4 + ButtonSeparation * 3;
|
|
||||||
|
|
||||||
var windowContents = new Control {CustomMinimumSize = (width, height)};
|
|
||||||
Contents.AddChild(windowContents);
|
|
||||||
|
|
||||||
void AddButton(Slots slot, string textureName, Vector2 position)
|
|
||||||
{
|
|
||||||
var texture = resourceCache.GetTexture($"/Textures/UserInterface/Inventory/{textureName}.png");
|
|
||||||
var button = new InventoryButton(slot, texture)
|
|
||||||
{
|
|
||||||
Position = position
|
|
||||||
};
|
|
||||||
|
|
||||||
windowContents.AddChild(button);
|
|
||||||
buttonDict.Add(slot, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int size = ButtonSize;
|
|
||||||
const int sep = ButtonSeparation;
|
|
||||||
const int rSep = RightSeparation;
|
|
||||||
|
|
||||||
// Left column.
|
|
||||||
AddButton(Slots.EYES, "glasses", (0, size + sep));
|
|
||||||
AddButton(Slots.INNERCLOTHING, "uniform", (0, 2 * (size + sep)));
|
|
||||||
AddButton(Slots.EXOSUITSLOT1, "suit_storage", (0, 3 * (size + sep)));
|
|
||||||
|
|
||||||
// Middle column.
|
|
||||||
AddButton(Slots.HEAD, "head", (size + sep, 0));
|
|
||||||
AddButton(Slots.MASK, "mask", (size + sep, size + sep));
|
|
||||||
AddButton(Slots.OUTERCLOTHING, "suit", (size + sep, 2 * (size + sep)));
|
|
||||||
AddButton(Slots.SHOES, "shoes", (size + sep, 3 * (size + sep)));
|
|
||||||
|
|
||||||
// Right column
|
|
||||||
AddButton(Slots.EARS, "ears", (2 * (size + sep), 0));
|
|
||||||
AddButton(Slots.IDCARD, "mask", (2 * (size + sep), size + sep));
|
|
||||||
AddButton(Slots.GLOVES, "gloves", (2 * (size + sep), 2 * (size + sep)));
|
|
||||||
|
|
||||||
// Far right column.
|
|
||||||
AddButton(Slots.BACKPACK, "back", (rSep + 3 * (size + sep), 0));
|
|
||||||
AddButton(Slots.BELT, "belt", (rSep + 3 * (size + sep), size + sep));
|
|
||||||
AddButton(Slots.POCKET1, "pocket", (rSep + 3 * (size + sep), 2 * (size + sep)));
|
|
||||||
AddButton(Slots.POCKET2, "pocket", (rSep + 3 * (size + sep), 3 * (size + sep)));
|
|
||||||
|
|
||||||
Size = CombinedMinimumSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
|
||||||
{
|
|
||||||
public sealed class InventoryButton : MarginContainer
|
|
||||||
{
|
|
||||||
public EquipmentSlotDefines.Slots Slot { get; }
|
|
||||||
public EntityUid EntityUid { get; set; }
|
|
||||||
|
|
||||||
public BaseButton Button { get; }
|
|
||||||
public SpriteView SpriteView { get; }
|
|
||||||
|
|
||||||
public Action<BaseButton.ButtonEventArgs> OnPressed { get; set; }
|
|
||||||
|
|
||||||
public InventoryButton(EquipmentSlotDefines.Slots slot, Texture texture)
|
|
||||||
{
|
|
||||||
Slot = slot;
|
|
||||||
|
|
||||||
CustomMinimumSize = (64, 64);
|
|
||||||
|
|
||||||
AddChild(Button = new TextureButton
|
|
||||||
{
|
|
||||||
TextureNormal = texture,
|
|
||||||
Scale = (2, 2),
|
|
||||||
});
|
|
||||||
|
|
||||||
Button.OnPressed += e => OnPressed?.Invoke(e);
|
|
||||||
|
|
||||||
AddChild(SpriteView = new SpriteView
|
|
||||||
{
|
|
||||||
MouseFilter = MouseFilterMode.Ignore,
|
|
||||||
Scale = (2, 2)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
|
||||||
{
|
|
||||||
public abstract class InventoryInterfaceController : IDisposable
|
|
||||||
{
|
|
||||||
// ReSharper disable once UnassignedGetOnlyAutoProperty
|
|
||||||
[field: Dependency] protected IGameHud GameHud { get; }
|
|
||||||
|
|
||||||
protected InventoryInterfaceController(ClientInventoryComponent owner)
|
|
||||||
{
|
|
||||||
Owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Initialize()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract SS14Window Window { get; }
|
|
||||||
protected ClientInventoryComponent Owner { get; }
|
|
||||||
|
|
||||||
public virtual void PlayerAttached()
|
|
||||||
{
|
|
||||||
GameHud.InventoryButtonVisible = true;
|
|
||||||
GameHud.InventoryButtonToggled = b =>
|
|
||||||
{
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
Window.Open();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Window.Close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void PlayerDetached()
|
|
||||||
{
|
|
||||||
GameHud.InventoryButtonVisible = false;
|
|
||||||
Window.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void AddToSlot(EquipmentSlotDefines.Slots slot, IEntity entity)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void RemoveFromSlot(EquipmentSlotDefines.Slots slot)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void RemoveFromInventory(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
args.Button.Pressed = false;
|
|
||||||
var control = (InventoryButton) args.Button.Parent;
|
|
||||||
|
|
||||||
Owner.SendUnequipMessage(control.Slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void AddToInventory(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
args.Button.Pressed = false;
|
|
||||||
var control = (InventoryButton) args.Button.Parent;
|
|
||||||
|
|
||||||
Owner.SendEquipMessage(control.Slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,287 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Content.Client.GameObjects.EntitySystems;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
using static Robust.Client.GameObjects.SpriteComponent;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.IconSmoothing
|
|
||||||
{
|
|
||||||
// TODO: Potential improvements:
|
|
||||||
// Defer updating of these.
|
|
||||||
// Get told by somebody to use a loop.
|
|
||||||
/// <summary>
|
|
||||||
/// Makes sprites of other grid-aligned entities like us connect.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// The system is based on Baystation12's smoothwalling, and thus will work with those.
|
|
||||||
/// To use, set <c>base</c> equal to the prefix of the corner states in the sprite base RSI.
|
|
||||||
/// Any objects with the same <c>key</c> will connect.
|
|
||||||
/// </remarks>
|
|
||||||
[RegisterComponent]
|
|
||||||
public class IconSmoothComponent : Component
|
|
||||||
{
|
|
||||||
private string _smoothKey;
|
|
||||||
private string _stateBase;
|
|
||||||
private IconSmoothingMode _mode;
|
|
||||||
|
|
||||||
public override string Name => "IconSmooth";
|
|
||||||
|
|
||||||
internal ISpriteComponent Sprite { get; private set; }
|
|
||||||
internal SnapGridComponent SnapGrid { get; private set; }
|
|
||||||
private (GridId, MapIndices) _lastPosition;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// We will smooth with other objects with the same key.
|
|
||||||
/// </summary>
|
|
||||||
public string SmoothKey => _smoothKey;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Prepended to the RSI state.
|
|
||||||
/// </summary>
|
|
||||||
public string StateBase => _stateBase;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mode that controls how the icon should be selected.
|
|
||||||
/// </summary>
|
|
||||||
public IconSmoothingMode Mode => _mode;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Used by <see cref="IconSmoothSystem"/> to reduce redundant updates.
|
|
||||||
/// </summary>
|
|
||||||
internal int UpdateGeneration { get; set; }
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
SnapGrid = Owner.GetComponent<SnapGridComponent>();
|
|
||||||
Sprite = Owner.GetComponent<ISpriteComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
|
||||||
|
|
||||||
serializer.DataFieldCached(ref _stateBase, "base", "");
|
|
||||||
serializer.DataFieldCached(ref _smoothKey, "key", null);
|
|
||||||
serializer.DataFieldCached(ref _mode, "mode", IconSmoothingMode.Corners);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Startup()
|
|
||||||
{
|
|
||||||
base.Startup();
|
|
||||||
|
|
||||||
SnapGrid.OnPositionChanged += SnapGridOnPositionChanged;
|
|
||||||
Owner.EntityManager.RaiseEvent(Owner, new IconSmoothDirtyEvent(null, SnapGrid.Offset, Mode));
|
|
||||||
if (Mode == IconSmoothingMode.Corners)
|
|
||||||
{
|
|
||||||
var state0 = $"{StateBase}0";
|
|
||||||
Sprite.LayerMapSet(CornerLayers.SE, Sprite.AddLayerState(state0));
|
|
||||||
Sprite.LayerSetDirOffset(CornerLayers.SE, DirectionOffset.None);
|
|
||||||
Sprite.LayerMapSet(CornerLayers.NE, Sprite.AddLayerState(state0));
|
|
||||||
Sprite.LayerSetDirOffset(CornerLayers.NE, DirectionOffset.CounterClockwise);
|
|
||||||
Sprite.LayerMapSet(CornerLayers.NW, Sprite.AddLayerState(state0));
|
|
||||||
Sprite.LayerSetDirOffset(CornerLayers.NW, DirectionOffset.Flip);
|
|
||||||
Sprite.LayerMapSet(CornerLayers.SW, Sprite.AddLayerState(state0));
|
|
||||||
Sprite.LayerSetDirOffset(CornerLayers.SW, DirectionOffset.Clockwise);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal virtual void CalculateNewSprite()
|
|
||||||
{
|
|
||||||
switch (Mode)
|
|
||||||
{
|
|
||||||
case IconSmoothingMode.Corners:
|
|
||||||
CalculateNewSpriteCorers();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IconSmoothingMode.CardinalFlags:
|
|
||||||
CalculateNewSpriteCardinal();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CalculateNewSpriteCardinal()
|
|
||||||
{
|
|
||||||
var dirs = CardinalConnectDirs.None;
|
|
||||||
|
|
||||||
if (MatchingEntity(SnapGrid.GetInDir(Direction.North)))
|
|
||||||
dirs |= CardinalConnectDirs.North;
|
|
||||||
if (MatchingEntity(SnapGrid.GetInDir(Direction.South)))
|
|
||||||
dirs |= CardinalConnectDirs.South;
|
|
||||||
if (MatchingEntity(SnapGrid.GetInDir(Direction.East)))
|
|
||||||
dirs |= CardinalConnectDirs.East;
|
|
||||||
if (MatchingEntity(SnapGrid.GetInDir(Direction.West)))
|
|
||||||
dirs |= CardinalConnectDirs.West;
|
|
||||||
|
|
||||||
Sprite.LayerSetState(0, $"{StateBase}{(int) dirs}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CalculateNewSpriteCorers()
|
|
||||||
{
|
|
||||||
var n = MatchingEntity(SnapGrid.GetInDir(Direction.North));
|
|
||||||
var ne = MatchingEntity(SnapGrid.GetInDir(Direction.NorthEast));
|
|
||||||
var e = MatchingEntity(SnapGrid.GetInDir(Direction.East));
|
|
||||||
var se = MatchingEntity(SnapGrid.GetInDir(Direction.SouthEast));
|
|
||||||
var s = MatchingEntity(SnapGrid.GetInDir(Direction.South));
|
|
||||||
var sw = MatchingEntity(SnapGrid.GetInDir(Direction.SouthWest));
|
|
||||||
var w = MatchingEntity(SnapGrid.GetInDir(Direction.West));
|
|
||||||
var nw = MatchingEntity(SnapGrid.GetInDir(Direction.NorthWest));
|
|
||||||
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
var cornerNE = CornerFill.None;
|
|
||||||
var cornerSE = CornerFill.None;
|
|
||||||
var cornerSW = CornerFill.None;
|
|
||||||
var cornerNW = CornerFill.None;
|
|
||||||
// ReSharper restore InconsistentNaming
|
|
||||||
|
|
||||||
if (n)
|
|
||||||
{
|
|
||||||
cornerNE |= CornerFill.CounterClockwise;
|
|
||||||
cornerNW |= CornerFill.Clockwise;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ne)
|
|
||||||
{
|
|
||||||
cornerNE |= CornerFill.Diagonal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e)
|
|
||||||
{
|
|
||||||
cornerNE |= CornerFill.Clockwise;
|
|
||||||
cornerSE |= CornerFill.CounterClockwise;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (se)
|
|
||||||
{
|
|
||||||
cornerSE |= CornerFill.Diagonal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
cornerSE |= CornerFill.Clockwise;
|
|
||||||
cornerSW |= CornerFill.CounterClockwise;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sw)
|
|
||||||
{
|
|
||||||
cornerSW |= CornerFill.Diagonal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w)
|
|
||||||
{
|
|
||||||
cornerSW |= CornerFill.Clockwise;
|
|
||||||
cornerNW |= CornerFill.CounterClockwise;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nw)
|
|
||||||
{
|
|
||||||
cornerNW |= CornerFill.Diagonal;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite.LayerSetState(CornerLayers.NE, $"{StateBase}{(int) cornerNE}");
|
|
||||||
Sprite.LayerSetState(CornerLayers.SE, $"{StateBase}{(int) cornerSE}");
|
|
||||||
Sprite.LayerSetState(CornerLayers.SW, $"{StateBase}{(int) cornerSW}");
|
|
||||||
Sprite.LayerSetState(CornerLayers.NW, $"{StateBase}{(int) cornerNW}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
SnapGrid.OnPositionChanged -= SnapGridOnPositionChanged;
|
|
||||||
Owner.EntityManager.RaiseEvent(Owner, new IconSmoothDirtyEvent(_lastPosition, SnapGrid.Offset, Mode));
|
|
||||||
|
|
||||||
base.Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SnapGridOnPositionChanged()
|
|
||||||
{
|
|
||||||
Owner.EntityManager.RaiseEvent(Owner, new IconSmoothDirtyEvent(_lastPosition, SnapGrid.Offset, Mode));
|
|
||||||
_lastPosition = (Owner.Transform.GridID, SnapGrid.Position);
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Diagnostics.Contracts.Pure]
|
|
||||||
protected bool MatchingEntity(IEnumerable<IEntity> candidates)
|
|
||||||
{
|
|
||||||
foreach (var entity in candidates)
|
|
||||||
{
|
|
||||||
if (!entity.TryGetComponent(out IconSmoothComponent other))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.SmoothKey == SmoothKey)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
private enum CardinalConnectDirs : byte
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
North = 1,
|
|
||||||
South = 2,
|
|
||||||
East = 4,
|
|
||||||
West = 8
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum CornerFill : byte
|
|
||||||
{
|
|
||||||
// These values are pulled from Baystation12.
|
|
||||||
// I'm too lazy to convert the state names.
|
|
||||||
None = 0,
|
|
||||||
|
|
||||||
// The cardinal tile counter-clockwise of this corner is filled.
|
|
||||||
CounterClockwise = 1,
|
|
||||||
|
|
||||||
// The diagonal tile in the direction of this corner.
|
|
||||||
Diagonal = 2,
|
|
||||||
|
|
||||||
// The cardinal tile clockwise of this corner is filled.
|
|
||||||
Clockwise = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
||||||
public enum CornerLayers
|
|
||||||
{
|
|
||||||
SE,
|
|
||||||
NE,
|
|
||||||
NW,
|
|
||||||
SW,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Controls the mode with which icon smoothing is calculated.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
|
||||||
public enum IconSmoothingMode
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Each icon is made up of 4 corners, each of which can get a different state depending on
|
|
||||||
/// adjacent entities clockwise, counter-clockwise and diagonal with the corner.
|
|
||||||
/// </summary>
|
|
||||||
Corners,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// There are 16 icons, only one of which is used at once.
|
|
||||||
/// The icon selected is a bit field made up of the cardinal direction flags that have adjacent entities.
|
|
||||||
/// </summary>
|
|
||||||
CardinalFlags,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
using Content.Shared.GameObjects;
|
||||||
|
using Content.Shared.Input;
|
||||||
|
using SS14.Client.GameObjects;
|
||||||
|
using SS14.Client.Interfaces.Input;
|
||||||
|
using SS14.Client.UserInterface;
|
||||||
|
using SS14.Client.UserInterface.Controls;
|
||||||
|
using SS14.Client.UserInterface.CustomControls;
|
||||||
|
using SS14.Shared.ContentPack;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects.Serialization;
|
||||||
|
using SS14.Shared.Input;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.Network;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Log;
|
||||||
|
using SS14.Shared.Maths;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||||
|
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
|
||||||
|
using static Content.Shared.GameObjects.SharedInventoryComponent.ServerInventoryMessage;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects
|
||||||
|
{
|
||||||
|
public class ClientInventoryComponent : SharedInventoryComponent
|
||||||
|
{
|
||||||
|
private InventoryWindow Window;
|
||||||
|
private string TemplateName = "HumanInventory"; //stored for serialization purposes
|
||||||
|
|
||||||
|
private InputCommand OpenMenuCommand;
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
base.OnRemove();
|
||||||
|
|
||||||
|
Window.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ExposeData(EntitySerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
|
||||||
|
Window = new InventoryWindow(this);
|
||||||
|
OpenMenuCommand = InputCommand.FromDelegate(() => { Window.AddToScreen(); Window.Open(); });
|
||||||
|
serializer.DataField(ref TemplateName, "Template", "HumanInventory");
|
||||||
|
Window.CreateInventory(TemplateName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||||
|
{
|
||||||
|
var inputMgr = IoCManager.Resolve<IInputManager>();
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
//Updates what we are storing in UI slots
|
||||||
|
case ServerInventoryMessage msg:
|
||||||
|
if (msg.Updatetype == ServerInventoryUpdate.Addition)
|
||||||
|
{
|
||||||
|
Window.AddToSlot(msg);
|
||||||
|
}
|
||||||
|
else if (msg.Updatetype == ServerInventoryUpdate.Removal)
|
||||||
|
{
|
||||||
|
Window.RemoveFromSlot(msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerAttachedMsg _:
|
||||||
|
inputMgr.SetInputCommand(ContentKeyFunctions.OpenCharacterMenu, OpenMenuCommand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerDetachedMsg _:
|
||||||
|
inputMgr.SetInputCommand(ContentKeyFunctions.OpenCharacterMenu, null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendUnequipMessage(Slots slot)
|
||||||
|
{
|
||||||
|
var unequipmessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Unequip);
|
||||||
|
SendNetworkMessage(unequipmessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendEquipMessage(Slots slot)
|
||||||
|
{
|
||||||
|
var equipmessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Equip);
|
||||||
|
SendNetworkMessage(equipmessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary window to hold the basis for inventory hud
|
||||||
|
/// </summary>
|
||||||
|
private class InventoryWindow : SS14Window
|
||||||
|
{
|
||||||
|
private int elements_x;
|
||||||
|
|
||||||
|
private GridContainer GridContainer;
|
||||||
|
private List<Slots> IndexedSlots;
|
||||||
|
private Dictionary<Slots, InventoryButton> InventorySlots = new Dictionary<Slots, InventoryButton>(); //ordered dictionary?
|
||||||
|
private ClientInventoryComponent InventoryComponent;
|
||||||
|
|
||||||
|
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Inventory/HumanInventory.tscn");
|
||||||
|
|
||||||
|
public InventoryWindow(ClientInventoryComponent inventory)
|
||||||
|
{
|
||||||
|
InventoryComponent = inventory;
|
||||||
|
|
||||||
|
HideOnClose = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a grid container filled with slot buttons loaded from an inventory template
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="TemplateName"></param>
|
||||||
|
public void CreateInventory(string TemplateName)
|
||||||
|
{
|
||||||
|
Type type = AppDomain.CurrentDomain.GetAssemblyByName("Content.Shared").GetType("Content.Shared.GameObjects." + TemplateName);
|
||||||
|
Inventory inventory = (Inventory)Activator.CreateInstance(type);
|
||||||
|
|
||||||
|
elements_x = inventory.Columns;
|
||||||
|
|
||||||
|
GridContainer = (GridContainer)Contents.GetChild("PanelContainer").GetChild("CenterContainer").GetChild("GridContainer");
|
||||||
|
GridContainer.Columns = elements_x;
|
||||||
|
IndexedSlots = new List<Slots>(inventory.SlotMasks);
|
||||||
|
|
||||||
|
foreach (Slots slot in IndexedSlots)
|
||||||
|
{
|
||||||
|
InventoryButton newbutton = new InventoryButton(slot);
|
||||||
|
|
||||||
|
if (slot == Slots.NONE)
|
||||||
|
{
|
||||||
|
//TODO: Re-enable when godot grid container maintains grid with invisible elements
|
||||||
|
//newbutton.Visible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Store slot button and give it the default onpress behavior for empty elements
|
||||||
|
newbutton.GetChild<Button>("Button").OnPressed += AddToInventory;
|
||||||
|
InventorySlots.Add(slot, newbutton);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SlotNames.ContainsKey(slot))
|
||||||
|
{
|
||||||
|
newbutton.GetChild<Button>("Button").Text = SlotNames[slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
GridContainer.AddChild(newbutton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the item we have equipped to the slot texture and prepares the slot button for removal
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
public void AddToSlot(ServerInventoryMessage message)
|
||||||
|
{
|
||||||
|
InventoryButton button = InventorySlots[message.Inventoryslot];
|
||||||
|
var entity = IoCManager.Resolve<IEntityManager>().GetEntity(message.EntityUid);
|
||||||
|
|
||||||
|
button.EntityUid = message.EntityUid;
|
||||||
|
var container = button.GetChild("CenterContainer");
|
||||||
|
button.GetChild<Button>("Button").OnPressed += RemoveFromInventory;
|
||||||
|
button.GetChild<Button>("Button").OnPressed -= AddToInventory;
|
||||||
|
|
||||||
|
//Gets entity sprite and assigns it to button texture
|
||||||
|
if (entity.TryGetComponent(out IconComponent sprite))
|
||||||
|
{
|
||||||
|
var tex = sprite.Icon.Default;
|
||||||
|
|
||||||
|
var rect = button.GetChild("CenterContainer").GetChild<TextureRect>("TextureRect");
|
||||||
|
|
||||||
|
if (tex != null)
|
||||||
|
{
|
||||||
|
rect.Texture = tex;
|
||||||
|
rect.Scale = new Vector2(Math.Min(CalculateMinimumSize().X, 32) / tex.Height, Math.Min(CalculateMinimumSize().Y, 32) / tex.Height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove element from the UI and update its button to blank texture and prepare for insertion again
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
public void RemoveFromSlot(ServerInventoryMessage message)
|
||||||
|
{
|
||||||
|
InventoryButton button = InventorySlots[message.Inventoryslot];
|
||||||
|
button.GetChild("CenterContainer").GetChild<TextureRect>("TextureRect").Texture = null;
|
||||||
|
button.EntityUid = EntityUid.Invalid;
|
||||||
|
button.GetChild<Button>("Button").OnPressed -= RemoveFromInventory;
|
||||||
|
button.GetChild<Button>("Button").OnPressed += AddToInventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveFromInventory(BaseButton.ButtonEventArgs args)
|
||||||
|
{
|
||||||
|
args.Button.Pressed = false;
|
||||||
|
var control = (InventoryButton)args.Button.Parent;
|
||||||
|
|
||||||
|
InventoryComponent.SendUnequipMessage(control.Slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddToInventory(BaseButton.ButtonEventArgs args)
|
||||||
|
{
|
||||||
|
args.Button.Pressed = false;
|
||||||
|
var control = (InventoryButton)args.Button.Parent;
|
||||||
|
|
||||||
|
InventoryComponent.SendEquipMessage(control.Slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InventoryButton : Control
|
||||||
|
{
|
||||||
|
public Slots Slot;
|
||||||
|
public EntityUid EntityUid;
|
||||||
|
|
||||||
|
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Inventory/StorageSlot.tscn");
|
||||||
|
|
||||||
|
public InventoryButton(Slots slot)
|
||||||
|
{
|
||||||
|
Slot = slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,62 +1,22 @@
|
|||||||
using System.Collections.Generic;
|
using Content.Client.Interfaces.GameObjects;
|
||||||
using System.Linq;
|
|
||||||
using Content.Client.Interfaces.GameObjects;
|
|
||||||
using Content.Client.UserInterface;
|
using Content.Client.UserInterface;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Robust.Client.GameObjects;
|
using SS14.Client.Interfaces.UserInterface;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using SS14.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using SS14.Shared.IoC;
|
||||||
using Robust.Shared.Interfaces.Network;
|
using System.Collections.Generic;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
namespace Content.Client.GameObjects
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
|
||||||
[ComponentReference(typeof(IHandsComponent))]
|
|
||||||
public class HandsComponent : SharedHandsComponent, IHandsComponent
|
public class HandsComponent : SharedHandsComponent, IHandsComponent
|
||||||
{
|
{
|
||||||
private HandsGui _gui;
|
private readonly Dictionary<string, IEntity> hands = new Dictionary<string, IEntity>();
|
||||||
|
public string ActiveIndex { get; private set; }
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
[ViewVariables] private readonly Dictionary<string, IEntity> _hands = new Dictionary<string, IEntity>();
|
|
||||||
|
|
||||||
[ViewVariables] public string ActiveIndex { get; private set; }
|
|
||||||
|
|
||||||
[ViewVariables] private ISpriteComponent _sprite;
|
|
||||||
|
|
||||||
[ViewVariables] public IEntity ActiveHand => GetEntity(ActiveIndex);
|
|
||||||
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
base.OnRemove();
|
|
||||||
|
|
||||||
_gui?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
if (Owner.TryGetComponent(out _sprite))
|
|
||||||
{
|
|
||||||
foreach (var slot in _hands.Keys)
|
|
||||||
{
|
|
||||||
_sprite.LayerMapReserveBlank($"hand-{slot}");
|
|
||||||
_setHand(slot, _hands[slot]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEntity GetEntity(string index)
|
public IEntity GetEntity(string index)
|
||||||
{
|
{
|
||||||
if (_hands.TryGetValue(index, out var entity))
|
if (hands.TryGetValue(index, out var entity))
|
||||||
{
|
{
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
@@ -64,109 +24,33 @@ namespace Content.Client.GameObjects
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
public override void HandleComponentState(ComponentState state)
|
||||||
{
|
{
|
||||||
if (curState == null)
|
var cast = (HandsComponentState)state;
|
||||||
return;
|
hands.Clear();
|
||||||
|
foreach (var hand in cast.Hands)
|
||||||
var cast = (HandsComponentState) curState;
|
|
||||||
foreach (var (slot, uid) in cast.Hands)
|
|
||||||
{
|
{
|
||||||
IEntity entity = null;
|
IEntity entity = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
entity = Owner.EntityManager.GetEntity(uid);
|
entity = Owner.EntityManager.GetEntity(hand.Value);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// Nothing.
|
// Nothing.
|
||||||
}
|
}
|
||||||
|
hands[hand.Key] = entity;
|
||||||
_hands[slot] = entity;
|
|
||||||
_setHand(slot, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var slot in _hands.Keys.ToList())
|
|
||||||
{
|
|
||||||
if (!cast.Hands.ContainsKey(slot))
|
|
||||||
{
|
|
||||||
_hands[slot] = null;
|
|
||||||
_setHand(slot, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ActiveIndex = cast.ActiveIndex;
|
ActiveIndex = cast.ActiveIndex;
|
||||||
|
// Tell UI to update.
|
||||||
_gui?.UpdateHandIcons();
|
var uiMgr = IoCManager.Resolve<IUserInterfaceManager>();
|
||||||
}
|
if (!uiMgr.StateRoot.TryGetChild<HandsGui>("HandsGui", out var control))
|
||||||
|
|
||||||
private void _setHand(string hand, IEntity entity)
|
|
||||||
{
|
{
|
||||||
if (_sprite == null)
|
control = new HandsGui();
|
||||||
{
|
uiMgr.StateRoot.AddChild(control);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
_sprite.LayerSetVisible($"hand-{hand}", false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var item = entity.GetComponent<ItemComponent>();
|
|
||||||
var maybeInhands = item.GetInHandStateInfo(hand);
|
|
||||||
if (!maybeInhands.HasValue)
|
|
||||||
{
|
|
||||||
_sprite.LayerSetVisible($"hand-{hand}", false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var (rsi, state) = maybeInhands.Value;
|
|
||||||
_sprite.LayerSetVisible($"hand-{hand}", true);
|
|
||||||
_sprite.LayerSetState($"hand-{hand}", state, rsi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
|
||||||
|
|
||||||
if (!serializer.Reading)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var slot in serializer.ReadDataFieldCached("hands", new List<string>()))
|
|
||||||
{
|
|
||||||
_hands.Add(slot, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
|
|
||||||
IComponent component = null)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, netChannel, component);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case PlayerAttachedMsg _:
|
|
||||||
if (_gui == null)
|
|
||||||
{
|
|
||||||
_gui = new HandsGui();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gui.Parent?.RemoveChild(_gui);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gameHud.HandsContainer.AddChild(_gui);
|
|
||||||
_gui.UpdateHandIcons();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PlayerDetachedMsg _:
|
|
||||||
_gui.Parent?.RemoveChild(_gui);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
control.UpdateHandIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendChangeHand(string index)
|
public void SendChangeHand(string index)
|
||||||
@@ -174,11 +58,6 @@ namespace Content.Client.GameObjects
|
|||||||
SendNetworkMessage(new ClientChangedHandMsg(index));
|
SendNetworkMessage(new ClientChangedHandMsg(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AttackByInHand(string index)
|
|
||||||
{
|
|
||||||
SendNetworkMessage(new ClientAttackByInHandMsg(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UseActiveHand()
|
public void UseActiveHand()
|
||||||
{
|
{
|
||||||
if(GetEntity(ActiveIndex) != null)
|
if(GetEntity(ActiveIndex) != null)
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.GameObjects;
|
|
||||||
using Content.Shared.GameObjects.Components.Items;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.ResourceManagement;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Components.Renderable;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public class ItemComponent : Component
|
|
||||||
{
|
|
||||||
public override string Name => "Item";
|
|
||||||
public override uint? NetID => ContentNetIDs.ITEM;
|
|
||||||
public override Type StateType => typeof(ItemComponentState);
|
|
||||||
|
|
||||||
[ViewVariables] protected ResourcePath RsiPath;
|
|
||||||
|
|
||||||
private string _equippedPrefix;
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public string EquippedPrefix
|
|
||||||
{
|
|
||||||
get => _equippedPrefix;
|
|
||||||
set => _equippedPrefix = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public (RSI rsi, RSI.StateId stateId)? GetInHandStateInfo(string hand)
|
|
||||||
{
|
|
||||||
if (RsiPath == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var rsi = GetRSI();
|
|
||||||
var stateId = EquippedPrefix != null ? $"{EquippedPrefix}-inhand-{hand}" : $"inhand-{hand}";
|
|
||||||
if (rsi.TryGetState(stateId, out _))
|
|
||||||
{
|
|
||||||
return (rsi, stateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
|
||||||
|
|
||||||
serializer.DataFieldCached(ref RsiPath, "sprite", null);
|
|
||||||
serializer.DataFieldCached(ref _equippedPrefix, "prefix", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected RSI GetRSI()
|
|
||||||
{
|
|
||||||
var resourceCache = IoCManager.Resolve<IResourceCache>();
|
|
||||||
return resourceCache.GetResource<RSIResource>(SharedSpriteComponent.TextureRoot / RsiPath).RSI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
||||||
{
|
|
||||||
if(curState == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var itemComponentState = (ItemComponentState)curState;
|
|
||||||
EquippedPrefix = itemComponentState.EquippedPrefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Content.Client.GameObjects.Components.IconSmoothing;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using static Robust.Client.GameObjects.SpriteComponent;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components
|
|
||||||
{
|
|
||||||
// TODO: Over layers should be placed ABOVE the window itself too.
|
|
||||||
// This is gonna require a client entity & parenting,
|
|
||||||
// so IsMapTransform being naive is gonna be a problem.
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Override of icon smoothing to handle the specific complexities of low walls.
|
|
||||||
/// </summary>
|
|
||||||
[RegisterComponent]
|
|
||||||
[ComponentReference(typeof(IconSmoothComponent))]
|
|
||||||
public class LowWallComponent : IconSmoothComponent
|
|
||||||
{
|
|
||||||
public override string Name => "LowWall";
|
|
||||||
|
|
||||||
public CornerFill LastCornerNE { get; private set; }
|
|
||||||
public CornerFill LastCornerSE { get; private set; }
|
|
||||||
public CornerFill LastCornerSW { get; private set; }
|
|
||||||
public CornerFill LastCornerNW { get; private set; }
|
|
||||||
|
|
||||||
public override void Startup()
|
|
||||||
{
|
|
||||||
base.Startup();
|
|
||||||
|
|
||||||
var overState0 = $"{StateBase}over_0";
|
|
||||||
Sprite.LayerMapSet(OverCornerLayers.SE, Sprite.AddLayerState(overState0));
|
|
||||||
Sprite.LayerSetDirOffset(OverCornerLayers.SE, DirectionOffset.None);
|
|
||||||
Sprite.LayerMapSet(OverCornerLayers.NE, Sprite.AddLayerState(overState0));
|
|
||||||
Sprite.LayerSetDirOffset(OverCornerLayers.NE, DirectionOffset.CounterClockwise);
|
|
||||||
Sprite.LayerMapSet(OverCornerLayers.NW, Sprite.AddLayerState(overState0));
|
|
||||||
Sprite.LayerSetDirOffset(OverCornerLayers.NW, DirectionOffset.Flip);
|
|
||||||
Sprite.LayerMapSet(OverCornerLayers.SW, Sprite.AddLayerState(overState0));
|
|
||||||
Sprite.LayerSetDirOffset(OverCornerLayers.SW, DirectionOffset.Clockwise);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void CalculateNewSprite()
|
|
||||||
{
|
|
||||||
base.CalculateNewSprite();
|
|
||||||
|
|
||||||
var (n, nl) = MatchingWall(SnapGrid.GetInDir(Direction.North));
|
|
||||||
var (ne, nel) = MatchingWall(SnapGrid.GetInDir(Direction.NorthEast));
|
|
||||||
var (e, el) = MatchingWall(SnapGrid.GetInDir(Direction.East));
|
|
||||||
var (se, sel) = MatchingWall(SnapGrid.GetInDir(Direction.SouthEast));
|
|
||||||
var (s, sl) = MatchingWall(SnapGrid.GetInDir(Direction.South));
|
|
||||||
var (sw, swl) = MatchingWall(SnapGrid.GetInDir(Direction.SouthWest));
|
|
||||||
var (w, wl) = MatchingWall(SnapGrid.GetInDir(Direction.West));
|
|
||||||
var (nw, nwl) = MatchingWall(SnapGrid.GetInDir(Direction.NorthWest));
|
|
||||||
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
var cornerNE = CornerFill.None;
|
|
||||||
var cornerSE = CornerFill.None;
|
|
||||||
var cornerSW = CornerFill.None;
|
|
||||||
var cornerNW = CornerFill.None;
|
|
||||||
|
|
||||||
var lowCornerNE = CornerFill.None;
|
|
||||||
var lowCornerSE = CornerFill.None;
|
|
||||||
var lowCornerSW = CornerFill.None;
|
|
||||||
var lowCornerNW = CornerFill.None;
|
|
||||||
// ReSharper restore InconsistentNaming
|
|
||||||
|
|
||||||
if (n)
|
|
||||||
{
|
|
||||||
cornerNE |= CornerFill.CounterClockwise;
|
|
||||||
cornerNW |= CornerFill.Clockwise;
|
|
||||||
|
|
||||||
if (!nl)
|
|
||||||
{
|
|
||||||
lowCornerNE |= CornerFill.CounterClockwise;
|
|
||||||
lowCornerNW |= CornerFill.Clockwise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ne)
|
|
||||||
{
|
|
||||||
cornerNE |= CornerFill.Diagonal;
|
|
||||||
|
|
||||||
if (!nel && (nl || el || n && e))
|
|
||||||
{
|
|
||||||
lowCornerNE |= CornerFill.Diagonal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e)
|
|
||||||
{
|
|
||||||
cornerNE |= CornerFill.Clockwise;
|
|
||||||
cornerSE |= CornerFill.CounterClockwise;
|
|
||||||
|
|
||||||
if (!el)
|
|
||||||
{
|
|
||||||
lowCornerNE |= CornerFill.Clockwise;
|
|
||||||
lowCornerSE |= CornerFill.CounterClockwise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (se)
|
|
||||||
{
|
|
||||||
cornerSE |= CornerFill.Diagonal;
|
|
||||||
|
|
||||||
if (!sel && (sl || el || s && e))
|
|
||||||
{
|
|
||||||
lowCornerSE |= CornerFill.Diagonal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
cornerSE |= CornerFill.Clockwise;
|
|
||||||
cornerSW |= CornerFill.CounterClockwise;
|
|
||||||
|
|
||||||
if (!sl)
|
|
||||||
{
|
|
||||||
lowCornerSE |= CornerFill.Clockwise;
|
|
||||||
lowCornerSW |= CornerFill.CounterClockwise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sw)
|
|
||||||
{
|
|
||||||
cornerSW |= CornerFill.Diagonal;
|
|
||||||
|
|
||||||
if (!swl && (sl || wl || s && w))
|
|
||||||
{
|
|
||||||
lowCornerSW |= CornerFill.Diagonal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w)
|
|
||||||
{
|
|
||||||
cornerSW |= CornerFill.Clockwise;
|
|
||||||
cornerNW |= CornerFill.CounterClockwise;
|
|
||||||
|
|
||||||
if (!wl)
|
|
||||||
{
|
|
||||||
lowCornerSW |= CornerFill.Clockwise;
|
|
||||||
lowCornerNW |= CornerFill.CounterClockwise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nw)
|
|
||||||
{
|
|
||||||
cornerNW |= CornerFill.Diagonal;
|
|
||||||
|
|
||||||
if (!nwl && (nl || wl || n && w))
|
|
||||||
{
|
|
||||||
lowCornerNW |= CornerFill.Diagonal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite.LayerSetState(CornerLayers.NE, $"{StateBase}{(int) cornerNE}");
|
|
||||||
Sprite.LayerSetState(CornerLayers.SE, $"{StateBase}{(int) cornerSE}");
|
|
||||||
Sprite.LayerSetState(CornerLayers.SW, $"{StateBase}{(int) cornerSW}");
|
|
||||||
Sprite.LayerSetState(CornerLayers.NW, $"{StateBase}{(int) cornerNW}");
|
|
||||||
|
|
||||||
Sprite.LayerSetState(OverCornerLayers.NE, $"{StateBase}over_{(int) lowCornerNE}");
|
|
||||||
Sprite.LayerSetState(OverCornerLayers.SE, $"{StateBase}over_{(int) lowCornerSE}");
|
|
||||||
Sprite.LayerSetState(OverCornerLayers.SW, $"{StateBase}over_{(int) lowCornerSW}");
|
|
||||||
Sprite.LayerSetState(OverCornerLayers.NW, $"{StateBase}over_{(int) lowCornerNW}");
|
|
||||||
|
|
||||||
LastCornerNE = cornerNE;
|
|
||||||
LastCornerSE = cornerSE;
|
|
||||||
LastCornerSW = cornerSW;
|
|
||||||
LastCornerNW = cornerNW;
|
|
||||||
|
|
||||||
foreach (var entity in SnapGrid.GetLocal())
|
|
||||||
{
|
|
||||||
if (entity.TryGetComponent(out WindowComponent window))
|
|
||||||
{
|
|
||||||
window.UpdateSprite();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Diagnostics.Contracts.Pure]
|
|
||||||
private (bool connected, bool lowWall) MatchingWall(IEnumerable<IEntity> candidates)
|
|
||||||
{
|
|
||||||
foreach (var entity in candidates)
|
|
||||||
{
|
|
||||||
if (!entity.TryGetComponent(out IconSmoothComponent other))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.SmoothKey == SmoothKey)
|
|
||||||
{
|
|
||||||
return (true, other is LowWallComponent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
||||||
private enum OverCornerLayers
|
|
||||||
{
|
|
||||||
SE,
|
|
||||||
NE,
|
|
||||||
NW,
|
|
||||||
SW,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.GameObjects.Components.Mobs;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Mobs
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
[ComponentReference(typeof(SharedCameraRecoilComponent))]
|
|
||||||
public sealed class CameraRecoilComponent : SharedCameraRecoilComponent
|
|
||||||
{
|
|
||||||
// Maximum rate of magnitude restore towards 0 kick.
|
|
||||||
private const float RestoreRateMax = 1.5f;
|
|
||||||
|
|
||||||
// Minimum rate of magnitude restore towards 0 kick.
|
|
||||||
private const float RestoreRateMin = 0.5f;
|
|
||||||
|
|
||||||
// Time in seconds since the last kick that lerps RestoreRateMin and RestoreRateMax
|
|
||||||
private const float RestoreRateRamp = 0.05f;
|
|
||||||
|
|
||||||
// The maximum magnitude of the kick applied to the camera at any point.
|
|
||||||
private const float KickMagnitudeMax = 0.25f;
|
|
||||||
|
|
||||||
private Vector2 _currentKick;
|
|
||||||
private float _lastKickTime;
|
|
||||||
|
|
||||||
private EyeComponent _eye;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
_eye = Owner.GetComponent<EyeComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Kick(Vector2 recoil)
|
|
||||||
{
|
|
||||||
// Use really bad math to "dampen" kicks when we're already kicked.
|
|
||||||
var existing = _currentKick.Length;
|
|
||||||
var dampen = existing/KickMagnitudeMax;
|
|
||||||
_currentKick += recoil * (1-dampen);
|
|
||||||
if (_currentKick.Length > KickMagnitudeMax)
|
|
||||||
{
|
|
||||||
_currentKick = _currentKick.Normalized * KickMagnitudeMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastKickTime = 0;
|
|
||||||
_updateEye();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, netChannel, component);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case RecoilKickMessage msg:
|
|
||||||
Kick(msg.Recoil);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FrameUpdate(float frameTime)
|
|
||||||
{
|
|
||||||
var magnitude = _currentKick.Length;
|
|
||||||
if (magnitude <= 0.005f)
|
|
||||||
{
|
|
||||||
_currentKick = Vector2.Zero;
|
|
||||||
_updateEye();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continually restore camera to 0.
|
|
||||||
var normalized = _currentKick.Normalized;
|
|
||||||
var restoreRate = FloatMath.Lerp(RestoreRateMin, RestoreRateMax, Math.Min(1, _lastKickTime/RestoreRateRamp));
|
|
||||||
var restore = normalized * restoreRate * frameTime;
|
|
||||||
_currentKick -= restore;
|
|
||||||
_updateEye();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _updateEye()
|
|
||||||
{
|
|
||||||
_eye.Offset = _currentKick;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using Content.Client.GameObjects.Components.Actor;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Mobs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An interface which is gathered to assemble the character window from multiple components
|
|
||||||
/// </summary>
|
|
||||||
public interface ICharacterUI
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The godot control which holds the character user interface to be included in the window
|
|
||||||
/// </summary>
|
|
||||||
Control Scene { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The order it will appear in the character UI, higher is lower
|
|
||||||
/// </summary>
|
|
||||||
UIPriority Priority { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.GameObjects.Components.Actor;
|
|
||||||
using Content.Client.Graphics.Overlays;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Client.Utility;
|
|
||||||
using Content.Shared.GameObjects;
|
|
||||||
using Content.Shared.GameObjects.Components.Mobs;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.Graphics.Overlays;
|
|
||||||
using Robust.Client.Interfaces.Graphics.Overlays;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.Interfaces.UserInterface;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Components.Renderable;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A character UI component which shows the current damage state of the mob (living/dead)
|
|
||||||
/// </summary>
|
|
||||||
[RegisterComponent]
|
|
||||||
public class SpeciesUI : SharedSpeciesComponent//, ICharacterUI
|
|
||||||
{
|
|
||||||
private StatusEffectsUI _ui;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Holds the godot control for the species window
|
|
||||||
/// </summary>
|
|
||||||
private SpeciesWindow _window;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An enum representing the current state being applied to the user
|
|
||||||
/// </summary>
|
|
||||||
private ScreenEffects _currentEffect = ScreenEffects.None;
|
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
// Required dependencies
|
|
||||||
[Dependency] private readonly IOverlayManager _overlayManager;
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
|
||||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager;
|
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
//Relevant interface implementation for the character UI controller
|
|
||||||
public Control Scene => _window;
|
|
||||||
public UIPriority Priority => UIPriority.Species;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Allows calculating if we need to act due to this component being controlled by the current mob
|
|
||||||
/// </summary>
|
|
||||||
private bool CurrentlyControlled => _playerManager.LocalPlayer.ControlledEntity == Owner;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Holds the screen effects that can be applied mapped ot their relevant overlay
|
|
||||||
/// </summary>
|
|
||||||
private Dictionary<ScreenEffects, Overlay> EffectsDictionary;
|
|
||||||
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
base.OnRemove();
|
|
||||||
|
|
||||||
_window.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnAdd()
|
|
||||||
{
|
|
||||||
base.OnAdd();
|
|
||||||
|
|
||||||
_window = new SpeciesWindow();
|
|
||||||
_ui = new StatusEffectsUI();
|
|
||||||
|
|
||||||
EffectsDictionary = new Dictionary<ScreenEffects, Overlay>()
|
|
||||||
{
|
|
||||||
{ ScreenEffects.CircleMask, new CircleMaskOverlay() },
|
|
||||||
{ ScreenEffects.GradientCircleMask, new GradientCircleMask() }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
|
||||||
{
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case HudStateChange msg:
|
|
||||||
if (CurrentlyControlled)
|
|
||||||
{
|
|
||||||
ChangeHudIcon(msg);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PlayerAttachedMsg _:
|
|
||||||
_ui.Parent?.RemoveChild(_ui);
|
|
||||||
|
|
||||||
_userInterfaceManager.StateRoot.AddChild(_ui);
|
|
||||||
ApplyOverlay();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PlayerDetachedMsg _:
|
|
||||||
_ui.Parent?.RemoveChild(_ui);
|
|
||||||
RemoveOverlay();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChangeHudIcon(HudStateChange changeMessage)
|
|
||||||
{
|
|
||||||
var path = SharedSpriteComponent.TextureRoot / changeMessage.StateSprite;
|
|
||||||
var texture = _resourceCache.GetTexture(path);
|
|
||||||
|
|
||||||
_window.SetIcon(texture);
|
|
||||||
_ui.SetHealthIcon(texture);
|
|
||||||
|
|
||||||
SetOverlay(changeMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetOverlay(HudStateChange message)
|
|
||||||
{
|
|
||||||
RemoveOverlay();
|
|
||||||
|
|
||||||
_currentEffect = message.effect;
|
|
||||||
|
|
||||||
ApplyOverlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveOverlay()
|
|
||||||
{
|
|
||||||
if (_currentEffect != ScreenEffects.None)
|
|
||||||
{
|
|
||||||
var appliedEffect = EffectsDictionary[_currentEffect];
|
|
||||||
_overlayManager.RemoveOverlay(appliedEffect.ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentEffect = ScreenEffects.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyOverlay()
|
|
||||||
{
|
|
||||||
if (_currentEffect != ScreenEffects.None)
|
|
||||||
{
|
|
||||||
var overlay = EffectsDictionary[_currentEffect];
|
|
||||||
if (_overlayManager.HasOverlay(overlay.ID))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_overlayManager.AddOverlay(overlay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SpeciesWindow : TextureRect
|
|
||||||
{
|
|
||||||
public SpeciesWindow()
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter;
|
|
||||||
SizeFlagsVertical = SizeFlags.None;
|
|
||||||
|
|
||||||
Texture = IoCManager.Resolve<IResourceCache>().GetTexture("/Textures/Mob/UI/Human/human0.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetIcon(Texture texture)
|
|
||||||
{
|
|
||||||
Texture = texture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Mobs;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Mobs
|
|
||||||
{
|
|
||||||
public class SpeciesVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
public override void InitializeEntity(IEntity entity)
|
|
||||||
{
|
|
||||||
base.InitializeEntity(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
if (component.TryGetData<SharedSpeciesComponent.MobState>(SharedSpeciesComponent.MobVisuals.RotationState, out var state))
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case SharedSpeciesComponent.MobState.Stand:
|
|
||||||
sprite.Rotation = 0;
|
|
||||||
break;
|
|
||||||
case SharedSpeciesComponent.MobState.Down:
|
|
||||||
sprite.Rotation = Angle.FromDegrees(90);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.GameObjects.Components.Movement;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Movement
|
|
||||||
{
|
|
||||||
[UsedImplicitly]
|
|
||||||
public class HandTeleporterVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
if (!component.TryGetData(TeleporterVisuals.VisualState, out TeleporterVisualState state))
|
|
||||||
{
|
|
||||||
state = TeleporterVisualState.Ready;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case TeleporterVisualState.Charging:
|
|
||||||
sprite.LayerSetState(0, "charging");
|
|
||||||
break;
|
|
||||||
case TeleporterVisualState.Ready:
|
|
||||||
sprite.LayerSetState(0, "ready");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Movement;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Movement
|
|
||||||
{
|
|
||||||
[UsedImplicitly]
|
|
||||||
public class PortalVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
public override void InitializeEntity(IEntity entity)
|
|
||||||
{
|
|
||||||
base.InitializeEntity(entity);
|
|
||||||
|
|
||||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
|
||||||
|
|
||||||
sprite.LayerMapSet(Layers.Portal, sprite.AddLayerState("portal-pending"));
|
|
||||||
sprite.LayerSetShader(Layers.Portal, "unshaded");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
if (component.TryGetData<PortalState>(PortalVisuals.State, out var state))
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case PortalState.Pending:
|
|
||||||
sprite.LayerSetState(Layers.Portal, "portal-pending");
|
|
||||||
break;
|
|
||||||
// TODO: Spritework here?
|
|
||||||
case PortalState.UnableToTeleport:
|
|
||||||
sprite.LayerSetState(Layers.Portal, "portal-unconnected");
|
|
||||||
break;
|
|
||||||
case PortalState.RecentlyTeleported:
|
|
||||||
sprite.LayerSetState(Layers.Portal, "portal-unconnected");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite.LayerSetState(Layers.Portal, "portal-pending");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Layers
|
|
||||||
{
|
|
||||||
Portal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
|
||||||
using NJsonSchema.Validation;
|
|
||||||
using OpenTK.Graphics.OpenGL4;
|
|
||||||
using Robust.Client.GameObjects.Components.UserInterface;
|
|
||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Interfaces.Graphics;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Power
|
|
||||||
{
|
|
||||||
public class ApcBoundUserInterface : BoundUserInterface
|
|
||||||
{
|
|
||||||
private ApcWindow _window;
|
|
||||||
private BaseButton _breakerButton;
|
|
||||||
private Label _externalPowerStateLabel;
|
|
||||||
private ProgressBar _chargeBar;
|
|
||||||
|
|
||||||
protected override void Open()
|
|
||||||
{
|
|
||||||
base.Open();
|
|
||||||
|
|
||||||
_window = new ApcWindow
|
|
||||||
{
|
|
||||||
MarginRight = 426.0f, MarginBottom = 270.0f
|
|
||||||
};
|
|
||||||
_window.OnClose += Close;
|
|
||||||
_window.OpenCenteredMinSize();
|
|
||||||
|
|
||||||
_breakerButton = _window.BreakerButton;
|
|
||||||
_breakerButton.OnPressed += _ => SendMessage(new ApcToggleMainBreakerMessage());
|
|
||||||
|
|
||||||
_externalPowerStateLabel = _window.ExternalPowerStateLabel;
|
|
||||||
_chargeBar = _window.ChargeBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApcBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateState(BoundUserInterfaceState state)
|
|
||||||
{
|
|
||||||
base.UpdateState(state);
|
|
||||||
|
|
||||||
var castState = (ApcBoundInterfaceState) state;
|
|
||||||
|
|
||||||
_breakerButton.Pressed = castState.MainBreaker;
|
|
||||||
switch (castState.ApcExternalPower)
|
|
||||||
{
|
|
||||||
case ApcExternalPowerState.None:
|
|
||||||
_externalPowerStateLabel.Text = "None";
|
|
||||||
_externalPowerStateLabel.SetOnlyStyleClass(NanoStyle.StyleClassPowerStateNone);
|
|
||||||
break;
|
|
||||||
case ApcExternalPowerState.Low:
|
|
||||||
_externalPowerStateLabel.Text = "Low";
|
|
||||||
_externalPowerStateLabel.SetOnlyStyleClass(NanoStyle.StyleClassPowerStateLow);
|
|
||||||
break;
|
|
||||||
case ApcExternalPowerState.Good:
|
|
||||||
_externalPowerStateLabel.Text = "Good";
|
|
||||||
_externalPowerStateLabel.SetOnlyStyleClass(NanoStyle.StyleClassPowerStateGood);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
|
|
||||||
_chargeBar.Value = castState.Charge;
|
|
||||||
UpdateChargeBarColor(castState.Charge);
|
|
||||||
float ChargePercentage = (castState.Charge / _chargeBar.MaxValue) * 100.0f;
|
|
||||||
_window.ChargePercentage.Text = " " + ChargePercentage.ToString("0.00") + "%";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateChargeBarColor(float charge)
|
|
||||||
{
|
|
||||||
float normalizedCharge = charge / _chargeBar.MaxValue;
|
|
||||||
|
|
||||||
float leftHue = 0.0f;// Red
|
|
||||||
float middleHue = 0.066f;// Orange
|
|
||||||
float rightHue = 0.33f;// Green
|
|
||||||
float saturation = 1.0f;// Uniform saturation
|
|
||||||
float value = 0.8f;// Uniform value / brightness
|
|
||||||
float alpha = 1.0f;// Uniform alpha
|
|
||||||
|
|
||||||
// These should add up to 1.0 or your transition won't be smooth
|
|
||||||
float leftSideSize = 0.5f;// Fraction of _chargeBar lerped from leftHue to middleHue
|
|
||||||
float rightSideSize = 0.5f;// Fraction of _chargeBar lerped from middleHue to rightHue
|
|
||||||
|
|
||||||
float finalHue;
|
|
||||||
if (normalizedCharge <= leftSideSize)
|
|
||||||
{
|
|
||||||
normalizedCharge /= leftSideSize;// Adjust range to 0.0 to 1.0
|
|
||||||
finalHue = FloatMath.Lerp(leftHue, middleHue, normalizedCharge);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
normalizedCharge = (normalizedCharge - leftSideSize) / rightSideSize;// Adjust range to 0.0 to 1.0.
|
|
||||||
finalHue = FloatMath.Lerp(middleHue, rightHue, normalizedCharge);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if null first to avoid repeatedly creating this.
|
|
||||||
if (_chargeBar.ForegroundStyleBoxOverride == null)
|
|
||||||
{
|
|
||||||
_chargeBar.ForegroundStyleBoxOverride = new StyleBoxFlat();
|
|
||||||
}
|
|
||||||
|
|
||||||
var foregroundStyleBoxOverride = (StyleBoxFlat)_chargeBar.ForegroundStyleBoxOverride;
|
|
||||||
foregroundStyleBoxOverride.BackgroundColor =
|
|
||||||
Color.FromHsv(new Vector4(finalHue, saturation, value, alpha));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
base.Dispose(disposing);
|
|
||||||
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
_window.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ApcWindow : SS14Window
|
|
||||||
{
|
|
||||||
public Button BreakerButton { get; set; }
|
|
||||||
public Label ExternalPowerStateLabel { get; set; }
|
|
||||||
public ProgressBar ChargeBar { get; set; }
|
|
||||||
public Label ChargePercentage { get; set; }
|
|
||||||
|
|
||||||
public ApcWindow()
|
|
||||||
{
|
|
||||||
Title = "APC";
|
|
||||||
var rows = new VBoxContainer("Rows");
|
|
||||||
|
|
||||||
var statusHeader = new Label("StatusHeader") { Text = "Power Status: " };
|
|
||||||
rows.AddChild(statusHeader);
|
|
||||||
|
|
||||||
var breaker = new HBoxContainer("Breaker");
|
|
||||||
var breakerLabel = new Label("Label") { Text = "Main Breaker: " };
|
|
||||||
BreakerButton = new CheckButton {Name = "Breaker", Text = "Toggle"};
|
|
||||||
breaker.AddChild(breakerLabel);
|
|
||||||
breaker.AddChild(BreakerButton);
|
|
||||||
rows.AddChild(breaker);
|
|
||||||
|
|
||||||
var externalStatus = new HBoxContainer("ExternalStatus");
|
|
||||||
var externalStatusLabel = new Label("Label") { Text = "External Power: " };
|
|
||||||
ExternalPowerStateLabel = new Label("Status") { Text = "Good" };
|
|
||||||
ExternalPowerStateLabel.SetOnlyStyleClass(NanoStyle.StyleClassPowerStateGood);
|
|
||||||
externalStatus.AddChild(externalStatusLabel);
|
|
||||||
externalStatus.AddChild(ExternalPowerStateLabel);
|
|
||||||
rows.AddChild(externalStatus);
|
|
||||||
|
|
||||||
var charge = new HBoxContainer("Charge");
|
|
||||||
var chargeLabel = new Label("Label") { Text = "Charge:" };
|
|
||||||
ChargeBar = new ProgressBar("Charge")
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = Control.SizeFlags.FillExpand,
|
|
||||||
MinValue = 0.0f,
|
|
||||||
MaxValue = 1.0f,
|
|
||||||
Page = 0.0f,
|
|
||||||
Value = 0.5f
|
|
||||||
};
|
|
||||||
ChargePercentage = new Label("ChargePercentage");
|
|
||||||
charge.AddChild(chargeLabel);
|
|
||||||
charge.AddChild(ChargeBar);
|
|
||||||
charge.AddChild(ChargePercentage);
|
|
||||||
rows.AddChild(charge);
|
|
||||||
|
|
||||||
Contents.AddChild(rows);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Power;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Power
|
|
||||||
{
|
|
||||||
public class ApcVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
public override void InitializeEntity(IEntity entity)
|
|
||||||
{
|
|
||||||
base.InitializeEntity(entity);
|
|
||||||
|
|
||||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
|
||||||
|
|
||||||
sprite.LayerMapSet(Layers.ChargeState, sprite.AddLayerState("apco3-0"));
|
|
||||||
sprite.LayerSetShader(Layers.ChargeState, "unshaded");
|
|
||||||
|
|
||||||
sprite.LayerMapSet(Layers.Lock, sprite.AddLayerState("apcox-0"));
|
|
||||||
sprite.LayerSetShader(Layers.Lock, "unshaded");
|
|
||||||
|
|
||||||
sprite.LayerMapSet(Layers.Equipment, sprite.AddLayerState("apco0-3"));
|
|
||||||
sprite.LayerSetShader(Layers.Equipment, "unshaded");
|
|
||||||
|
|
||||||
sprite.LayerMapSet(Layers.Lighting, sprite.AddLayerState("apco1-3"));
|
|
||||||
sprite.LayerSetShader(Layers.Lighting, "unshaded");
|
|
||||||
|
|
||||||
sprite.LayerMapSet(Layers.Environment, sprite.AddLayerState("apco2-3"));
|
|
||||||
sprite.LayerSetShader(Layers.Environment, "unshaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
if (component.TryGetData<ApcChargeState>(ApcVisuals.ChargeState, out var state))
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case ApcChargeState.Lack:
|
|
||||||
sprite.LayerSetState(Layers.ChargeState, "apco3-0");
|
|
||||||
break;
|
|
||||||
case ApcChargeState.Charging:
|
|
||||||
sprite.LayerSetState(Layers.ChargeState, "apco3-1");
|
|
||||||
break;
|
|
||||||
case ApcChargeState.Full:
|
|
||||||
sprite.LayerSetState(Layers.ChargeState, "apco3-2");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite.LayerSetState(Layers.ChargeState, "apco3-0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Layers
|
|
||||||
{
|
|
||||||
ChargeState,
|
|
||||||
Lock,
|
|
||||||
Equipment,
|
|
||||||
Lighting,
|
|
||||||
Environment,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Power;
|
|
||||||
using Content.Shared.Utility;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Power
|
|
||||||
{
|
|
||||||
public class PowerCellVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
private string _prefix;
|
|
||||||
|
|
||||||
public override void LoadData(YamlMappingNode node)
|
|
||||||
{
|
|
||||||
base.LoadData(node);
|
|
||||||
|
|
||||||
_prefix = node.GetNode("prefix").AsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void InitializeEntity(IEntity entity)
|
|
||||||
{
|
|
||||||
base.InitializeEntity(entity);
|
|
||||||
|
|
||||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
|
||||||
|
|
||||||
sprite.LayerMapSet(Layers.Charge, sprite.AddLayerState($"{_prefix}_100"));
|
|
||||||
sprite.LayerSetShader(Layers.Charge, "unshaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
if (component.TryGetData(PowerCellVisuals.ChargeLevel, out float fraction))
|
|
||||||
{
|
|
||||||
sprite.LayerSetState(Layers.Charge, $"{_prefix}_{ContentHelpers.RoundToLevels(fraction, 1, 5) * 25}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum Layers
|
|
||||||
{
|
|
||||||
Charge
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using SS14.Client.UserInterface.Controls;
|
||||||
using Robust.Shared.GameObjects;
|
using SS14.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Network;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.Network;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Power
|
namespace Content.Client.GameObjects.Components.Power
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
|
||||||
public class PowerDebugTool : SharedPowerDebugTool
|
public class PowerDebugTool : SharedPowerDebugTool
|
||||||
{
|
{
|
||||||
SS14Window LastWindow;
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||||
{
|
{
|
||||||
base.HandleMessage(message, netChannel, component);
|
base.HandleMessage(message, netChannel, component);
|
||||||
@@ -18,16 +17,13 @@ namespace Content.Client.GameObjects.Components.Power
|
|||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case OpenDataWindowMsg msg:
|
case OpenDataWindowMsg msg:
|
||||||
if (LastWindow != null && !LastWindow.Disposed)
|
var window = new SS14Window
|
||||||
{
|
{
|
||||||
LastWindow.Dispose();
|
Title = "Power Debug Tool"
|
||||||
}
|
|
||||||
LastWindow = new SS14Window()
|
|
||||||
{
|
|
||||||
Title = "Power Debug Tool",
|
|
||||||
};
|
};
|
||||||
LastWindow.Contents.AddChild(new Label() { Text = msg.Data });
|
window.Contents.AddChild(new Label() { Text = msg.Data });
|
||||||
LastWindow.Open();
|
window.AddToScreen();
|
||||||
|
window.Open();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Power;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Power
|
|
||||||
{
|
|
||||||
public class SmesVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
public override void InitializeEntity(IEntity entity)
|
|
||||||
{
|
|
||||||
base.InitializeEntity(entity);
|
|
||||||
|
|
||||||
var sprite = entity.GetComponent<ISpriteComponent>();
|
|
||||||
|
|
||||||
sprite.LayerMapSet(Layers.Input, sprite.AddLayerState("smes-oc0"));
|
|
||||||
sprite.LayerSetShader(Layers.Input, "unshaded");
|
|
||||||
sprite.LayerMapSet(Layers.Charge, sprite.AddLayerState("smes-og1"));
|
|
||||||
sprite.LayerSetShader(Layers.Charge, "unshaded");
|
|
||||||
sprite.LayerSetVisible(Layers.Charge, false);
|
|
||||||
sprite.LayerMapSet(Layers.Output, sprite.AddLayerState("smes-op0"));
|
|
||||||
sprite.LayerSetShader(Layers.Output, "unshaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
if (!component.TryGetData<int>(SmesVisuals.LastChargeLevel, out var level) || level == 0)
|
|
||||||
{
|
|
||||||
sprite.LayerSetVisible(Layers.Charge, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite.LayerSetVisible(Layers.Charge, true);
|
|
||||||
sprite.LayerSetState(Layers.Charge, $"smes-og{level}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (component.TryGetData<ChargeState>(SmesVisuals.LastChargeState, out var state))
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case ChargeState.Still:
|
|
||||||
sprite.LayerSetState(Layers.Input, "smes-oc0");
|
|
||||||
sprite.LayerSetState(Layers.Output, "smes-op1");
|
|
||||||
break;
|
|
||||||
case ChargeState.Charging:
|
|
||||||
sprite.LayerSetState(Layers.Input, "smes-oc1");
|
|
||||||
sprite.LayerSetState(Layers.Output, "smes-op1");
|
|
||||||
break;
|
|
||||||
case ChargeState.Discharging:
|
|
||||||
sprite.LayerSetState(Layers.Input, "smes-oc0");
|
|
||||||
sprite.LayerSetState(Layers.Output, "smes-op2");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite.LayerSetState(Layers.Input, "smes-oc0");
|
|
||||||
sprite.LayerSetState(Layers.Output, "smes-op1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Layers
|
|
||||||
{
|
|
||||||
Input,
|
|
||||||
Charge,
|
|
||||||
Output,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.Research;
|
|
||||||
using Content.Shared.GameObjects.Components.Research;
|
|
||||||
using Content.Shared.Research;
|
|
||||||
using Robust.Client.GameObjects.Components.UserInterface;
|
|
||||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Research
|
|
||||||
{
|
|
||||||
public class LatheBoundUserInterface : BoundUserInterface
|
|
||||||
{
|
|
||||||
#pragma warning disable CS0649
|
|
||||||
[Dependency]
|
|
||||||
private IPrototypeManager _prototypeManager;
|
|
||||||
#pragma warning restore
|
|
||||||
[ViewVariables]
|
|
||||||
private LatheMenu menu;
|
|
||||||
[ViewVariables]
|
|
||||||
private LatheQueueMenu queueMenu;
|
|
||||||
|
|
||||||
public MaterialStorageComponent Storage { get; private set; }
|
|
||||||
public SharedLatheComponent Lathe { get; private set; }
|
|
||||||
public LatheDatabaseComponent Database { get; private set; }
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public Queue<LatheRecipePrototype> QueuedRecipes => _queuedRecipes;
|
|
||||||
private Queue<LatheRecipePrototype> _queuedRecipes = new Queue<LatheRecipePrototype>();
|
|
||||||
|
|
||||||
public LatheBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
|
||||||
{
|
|
||||||
SendMessage(new SharedLatheComponent.LatheSyncRequestMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Open()
|
|
||||||
{
|
|
||||||
base.Open();
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
if (!Owner.Owner.TryGetComponent(out MaterialStorageComponent storage)
|
|
||||||
|| !Owner.Owner.TryGetComponent(out SharedLatheComponent lathe)
|
|
||||||
|| !Owner.Owner.TryGetComponent(out LatheDatabaseComponent database)) return;
|
|
||||||
|
|
||||||
Storage = storage;
|
|
||||||
Lathe = lathe;
|
|
||||||
Database = database;
|
|
||||||
|
|
||||||
menu = new LatheMenu {Owner = this};
|
|
||||||
queueMenu = new LatheQueueMenu { Owner = this };
|
|
||||||
|
|
||||||
menu.OnClose += Close;
|
|
||||||
|
|
||||||
menu.Populate();
|
|
||||||
menu.PopulateMaterials();
|
|
||||||
|
|
||||||
menu.QueueButton.OnPressed += (args) => { queueMenu.OpenCentered(); };
|
|
||||||
|
|
||||||
storage.OnMaterialStorageChanged += menu.PopulateDisabled;
|
|
||||||
storage.OnMaterialStorageChanged += menu.PopulateMaterials;
|
|
||||||
|
|
||||||
menu.OpenCentered();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Queue(LatheRecipePrototype recipe, int quantity = 1)
|
|
||||||
{
|
|
||||||
SendMessage(new SharedLatheComponent.LatheQueueRecipeMessage(recipe.ID, quantity));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
|
|
||||||
{
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case SharedLatheComponent.LatheProducingRecipeMessage msg:
|
|
||||||
if (!_prototypeManager.TryIndex(msg.ID, out LatheRecipePrototype recipe)) break;
|
|
||||||
queueMenu.SetInfo(recipe);
|
|
||||||
break;
|
|
||||||
case SharedLatheComponent.LatheStoppedProducingRecipeMessage msg:
|
|
||||||
queueMenu.ClearInfo();
|
|
||||||
break;
|
|
||||||
case SharedLatheComponent.LatheFullQueueMessage msg:
|
|
||||||
_queuedRecipes.Clear();
|
|
||||||
foreach (var id in msg.Recipes)
|
|
||||||
{
|
|
||||||
if (!_prototypeManager.TryIndex(id, out LatheRecipePrototype recipePrototype)) break;
|
|
||||||
_queuedRecipes.Enqueue(recipePrototype);
|
|
||||||
}
|
|
||||||
queueMenu.PopulateList();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
base.Dispose(disposing);
|
|
||||||
if (!disposing) return;
|
|
||||||
menu?.Dispose();
|
|
||||||
queueMenu?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Research;
|
|
||||||
using Content.Shared.Research;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Research
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
[ComponentReference(typeof(SharedLatheDatabaseComponent))]
|
|
||||||
public class LatheDatabaseComponent : SharedLatheDatabaseComponent
|
|
||||||
{
|
|
||||||
#pragma warning disable CS0649
|
|
||||||
[Dependency]
|
|
||||||
private IPrototypeManager _prototypeManager;
|
|
||||||
#pragma warning restore
|
|
||||||
|
|
||||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
||||||
{
|
|
||||||
base.HandleComponentState(curState, nextState);
|
|
||||||
if (!(curState is LatheDatabaseState state)) return;
|
|
||||||
Clear();
|
|
||||||
foreach (var ID in state.Recipes)
|
|
||||||
{
|
|
||||||
if(!_prototypeManager.TryIndex(ID, out LatheRecipePrototype recipe)) continue;
|
|
||||||
AddRecipe(recipe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Content.Shared.GameObjects.Components.Research;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Research
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
[ComponentReference(typeof(SharedMaterialStorageComponent))]
|
|
||||||
public class MaterialStorageComponent : SharedMaterialStorageComponent
|
|
||||||
{
|
|
||||||
protected override Dictionary<string, int> Storage { get; set; } = new Dictionary<string, int>();
|
|
||||||
|
|
||||||
public event Action OnMaterialStorageChanged;
|
|
||||||
|
|
||||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
||||||
{
|
|
||||||
base.HandleComponentState(curState, nextState);
|
|
||||||
if (!(curState is MaterialStorageState state)) return;
|
|
||||||
Storage = state.Storage;
|
|
||||||
OnMaterialStorageChanged?.Invoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Content.Shared.GameObjects.Components.Sound;
|
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
using Robust.Shared.Timers;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Sound
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public class SoundComponent : SharedSoundComponent
|
|
||||||
{
|
|
||||||
private readonly List<ScheduledSound> _schedules = new List<ScheduledSound>();
|
|
||||||
private AudioSystem _audioSystem;
|
|
||||||
private Random Random;
|
|
||||||
|
|
||||||
public override void StopAllSounds()
|
|
||||||
{
|
|
||||||
foreach (var schedule in _schedules)
|
|
||||||
{
|
|
||||||
schedule.Play = false;
|
|
||||||
}
|
|
||||||
_schedules.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void StopScheduledSound(string filename)
|
|
||||||
{
|
|
||||||
foreach (var schedule in _schedules.ToArray())
|
|
||||||
{
|
|
||||||
if (schedule.Filename != filename) continue;
|
|
||||||
schedule.Play = false;
|
|
||||||
_schedules.Remove(schedule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AddScheduledSound(ScheduledSound schedule)
|
|
||||||
{
|
|
||||||
_schedules.Add(schedule);
|
|
||||||
Play(schedule);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Play(ScheduledSound schedule)
|
|
||||||
{
|
|
||||||
if (!schedule.Play) return;
|
|
||||||
if (Random == null) Random = new Random(Owner.Uid.GetHashCode() ^ DateTime.Now.GetHashCode());
|
|
||||||
|
|
||||||
Timer.Spawn((int) schedule.Delay + (Random.Next((int) schedule.RandomDelay)),() =>
|
|
||||||
{
|
|
||||||
if (!schedule.Play) return; // We make sure this hasn't changed.
|
|
||||||
if (_audioSystem == null) _audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
|
||||||
_audioSystem.Play(schedule.Filename, Owner, schedule.AudioParams);
|
|
||||||
|
|
||||||
if (schedule.Times == 0)
|
|
||||||
{
|
|
||||||
_schedules.Remove(schedule);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (schedule.Times > 0)
|
|
||||||
schedule.Times--;
|
|
||||||
|
|
||||||
Play(schedule);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, netChannel, component);
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case ScheduledSoundMessage msg:
|
|
||||||
AddScheduledSound(msg.Schedule);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StopSoundScheduleMessage msg:
|
|
||||||
StopScheduledSound(msg.Filename);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StopAllSoundsMessage msg:
|
|
||||||
StopAllSounds();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
IoCManager.Resolve<IEntitySystemManager>().TryGetEntitySystem(out _audioSystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
|
||||||
if (serializer.Writing) return;
|
|
||||||
serializer.TryReadDataField("schedules", out List<ScheduledSound> schedules);
|
|
||||||
if (schedules == null) return;
|
|
||||||
foreach (var schedule in schedules)
|
|
||||||
{
|
|
||||||
if (schedule == null) continue;
|
|
||||||
AddScheduledSound(schedule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,24 @@
|
|||||||
using System;
|
using Content.Shared.GameObjects;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Content.Shared.GameObjects.Components.Storage;
|
using Content.Shared.GameObjects.Components.Storage;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using SS14.Client.GameObjects;
|
||||||
using Robust.Client.UserInterface;
|
using SS14.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using SS14.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using SS14.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Network;
|
using SS14.Shared.Interfaces.Network;
|
||||||
using Robust.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using Robust.Shared.Maths;
|
using SS14.Shared.Log;
|
||||||
using Robust.Shared.Serialization;
|
using SS14.Shared.Maths;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Storage
|
namespace Content.Client.GameObjects.Components.Storage
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Client version of item storage containers, contains a UI which displays stored entities and their size
|
/// Client version of item storage containers, contains a UI which displays stored entities and their size
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
|
||||||
public class ClientStorageComponent : SharedStorageComponent
|
public class ClientStorageComponent : SharedStorageComponent
|
||||||
{
|
{
|
||||||
private Dictionary<EntityUid, int> StoredEntities { get; set; } = new Dictionary<EntityUid, int>();
|
private Dictionary<EntityUid, int> StoredEntities { get; set; } = new Dictionary<EntityUid, int>();
|
||||||
@@ -36,12 +37,8 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
public override void OnRemove()
|
public override void OnRemove()
|
||||||
{
|
{
|
||||||
Window.Dispose();
|
Window.Dispose();
|
||||||
base.OnRemove();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
base.OnRemove();
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||||
@@ -56,9 +53,6 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
case OpenStorageUIMessage msg:
|
case OpenStorageUIMessage msg:
|
||||||
OpenUI();
|
OpenUI();
|
||||||
break;
|
break;
|
||||||
case CloseStorageUIMessage msg:
|
|
||||||
CloseUI();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,14 +73,10 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void OpenUI()
|
private void OpenUI()
|
||||||
{
|
{
|
||||||
|
Window.AddToScreen();
|
||||||
Window.Open();
|
Window.Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseUI()
|
|
||||||
{
|
|
||||||
Window.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Function for clicking one of the stored entity buttons in the UI, tells server to remove that entity
|
/// Function for clicking one of the stored entity buttons in the UI, tells server to remove that entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -106,46 +96,18 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
private Label Information;
|
private Label Information;
|
||||||
public ClientStorageComponent StorageEntity;
|
public ClientStorageComponent StorageEntity;
|
||||||
|
|
||||||
public StorageWindow()
|
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Storage/Storage.tscn");
|
||||||
{
|
|
||||||
Size = new Vector2(180.0f, 320.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
Title = "Storage Item";
|
HideOnClose = true;
|
||||||
RectClipContent = true;
|
|
||||||
|
|
||||||
VSplitContainer = new VBoxContainer("VSplitContainer");
|
// Get all the controls.
|
||||||
Information = new Label("Information")
|
VSplitContainer = Contents.GetChild("VSplitContainer");
|
||||||
{
|
EntityList = VSplitContainer.GetChild("ListScrollContainer").GetChild<VBoxContainer>("EntityList");
|
||||||
Text = "Items: 0 Volume: 0/0 Stuff",
|
Information = VSplitContainer.GetChild<Label>("Information");
|
||||||
SizeFlagsVertical = SizeFlags.ShrinkCenter
|
|
||||||
};
|
|
||||||
VSplitContainer.AddChild(Information);
|
|
||||||
|
|
||||||
var listScrollContainer = new ScrollContainer("ListScrollContainer")
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
HScrollEnabled = true,
|
|
||||||
VScrollEnabled = true
|
|
||||||
};
|
|
||||||
EntityList = new VBoxContainer("EntityList")
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand
|
|
||||||
};
|
|
||||||
listScrollContainer.AddChild(EntityList);
|
|
||||||
VSplitContainer.AddChild(listScrollContainer);
|
|
||||||
Contents.AddChild(VSplitContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Close()
|
|
||||||
{
|
|
||||||
StorageEntity.SendNetworkMessage(new CloseStorageUIMessage());
|
|
||||||
base.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -165,15 +127,29 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
{
|
{
|
||||||
EntityuID = entityuid.Key
|
EntityuID = entityuid.Key
|
||||||
};
|
};
|
||||||
|
var container = button.GetChild("HBoxContainer");
|
||||||
button.ActualButton.OnToggled += OnItemButtonToggled;
|
button.ActualButton.OnToggled += OnItemButtonToggled;
|
||||||
//Name and Size labels set
|
//Name and Size labels set
|
||||||
button.EntityName.Text = entity.Name;
|
container.GetChild<Label>("Name").Text = entity.Name;
|
||||||
button.EntitySize.Text = string.Format("{0}", entityuid.Value);
|
container.GetChild<Control>("Control").GetChild<Label>("Size").Text = string.Format("{0}", entityuid.Value);
|
||||||
|
|
||||||
//Gets entity sprite and assigns it to button texture
|
//Gets entity sprite and assigns it to button texture
|
||||||
if (entity.TryGetComponent(out ISpriteComponent sprite))
|
if (entity.TryGetComponent(out IconComponent icon))
|
||||||
{
|
{
|
||||||
button.EntitySpriteView.Sprite = sprite;
|
var tex = icon.Icon.Default;
|
||||||
|
var rect = container.GetChild("TextureWrap").GetChild<TextureRect>("TextureRect");
|
||||||
|
|
||||||
|
if (tex != null)
|
||||||
|
{
|
||||||
|
rect.Texture = tex;
|
||||||
|
// Copypasted but replaced with 32 dunno if good
|
||||||
|
var scale = (float)32 / tex.Height;
|
||||||
|
rect.Scale = new Vector2(scale, scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rect.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityList.AddChild(button);
|
EntityList.AddChild(button);
|
||||||
@@ -205,64 +181,17 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Button created for each entity that represents that item in the storage UI, with a texture, and name and size label
|
/// Button created for each entity that represents that item in the storage UI, with a texture, and name and size label
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private class EntityButton : PanelContainer
|
private class EntityButton : Control
|
||||||
{
|
{
|
||||||
public EntityUid EntityuID { get; set; }
|
public EntityUid EntityuID { get; set; }
|
||||||
public Button ActualButton { get; private set; }
|
public Button ActualButton { get; private set; }
|
||||||
public SpriteView EntitySpriteView { get; private set; }
|
|
||||||
public Control EntityControl { get; private set; }
|
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Storage/StorageEntity.tscn");
|
||||||
public Label EntityName { get; private set; }
|
|
||||||
public Label EntitySize { get; private set; }
|
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
ActualButton = GetChild<Button>("Button");
|
||||||
ActualButton = new Button("Button")
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
ToggleMode = true,
|
|
||||||
MouseFilter = MouseFilterMode.Stop
|
|
||||||
};
|
|
||||||
AddChild(ActualButton);
|
|
||||||
|
|
||||||
var hBoxContainer = new HBoxContainer("HBoxContainer") {MouseFilter = MouseFilterMode.Ignore};
|
|
||||||
EntitySpriteView = new SpriteView("SpriteView")
|
|
||||||
{
|
|
||||||
CustomMinimumSize = new Vector2(32.0f, 32.0f), MouseFilter = MouseFilterMode.Ignore
|
|
||||||
};
|
|
||||||
EntityName = new Label("Name")
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
|
||||||
Text = "Backpack",
|
|
||||||
MouseFilter = MouseFilterMode.Ignore
|
|
||||||
};
|
|
||||||
hBoxContainer.AddChild(EntitySpriteView);
|
|
||||||
hBoxContainer.AddChild(EntityName);
|
|
||||||
|
|
||||||
EntityControl = new Control("Control")
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand, MouseFilter = MouseFilterMode.Ignore
|
|
||||||
};
|
|
||||||
EntitySize = new Label("Size")
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
|
||||||
Text = "Size 6",
|
|
||||||
Align = Label.AlignMode.Right,
|
|
||||||
AnchorLeft = 1.0f,
|
|
||||||
AnchorRight = 1.0f,
|
|
||||||
AnchorBottom = 0.5f,
|
|
||||||
AnchorTop = 0.5f,
|
|
||||||
MarginLeft = -38.0f,
|
|
||||||
MarginTop = -7.0f,
|
|
||||||
MarginRight = -5.0f,
|
|
||||||
MarginBottom = 7.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
EntityControl.AddChild(EntitySize);
|
|
||||||
hBoxContainer.AddChild(EntityControl);
|
|
||||||
AddChild(hBoxContainer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Storage;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Storage
|
|
||||||
{
|
|
||||||
public sealed class StorageVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
private string _stateOpen;
|
|
||||||
private string _stateClosed;
|
|
||||||
|
|
||||||
public override void LoadData(YamlMappingNode node)
|
|
||||||
{
|
|
||||||
base.LoadData(node);
|
|
||||||
|
|
||||||
if (node.TryGetNode("state_open", out var child))
|
|
||||||
{
|
|
||||||
_stateOpen = child.AsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.TryGetNode("state_closed", out child))
|
|
||||||
{
|
|
||||||
_stateClosed = child.AsString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
if (!component.Owner.TryGetComponent(out ISpriteComponent sprite))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
component.TryGetData(StorageVisuals.Open, out bool open);
|
|
||||||
sprite.LayerSetState(StorageVisualLayers.Door, open ? _stateOpen : _stateClosed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum StorageVisualLayers
|
|
||||||
{
|
|
||||||
Door
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
using Content.Shared.Maps;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Simple component that automatically hides the sibling <see cref="ISpriteComponent"/> when the tile it's on
|
|
||||||
/// is not a sub floor (plating).
|
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="ContentTileDefinition.IsSubFloor"/>
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed class SubFloorHideComponent : Component
|
|
||||||
{
|
|
||||||
private SnapGridComponent _snapGridComponent;
|
|
||||||
|
|
||||||
public override string Name => "SubFloorHide";
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
_snapGridComponent = Owner.GetComponent<SnapGridComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Startup()
|
|
||||||
{
|
|
||||||
base.Startup();
|
|
||||||
|
|
||||||
_snapGridComponent.OnPositionChanged += SnapGridOnPositionChanged;
|
|
||||||
Owner.EntityManager.RaiseEvent(Owner, new SubFloorHideDirtyEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
|
|
||||||
_snapGridComponent.OnPositionChanged -= SnapGridOnPositionChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SnapGridOnPositionChanged()
|
|
||||||
{
|
|
||||||
Owner.EntityManager.RaiseEvent(Owner, new SubFloorHideDirtyEvent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class SubFloorHideDirtyEvent : EntitySystemMessage
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.GameObjects.Components.Triggers;
|
|
||||||
using Robust.Client.Animations;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.GameObjects.Components.Animations;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Doors
|
|
||||||
{
|
|
||||||
public class TimerTriggerVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
private const string AnimationKey = "priming_animation";
|
|
||||||
|
|
||||||
private Animation PrimingAnimation;
|
|
||||||
|
|
||||||
public override void LoadData(YamlMappingNode node)
|
|
||||||
{
|
|
||||||
base.LoadData(node);
|
|
||||||
|
|
||||||
var countdownSound = node.GetNode("countdown_sound").AsString();
|
|
||||||
|
|
||||||
|
|
||||||
PrimingAnimation = new Animation { Length = TimeSpan.MaxValue };
|
|
||||||
{
|
|
||||||
var flick = new AnimationTrackSpriteFlick();
|
|
||||||
PrimingAnimation.AnimationTracks.Add(flick);
|
|
||||||
flick.LayerKey = TriggerVisualLayers.Base;
|
|
||||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame("primed", 0f));
|
|
||||||
|
|
||||||
var sound = new AnimationTrackPlaySound();
|
|
||||||
PrimingAnimation.AnimationTracks.Add(sound);
|
|
||||||
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(countdownSound, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void InitializeEntity(IEntity entity)
|
|
||||||
{
|
|
||||||
if (!entity.HasComponent<AnimationPlayerComponent>())
|
|
||||||
{
|
|
||||||
entity.AddComponent<AnimationPlayerComponent>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
var animPlayer = component.Owner.GetComponent<AnimationPlayerComponent>();
|
|
||||||
if (!component.TryGetData(TriggerVisuals.VisualState, out TriggerVisualState state))
|
|
||||||
{
|
|
||||||
state = TriggerVisualState.Unprimed;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case TriggerVisualState.Primed:
|
|
||||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
|
||||||
{
|
|
||||||
animPlayer.Play(PrimingAnimation, AnimationKey);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TriggerVisualState.Unprimed:
|
|
||||||
sprite.LayerSetState(0, "icon");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public enum TriggerVisualLayers
|
|
||||||
{
|
|
||||||
Base
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
|
||||||
using Content.Shared.Utility;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Weapons.Ranged
|
|
||||||
{
|
|
||||||
public sealed class BallisticMagazineVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
private string _baseState;
|
|
||||||
private int _steps;
|
|
||||||
|
|
||||||
public override void LoadData(YamlMappingNode node)
|
|
||||||
{
|
|
||||||
base.LoadData(node);
|
|
||||||
|
|
||||||
_baseState = node.GetNode("base_state").AsString();
|
|
||||||
_steps = node.GetNode("steps").AsInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
|
|
||||||
if (!component.TryGetData(BallisticMagazineVisuals.AmmoCapacity, out int capacity))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!component.TryGetData(BallisticMagazineVisuals.AmmoLeft, out int current))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var step = ContentHelpers.RoundToLevels(current, capacity, _steps);
|
|
||||||
|
|
||||||
sprite.LayerSetState(0, $"{_baseState}-{step}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
|
||||||
using Content.Shared.Utility;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Weapons.Ranged
|
|
||||||
{
|
|
||||||
public sealed class BallisticMagazineWeaponVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
private string _baseState;
|
|
||||||
private int _steps;
|
|
||||||
|
|
||||||
public override void LoadData(YamlMappingNode node)
|
|
||||||
{
|
|
||||||
base.LoadData(node);
|
|
||||||
|
|
||||||
_baseState = node.GetNode("base_state").AsString();
|
|
||||||
_steps = node.GetNode("steps").AsInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
|
|
||||||
component.TryGetData(BallisticMagazineWeaponVisuals.MagazineLoaded, out bool loaded);
|
|
||||||
|
|
||||||
if (loaded)
|
|
||||||
{
|
|
||||||
if (!component.TryGetData(BallisticMagazineWeaponVisuals.AmmoCapacity, out int capacity))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!component.TryGetData(BallisticMagazineWeaponVisuals.AmmoLeft, out int current))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var step = ContentHelpers.RoundToLevels(current, capacity, _steps);
|
|
||||||
|
|
||||||
sprite.LayerSetState(0, $"{_baseState}-{step}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite.LayerSetState(0, _baseState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Timing;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Weapons.Ranged
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed class ClientRangedWeaponComponent : SharedRangedWeaponComponent
|
|
||||||
{
|
|
||||||
private TimeSpan _lastFireTime;
|
|
||||||
private int _tick;
|
|
||||||
|
|
||||||
public void TryFire(GridCoordinates worldPos)
|
|
||||||
{
|
|
||||||
var curTime = IoCManager.Resolve<IGameTiming>().CurTime;
|
|
||||||
var span = curTime - _lastFireTime;
|
|
||||||
if (span.TotalSeconds < 1 / FireRate)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastFireTime = curTime;
|
|
||||||
SendNetworkMessage(new FireMessage(worldPos, _tick++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
using Content.Shared.GameObjects.Components.Power;
|
|
||||||
using Content.Shared.Utility;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Power
|
|
||||||
{
|
|
||||||
public class HitscanWeaponVisualizer2D : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
private string _prefix;
|
|
||||||
|
|
||||||
public override void LoadData(YamlMappingNode node)
|
|
||||||
{
|
|
||||||
base.LoadData(node);
|
|
||||||
|
|
||||||
_prefix = node.GetNode("prefix").AsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
|
||||||
if (component.TryGetData(PowerCellVisuals.ChargeLevel, out float fraction))
|
|
||||||
{
|
|
||||||
sprite.LayerSetState(0, $"{_prefix}_{ContentHelpers.RoundToLevels(fraction, 1, 5) * 25}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
using Content.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
using static Content.Client.GameObjects.Components.IconSmoothing.IconSmoothComponent;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed class WindowComponent : Component
|
|
||||||
{
|
|
||||||
public override string Name => "Window";
|
|
||||||
|
|
||||||
private string _stateBase;
|
|
||||||
private ISpriteComponent _sprite;
|
|
||||||
private SnapGridComponent _snapGrid;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
_sprite = Owner.GetComponent<ISpriteComponent>();
|
|
||||||
_snapGrid = Owner.GetComponent<SnapGridComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Startup()
|
|
||||||
{
|
|
||||||
base.Startup();
|
|
||||||
|
|
||||||
_snapGrid.OnPositionChanged += SnapGridOnPositionChanged;
|
|
||||||
Owner.EntityManager.RaiseEvent(Owner, new WindowSmoothDirtyEvent());
|
|
||||||
|
|
||||||
var state0 = $"{_stateBase}0";
|
|
||||||
_sprite.LayerMapSet(CornerLayers.SE, _sprite.AddLayerState(state0));
|
|
||||||
_sprite.LayerSetDirOffset(CornerLayers.SE, SpriteComponent.DirectionOffset.None);
|
|
||||||
_sprite.LayerMapSet(CornerLayers.NE, _sprite.AddLayerState(state0));
|
|
||||||
_sprite.LayerSetDirOffset(CornerLayers.NE, SpriteComponent.DirectionOffset.CounterClockwise);
|
|
||||||
_sprite.LayerMapSet(CornerLayers.NW, _sprite.AddLayerState(state0));
|
|
||||||
_sprite.LayerSetDirOffset(CornerLayers.NW, SpriteComponent.DirectionOffset.Flip);
|
|
||||||
_sprite.LayerMapSet(CornerLayers.SW, _sprite.AddLayerState(state0));
|
|
||||||
_sprite.LayerSetDirOffset(CornerLayers.SW, SpriteComponent.DirectionOffset.Clockwise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
_snapGrid.OnPositionChanged -= SnapGridOnPositionChanged;
|
|
||||||
|
|
||||||
base.Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SnapGridOnPositionChanged()
|
|
||||||
{
|
|
||||||
Owner.EntityManager.RaiseEvent(Owner, new WindowSmoothDirtyEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateSprite()
|
|
||||||
{
|
|
||||||
var lowWall = FindLowWall();
|
|
||||||
if (lowWall == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_sprite.LayerSetState(CornerLayers.NE, $"{_stateBase}{(int) lowWall.LastCornerNE}");
|
|
||||||
_sprite.LayerSetState(CornerLayers.SE, $"{_stateBase}{(int) lowWall.LastCornerSE}");
|
|
||||||
_sprite.LayerSetState(CornerLayers.SW, $"{_stateBase}{(int) lowWall.LastCornerSW}");
|
|
||||||
_sprite.LayerSetState(CornerLayers.NW, $"{_stateBase}{(int) lowWall.LastCornerNW}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private LowWallComponent FindLowWall()
|
|
||||||
{
|
|
||||||
foreach (var entity in _snapGrid.GetLocal())
|
|
||||||
{
|
|
||||||
if (entity.TryGetComponent(out LowWallComponent lowWall))
|
|
||||||
{
|
|
||||||
return lowWall;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
|
||||||
{
|
|
||||||
base.ExposeData(serializer);
|
|
||||||
|
|
||||||
serializer.DataField(ref _stateBase, "base", null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using Content.Client.GameObjects.Components.Mobs;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
public sealed class CameraRecoilSystem : EntitySystem
|
|
||||||
{
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
EntityQuery = new TypeEntityQuery(typeof(CameraRecoilComponent));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void FrameUpdate(float frameTime)
|
|
||||||
{
|
|
||||||
base.FrameUpdate(frameTime);
|
|
||||||
|
|
||||||
foreach (var entity in RelevantEntities)
|
|
||||||
{
|
|
||||||
var recoil = entity.GetComponent<CameraRecoilComponent>();
|
|
||||||
recoil.FrameUpdate(frameTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
using Content.Client.GameObjects.Components.Actor;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
public sealed class CharacterInterfaceSystem : EntitySystem
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
var inputSys = EntitySystemManager.GetEntitySystem<InputSystem>();
|
|
||||||
inputSys.BindMap.BindFunction(ContentKeyFunctions.OpenCharacterMenu,
|
|
||||||
InputCmdHandler.FromDelegate(s => HandleOpenCharacterMenu()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleOpenCharacterMenu()
|
|
||||||
{
|
|
||||||
if (_playerManager.LocalPlayer.ControlledEntity == null
|
|
||||||
|| !_playerManager.LocalPlayer.ControlledEntity.TryGetComponent(out CharacterInterface characterInterface))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var menu = characterInterface.Window;
|
|
||||||
|
|
||||||
if (menu == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menu.IsOpen)
|
|
||||||
{
|
|
||||||
if (menu.IsAtFront())
|
|
||||||
{
|
|
||||||
_setOpenValue(menu, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
menu.MoveToFront();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_setOpenValue(menu, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _setOpenValue(SS14Window menu, bool value)
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
_gameHud.CharacterButtonDown = true;
|
|
||||||
menu.OpenCentered();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gameHud.CharacterButtonDown = false;
|
|
||||||
menu.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
public sealed class ClientInventorySystem : EntitySystem
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
var inputSys = EntitySystemManager.GetEntitySystem<InputSystem>();
|
|
||||||
inputSys.BindMap.BindFunction(ContentKeyFunctions.OpenInventoryMenu,
|
|
||||||
InputCmdHandler.FromDelegate(s => HandleOpenInventoryMenu()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleOpenInventoryMenu()
|
|
||||||
{
|
|
||||||
if (_playerManager.LocalPlayer.ControlledEntity == null
|
|
||||||
|| !_playerManager.LocalPlayer.ControlledEntity.TryGetComponent(out ClientInventoryComponent clientInventory))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var menu = clientInventory.InterfaceController.Window;
|
|
||||||
|
|
||||||
if (menu.IsOpen)
|
|
||||||
{
|
|
||||||
if (menu.IsAtFront())
|
|
||||||
{
|
|
||||||
_setOpenValue(menu, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
menu.MoveToFront();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_setOpenValue(menu, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _setOpenValue(SS14Window menu, bool value)
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
_gameHud.InventoryButtonDown = true;
|
|
||||||
menu.OpenCentered();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gameHud.InventoryButtonDown = false;
|
|
||||||
menu.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
public class ClientNotifySystem
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
using Content.Client.Construction;
|
|
||||||
using Content.Client.GameObjects.Components.Construction;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
public sealed class ConstructorSystem : EntitySystem
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
var inputSys = EntitySystemManager.GetEntitySystem<InputSystem>();
|
|
||||||
inputSys.BindMap.BindFunction(ContentKeyFunctions.OpenCraftingMenu,
|
|
||||||
new PointerInputCmdHandler(HandleOpenCraftingMenu));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleOpenCraftingMenu(in PointerInputCmdHandler.PointerInputCmdArgs args)
|
|
||||||
{
|
|
||||||
if (_playerManager.LocalPlayer.ControlledEntity == null
|
|
||||||
|| !_playerManager.LocalPlayer.ControlledEntity.TryGetComponent(out ConstructorComponent constructor))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var menu = constructor.ConstructionMenu;
|
|
||||||
|
|
||||||
if (menu.IsOpen)
|
|
||||||
{
|
|
||||||
if (menu.IsAtFront())
|
|
||||||
{
|
|
||||||
_setOpenValue(menu, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
menu.MoveToFront();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_setOpenValue(menu, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _setOpenValue(ConstructionMenu menu, bool value)
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
_gameHud.CraftingButtonDown = true;
|
|
||||||
menu.OpenCentered();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gameHud.CraftingButtonDown = false;
|
|
||||||
menu.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Content.Shared.GameObjects.EntitySystemMessages;
|
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.Interfaces.UserInterface;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Players;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
[UsedImplicitly]
|
|
||||||
internal sealed class ExamineSystem : ExamineSystemShared
|
|
||||||
{
|
|
||||||
public const string StyleClassEntityTooltip = "entity-tooltip";
|
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private IInputManager _inputManager;
|
|
||||||
[Dependency] private IUserInterfaceManager _userInterfaceManager;
|
|
||||||
[Dependency] private IEntityManager _entityManager;
|
|
||||||
[Dependency] private IPlayerManager _playerManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private Popup _examineTooltipOpen;
|
|
||||||
private CancellationTokenSource _requestCancelTokenSource;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
var inputSys = EntitySystemManager.GetEntitySystem<InputSystem>();
|
|
||||||
inputSys.BindMap.BindFunction(ContentKeyFunctions.ExamineEntity, new PointerInputCmdHandler(HandleExamine));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RegisterMessageTypes()
|
|
||||||
{
|
|
||||||
base.RegisterMessageTypes();
|
|
||||||
|
|
||||||
RegisterMessageType<ExamineSystemMessages.ExamineInfoResponseMessage>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleExamine(ICommonSession session, GridCoordinates coords, EntityUid uid)
|
|
||||||
{
|
|
||||||
if (!uid.IsValid() || !_entityManager.TryGetEntity(uid, out var examined))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var playerEntity = _playerManager.LocalPlayer.ControlledEntity;
|
|
||||||
|
|
||||||
if (playerEntity == null || !CanExamine(playerEntity, examined))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DoExamine(examined);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async void DoExamine(IEntity entity)
|
|
||||||
{
|
|
||||||
CloseTooltip();
|
|
||||||
|
|
||||||
var mousePos = _inputManager.MouseScreenPosition;
|
|
||||||
|
|
||||||
// Actually open the tooltip.
|
|
||||||
_examineTooltipOpen = new Popup();
|
|
||||||
_userInterfaceManager.StateRoot.AddChild(_examineTooltipOpen);
|
|
||||||
var panel = new PanelContainer();
|
|
||||||
panel.AddStyleClass(StyleClassEntityTooltip);
|
|
||||||
panel.ModulateSelfOverride = Color.LightGray.WithAlpha(0.90f);
|
|
||||||
_examineTooltipOpen.AddChild(panel);
|
|
||||||
panel.SetAnchorAndMarginPreset(Control.LayoutPreset.Wide);
|
|
||||||
var vBox = new VBoxContainer();
|
|
||||||
panel.AddChild(vBox);
|
|
||||||
var hBox = new HBoxContainer { SeparationOverride = 5};
|
|
||||||
vBox.AddChild(hBox);
|
|
||||||
if (entity.TryGetComponent(out ISpriteComponent sprite))
|
|
||||||
{
|
|
||||||
hBox.AddChild(new SpriteView {Sprite = sprite});
|
|
||||||
}
|
|
||||||
|
|
||||||
hBox.AddChild(new Label
|
|
||||||
{
|
|
||||||
Text = entity.Name,
|
|
||||||
SizeFlagsHorizontal = Control.SizeFlags.FillExpand,
|
|
||||||
});
|
|
||||||
|
|
||||||
const float minWidth = 300;
|
|
||||||
var size = Vector2.ComponentMax((minWidth, 0), panel.CombinedMinimumSize);
|
|
||||||
_examineTooltipOpen.Open(UIBox2.FromDimensions(mousePos, size));
|
|
||||||
|
|
||||||
if (entity.Uid.IsClientSide())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask server for extra examine info.
|
|
||||||
RaiseNetworkEvent(new ExamineSystemMessages.RequestExamineInfoMessage(entity.Uid));
|
|
||||||
|
|
||||||
ExamineSystemMessages.ExamineInfoResponseMessage response;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_requestCancelTokenSource = new CancellationTokenSource();
|
|
||||||
response =
|
|
||||||
await AwaitNetMessage<ExamineSystemMessages.ExamineInfoResponseMessage>(_requestCancelTokenSource
|
|
||||||
.Token);
|
|
||||||
}
|
|
||||||
catch (TaskCanceledException)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_requestCancelTokenSource = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var richLabel = new RichTextLabel();
|
|
||||||
richLabel.SetMessage(response.Message);
|
|
||||||
vBox.AddChild(richLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CloseTooltip()
|
|
||||||
{
|
|
||||||
if (_examineTooltipOpen != null)
|
|
||||||
{
|
|
||||||
_examineTooltipOpen.Dispose();
|
|
||||||
_examineTooltipOpen = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_requestCancelTokenSource != null)
|
|
||||||
{
|
|
||||||
_requestCancelTokenSource.Cancel();
|
|
||||||
_requestCancelTokenSource = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Client.GameObjects.Components.IconSmoothing;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Map;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Entity system implementing the logic for <see cref="IconSmoothComponent"/>
|
|
||||||
/// </summary>
|
|
||||||
[UsedImplicitly]
|
|
||||||
internal sealed class IconSmoothSystem : EntitySystem
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IMapManager _mapManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private readonly Queue<IEntity> _dirtyEntities = new Queue<IEntity>();
|
|
||||||
|
|
||||||
private int _generation;
|
|
||||||
|
|
||||||
public override void SubscribeEvents()
|
|
||||||
{
|
|
||||||
base.SubscribeEvents();
|
|
||||||
|
|
||||||
SubscribeEvent<IconSmoothDirtyEvent>(HandleDirtyEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void FrameUpdate(float frameTime)
|
|
||||||
{
|
|
||||||
base.FrameUpdate(frameTime);
|
|
||||||
|
|
||||||
if (_dirtyEntities.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_generation += 1;
|
|
||||||
|
|
||||||
// Performance: This could be spread over multiple updates, or made parallel.
|
|
||||||
while (_dirtyEntities.Count > 0)
|
|
||||||
{
|
|
||||||
CalculateNewSprite(_dirtyEntities.Dequeue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleDirtyEvent(object sender, IconSmoothDirtyEvent ev)
|
|
||||||
{
|
|
||||||
// Yes, we updates ALL smoothing entities surrounding us even if they would never smooth with us.
|
|
||||||
// This is simpler to implement. If you want to optimize it be my guest.
|
|
||||||
if (sender is IEntity senderEnt && senderEnt.IsValid() &&
|
|
||||||
senderEnt.HasComponent<IconSmoothComponent>())
|
|
||||||
{
|
|
||||||
var snapGrid = senderEnt.GetComponent<SnapGridComponent>();
|
|
||||||
|
|
||||||
_dirtyEntities.Enqueue(senderEnt);
|
|
||||||
AddValidEntities(snapGrid.GetInDir(Direction.North));
|
|
||||||
AddValidEntities(snapGrid.GetInDir(Direction.South));
|
|
||||||
AddValidEntities(snapGrid.GetInDir(Direction.East));
|
|
||||||
AddValidEntities(snapGrid.GetInDir(Direction.West));
|
|
||||||
if (ev.Mode == IconSmoothingMode.Corners)
|
|
||||||
{
|
|
||||||
|
|
||||||
AddValidEntities(snapGrid.GetInDir(Direction.NorthEast));
|
|
||||||
AddValidEntities(snapGrid.GetInDir(Direction.SouthEast));
|
|
||||||
AddValidEntities(snapGrid.GetInDir(Direction.SouthWest));
|
|
||||||
AddValidEntities(snapGrid.GetInDir(Direction.NorthWest));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ev.LastPosition.HasValue)
|
|
||||||
{
|
|
||||||
// Entity is no longer valid, update around the last position it was at.
|
|
||||||
var grid = _mapManager.GetGrid(ev.LastPosition.Value.grid);
|
|
||||||
var pos = ev.LastPosition.Value.pos;
|
|
||||||
|
|
||||||
AddValidEntities(grid.GetSnapGridCell(pos + new MapIndices(1, 0), ev.Offset));
|
|
||||||
AddValidEntities(grid.GetSnapGridCell(pos + new MapIndices(-1, 0), ev.Offset));
|
|
||||||
AddValidEntities(grid.GetSnapGridCell(pos + new MapIndices(0, 1), ev.Offset));
|
|
||||||
AddValidEntities(grid.GetSnapGridCell(pos + new MapIndices(0, -1), ev.Offset));
|
|
||||||
if (ev.Mode == IconSmoothingMode.Corners)
|
|
||||||
{
|
|
||||||
AddValidEntities(grid.GetSnapGridCell(pos + new MapIndices(1, 1), ev.Offset));
|
|
||||||
AddValidEntities(grid.GetSnapGridCell(pos + new MapIndices(-1, -1), ev.Offset));
|
|
||||||
AddValidEntities(grid.GetSnapGridCell(pos + new MapIndices(-1, 1), ev.Offset));
|
|
||||||
AddValidEntities(grid.GetSnapGridCell(pos + new MapIndices(1, -1), ev.Offset));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddValidEntities(IEnumerable<IEntity> candidates)
|
|
||||||
{
|
|
||||||
foreach (var entity in candidates)
|
|
||||||
{
|
|
||||||
if (entity.HasComponent<IconSmoothComponent>())
|
|
||||||
{
|
|
||||||
_dirtyEntities.Enqueue(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddValidEntities(IEnumerable<IComponent> candidates)
|
|
||||||
{
|
|
||||||
AddValidEntities(candidates.Select(c => c.Owner));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CalculateNewSprite(IEntity entity)
|
|
||||||
{
|
|
||||||
// The generation check prevents updating an entity multiple times per tick.
|
|
||||||
// As it stands now, it's totally possible for something to get queued twice.
|
|
||||||
// Generation on the component is set after an update so we can cull updates that happened this generation.
|
|
||||||
if (!entity.IsValid()
|
|
||||||
|| !entity.TryGetComponent(out IconSmoothComponent smoothing)
|
|
||||||
|| smoothing.UpdateGeneration == _generation)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
smoothing.CalculateNewSprite();
|
|
||||||
|
|
||||||
smoothing.UpdateGeneration = _generation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event raised by a <see cref="IconSmoothComponent"/> when it needs to be recalculated.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class IconSmoothDirtyEvent : EntitySystemMessage
|
|
||||||
{
|
|
||||||
public IconSmoothDirtyEvent((GridId grid, MapIndices pos)? lastPosition, SnapGridOffset offset, IconSmoothingMode mode)
|
|
||||||
{
|
|
||||||
LastPosition = lastPosition;
|
|
||||||
Offset = offset;
|
|
||||||
Mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public (GridId grid, MapIndices pos)? LastPosition { get; }
|
|
||||||
public SnapGridOffset Offset { get; }
|
|
||||||
public IconSmoothingMode Mode { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
using Content.Client.GameObjects.Components.Weapons.Ranged;
|
|
||||||
using Content.Client.Interfaces.GameObjects;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
public class RangedWeaponSystem : EntitySystem
|
|
||||||
{
|
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
|
||||||
[Dependency] private readonly IEyeManager _eyeManager;
|
|
||||||
[Dependency] private readonly IInputManager _inputManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private InputSystem _inputSystem;
|
|
||||||
private bool _isFirstShot;
|
|
||||||
private bool _blocked;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
_inputSystem = EntitySystemManager.GetEntitySystem<InputSystem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
|
||||||
{
|
|
||||||
base.Update(frameTime);
|
|
||||||
|
|
||||||
var canFireSemi = _isFirstShot;
|
|
||||||
var state = _inputSystem.CmdStates.GetState(ContentKeyFunctions.UseItemInHand);
|
|
||||||
if (state != BoundKeyState.Down)
|
|
||||||
{
|
|
||||||
_isFirstShot = true;
|
|
||||||
_blocked = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_isFirstShot = false;
|
|
||||||
|
|
||||||
var entity = _playerManager.LocalPlayer.ControlledEntity;
|
|
||||||
if (entity == null || !entity.TryGetComponent(out IHandsComponent hands))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var held = hands.ActiveHand;
|
|
||||||
if (held == null || !held.TryGetComponent(out ClientRangedWeaponComponent weapon))
|
|
||||||
{
|
|
||||||
_blocked = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_blocked)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var worldPos = _eyeManager.ScreenToWorld(_inputManager.MouseScreenPosition);
|
|
||||||
|
|
||||||
if (weapon.Automatic || canFireSemi)
|
|
||||||
{
|
|
||||||
weapon.TryFire(worldPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
using Content.Client.GameObjects.Components;
|
|
||||||
using Content.Shared.Maps;
|
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Map;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Entity system backing <see cref="SubFloorHideComponent"/>.
|
|
||||||
/// </summary>
|
|
||||||
internal sealed class SubFloorHideSystem : EntitySystem
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IMapManager _mapManager;
|
|
||||||
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
_mapManager.GridChanged += MapManagerOnGridChanged;
|
|
||||||
_mapManager.TileChanged += MapManagerOnTileChanged;
|
|
||||||
|
|
||||||
SubscribeEvent<SubFloorHideDirtyEvent>(HandleDirtyEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleDirtyEvent(object sender, SubFloorHideDirtyEvent ev)
|
|
||||||
{
|
|
||||||
if (!(sender is IEntity senderEnt))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var sprite = senderEnt.GetComponent<ISpriteComponent>();
|
|
||||||
var grid = _mapManager.GetGrid(senderEnt.Transform.GridID);
|
|
||||||
var position = senderEnt.Transform.GridPosition;
|
|
||||||
var tileRef = grid.GetTileRef(position);
|
|
||||||
var tileDef = (ContentTileDefinition) _tileDefinitionManager[tileRef.Tile.TypeId];
|
|
||||||
sprite.Visible = tileDef.IsSubFloor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MapManagerOnTileChanged(object sender, TileChangedEventArgs e)
|
|
||||||
{
|
|
||||||
UpdateTile(_mapManager.GetGrid(e.NewTile.GridIndex), e.NewTile.GridIndices);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MapManagerOnGridChanged(object sender, GridChangedEventArgs e)
|
|
||||||
{
|
|
||||||
foreach (var modified in e.Modified)
|
|
||||||
{
|
|
||||||
UpdateTile(e.Grid, modified.position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateTile(IMapGrid grid, MapIndices position)
|
|
||||||
{
|
|
||||||
var tile = grid.GetTileRef(position);
|
|
||||||
var tileDef = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
|
|
||||||
foreach (var snapGridComponent in grid.GetSnapGridCell(position, SnapGridOffset.Center))
|
|
||||||
{
|
|
||||||
var entity = snapGridComponent.Owner;
|
|
||||||
if (!entity.HasComponent<SubFloorHideComponent>() ||
|
|
||||||
!entity.TryGetComponent(out ISpriteComponent spriteComponent))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
spriteComponent.Visible = tileDef.IsSubFloor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,235 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Shared.GameObjects;
|
|
||||||
using Content.Shared.GameObjects.EntitySystemMessages;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.Interfaces.State;
|
|
||||||
using Robust.Client.Interfaces.UserInterface;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Client.State.States;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
public class VerbSystem : EntitySystem
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IStateManager _stateManager;
|
|
||||||
[Dependency] private readonly IEntityManager _entityManager;
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
|
||||||
[Dependency] private readonly IInputManager _inputManager;
|
|
||||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private Popup _currentPopup;
|
|
||||||
private EntityUid _currentEntity;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
var input = EntitySystemManager.GetEntitySystem<InputSystem>();
|
|
||||||
input.BindMap.BindFunction(ContentKeyFunctions.OpenContextMenu,
|
|
||||||
new PointerInputCmdHandler(OnOpenContextMenu));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RegisterMessageTypes()
|
|
||||||
{
|
|
||||||
base.RegisterMessageTypes();
|
|
||||||
|
|
||||||
RegisterMessageType<VerbSystemMessages.VerbsResponseMessage>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OpenContextMenu(IEntity entity, ScreenCoordinates screenCoordinates)
|
|
||||||
{
|
|
||||||
if (_currentPopup != null)
|
|
||||||
{
|
|
||||||
_closeContextMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentEntity = entity.Uid;
|
|
||||||
_currentPopup = new Popup();
|
|
||||||
_currentPopup.UserInterfaceManager.StateRoot.AddChild(_currentPopup);
|
|
||||||
_currentPopup.OnPopupHide += _closeContextMenu;
|
|
||||||
var vBox = new VBoxContainer("ButtonBox");
|
|
||||||
_currentPopup.AddChild(vBox);
|
|
||||||
|
|
||||||
vBox.AddChild(new Label {Text = "Waiting on Server..."});
|
|
||||||
RaiseNetworkEvent(new VerbSystemMessages.RequestVerbsMessage(_currentEntity));
|
|
||||||
|
|
||||||
var size = vBox.CombinedMinimumSize;
|
|
||||||
var box = UIBox2.FromDimensions(screenCoordinates.Position, size);
|
|
||||||
_currentPopup.Open(box);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnOpenContextMenu(in PointerInputCmdHandler.PointerInputCmdArgs args)
|
|
||||||
{
|
|
||||||
if (_currentPopup != null)
|
|
||||||
{
|
|
||||||
_closeContextMenu();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(_stateManager.CurrentState is GameScreen gameScreen))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var entities = gameScreen.GetEntitiesUnderPosition(args.Coordinates);
|
|
||||||
|
|
||||||
_currentPopup = new Popup();
|
|
||||||
_currentPopup.OnPopupHide += _closeContextMenu;
|
|
||||||
var vBox = new VBoxContainer("ButtonBox");
|
|
||||||
_currentPopup.AddChild(vBox);
|
|
||||||
foreach (var entity in entities)
|
|
||||||
{
|
|
||||||
var button = new Button {Text = entity.Name};
|
|
||||||
vBox.AddChild(button);
|
|
||||||
button.OnPressed += _ => OnContextButtonPressed(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentPopup.UserInterfaceManager.StateRoot.AddChild(_currentPopup);
|
|
||||||
|
|
||||||
var size = vBox.CombinedMinimumSize;
|
|
||||||
var box = UIBox2.FromDimensions(args.ScreenCoordinates.Position, size);
|
|
||||||
_currentPopup.Open(box);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnContextButtonPressed(IEntity entity)
|
|
||||||
{
|
|
||||||
OpenContextMenu(entity, new ScreenCoordinates(_inputManager.MouseScreenPosition));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleNetMessage(INetChannel channel, EntitySystemMessage message)
|
|
||||||
{
|
|
||||||
base.HandleNetMessage(channel, message);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case VerbSystemMessages.VerbsResponseMessage resp:
|
|
||||||
_fillEntityPopup(resp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _fillEntityPopup(VerbSystemMessages.VerbsResponseMessage msg)
|
|
||||||
{
|
|
||||||
if (_currentEntity != msg.Entity || !_entityManager.TryGetEntity(_currentEntity, out var entity))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugTools.AssertNotNull(_currentPopup);
|
|
||||||
|
|
||||||
var buttons = new List<Button>();
|
|
||||||
|
|
||||||
var vBox = _currentPopup.GetChild<VBoxContainer>("ButtonBox");
|
|
||||||
vBox.DisposeAllChildren();
|
|
||||||
foreach (var data in msg.Verbs)
|
|
||||||
{
|
|
||||||
var button = new Button {Text = data.Text, Disabled = !data.Available};
|
|
||||||
if (data.Available)
|
|
||||||
{
|
|
||||||
button.OnPressed += _ =>
|
|
||||||
{
|
|
||||||
RaiseNetworkEvent(new VerbSystemMessages.UseVerbMessage(_currentEntity, data.Key));
|
|
||||||
_closeContextMenu();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons.Add(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
var user = GetUserEntity();
|
|
||||||
foreach (var (component, verb) in VerbUtility.GetVerbs(entity))
|
|
||||||
{
|
|
||||||
if (verb.RequireInteractionRange)
|
|
||||||
{
|
|
||||||
var distanceSquared = (user.Transform.WorldPosition - entity.Transform.WorldPosition)
|
|
||||||
.LengthSquared;
|
|
||||||
if (distanceSquared > Verb.InteractionRangeSquared)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var disabled = verb.GetVisibility(user, component) != VerbVisibility.Visible;
|
|
||||||
var button = new Button
|
|
||||||
{
|
|
||||||
Text = verb.GetText(user, component),
|
|
||||||
Disabled = disabled
|
|
||||||
};
|
|
||||||
if (!disabled)
|
|
||||||
{
|
|
||||||
button.OnPressed += _ =>
|
|
||||||
{
|
|
||||||
_closeContextMenu();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
verb.Activate(user, component);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.ErrorS("verb", "Exception in verb {0} on {1}:\n{2}", verb, entity, e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons.Add(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buttons.Count > 0)
|
|
||||||
{
|
|
||||||
buttons.Sort((a, b) => string.Compare(a.Text, b.Text, StringComparison.Ordinal));
|
|
||||||
|
|
||||||
foreach (var button in buttons)
|
|
||||||
{
|
|
||||||
vBox.AddChild(button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var panel = new PanelContainer();
|
|
||||||
panel.AddChild(new Label {Text = "No verbs!"});
|
|
||||||
vBox.AddChild(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentPopup.Size = vBox.CombinedMinimumSize;
|
|
||||||
|
|
||||||
// If we're at the bottom of the window and the menu would go below the bottom of the window,
|
|
||||||
// shift it up so it extends UP.
|
|
||||||
var bottomCoord = vBox.CombinedMinimumSize.Y + _currentPopup.Position.Y;
|
|
||||||
if (bottomCoord > _userInterfaceManager.StateRoot.Size.Y)
|
|
||||||
{
|
|
||||||
_currentPopup.Position = _currentPopup.Position - new Vector2(0, vBox.CombinedMinimumSize.Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _closeContextMenu()
|
|
||||||
{
|
|
||||||
_currentPopup?.Dispose();
|
|
||||||
_currentPopup = null;
|
|
||||||
_currentEntity = EntityUid.Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEntity GetUserEntity()
|
|
||||||
{
|
|
||||||
return _playerManager.LocalPlayer.ControlledEntity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.GameObjects.Components;
|
|
||||||
using Content.Client.GameObjects.Components.IconSmoothing;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
[UsedImplicitly]
|
|
||||||
public sealed class WindowSystem : EntitySystem
|
|
||||||
{
|
|
||||||
private readonly Queue<IEntity> _dirtyEntities = new Queue<IEntity>();
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
SubscribeEvent<WindowSmoothDirtyEvent>(HandleDirtyEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleDirtyEvent(object sender, WindowSmoothDirtyEvent ev)
|
|
||||||
{
|
|
||||||
if (sender is IEntity senderEnt && senderEnt.HasComponent<WindowComponent>())
|
|
||||||
{
|
|
||||||
_dirtyEntities.Enqueue(senderEnt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void FrameUpdate(float frameTime)
|
|
||||||
{
|
|
||||||
base.FrameUpdate(frameTime);
|
|
||||||
|
|
||||||
// Performance: This could be spread over multiple updates, or made parallel.
|
|
||||||
while (_dirtyEntities.Count > 0)
|
|
||||||
{
|
|
||||||
_dirtyEntities.Dequeue().GetComponent<WindowComponent>().UpdateSprite();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event raised by a <see cref="WindowComponent"/> when it needs to be recalculated.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class WindowSmoothDirtyEvent : EntitySystemMessage
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,270 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Client.Chat;
|
|
||||||
using Content.Client.Interfaces;
|
|
||||||
using Content.Client.Interfaces.Chat;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client;
|
|
||||||
using Robust.Client.Console;
|
|
||||||
using Robust.Client.Interfaces;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.Interfaces.UserInterface;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Client.GameTicking
|
|
||||||
{
|
|
||||||
public class ClientGameTicker : SharedGameTicker, IClientGameTicker
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private IClientNetManager _netManager;
|
|
||||||
[Dependency] private IUserInterfaceManager _userInterfaceManager;
|
|
||||||
[Dependency] private IInputManager _inputManager;
|
|
||||||
[Dependency] private IBaseClient _baseClient;
|
|
||||||
[Dependency] private IChatManager _chatManager;
|
|
||||||
[Dependency] private IClientConsole _console;
|
|
||||||
[Dependency] private ILocalizationManager _localization;
|
|
||||||
[Dependency] private IResourceCache _resourceCache;
|
|
||||||
[Dependency] private IPlayerManager _playerManager;
|
|
||||||
[Dependency] private IGameHud _gameHud;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
[ViewVariables] private bool _areWeReady;
|
|
||||||
[ViewVariables] private bool _initialized;
|
|
||||||
[ViewVariables] private TickerState _tickerState;
|
|
||||||
[ViewVariables] private ChatBox _gameChat;
|
|
||||||
[ViewVariables] private LobbyGui _lobby;
|
|
||||||
[ViewVariables] private bool _gameStarted;
|
|
||||||
[ViewVariables] private DateTime _startTime;
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
DebugTools.Assert(!_initialized);
|
|
||||||
|
|
||||||
_netManager.RegisterNetMessage<MsgTickerJoinLobby>(nameof(MsgTickerJoinLobby), _joinLobby);
|
|
||||||
_netManager.RegisterNetMessage<MsgTickerJoinGame>(nameof(MsgTickerJoinGame), _joinGame);
|
|
||||||
_netManager.RegisterNetMessage<MsgTickerLobbyStatus>(nameof(MsgTickerLobbyStatus), _lobbyStatus);
|
|
||||||
|
|
||||||
_baseClient.RunLevelChanged += BaseClientOnRunLevelChanged;
|
|
||||||
_playerManager.PlayerListUpdated += PlayerManagerOnPlayerListUpdated;
|
|
||||||
|
|
||||||
_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PlayerManagerOnPlayerListUpdated(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (_lobby == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_updatePlayerList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _updatePlayerList()
|
|
||||||
{
|
|
||||||
_lobby.OnlinePlayerItemList.Clear();
|
|
||||||
foreach (var session in _playerManager.Sessions.OrderBy(s => s.Name))
|
|
||||||
{
|
|
||||||
_lobby.OnlinePlayerItemList.AddItem(session.Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BaseClientOnRunLevelChanged(object sender, RunLevelChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.NewLevel != ClientRunLevel.Initialize)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_tickerState = TickerState.Unset;
|
|
||||||
_lobby?.Dispose();
|
|
||||||
_lobby = null;
|
|
||||||
_gameChat?.Dispose();
|
|
||||||
_gameChat = null;
|
|
||||||
_gameHud.RootControl.Orphan();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FrameUpdate(RenderFrameEventArgs renderFrameEventArgs)
|
|
||||||
{
|
|
||||||
if (_lobby == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_gameStarted)
|
|
||||||
{
|
|
||||||
_lobby.StartTime.Text = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string text;
|
|
||||||
var difference = _startTime - DateTime.UtcNow;
|
|
||||||
if (difference.Ticks < 0)
|
|
||||||
{
|
|
||||||
if (difference.TotalSeconds < -5)
|
|
||||||
{
|
|
||||||
text = _localization.GetString("Right Now?");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
text = _localization.GetString("Right Now");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
text = $"{(int) Math.Floor(difference.TotalMinutes)}:{difference.Seconds:D2}";
|
|
||||||
}
|
|
||||||
|
|
||||||
_lobby.StartTime.Text = _localization.GetString("Round Starts In: {0}", text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _lobbyStatus(MsgTickerLobbyStatus message)
|
|
||||||
{
|
|
||||||
_startTime = message.StartTime;
|
|
||||||
_gameStarted = message.IsRoundStarted;
|
|
||||||
_areWeReady = message.YouAreReady;
|
|
||||||
|
|
||||||
_updateLobbyUi();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _updateLobbyUi()
|
|
||||||
{
|
|
||||||
if (_lobby == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_gameStarted)
|
|
||||||
{
|
|
||||||
_lobby.ReadyButton.Text = _localization.GetString("Join");
|
|
||||||
_lobby.ReadyButton.ToggleMode = false;
|
|
||||||
_lobby.ReadyButton.Pressed = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_lobby.StartTime.Text = "";
|
|
||||||
_lobby.ReadyButton.Text = _localization.GetString("Ready Up");
|
|
||||||
_lobby.ReadyButton.ToggleMode = true;
|
|
||||||
_lobby.ReadyButton.Pressed = _areWeReady;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _joinLobby(MsgTickerJoinLobby message)
|
|
||||||
{
|
|
||||||
if (_tickerState == TickerState.InLobby)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_gameChat != null)
|
|
||||||
{
|
|
||||||
_gameChat.Dispose();
|
|
||||||
_gameChat = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gameHud.RootControl.Orphan();
|
|
||||||
|
|
||||||
_tickerState = TickerState.InLobby;
|
|
||||||
|
|
||||||
_lobby = new LobbyGui(_localization, _resourceCache);
|
|
||||||
_userInterfaceManager.StateRoot.AddChild(_lobby);
|
|
||||||
|
|
||||||
_lobby.SetAnchorAndMarginPreset(Control.LayoutPreset.Wide, margin: 20);
|
|
||||||
|
|
||||||
_chatManager.SetChatBox(_lobby.Chat);
|
|
||||||
_lobby.Chat.DefaultChatFormat = "ooc \"{0}\"";
|
|
||||||
|
|
||||||
_lobby.ServerName.Text = _baseClient.GameInfo.ServerName;
|
|
||||||
|
|
||||||
_inputManager.SetInputCommand(ContentKeyFunctions.FocusChat,
|
|
||||||
InputCmdHandler.FromDelegate(session =>
|
|
||||||
{
|
|
||||||
_lobby.Chat.Input.IgnoreNext = true;
|
|
||||||
_lobby.Chat.Input.GrabKeyboardFocus();
|
|
||||||
}));
|
|
||||||
|
|
||||||
_updateLobbyUi();
|
|
||||||
|
|
||||||
_lobby.ObserveButton.OnPressed += args => _console.ProcessCommand("observe");
|
|
||||||
_lobby.ReadyButton.OnPressed += args =>
|
|
||||||
{
|
|
||||||
if (!_gameStarted)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_console.ProcessCommand("joingame");
|
|
||||||
};
|
|
||||||
|
|
||||||
_lobby.ReadyButton.OnToggled += args =>
|
|
||||||
{
|
|
||||||
if (_gameStarted)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_console.ProcessCommand($"toggleready {args.Pressed}");
|
|
||||||
};
|
|
||||||
|
|
||||||
_lobby.LeaveButton.OnPressed += args => _console.ProcessCommand("disconnect");
|
|
||||||
|
|
||||||
_updatePlayerList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _joinGame(MsgTickerJoinGame message)
|
|
||||||
{
|
|
||||||
if (_tickerState == TickerState.InGame)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_tickerState = TickerState.InGame;
|
|
||||||
|
|
||||||
if (_lobby != null)
|
|
||||||
{
|
|
||||||
_lobby.Dispose();
|
|
||||||
_lobby = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_inputManager.SetInputCommand(ContentKeyFunctions.FocusChat,
|
|
||||||
InputCmdHandler.FromDelegate(session =>
|
|
||||||
{
|
|
||||||
_gameChat.Input.IgnoreNext = true;
|
|
||||||
_gameChat.Input.GrabKeyboardFocus();
|
|
||||||
}));
|
|
||||||
|
|
||||||
_gameChat = new ChatBox();
|
|
||||||
_userInterfaceManager.StateRoot.AddChild(_gameChat);
|
|
||||||
_userInterfaceManager.StateRoot.AddChild(_gameHud.RootControl);
|
|
||||||
_chatManager.SetChatBox(_gameChat);
|
|
||||||
_gameChat.DefaultChatFormat = "say \"{0}\"";
|
|
||||||
_gameChat.Input.PlaceHolder = _localization.GetString("Say something! [ for OOC");
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum TickerState
|
|
||||||
{
|
|
||||||
Unset = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The client is in the lobby.
|
|
||||||
/// </summary>
|
|
||||||
InLobby = 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The client is NOT in the lobby.
|
|
||||||
/// Do not confuse this with the client session status.
|
|
||||||
/// </summary>
|
|
||||||
InGame = 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Graphics.Overlays;
|
|
||||||
using Robust.Client.Graphics.Shaders;
|
|
||||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
|
||||||
using Robust.Client.Interfaces.Graphics.Overlays;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.Graphics.Overlays
|
|
||||||
{
|
|
||||||
public class CircleMaskOverlay : Overlay
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
|
||||||
[Dependency] private readonly IEyeManager _eyeManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
|
||||||
|
|
||||||
public CircleMaskOverlay() : base(nameof(CircleMaskOverlay))
|
|
||||||
{
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
Shader = _prototypeManager.Index<ShaderPrototype>("circlemask").Instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Draw(DrawingHandleBase handle)
|
|
||||||
{
|
|
||||||
var worldHandle = (DrawingHandleWorld)handle;
|
|
||||||
var viewport = _eyeManager.GetWorldViewport();
|
|
||||||
worldHandle.DrawRect(viewport, Color.White);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Graphics.Overlays;
|
|
||||||
using Robust.Client.Graphics.Shaders;
|
|
||||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
|
||||||
using Robust.Client.Interfaces.Graphics.Overlays;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.Graphics.Overlays
|
|
||||||
{
|
|
||||||
public class GradientCircleMask : Overlay
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
|
||||||
[Dependency] private readonly IEyeManager _eyeManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
|
||||||
|
|
||||||
public GradientCircleMask() : base(nameof(GradientCircleMask))
|
|
||||||
{
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
Shader = _prototypeManager.Index<ShaderPrototype>("gradientcirclemask").Instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Draw(DrawingHandleBase handle)
|
|
||||||
{
|
|
||||||
var worldHandle = (DrawingHandleWorld)handle;
|
|
||||||
var viewport = _eyeManager.GetWorldViewport();
|
|
||||||
worldHandle.DrawRect(viewport, Color.White);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
|
|
||||||
namespace Content.Client.Input
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Contains a helper function for setting up all content
|
|
||||||
/// contexts, and modifying existing engine ones.
|
|
||||||
/// </summary>
|
|
||||||
public static class ContentContexts
|
|
||||||
{
|
|
||||||
public static void SetupContexts(IInputContextContainer contexts)
|
|
||||||
{
|
|
||||||
var common = contexts.GetContext("common");
|
|
||||||
common.AddFunction(ContentKeyFunctions.FocusChat);
|
|
||||||
common.AddFunction(ContentKeyFunctions.ExamineEntity);
|
|
||||||
common.AddFunction(ContentKeyFunctions.OpenTutorial);
|
|
||||||
|
|
||||||
var human = contexts.GetContext("human");
|
|
||||||
human.AddFunction(ContentKeyFunctions.SwapHands);
|
|
||||||
human.AddFunction(ContentKeyFunctions.Drop);
|
|
||||||
human.AddFunction(ContentKeyFunctions.ActivateItemInHand);
|
|
||||||
human.AddFunction(ContentKeyFunctions.OpenCharacterMenu);
|
|
||||||
human.AddFunction(ContentKeyFunctions.UseItemInHand);
|
|
||||||
human.AddFunction(ContentKeyFunctions.ActivateItemInWorld);
|
|
||||||
human.AddFunction(ContentKeyFunctions.ThrowItemInHand);
|
|
||||||
human.AddFunction(ContentKeyFunctions.OpenContextMenu);
|
|
||||||
human.AddFunction(ContentKeyFunctions.OpenCraftingMenu);
|
|
||||||
human.AddFunction(ContentKeyFunctions.OpenInventoryMenu);
|
|
||||||
// Disabled until there is feedback, so hitting tab doesn't suddenly break interaction.
|
|
||||||
// human.AddFunction(ContentKeyFunctions.ToggleCombatMode);
|
|
||||||
|
|
||||||
var ghost = contexts.New("ghost", "common");
|
|
||||||
ghost.AddFunction(EngineKeyFunctions.MoveUp);
|
|
||||||
ghost.AddFunction(EngineKeyFunctions.MoveDown);
|
|
||||||
ghost.AddFunction(EngineKeyFunctions.MoveLeft);
|
|
||||||
ghost.AddFunction(EngineKeyFunctions.MoveRight);
|
|
||||||
ghost.AddFunction(EngineKeyFunctions.Run);
|
|
||||||
ghost.AddFunction(ContentKeyFunctions.OpenContextMenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using Content.Client.Chat;
|
|
||||||
using Robust.Client;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Client.Interfaces.Chat
|
|
||||||
{
|
|
||||||
public interface IChatManager
|
|
||||||
{
|
|
||||||
void Initialize();
|
|
||||||
|
|
||||||
void FrameUpdate(RenderFrameEventArgs delta);
|
|
||||||
|
|
||||||
void SetChatBox(ChatBox chatBox);
|
|
||||||
|
|
||||||
void RemoveSpeechBubble(EntityUid entityUid, SpeechBubble bubble);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Robust.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
namespace Content.Client.Interfaces.GameObjects
|
namespace Content.Client.Interfaces.GameObjects
|
||||||
{
|
{
|
||||||
@@ -8,9 +8,7 @@ namespace Content.Client.Interfaces.GameObjects
|
|||||||
{
|
{
|
||||||
IEntity GetEntity(string index);
|
IEntity GetEntity(string index);
|
||||||
string ActiveIndex { get; }
|
string ActiveIndex { get; }
|
||||||
IEntity ActiveHand { get; }
|
|
||||||
|
|
||||||
void SendChangeHand(string index);
|
void SendChangeHand(string index);
|
||||||
void AttackByInHand(string index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
using Content.Client.UserInterface;
|
|
||||||
using Robust.Client;
|
|
||||||
|
|
||||||
namespace Content.Client.Interfaces
|
|
||||||
{
|
|
||||||
public interface IClientGameTicker
|
|
||||||
{
|
|
||||||
void Initialize();
|
|
||||||
void FrameUpdate(RenderFrameEventArgs renderFrameEventArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using Content.Shared.Interfaces;
|
|
||||||
using Robust.Client;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
|
|
||||||
namespace Content.Client.Interfaces
|
|
||||||
{
|
|
||||||
public interface IClientNotifyManager : ISharedNotifyManager
|
|
||||||
{
|
|
||||||
void Initialize();
|
|
||||||
void PopupMessage(ScreenCoordinates coordinates, string message);
|
|
||||||
void PopupMessage(string message);
|
|
||||||
void FrameUpdate(RenderFrameEventArgs eventArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
|
|
||||||
namespace Content.Client.Interfaces.Parallax
|
|
||||||
{
|
|
||||||
public interface IParallaxManager
|
|
||||||
{
|
|
||||||
event Action<Texture> OnTextureLoaded;
|
|
||||||
Texture ParallaxTexture { get; }
|
|
||||||
void LoadParallax();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,418 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using Nett;
|
|
||||||
using SixLabors.ImageSharp;
|
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
|
||||||
using SixLabors.Primitives;
|
|
||||||
using Robust.Client.Utility;
|
|
||||||
using Robust.Shared.Interfaces.Log;
|
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Noise;
|
|
||||||
using BlendFactor = Robust.Shared.Maths.Color.BlendFactor;
|
|
||||||
|
|
||||||
namespace Content.Client.Parallax
|
|
||||||
{
|
|
||||||
public class ParallaxGenerator
|
|
||||||
{
|
|
||||||
private readonly List<Layer> Layers = new List<Layer>();
|
|
||||||
|
|
||||||
public static Image<Rgba32> GenerateParallax(TomlTable config, Size size, ISawmill sawmill)
|
|
||||||
{
|
|
||||||
sawmill.Debug("Generating parallax!");
|
|
||||||
var generator = new ParallaxGenerator();
|
|
||||||
generator._loadConfig(config);
|
|
||||||
|
|
||||||
var image = new Image<Rgba32>(Configuration.Default, size.Width, size.Height, Rgba32.Black);
|
|
||||||
var count = 0;
|
|
||||||
foreach (var layer in generator.Layers)
|
|
||||||
{
|
|
||||||
layer.Apply(image);
|
|
||||||
sawmill.Debug("Layer {0} done!", count++);
|
|
||||||
}
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _loadConfig(TomlTable config)
|
|
||||||
{
|
|
||||||
foreach (var layerArray in config.Get<TomlTableArray>("layers").Items)
|
|
||||||
{
|
|
||||||
var layer = layerArray.Get<TomlTable>();
|
|
||||||
switch (layer.Get<string>("type"))
|
|
||||||
{
|
|
||||||
case "noise":
|
|
||||||
var layerNoise = new LayerNoise(layer);
|
|
||||||
Layers.Add(layerNoise);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "points":
|
|
||||||
var layerPoint = new LayerPoints(layer);
|
|
||||||
Layers.Add(layerPoint);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private abstract class Layer
|
|
||||||
{
|
|
||||||
public abstract void Apply(Image<Rgba32> bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LayerNoise : Layer
|
|
||||||
{
|
|
||||||
private readonly Color InnerColor = Color.White;
|
|
||||||
private readonly Color OuterColor = Color.Black;
|
|
||||||
private readonly NoiseGenerator.NoiseType NoiseType = NoiseGenerator.NoiseType.Fbm;
|
|
||||||
private readonly uint Seed = 1234;
|
|
||||||
private readonly double Persistence = 0.5;
|
|
||||||
private readonly double Lacunarity = Math.PI * 2 / 3;
|
|
||||||
private readonly double Frequency = 1;
|
|
||||||
private readonly uint Octaves = 3;
|
|
||||||
private readonly double Threshold;
|
|
||||||
private readonly double Power = 1;
|
|
||||||
private readonly BlendFactor SrcFactor = BlendFactor.One;
|
|
||||||
private readonly BlendFactor DstFactor = BlendFactor.One;
|
|
||||||
|
|
||||||
public LayerNoise(TomlTable table)
|
|
||||||
{
|
|
||||||
if (table.TryGetValue("innercolor", out var tomlObject))
|
|
||||||
{
|
|
||||||
InnerColor = Color.FromHex(tomlObject.Get<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("outercolor", out tomlObject))
|
|
||||||
{
|
|
||||||
OuterColor = Color.FromHex(tomlObject.Get<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("seed", out tomlObject))
|
|
||||||
{
|
|
||||||
Seed = (uint) tomlObject.Get<int>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("persistence", out tomlObject))
|
|
||||||
{
|
|
||||||
Persistence = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("lacunarity", out tomlObject))
|
|
||||||
{
|
|
||||||
Lacunarity = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("frequency", out tomlObject))
|
|
||||||
{
|
|
||||||
Frequency = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("octaves", out tomlObject))
|
|
||||||
{
|
|
||||||
Octaves = (uint) tomlObject.Get<int>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("threshold", out tomlObject))
|
|
||||||
{
|
|
||||||
Threshold = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("sourcefactor", out tomlObject))
|
|
||||||
{
|
|
||||||
SrcFactor = (BlendFactor) Enum.Parse(typeof(BlendFactor), tomlObject.Get<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("destfactor", out tomlObject))
|
|
||||||
{
|
|
||||||
DstFactor = (BlendFactor) Enum.Parse(typeof(BlendFactor), tomlObject.Get<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("power", out tomlObject))
|
|
||||||
{
|
|
||||||
Power = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("noise_type", out tomlObject))
|
|
||||||
{
|
|
||||||
switch (tomlObject.Get<string>())
|
|
||||||
{
|
|
||||||
case "fbm":
|
|
||||||
NoiseType = NoiseGenerator.NoiseType.Fbm;
|
|
||||||
break;
|
|
||||||
case "ridged":
|
|
||||||
NoiseType = NoiseGenerator.NoiseType.Ridged;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Apply(Image<Rgba32> bitmap)
|
|
||||||
{
|
|
||||||
var noise = new NoiseGenerator(NoiseType);
|
|
||||||
noise.SetSeed(Seed);
|
|
||||||
noise.SetFrequency(Frequency);
|
|
||||||
noise.SetPersistence(Persistence);
|
|
||||||
noise.SetLacunarity(Lacunarity);
|
|
||||||
noise.SetOctaves(Octaves);
|
|
||||||
noise.SetPeriodX(bitmap.Width);
|
|
||||||
noise.SetPeriodY(bitmap.Height);
|
|
||||||
var threshVal = 1 / (1 - Threshold);
|
|
||||||
var powFactor = 1 / Power;
|
|
||||||
for (var x = 0; x < bitmap.Width; x++)
|
|
||||||
{
|
|
||||||
for (var y = 0; y < bitmap.Height; y++)
|
|
||||||
{
|
|
||||||
// Do noise calculations.
|
|
||||||
var noiseVal = Math.Min(1, Math.Max(0, (noise.GetNoiseTiled(x, y) + 1) / 2));
|
|
||||||
|
|
||||||
// Threshold
|
|
||||||
noiseVal = Math.Max(0, noiseVal - Threshold);
|
|
||||||
noiseVal *= threshVal;
|
|
||||||
noiseVal = Math.Pow(noiseVal, powFactor);
|
|
||||||
|
|
||||||
// Get colors based on noise values.
|
|
||||||
var srcColor = Color.InterpolateBetween(InnerColor, OuterColor, (float) noiseVal)
|
|
||||||
.WithAlpha((float) noiseVal);
|
|
||||||
|
|
||||||
// Apply blending factors & write back.
|
|
||||||
var dstColor = bitmap[x, y].ConvertImgSharp();
|
|
||||||
bitmap[x, y] = Color.Blend(dstColor, srcColor, DstFactor, SrcFactor).ConvertImgSharp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LayerPoints : Layer
|
|
||||||
{
|
|
||||||
private readonly int Seed = 1234;
|
|
||||||
private readonly int PointCount = 100;
|
|
||||||
|
|
||||||
private readonly Color CloseColor = Color.White;
|
|
||||||
private readonly Color FarColor = Color.Black;
|
|
||||||
|
|
||||||
private readonly BlendFactor SrcFactor = BlendFactor.One;
|
|
||||||
private readonly BlendFactor DstFactor = BlendFactor.One;
|
|
||||||
|
|
||||||
// Noise mask stuff.
|
|
||||||
private readonly bool Masked;
|
|
||||||
private readonly NoiseGenerator.NoiseType MaskNoiseType = NoiseGenerator.NoiseType.Fbm;
|
|
||||||
private readonly uint MaskSeed = 1234;
|
|
||||||
private readonly double MaskPersistence = 0.5;
|
|
||||||
private readonly double MaskLacunarity = Math.PI * 2 / 3;
|
|
||||||
private readonly double MaskFrequency = 1;
|
|
||||||
private readonly uint MaskOctaves = 3;
|
|
||||||
private readonly double MaskThreshold;
|
|
||||||
private readonly int PointSize = 1;
|
|
||||||
private readonly double MaskPower = 1;
|
|
||||||
|
|
||||||
|
|
||||||
public LayerPoints(TomlTable table)
|
|
||||||
{
|
|
||||||
if (table.TryGetValue("seed", out var tomlObject))
|
|
||||||
{
|
|
||||||
Seed = tomlObject.Get<int>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("count", out tomlObject))
|
|
||||||
{
|
|
||||||
PointCount = tomlObject.Get<int>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("sourcefactor", out tomlObject))
|
|
||||||
{
|
|
||||||
SrcFactor = (BlendFactor) Enum.Parse(typeof(BlendFactor), tomlObject.Get<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("destfactor", out tomlObject))
|
|
||||||
{
|
|
||||||
DstFactor = (BlendFactor) Enum.Parse(typeof(BlendFactor), tomlObject.Get<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("farcolor", out tomlObject))
|
|
||||||
{
|
|
||||||
FarColor = Color.FromHex(tomlObject.Get<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("closecolor", out tomlObject))
|
|
||||||
{
|
|
||||||
CloseColor = Color.FromHex(tomlObject.Get<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("pointsize", out tomlObject))
|
|
||||||
{
|
|
||||||
PointSize = tomlObject.Get<int>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Noise mask stuff.
|
|
||||||
if (table.TryGetValue("mask", out tomlObject))
|
|
||||||
{
|
|
||||||
Masked = tomlObject.Get<bool>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("maskseed", out tomlObject))
|
|
||||||
{
|
|
||||||
MaskSeed = (uint) tomlObject.Get<int>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("maskpersistence", out tomlObject))
|
|
||||||
{
|
|
||||||
MaskPersistence = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("masklacunarity", out tomlObject))
|
|
||||||
{
|
|
||||||
MaskLacunarity = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("maskfrequency", out tomlObject))
|
|
||||||
{
|
|
||||||
MaskFrequency = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("maskoctaves", out tomlObject))
|
|
||||||
{
|
|
||||||
MaskOctaves = (uint) tomlObject.Get<int>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("maskthreshold", out tomlObject))
|
|
||||||
{
|
|
||||||
MaskThreshold = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("masknoise_type", out tomlObject))
|
|
||||||
{
|
|
||||||
switch (tomlObject.Get<string>())
|
|
||||||
{
|
|
||||||
case "fbm":
|
|
||||||
MaskNoiseType = NoiseGenerator.NoiseType.Fbm;
|
|
||||||
break;
|
|
||||||
case "ridged":
|
|
||||||
MaskNoiseType = NoiseGenerator.NoiseType.Ridged;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.TryGetValue("maskpower", out tomlObject))
|
|
||||||
{
|
|
||||||
MaskPower = double.Parse(tomlObject.Get<string>(), CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Apply(Image<Rgba32> bitmap)
|
|
||||||
{
|
|
||||||
// Temporary buffer so we don't mess up blending.
|
|
||||||
var buffer = new Image<Rgba32>(Configuration.Default, bitmap.Width, bitmap.Height, Rgba32.Black);
|
|
||||||
|
|
||||||
if (Masked)
|
|
||||||
{
|
|
||||||
GenPointsMasked(buffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GenPoints(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var x = 0; x < bitmap.Width; x++)
|
|
||||||
{
|
|
||||||
for (var y = 0; y < bitmap.Height; y++)
|
|
||||||
{
|
|
||||||
var dstColor = bitmap[x, y].ConvertImgSharp();
|
|
||||||
var srcColor = buffer[x, y].ConvertImgSharp();
|
|
||||||
|
|
||||||
bitmap[x, y] = Color.Blend(dstColor, srcColor, DstFactor, SrcFactor).ConvertImgSharp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GenPoints(Image<Rgba32> buffer)
|
|
||||||
{
|
|
||||||
var o = PointSize - 1;
|
|
||||||
var random = new Random(Seed);
|
|
||||||
for (var i = 0; i < PointCount; i++)
|
|
||||||
{
|
|
||||||
var relX = random.NextDouble();
|
|
||||||
var relY = random.NextDouble();
|
|
||||||
|
|
||||||
var x = (int) (relX * buffer.Width);
|
|
||||||
var y = (int) (relY * buffer.Height);
|
|
||||||
|
|
||||||
var dist = random.NextDouble();
|
|
||||||
|
|
||||||
for (var ox = x - o; ox <= x + o; ox++)
|
|
||||||
{
|
|
||||||
for (var oy = y - o; oy <= y + o; oy++)
|
|
||||||
{
|
|
||||||
var color = Color.InterpolateBetween(FarColor, CloseColor, (float) dist).ConvertImgSharp();
|
|
||||||
buffer[MathHelper.Mod(ox, buffer.Width), MathHelper.Mod(oy, buffer.Width)] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenPointsMasked(Image<Rgba32> buffer)
|
|
||||||
{
|
|
||||||
var o = PointSize - 1;
|
|
||||||
var random = new Random(Seed);
|
|
||||||
var noise = new NoiseGenerator(MaskNoiseType);
|
|
||||||
noise.SetSeed(MaskSeed);
|
|
||||||
noise.SetFrequency(MaskFrequency);
|
|
||||||
noise.SetPersistence(MaskPersistence);
|
|
||||||
noise.SetLacunarity(MaskLacunarity);
|
|
||||||
noise.SetOctaves(MaskOctaves);
|
|
||||||
noise.SetPeriodX(buffer.Width);
|
|
||||||
noise.SetPeriodY(buffer.Height);
|
|
||||||
|
|
||||||
var threshVal = 1 / (1 - MaskThreshold);
|
|
||||||
var powFactor = 1 / MaskPower;
|
|
||||||
|
|
||||||
const int maxPointAttemptCount = 9999;
|
|
||||||
var pointAttemptCount = 0;
|
|
||||||
|
|
||||||
for (var i = 0; i < PointCount; i++)
|
|
||||||
{
|
|
||||||
var relX = random.NextDouble();
|
|
||||||
var relY = random.NextDouble();
|
|
||||||
|
|
||||||
var x = (int) (relX * buffer.Width);
|
|
||||||
var y = (int) (relY * buffer.Height);
|
|
||||||
|
|
||||||
// Grab noise at this point.
|
|
||||||
var noiseVal = Math.Min(1, Math.Max(0, (noise.GetNoiseTiled(x, y) + 1) / 2));
|
|
||||||
// Threshold
|
|
||||||
noiseVal = Math.Max(0, noiseVal - MaskThreshold);
|
|
||||||
noiseVal *= threshVal;
|
|
||||||
noiseVal = Math.Pow(noiseVal, powFactor);
|
|
||||||
|
|
||||||
var randomThresh = random.NextDouble();
|
|
||||||
if (randomThresh > noiseVal)
|
|
||||||
{
|
|
||||||
if (++pointAttemptCount <= maxPointAttemptCount)
|
|
||||||
{
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var dist = random.NextDouble();
|
|
||||||
|
|
||||||
for (var ox = x - o; ox <= x + o; ox++)
|
|
||||||
{
|
|
||||||
for (var oy = y - o; oy <= y + o; oy++)
|
|
||||||
{
|
|
||||||
var color = Color.InterpolateBetween(FarColor, CloseColor, (float) dist).ConvertImgSharp();
|
|
||||||
buffer[MathHelper.Mod(ox, buffer.Width), MathHelper.Mod(oy, buffer.Height)] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Content.Client.Interfaces.Parallax;
|
|
||||||
using Nett;
|
|
||||||
using SixLabors.ImageSharp;
|
|
||||||
using SixLabors.Primitives;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Shared.Interfaces.Configuration;
|
|
||||||
using Robust.Shared.Interfaces.Log;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client.Parallax
|
|
||||||
{
|
|
||||||
internal sealed class ParallaxManager : IParallaxManager, IPostInjectInit
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
|
||||||
[Dependency] private readonly ILogManager _logManager;
|
|
||||||
[Dependency] private readonly IConfigurationManager _configurationManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private static readonly ResourcePath ParallaxConfigPath = new ResourcePath("/parallax_config.toml");
|
|
||||||
|
|
||||||
// Both of these below are in the user directory.
|
|
||||||
private static readonly ResourcePath ParallaxPath = new ResourcePath("/parallax_cache.png");
|
|
||||||
private static readonly ResourcePath ParallaxConfigOld = new ResourcePath("/parallax_config_old");
|
|
||||||
|
|
||||||
public event Action<Texture> OnTextureLoaded;
|
|
||||||
public Texture ParallaxTexture { get; private set; }
|
|
||||||
|
|
||||||
public async void LoadParallax()
|
|
||||||
{
|
|
||||||
if (!_configurationManager.GetCVar<bool>("parallax.enabled"))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryStream configStream = null;
|
|
||||||
string contents;
|
|
||||||
TomlTable table;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Load normal config into memory
|
|
||||||
if (!_resourceCache.TryContentFileRead(ParallaxConfigPath, out configStream))
|
|
||||||
{
|
|
||||||
Logger.ErrorS("parallax", "Parallax config not found.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var reader = new StreamReader(configStream, EncodingHelpers.UTF8))
|
|
||||||
{
|
|
||||||
contents = reader.ReadToEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_resourceCache.UserData.Exists(ParallaxConfigOld))
|
|
||||||
{
|
|
||||||
bool match;
|
|
||||||
using (var data = _resourceCache.UserData.Open(ParallaxConfigOld, FileMode.Open))
|
|
||||||
using (var reader = new StreamReader(data, EncodingHelpers.UTF8))
|
|
||||||
{
|
|
||||||
match = reader.ReadToEnd() == contents;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match)
|
|
||||||
{
|
|
||||||
using (var stream = _resourceCache.UserData.Open(ParallaxPath, FileMode.Open))
|
|
||||||
{
|
|
||||||
ParallaxTexture = Texture.LoadFromPNGStream(stream, "Parallax");
|
|
||||||
}
|
|
||||||
|
|
||||||
OnTextureLoaded?.Invoke(ParallaxTexture);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table = Toml.ReadString(contents);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
configStream?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
var sawmill = _logManager.GetSawmill("parallax");
|
|
||||||
// Generate the parallax in the thread pool.
|
|
||||||
var image = await Task.Run(() => ParallaxGenerator.GenerateParallax(table, new Size(1920, 1080), sawmill));
|
|
||||||
// And load it in the main thread for safety reasons.
|
|
||||||
ParallaxTexture = Texture.LoadFromImage(image, "Parallax");
|
|
||||||
|
|
||||||
// Store it and CRC so further game starts don't need to regenerate it.
|
|
||||||
using (var stream = _resourceCache.UserData.Open(ParallaxPath, FileMode.Create))
|
|
||||||
{
|
|
||||||
image.SaveAsPng(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var stream = _resourceCache.UserData.Open(ParallaxConfigOld, FileMode.Create))
|
|
||||||
using (var writer = new StreamWriter(stream, EncodingHelpers.UTF8))
|
|
||||||
{
|
|
||||||
writer.Write(contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnTextureLoaded?.Invoke(ParallaxTexture);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInject()
|
|
||||||
{
|
|
||||||
_configurationManager.RegisterCVar("parallax.enabled", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
using Content.Client.Interfaces.Parallax;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Graphics.Overlays;
|
|
||||||
using Robust.Client.Graphics.Shaders;
|
|
||||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
|
||||||
using Robust.Client.Interfaces.Graphics.Overlays;
|
|
||||||
using Robust.Shared.Interfaces.Map;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.Parallax
|
|
||||||
{
|
|
||||||
public class ParallaxOverlay : Overlay
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IParallaxManager _parallaxManager;
|
|
||||||
[Dependency] private readonly IEyeManager _eyeManager;
|
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
|
||||||
[Dependency] private readonly IMapManager _mapManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override bool AlwaysDirty => true;
|
|
||||||
private const float Slowness = 0.5f;
|
|
||||||
|
|
||||||
private Texture _parallaxTexture;
|
|
||||||
|
|
||||||
public override OverlaySpace Space => OverlaySpace.ScreenSpaceBelowWorld;
|
|
||||||
|
|
||||||
public ParallaxOverlay() : base(nameof(ParallaxOverlay))
|
|
||||||
{
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
Shader = _prototypeManager.Index<ShaderPrototype>("unshaded").Instance();
|
|
||||||
|
|
||||||
if (_parallaxManager.ParallaxTexture == null)
|
|
||||||
{
|
|
||||||
_parallaxManager.OnTextureLoaded += texture => _parallaxTexture = texture;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_parallaxTexture = _parallaxManager.ParallaxTexture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Draw(DrawingHandleBase handle)
|
|
||||||
{
|
|
||||||
if (_parallaxTexture == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var screenHandle = (DrawingHandleScreen) handle;
|
|
||||||
|
|
||||||
var (sizeX, sizeY) = _parallaxTexture.Size;
|
|
||||||
var (posX, posY) = _eyeManager.ScreenToWorld(Vector2.Zero).ToWorld(_mapManager).Position;
|
|
||||||
var (ox, oy) = (Vector2i) new Vector2(-posX / Slowness, posY / Slowness);
|
|
||||||
ox = MathHelper.Mod(ox, sizeX);
|
|
||||||
oy = MathHelper.Mod(oy, sizeY);
|
|
||||||
|
|
||||||
screenHandle.DrawTexture(_parallaxTexture, new Vector2(ox, oy));
|
|
||||||
screenHandle.DrawTexture(_parallaxTexture, new Vector2(ox - sizeX, oy));
|
|
||||||
screenHandle.DrawTexture(_parallaxTexture, new Vector2(ox, oy - sizeY));
|
|
||||||
screenHandle.DrawTexture(_parallaxTexture, new Vector2(ox - sizeX, oy - sizeY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
36
Content.Client/Properties/AssemblyInfo.cs
Normal file
36
Content.Client/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("Content.Client")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("Content.Client")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("a2e5f175-78af-4ddd-8f97-e2d2552372ed")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
@@ -1,251 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.GameObjects.Components.Research;
|
|
||||||
using Content.Shared.Materials;
|
|
||||||
using Content.Shared.Research;
|
|
||||||
using Robust.Client.Interfaces.Graphics;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Client.Utility;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.Timers;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client.Research
|
|
||||||
{
|
|
||||||
public class LatheMenu : SS14Window
|
|
||||||
{
|
|
||||||
#pragma warning disable CS0649
|
|
||||||
[Dependency]
|
|
||||||
private IPrototypeManager PrototypeManager;
|
|
||||||
#pragma warning restore
|
|
||||||
|
|
||||||
private ItemList Items;
|
|
||||||
private ItemList Materials;
|
|
||||||
private LineEdit AmountLineEdit;
|
|
||||||
private LineEdit SearchBar;
|
|
||||||
public Button QueueButton;
|
|
||||||
protected override Vector2? CustomSize => (300, 450);
|
|
||||||
|
|
||||||
public LatheBoundUserInterface Owner { get; set; }
|
|
||||||
|
|
||||||
private List<LatheRecipePrototype> _recipes = new List<LatheRecipePrototype>();
|
|
||||||
private List<LatheRecipePrototype> _shownRecipes = new List<LatheRecipePrototype>();
|
|
||||||
|
|
||||||
public LatheMenu()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public LatheMenu(string name) : base(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
Title = "Lathe Menu";
|
|
||||||
|
|
||||||
var margin = new MarginContainer()
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
MarginTop = 5f,
|
|
||||||
MarginLeft = 5f,
|
|
||||||
MarginRight = -5f,
|
|
||||||
MarginBottom = -5f,
|
|
||||||
};
|
|
||||||
|
|
||||||
margin.SetAnchorAndMarginPreset(LayoutPreset.Wide);
|
|
||||||
|
|
||||||
var vbox = new VBoxContainer()
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SeparationOverride = 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
vbox.SetAnchorAndMarginPreset(LayoutPreset.Wide);
|
|
||||||
|
|
||||||
var hboxButtons = new HBoxContainer()
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
QueueButton = new Button()
|
|
||||||
{
|
|
||||||
Text = "Queue",
|
|
||||||
TextAlign = Button.AlignMode.Center,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
var spacer = new Control()
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
spacer.SetAnchorAndMarginPreset(LayoutPreset.Wide);
|
|
||||||
|
|
||||||
var hboxFilter = new HBoxContainer()
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
SearchBar = new LineEdit()
|
|
||||||
{
|
|
||||||
PlaceHolder = "Search Designs",
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
SearchBar.OnTextChanged += Populate;
|
|
||||||
|
|
||||||
var filterButton = new Button()
|
|
||||||
{
|
|
||||||
Text = "Filter",
|
|
||||||
TextAlign = Button.AlignMode.Center,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 1,
|
|
||||||
Disabled = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
Items = new ItemList()
|
|
||||||
{
|
|
||||||
SizeFlagsStretchRatio = 8,
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Items.OnItemSelected += ItemSelected;
|
|
||||||
|
|
||||||
AmountLineEdit = new LineEdit()
|
|
||||||
{
|
|
||||||
PlaceHolder = "Amount",
|
|
||||||
Text = "1",
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
};
|
|
||||||
|
|
||||||
AmountLineEdit.OnTextChanged += PopulateDisabled;
|
|
||||||
|
|
||||||
Materials = new ItemList()
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
hboxButtons.AddChild(spacer);
|
|
||||||
hboxButtons.AddChild(QueueButton);
|
|
||||||
|
|
||||||
hboxFilter.AddChild(SearchBar);
|
|
||||||
hboxFilter.AddChild(filterButton);
|
|
||||||
|
|
||||||
vbox.AddChild(hboxButtons);
|
|
||||||
vbox.AddChild(hboxFilter);
|
|
||||||
vbox.AddChild(Items);
|
|
||||||
vbox.AddChild(AmountLineEdit);
|
|
||||||
vbox.AddChild(Materials);
|
|
||||||
|
|
||||||
margin.AddChild(vbox);
|
|
||||||
|
|
||||||
Contents.AddChild(margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ItemSelected(ItemList.ItemListSelectedEventArgs args)
|
|
||||||
{
|
|
||||||
int.TryParse(AmountLineEdit.Text, out var quantity);
|
|
||||||
if (quantity <= 0) quantity = 1;
|
|
||||||
Owner.Queue(_shownRecipes[args.ItemIndex], quantity);
|
|
||||||
Items.SelectMode = ItemList.ItemListSelectMode.None;
|
|
||||||
Timer.Spawn(100, () =>
|
|
||||||
{
|
|
||||||
Items.Unselect(args.ItemIndex);
|
|
||||||
Items.SelectMode = ItemList.ItemListSelectMode.Single;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PopulateMaterials()
|
|
||||||
{
|
|
||||||
Materials.Clear();
|
|
||||||
|
|
||||||
foreach (var (id, amount) in Owner.Storage)
|
|
||||||
{
|
|
||||||
if (!PrototypeManager.TryIndex(id, out MaterialPrototype materialPrototype)) continue;
|
|
||||||
var material = materialPrototype.Material;
|
|
||||||
Materials.AddItem($"{material.Name} {amount} cm³", material.Icon.Frame0(), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disables or enables shown recipes depending on whether there are enough materials for it or not.
|
|
||||||
/// </summary>
|
|
||||||
public void PopulateDisabled()
|
|
||||||
{
|
|
||||||
int.TryParse(AmountLineEdit.Text, out var quantity);
|
|
||||||
if (quantity <= 0) quantity = 1;
|
|
||||||
for (var i = 0; i < _shownRecipes.Count; i++)
|
|
||||||
{
|
|
||||||
var prototype = _shownRecipes[i];
|
|
||||||
Items.SetItemDisabled(i, !Owner.Lathe.CanProduce(prototype, quantity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="PopulateDisabled()"/>
|
|
||||||
public void PopulateDisabled(LineEdit.LineEditEventArgs args)
|
|
||||||
{
|
|
||||||
PopulateDisabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds shown recipes to the ItemList control.
|
|
||||||
/// </summary>
|
|
||||||
public void PopulateList()
|
|
||||||
{
|
|
||||||
Items.Clear();
|
|
||||||
for (var i = 0; i < _shownRecipes.Count; i++)
|
|
||||||
{
|
|
||||||
var prototype = _shownRecipes[i];
|
|
||||||
Items.AddItem(prototype.Name, prototype.Icon.Frame0());
|
|
||||||
}
|
|
||||||
|
|
||||||
PopulateDisabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Populates the list of recipes that will actually be shown, using the current filters.
|
|
||||||
/// </summary>
|
|
||||||
public void Populate()
|
|
||||||
{
|
|
||||||
_shownRecipes.Clear();
|
|
||||||
|
|
||||||
foreach (var prototype in Owner.Database)
|
|
||||||
{
|
|
||||||
if (SearchBar.Text.Trim().Length != 0)
|
|
||||||
{
|
|
||||||
if (prototype.Name.ToLowerInvariant().Contains(SearchBar.Text.Trim().ToLowerInvariant()))
|
|
||||||
_shownRecipes.Add(prototype);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_shownRecipes.Add(prototype);
|
|
||||||
}
|
|
||||||
|
|
||||||
PopulateList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Populate"/>
|
|
||||||
public void Populate(LineEdit.LineEditEventArgs args)
|
|
||||||
{
|
|
||||||
Populate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
using Content.Client.GameObjects.Components.Research;
|
|
||||||
using Content.Shared.Research;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Interfaces.Graphics;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Client.Utility;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Client.Research
|
|
||||||
{
|
|
||||||
public class LatheQueueMenu : SS14Window
|
|
||||||
{
|
|
||||||
protected override Vector2? CustomSize => (300, 450);
|
|
||||||
|
|
||||||
public LatheBoundUserInterface Owner { get; set; }
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private ItemList QueueList;
|
|
||||||
private Label NameLabel;
|
|
||||||
private Label Description;
|
|
||||||
private TextureRect Icon;
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
Title = "Lathe Queue";
|
|
||||||
|
|
||||||
var margin = new MarginContainer()
|
|
||||||
{
|
|
||||||
MarginTop = 5f,
|
|
||||||
MarginLeft = 5f,
|
|
||||||
MarginRight = -5f,
|
|
||||||
MarginBottom = -5f,
|
|
||||||
};
|
|
||||||
|
|
||||||
margin.SetAnchorAndMarginPreset(LayoutPreset.Wide);
|
|
||||||
|
|
||||||
var vbox = new VBoxContainer();
|
|
||||||
|
|
||||||
vbox.SetAnchorAndMarginPreset(LayoutPreset.Wide);
|
|
||||||
|
|
||||||
var descMargin = new MarginContainer()
|
|
||||||
{
|
|
||||||
MarginTop = 5f,
|
|
||||||
MarginLeft = 5f,
|
|
||||||
MarginRight = -5f,
|
|
||||||
MarginBottom = -5f,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
var hbox = new HBoxContainer()
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
};
|
|
||||||
|
|
||||||
Icon = new TextureRect()
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
var vboxInfo = new VBoxContainer()
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
NameLabel = new Label()
|
|
||||||
{
|
|
||||||
RectClipContent = true,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.Fill,
|
|
||||||
};
|
|
||||||
|
|
||||||
Description = new Label()
|
|
||||||
{
|
|
||||||
RectClipContent = true,
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.Fill,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
QueueList = new ItemList()
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.Fill,
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
SizeFlagsStretchRatio = 3,
|
|
||||||
SelectMode = ItemList.ItemListSelectMode.None
|
|
||||||
};
|
|
||||||
|
|
||||||
vboxInfo.AddChild(NameLabel);
|
|
||||||
vboxInfo.AddChild(Description);
|
|
||||||
|
|
||||||
hbox.AddChild(Icon);
|
|
||||||
hbox.AddChild(vboxInfo);
|
|
||||||
|
|
||||||
descMargin.AddChild(hbox);
|
|
||||||
|
|
||||||
vbox.AddChild(descMargin);
|
|
||||||
vbox.AddChild(QueueList);
|
|
||||||
|
|
||||||
margin.AddChild(vbox);
|
|
||||||
|
|
||||||
Contents.AddChild(margin);
|
|
||||||
|
|
||||||
ClearInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetInfo(LatheRecipePrototype recipe)
|
|
||||||
{
|
|
||||||
Icon.Texture = recipe.Icon.Frame0();
|
|
||||||
if (recipe.Name != null)
|
|
||||||
NameLabel.Text = recipe.Name;
|
|
||||||
if (recipe.Description != null)
|
|
||||||
Description.Text = recipe.Description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearInfo()
|
|
||||||
{
|
|
||||||
Icon.Texture = Texture.Transparent;
|
|
||||||
NameLabel.Text = "-------";
|
|
||||||
Description.Text = "Not producing anything.";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PopulateList()
|
|
||||||
{
|
|
||||||
QueueList.Clear();
|
|
||||||
var idx = 1;
|
|
||||||
foreach (var recipe in Owner.QueuedRecipes)
|
|
||||||
{
|
|
||||||
QueueList.AddItem($"{idx}. {recipe.Name}", recipe.Icon.Frame0(), false);
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
using Robust.Client.Console;
|
|
||||||
using Robust.Client.Interfaces.Graphics;
|
|
||||||
using Robust.Client.Interfaces.Placement;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.Interfaces.Configuration;
|
|
||||||
using Robust.Shared.Interfaces.Map;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
|
||||||
{
|
|
||||||
internal sealed class EscapeMenu : SS14Window
|
|
||||||
{
|
|
||||||
private readonly IClientConsole _console;
|
|
||||||
private readonly ITileDefinitionManager __tileDefinitionManager;
|
|
||||||
private readonly IPlacementManager _placementManager;
|
|
||||||
private readonly IPrototypeManager _prototypeManager;
|
|
||||||
private readonly IResourceCache _resourceCache;
|
|
||||||
private readonly IConfigurationManager _configSystem;
|
|
||||||
private readonly ILocalizationManager _localizationManager;
|
|
||||||
|
|
||||||
private BaseButton QuitButton;
|
|
||||||
private BaseButton OptionsButton;
|
|
||||||
private BaseButton SpawnEntitiesButton;
|
|
||||||
private BaseButton SpawnTilesButton;
|
|
||||||
private OptionsMenu optionsMenu;
|
|
||||||
|
|
||||||
public EscapeMenu(IClientConsole console,
|
|
||||||
ITileDefinitionManager tileDefinitionManager,
|
|
||||||
IPlacementManager placementManager,
|
|
||||||
IPrototypeManager prototypeManager,
|
|
||||||
IResourceCache resourceCache,
|
|
||||||
IConfigurationManager configSystem, ILocalizationManager localizationManager)
|
|
||||||
{
|
|
||||||
_configSystem = configSystem;
|
|
||||||
_localizationManager = localizationManager;
|
|
||||||
_console = console;
|
|
||||||
__tileDefinitionManager = tileDefinitionManager;
|
|
||||||
_placementManager = placementManager;
|
|
||||||
_prototypeManager = prototypeManager;
|
|
||||||
_resourceCache = resourceCache;
|
|
||||||
|
|
||||||
PerformLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PerformLayout()
|
|
||||||
{
|
|
||||||
optionsMenu = new OptionsMenu(_configSystem);
|
|
||||||
|
|
||||||
Resizable = false;
|
|
||||||
|
|
||||||
Title = "Menu";
|
|
||||||
|
|
||||||
var vBox = new VBoxContainer {SeparationOverride = 2};
|
|
||||||
Contents.AddChild(vBox);
|
|
||||||
|
|
||||||
SpawnEntitiesButton = new Button {Text = "Spawn Entities"};
|
|
||||||
SpawnEntitiesButton.OnPressed += OnSpawnEntitiesButtonClicked;
|
|
||||||
vBox.AddChild(SpawnEntitiesButton);
|
|
||||||
|
|
||||||
SpawnTilesButton = new Button {Text = "Spawn Tiles"};
|
|
||||||
SpawnTilesButton.OnPressed += OnSpawnTilesButtonClicked;
|
|
||||||
vBox.AddChild(SpawnTilesButton);
|
|
||||||
|
|
||||||
// Add a spacer.
|
|
||||||
vBox.AddChild(new Control { CustomMinimumSize = (0, 5)});
|
|
||||||
|
|
||||||
OptionsButton = new Button {Text = "Options"};
|
|
||||||
OptionsButton.OnPressed += OnOptionsButtonClicked;
|
|
||||||
vBox.AddChild(OptionsButton);
|
|
||||||
|
|
||||||
QuitButton = new Button {Text = "Quit"};
|
|
||||||
QuitButton.OnPressed += OnQuitButtonClicked;
|
|
||||||
vBox.AddChild(QuitButton);
|
|
||||||
|
|
||||||
Size = CombinedMinimumSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnQuitButtonClicked(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
_console.ProcessCommand("disconnect");
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnOptionsButtonClicked(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
optionsMenu.OpenCentered();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnSpawnEntitiesButtonClicked(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
var window = new EntitySpawnWindow(_placementManager, _prototypeManager, _resourceCache, _localizationManager);
|
|
||||||
window.OpenToLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnSpawnTilesButtonClicked(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
var window = new TileSpawnWindow(__tileDefinitionManager, _placementManager, _resourceCache);
|
|
||||||
window.OpenToLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
base.Dispose(disposing);
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
optionsMenu.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,391 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Content.Client.Utility;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Interfaces.Input;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Responsible for laying out the default game HUD.
|
|
||||||
/// </summary>
|
|
||||||
public interface IGameHud
|
|
||||||
{
|
|
||||||
Control RootControl { get; }
|
|
||||||
|
|
||||||
// Escape top button.
|
|
||||||
bool EscapeButtonDown { get; set; }
|
|
||||||
Action<bool> EscapeButtonToggled { get; set; }
|
|
||||||
|
|
||||||
// Character top button.
|
|
||||||
bool CharacterButtonDown { get; set; }
|
|
||||||
bool CharacterButtonVisible { get; set; }
|
|
||||||
Action<bool> CharacterButtonToggled { get; set; }
|
|
||||||
|
|
||||||
// Inventory top button.
|
|
||||||
bool InventoryButtonDown { get; set; }
|
|
||||||
bool InventoryButtonVisible { get; set; }
|
|
||||||
Action<bool> InventoryButtonToggled { get; set; }
|
|
||||||
|
|
||||||
// Crafting top button.
|
|
||||||
bool CraftingButtonDown { get; set; }
|
|
||||||
bool CraftingButtonVisible { get; set; }
|
|
||||||
Action<bool> CraftingButtonToggled { get; set; }
|
|
||||||
|
|
||||||
// Sandbox top button.
|
|
||||||
bool SandboxButtonDown { get; set; }
|
|
||||||
bool SandboxButtonVisible { get; set; }
|
|
||||||
Action<bool> SandboxButtonToggled { get; set; }
|
|
||||||
|
|
||||||
Control HandsContainer { get; }
|
|
||||||
Control InventoryQuickButtonContainer { get; }
|
|
||||||
|
|
||||||
// Init logic.
|
|
||||||
void Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class GameHud : IGameHud
|
|
||||||
{
|
|
||||||
private HBoxContainer _topButtonsContainer;
|
|
||||||
private TopButton _buttonEscapeMenu;
|
|
||||||
private TopButton _buttonTutorial;
|
|
||||||
private TopButton _buttonCharacterMenu;
|
|
||||||
private TopButton _buttonInventoryMenu;
|
|
||||||
private TopButton _buttonCraftingMenu;
|
|
||||||
private TopButton _buttonSandboxMenu;
|
|
||||||
private TutorialWindow _tutorialWindow;
|
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
|
||||||
[Dependency] private readonly ILocalizationManager _loc;
|
|
||||||
[Dependency] private readonly IInputManager _inputManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public Control HandsContainer { get; private set; }
|
|
||||||
public Control InventoryQuickButtonContainer { get; private set; }
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
RootControl = new Control {MouseFilter = Control.MouseFilterMode.Ignore};
|
|
||||||
|
|
||||||
RootControl.SetAnchorPreset(Control.LayoutPreset.Wide);
|
|
||||||
|
|
||||||
var escapeTexture = _resourceCache.GetTexture("/Textures/UserInterface/hamburger.svg.96dpi.png");
|
|
||||||
var characterTexture = _resourceCache.GetTexture("/Textures/UserInterface/character.svg.96dpi.png");
|
|
||||||
var inventoryTexture = _resourceCache.GetTexture("/Textures/UserInterface/inventory.svg.96dpi.png");
|
|
||||||
var craftingTexture = _resourceCache.GetTexture("/Textures/UserInterface/hammer.svg.96dpi.png");
|
|
||||||
var tutorialTexture = _resourceCache.GetTexture("/Textures/UserInterface/students-cap.svg.96dpi.png");
|
|
||||||
var sandboxTexture = _resourceCache.GetTexture("/Textures/UserInterface/sandbox.svg.96dpi.png");
|
|
||||||
|
|
||||||
_topButtonsContainer = new HBoxContainer
|
|
||||||
{
|
|
||||||
SeparationOverride = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
RootControl.AddChild(_topButtonsContainer);
|
|
||||||
_topButtonsContainer.SetAnchorAndMarginPreset(Control.LayoutPreset.TopLeft, margin: 10);
|
|
||||||
|
|
||||||
// TODO: Pull key names here from the actual key binding config.
|
|
||||||
// Escape
|
|
||||||
_buttonEscapeMenu = new TopButton(escapeTexture, "Esc")
|
|
||||||
{
|
|
||||||
ToolTip = _loc.GetString("Open escape menu.")
|
|
||||||
};
|
|
||||||
|
|
||||||
_topButtonsContainer.AddChild(_buttonEscapeMenu);
|
|
||||||
|
|
||||||
_buttonEscapeMenu.OnToggled += args => EscapeButtonToggled?.Invoke(args.Pressed);
|
|
||||||
|
|
||||||
// Tutorial
|
|
||||||
_buttonTutorial = new TopButton(tutorialTexture, "F1")
|
|
||||||
{
|
|
||||||
ToolTip = _loc.GetString("Open tutorial.")
|
|
||||||
};
|
|
||||||
|
|
||||||
_topButtonsContainer.AddChild(_buttonTutorial);
|
|
||||||
|
|
||||||
_buttonTutorial.OnToggled += a => ButtonTutorialOnOnToggled();
|
|
||||||
|
|
||||||
// Character
|
|
||||||
_buttonCharacterMenu = new TopButton(characterTexture, "C")
|
|
||||||
{
|
|
||||||
ToolTip = _loc.GetString("Open character menu."),
|
|
||||||
Visible = false
|
|
||||||
};
|
|
||||||
|
|
||||||
_topButtonsContainer.AddChild(_buttonCharacterMenu);
|
|
||||||
|
|
||||||
_buttonCharacterMenu.OnToggled += args => CharacterButtonToggled?.Invoke(args.Pressed);
|
|
||||||
|
|
||||||
// Inventory
|
|
||||||
_buttonInventoryMenu = new TopButton(inventoryTexture, "I")
|
|
||||||
{
|
|
||||||
ToolTip = _loc.GetString("Open inventory menu."),
|
|
||||||
Visible = false
|
|
||||||
};
|
|
||||||
|
|
||||||
_topButtonsContainer.AddChild(_buttonInventoryMenu);
|
|
||||||
|
|
||||||
_buttonInventoryMenu.OnToggled += args => InventoryButtonToggled?.Invoke(args.Pressed);
|
|
||||||
|
|
||||||
// Crafting
|
|
||||||
_buttonCraftingMenu = new TopButton(craftingTexture, "G")
|
|
||||||
{
|
|
||||||
ToolTip = _loc.GetString("Open crafting menu."),
|
|
||||||
Visible = false
|
|
||||||
};
|
|
||||||
|
|
||||||
_topButtonsContainer.AddChild(_buttonCraftingMenu);
|
|
||||||
|
|
||||||
_buttonCraftingMenu.OnToggled += args => CraftingButtonToggled?.Invoke(args.Pressed);
|
|
||||||
|
|
||||||
// Sandbox
|
|
||||||
_buttonSandboxMenu = new TopButton(sandboxTexture, "B")
|
|
||||||
{
|
|
||||||
ToolTip = _loc.GetString("Open sandbox menu."),
|
|
||||||
Visible = true
|
|
||||||
};
|
|
||||||
|
|
||||||
_topButtonsContainer.AddChild(_buttonSandboxMenu);
|
|
||||||
|
|
||||||
_buttonSandboxMenu.OnToggled += args => SandboxButtonToggled?.Invoke(args.Pressed);
|
|
||||||
|
|
||||||
_tutorialWindow = new TutorialWindow();
|
|
||||||
|
|
||||||
_tutorialWindow.OnClose += () => _buttonTutorial.Pressed = false;
|
|
||||||
|
|
||||||
_inputManager.SetInputCommand(ContentKeyFunctions.OpenTutorial,
|
|
||||||
InputCmdHandler.FromDelegate(s => ButtonTutorialOnOnToggled()));
|
|
||||||
|
|
||||||
var inventoryContainer = new HBoxContainer
|
|
||||||
{
|
|
||||||
GrowHorizontal = Control.GrowDirection.Begin,
|
|
||||||
GrowVertical = Control.GrowDirection.Begin,
|
|
||||||
SeparationOverride = 10
|
|
||||||
};
|
|
||||||
|
|
||||||
RootControl.AddChild(inventoryContainer);
|
|
||||||
inventoryContainer.SetAnchorAndMarginPreset(Control.LayoutPreset.BottomRight);
|
|
||||||
|
|
||||||
InventoryQuickButtonContainer = new MarginContainer
|
|
||||||
{
|
|
||||||
GrowHorizontal = Control.GrowDirection.Begin,
|
|
||||||
GrowVertical = Control.GrowDirection.Begin,
|
|
||||||
};
|
|
||||||
|
|
||||||
HandsContainer = new MarginContainer
|
|
||||||
{
|
|
||||||
GrowHorizontal = Control.GrowDirection.Both,
|
|
||||||
GrowVertical = Control.GrowDirection.Begin
|
|
||||||
};
|
|
||||||
|
|
||||||
inventoryContainer.Children.Add(HandsContainer);
|
|
||||||
inventoryContainer.Children.Add(InventoryQuickButtonContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ButtonTutorialOnOnToggled()
|
|
||||||
{
|
|
||||||
if (_tutorialWindow.IsOpen)
|
|
||||||
{
|
|
||||||
if (!_tutorialWindow.IsAtFront())
|
|
||||||
{
|
|
||||||
_tutorialWindow.MoveToFront();
|
|
||||||
_buttonTutorial.Pressed = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_tutorialWindow.Close();
|
|
||||||
_buttonTutorial.Pressed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_tutorialWindow.OpenCentered();
|
|
||||||
_buttonTutorial.Pressed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Control RootControl { get; private set; }
|
|
||||||
|
|
||||||
public bool EscapeButtonDown
|
|
||||||
{
|
|
||||||
get => _buttonEscapeMenu.Pressed;
|
|
||||||
set => _buttonEscapeMenu.Pressed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action<bool> EscapeButtonToggled { get; set; }
|
|
||||||
|
|
||||||
public bool CharacterButtonDown
|
|
||||||
{
|
|
||||||
get => _buttonCharacterMenu.Pressed;
|
|
||||||
set => _buttonCharacterMenu.Pressed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CharacterButtonVisible
|
|
||||||
{
|
|
||||||
get => _buttonCharacterMenu.Visible;
|
|
||||||
set => _buttonCharacterMenu.Visible = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action<bool> CharacterButtonToggled { get; set; }
|
|
||||||
|
|
||||||
public bool InventoryButtonDown
|
|
||||||
{
|
|
||||||
get => _buttonInventoryMenu.Pressed;
|
|
||||||
set => _buttonInventoryMenu.Pressed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool InventoryButtonVisible
|
|
||||||
{
|
|
||||||
get => _buttonInventoryMenu.Visible;
|
|
||||||
set => _buttonInventoryMenu.Visible = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action<bool> InventoryButtonToggled { get; set; }
|
|
||||||
|
|
||||||
public bool CraftingButtonDown
|
|
||||||
{
|
|
||||||
get => _buttonCraftingMenu.Pressed;
|
|
||||||
set => _buttonCraftingMenu.Pressed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CraftingButtonVisible
|
|
||||||
{
|
|
||||||
get => _buttonCraftingMenu.Visible;
|
|
||||||
set => _buttonCraftingMenu.Visible = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action<bool> CraftingButtonToggled { get; set; }
|
|
||||||
|
|
||||||
public bool SandboxButtonDown
|
|
||||||
{
|
|
||||||
get => _buttonSandboxMenu.Pressed;
|
|
||||||
set => _buttonSandboxMenu.Pressed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SandboxButtonVisible
|
|
||||||
{
|
|
||||||
get => _buttonSandboxMenu.Visible;
|
|
||||||
set => _buttonSandboxMenu.Visible = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action<bool> SandboxButtonToggled { get; set; }
|
|
||||||
|
|
||||||
public sealed class TopButton : BaseButton
|
|
||||||
{
|
|
||||||
public const string StyleClassLabelTopButton = "topButtonLabel";
|
|
||||||
|
|
||||||
private static readonly Color ColorNormal = Color.FromHex("#7b7e9e");
|
|
||||||
private static readonly Color ColorHovered = Color.FromHex("#9699bb");
|
|
||||||
private static readonly Color ColorPressed = Color.FromHex("#789B8C");
|
|
||||||
|
|
||||||
private readonly VBoxContainer _container;
|
|
||||||
private readonly TextureRect _textureRect;
|
|
||||||
private readonly Label _label;
|
|
||||||
|
|
||||||
public TopButton(Texture texture, string keyName)
|
|
||||||
{
|
|
||||||
ToggleMode = true;
|
|
||||||
|
|
||||||
_container = new VBoxContainer {MouseFilter = MouseFilterMode.Ignore};
|
|
||||||
AddChild(_container);
|
|
||||||
_container.AddChild(_textureRect = new TextureRect
|
|
||||||
{
|
|
||||||
Texture = texture,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
|
||||||
SizeFlagsVertical = SizeFlags.Expand | SizeFlags.ShrinkCenter,
|
|
||||||
MouseFilter = MouseFilterMode.Ignore,
|
|
||||||
ModulateSelfOverride = ColorNormal,
|
|
||||||
CustomMinimumSize = (0, 32),
|
|
||||||
Stretch = TextureRect.StretchMode.KeepCentered
|
|
||||||
});
|
|
||||||
|
|
||||||
_container.AddChild(_label = new Label
|
|
||||||
{
|
|
||||||
Text = keyName,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
|
||||||
MouseFilter = MouseFilterMode.Ignore,
|
|
||||||
ModulateSelfOverride = ColorNormal
|
|
||||||
});
|
|
||||||
|
|
||||||
_label.AddStyleClass(StyleClassLabelTopButton);
|
|
||||||
|
|
||||||
_container.SetAnchorAndMarginPreset(LayoutPreset.Wide);
|
|
||||||
|
|
||||||
DrawModeChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Vector2 CalculateMinimumSize()
|
|
||||||
{
|
|
||||||
var styleSize = ActualStyleBox?.MinimumSize ?? Vector2.Zero;
|
|
||||||
return (0, 4) + styleSize + _container?.CombinedMinimumSize ?? Vector2.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Draw(DrawingHandleScreen handle)
|
|
||||||
{
|
|
||||||
ActualStyleBox?.Draw(handle, PixelSizeBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
private StyleBox ActualStyleBox
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
TryGetStyleProperty(Button.StylePropertyStyleBox, out StyleBox ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void DrawModeChanged()
|
|
||||||
{
|
|
||||||
switch (DrawMode)
|
|
||||||
{
|
|
||||||
case DrawModeEnum.Normal:
|
|
||||||
StylePseudoClass = Button.StylePseudoClassNormal;
|
|
||||||
_textureRect.ModulateSelfOverride = ColorNormal;
|
|
||||||
_label.ModulateSelfOverride = ColorNormal;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DrawModeEnum.Pressed:
|
|
||||||
StylePseudoClass = Button.StylePseudoClassPressed;
|
|
||||||
_textureRect.ModulateSelfOverride = ColorPressed;
|
|
||||||
_label.ModulateSelfOverride = ColorPressed;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DrawModeEnum.Hover:
|
|
||||||
StylePseudoClass = Button.StylePseudoClassHover;
|
|
||||||
_textureRect.ModulateSelfOverride = ColorHovered;
|
|
||||||
_label.ModulateSelfOverride = ColorHovered;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DrawModeEnum.Disabled:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void StylePropertiesChanged()
|
|
||||||
{
|
|
||||||
base.StylePropertiesChanged();
|
|
||||||
|
|
||||||
if (_container == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var box = ActualStyleBox ?? new StyleBoxEmpty();
|
|
||||||
|
|
||||||
_container.MarginLeft = box.GetContentMargin(StyleBox.Margin.Left);
|
|
||||||
_container.MarginRight = -box.GetContentMargin(StyleBox.Margin.Right);
|
|
||||||
_container.MarginTop = box.GetContentMargin(StyleBox.Margin.Top) + 4;
|
|
||||||
_container.MarginBottom = -box.GetContentMargin(StyleBox.Margin.Bottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,109 +1,95 @@
|
|||||||
using Content.Client.GameObjects;
|
using Content.Client.GameObjects;
|
||||||
using Content.Client.GameObjects.EntitySystems;
|
|
||||||
using Content.Client.Interfaces.GameObjects;
|
using Content.Client.Interfaces.GameObjects;
|
||||||
using Content.Client.Utility;
|
using SS14.Client.GameObjects;
|
||||||
using Robust.Client.Graphics;
|
using SS14.Client.Graphics;
|
||||||
using Robust.Client.Input;
|
using SS14.Client.Graphics.Drawing;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using SS14.Client.Input;
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
using SS14.Client.Interfaces.Player;
|
||||||
using Robust.Client.Player;
|
using SS14.Client.Interfaces.ResourceManagement;
|
||||||
using Robust.Client.UserInterface;
|
using SS14.Client.Interfaces.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using SS14.Client.ResourceManagement;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using SS14.Client.UserInterface;
|
||||||
using Robust.Shared.IoC;
|
using SS14.Client.UserInterface.Controls;
|
||||||
using Robust.Shared.Localization;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Map;
|
using SS14.Shared.IoC;
|
||||||
using Robust.Shared.Maths;
|
using SS14.Shared.Log;
|
||||||
|
using SS14.Shared.Maths;
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
namespace Content.Client.UserInterface
|
||||||
{
|
{
|
||||||
public class HandsGui : Control
|
public class HandsGui : Control
|
||||||
{
|
{
|
||||||
private const int BoxSpacing = 0;
|
private static readonly Color _inactiveColor = new Color(90, 90, 90);
|
||||||
private const int BoxSize = 64;
|
private const int BOX_SPACING = 1;
|
||||||
|
// The boxes are square so that's both width and height.
|
||||||
|
private const int BOX_SIZE = 50;
|
||||||
|
|
||||||
#pragma warning disable 0649
|
private readonly IPlayerManager _playerManager = IoCManager.Resolve<IPlayerManager>();
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
private readonly IUserInterfaceManager _userInterfaceManager = IoCManager.Resolve<IUserInterfaceManager>();
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
private StyleBoxTexture handBox;
|
||||||
[Dependency] private readonly ILocalizationManager _loc;
|
private StyleBoxTexture inactiveHandBox;
|
||||||
#pragma warning restore 0649
|
|
||||||
|
|
||||||
private Texture TextureHandLeft;
|
private UiHandInfo LeftHand;
|
||||||
private Texture TextureHandRight;
|
private UiHandInfo RightHand;
|
||||||
private Texture TextureHandActive;
|
private Box2i handL;
|
||||||
|
private Box2i handR;
|
||||||
private IEntity LeftHand;
|
|
||||||
private IEntity RightHand;
|
|
||||||
private UIBox2i _handL;
|
|
||||||
private UIBox2i _handR;
|
|
||||||
|
|
||||||
private SpriteView LeftSpriteView;
|
|
||||||
private SpriteView RightSpriteView;
|
|
||||||
private TextureRect ActiveHandRect;
|
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
IoCManager.InjectDependencies(this);
|
var _resMgr = IoCManager.Resolve<IResourceCache>();
|
||||||
|
var handsBoxTexture = _resMgr.GetResource<TextureResource>("/Textures/UserInterface/handsbox.png");
|
||||||
ToolTip = _loc.GetString("Your hands");
|
handBox = new StyleBoxTexture()
|
||||||
|
{
|
||||||
_handR = new UIBox2i(0, 0, BoxSize, BoxSize);
|
Texture = handsBoxTexture,
|
||||||
_handL = _handR.Translated((BoxSize + BoxSpacing, 0));
|
};
|
||||||
|
handBox.SetMargin(StyleBox.Margin.All, 6);
|
||||||
|
inactiveHandBox = new StyleBoxTexture(handBox)
|
||||||
|
{
|
||||||
|
Modulate = _inactiveColor,
|
||||||
|
};
|
||||||
|
SetMarginsPreset(LayoutPreset.CenterBottom);
|
||||||
|
SetAnchorPreset(LayoutPreset.CenterBottom);
|
||||||
|
|
||||||
|
handL = new Box2i(0, 0, BOX_SIZE, BOX_SIZE);
|
||||||
|
handR = handL.Translated(new Vector2i(BOX_SIZE + BOX_SPACING, 0));
|
||||||
|
SS14.Shared.Log.Logger.Debug($"{handL}, {handR}");
|
||||||
MouseFilter = MouseFilterMode.Stop;
|
MouseFilter = MouseFilterMode.Stop;
|
||||||
|
|
||||||
TextureHandLeft = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_l.png");
|
|
||||||
TextureHandRight = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_r.png");
|
|
||||||
TextureHandActive = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_active.png");
|
|
||||||
|
|
||||||
AddChild(new TextureRect
|
|
||||||
{
|
|
||||||
Texture = TextureHandLeft,
|
|
||||||
Size = _handL.Size,
|
|
||||||
Position = _handL.TopLeft,
|
|
||||||
TextureScale = (2, 2)
|
|
||||||
});
|
|
||||||
|
|
||||||
AddChild(new TextureRect
|
|
||||||
{
|
|
||||||
Texture = TextureHandRight,
|
|
||||||
Size = _handR.Size,
|
|
||||||
Position = _handR.TopLeft,
|
|
||||||
TextureScale = (2, 2)
|
|
||||||
});
|
|
||||||
|
|
||||||
AddChild(ActiveHandRect = new TextureRect
|
|
||||||
{
|
|
||||||
Texture = TextureHandActive,
|
|
||||||
Size = _handL.Size,
|
|
||||||
Position = _handL.TopLeft,
|
|
||||||
TextureScale = (2, 2)
|
|
||||||
});
|
|
||||||
|
|
||||||
LeftSpriteView = new SpriteView
|
|
||||||
{
|
|
||||||
MouseFilter = MouseFilterMode.Ignore,
|
|
||||||
Scale = (2, 2)
|
|
||||||
};
|
|
||||||
AddChild(LeftSpriteView);
|
|
||||||
LeftSpriteView.Size = _handL.Size;
|
|
||||||
LeftSpriteView.Position = _handL.TopLeft;
|
|
||||||
|
|
||||||
RightSpriteView = new SpriteView
|
|
||||||
{
|
|
||||||
MouseFilter = MouseFilterMode.Ignore,
|
|
||||||
Scale = (2, 2)
|
|
||||||
};
|
|
||||||
AddChild(RightSpriteView);
|
|
||||||
RightSpriteView.Size = _handR.Size;
|
|
||||||
RightSpriteView.Position = _handR.TopLeft;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Vector2 CalculateMinimumSize()
|
protected override Vector2 CalculateMinimumSize()
|
||||||
{
|
{
|
||||||
return new Vector2(BoxSize * 2 + BoxSpacing, BoxSize) * UIScale;
|
return new Vector2(BOX_SIZE * 2 + 1, BOX_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandle handle)
|
||||||
|
{
|
||||||
|
if (!TryGetHands(out IHandsComponent hands))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var leftActive = hands.ActiveIndex == "left";
|
||||||
|
|
||||||
|
handle.DrawStyleBox(handBox, leftActive ? handL : handR);
|
||||||
|
handle.DrawStyleBox(inactiveHandBox, leftActive ? handR : handL);
|
||||||
|
|
||||||
|
if (LeftHand.Entity != null && LeftHand.HeldSprite != null)
|
||||||
|
{
|
||||||
|
var bounds = LeftHand.HeldSprite.Size;
|
||||||
|
handle.DrawTextureRect(LeftHand.HeldSprite,
|
||||||
|
Box2i.FromDimensions(handL.Left + (int)(handL.Width / 2f - bounds.X / 2f),
|
||||||
|
handL.Top + (int)(handL.Height / 2f - bounds.Y / 2f),
|
||||||
|
(int)bounds.X, (int)bounds.Y), tile: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RightHand.Entity != null && RightHand.HeldSprite != null)
|
||||||
|
{
|
||||||
|
var bounds = RightHand.HeldSprite.Size;
|
||||||
|
handle.DrawTextureRect(RightHand.HeldSprite,
|
||||||
|
Box2i.FromDimensions(handR.Left + (int)(handR.Width / 2f - bounds.Y / 2f),
|
||||||
|
handR.Top + (int)(handR.Height / 2f - bounds.Y / 2f),
|
||||||
|
(int)bounds.X, (int)bounds.Y), tile: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -113,58 +99,57 @@ namespace Content.Client.UserInterface
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool TryGetHands(out IHandsComponent hands)
|
private bool TryGetHands(out IHandsComponent hands)
|
||||||
{
|
{
|
||||||
hands = default;
|
hands = null;
|
||||||
|
if (_playerManager?.LocalPlayer == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var entity = _playerManager?.LocalPlayer?.ControlledEntity;
|
IEntity entity = _playerManager.LocalPlayer.ControlledEntity;
|
||||||
return entity != null && entity.TryGetComponent(out hands);
|
if (entity == null || !entity.TryGetComponent(out hands))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateHandIcons()
|
public void UpdateHandIcons()
|
||||||
{
|
{
|
||||||
if (Parent == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateDraw();
|
UpdateDraw();
|
||||||
|
|
||||||
if (!TryGetHands(out var hands))
|
if (!TryGetHands(out IHandsComponent hands))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var left = hands.GetEntity("left");
|
var left = hands.GetEntity("left");
|
||||||
var right = hands.GetEntity("right");
|
var right = hands.GetEntity("right");
|
||||||
|
|
||||||
ActiveHandRect.Position = hands.ActiveIndex == "left" ? _handL.TopLeft : _handR.TopLeft;
|
|
||||||
|
|
||||||
if (left != null)
|
if (left != null)
|
||||||
{
|
{
|
||||||
if (left != LeftHand)
|
if (left != LeftHand.Entity)
|
||||||
{
|
{
|
||||||
LeftHand = left;
|
LeftHand.Entity = left;
|
||||||
if (LeftHand.TryGetComponent(out ISpriteComponent sprite))
|
LeftHand.HeldSprite = GetIconSprite(left);
|
||||||
{
|
|
||||||
LeftSpriteView.Sprite = sprite;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LeftHand = null;
|
LeftHand.Entity = null;
|
||||||
LeftSpriteView.Sprite = null;
|
LeftHand.HeldSprite = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right != null)
|
if (right != null)
|
||||||
{
|
{
|
||||||
RightHand = right;
|
if (right != RightHand.Entity)
|
||||||
if (RightHand.TryGetComponent(out ISpriteComponent sprite))
|
|
||||||
{
|
{
|
||||||
RightSpriteView.Sprite = sprite;
|
RightHand.Entity = right;
|
||||||
|
RightHand.HeldSprite = GetIconSprite(right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RightHand = null;
|
RightHand.Entity = null;
|
||||||
RightSpriteView.Sprite = null;
|
RightHand.HeldSprite = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,77 +170,53 @@ namespace Content.Client.UserInterface
|
|||||||
((HandsComponent)hands).UseActiveHand();
|
((HandsComponent)hands).UseActiveHand();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AttackByInHand(string hand)
|
|
||||||
{
|
|
||||||
if (!TryGetHands(out var hands))
|
|
||||||
return;
|
|
||||||
|
|
||||||
hands.AttackByInHand(hand);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool HasPoint(Vector2 point)
|
protected override bool HasPoint(Vector2 point)
|
||||||
{
|
{
|
||||||
return _handL.Contains((Vector2i) point) || _handR.Contains((Vector2i) point);
|
return handL.Contains((Vector2i)point) || handR.Contains((Vector2i)point);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void MouseDown(GUIMouseButtonEventArgs args)
|
protected override void MouseDown(GUIMouseButtonEventArgs args)
|
||||||
{
|
{
|
||||||
base.MouseDown(args);
|
base.MouseDown(args);
|
||||||
|
|
||||||
var leftHandContains = _handL.Contains((Vector2i) args.RelativePosition);
|
var lefthandcontains = handL.Contains((Vector2i)args.RelativePosition);
|
||||||
var rightHandContains = _handR.Contains((Vector2i) args.RelativePosition);
|
var righthandcontains = handR.Contains((Vector2i)args.RelativePosition);
|
||||||
|
|
||||||
string handIndex;
|
|
||||||
if (leftHandContains)
|
|
||||||
{
|
|
||||||
handIndex = "left";
|
|
||||||
}
|
|
||||||
else if (rightHandContains)
|
|
||||||
{
|
|
||||||
handIndex = "right";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.Button == Mouse.Button.Left)
|
if (args.Button == Mouse.Button.Left)
|
||||||
{
|
{
|
||||||
if (!TryGetHands(out var hands))
|
if (!TryGetHands(out IHandsComponent hands))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ((hands.ActiveIndex == "left" && lefthandcontains)
|
||||||
if (hands.ActiveIndex == handIndex)
|
|| (hands.ActiveIndex == "right" && righthandcontains))
|
||||||
{
|
|
||||||
UseActiveHand();
|
UseActiveHand();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
AttackByInHand(handIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (args.Button == Mouse.Button.Middle)
|
|
||||||
{
|
|
||||||
SendSwitchHandTo(handIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (args.Button == Mouse.Button.Right)
|
else if (args.Button == Mouse.Button.Right)
|
||||||
{
|
{
|
||||||
if (!TryGetHands(out var hands))
|
if (lefthandcontains)
|
||||||
{
|
{
|
||||||
return;
|
SendSwitchHandTo("left");
|
||||||
|
}
|
||||||
|
if (righthandcontains)
|
||||||
|
{
|
||||||
|
SendSwitchHandTo("right");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var entity = hands.GetEntity(handIndex);
|
private static Texture GetIconSprite(IEntity entity)
|
||||||
if (entity == null)
|
|
||||||
{
|
{
|
||||||
return;
|
if (entity.TryGetComponent<IconComponent>(out var component) && component.Icon != null)
|
||||||
|
{
|
||||||
|
return component.Icon.Default;
|
||||||
|
}
|
||||||
|
return IoCManager.Resolve<IResourceCache>().GetFallback<TextureResource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var esm = IoCManager.Resolve<IEntitySystemManager>();
|
private struct UiHandInfo
|
||||||
esm.GetEntitySystem<VerbSystem>().OpenContextMenu(entity, new ScreenCoordinates(args.GlobalPosition));
|
{
|
||||||
}
|
public IEntity Entity { get; set; }
|
||||||
|
public Texture HeldSprite { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
using Content.Client.Chat;
|
|
||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
|
||||||
{
|
|
||||||
internal sealed class LobbyGui : PanelContainer
|
|
||||||
{
|
|
||||||
public Label ServerName { get; }
|
|
||||||
public Label StartTime { get; }
|
|
||||||
public Button ReadyButton { get; }
|
|
||||||
public Button ObserveButton { get; }
|
|
||||||
public Button LeaveButton { get; }
|
|
||||||
public ChatBox Chat { get; }
|
|
||||||
public ItemList OnlinePlayerItemList { get; }
|
|
||||||
|
|
||||||
public LobbyGui(ILocalizationManager localization, IResourceCache resourceCache)
|
|
||||||
{
|
|
||||||
PanelOverride = new StyleBoxFlat {BackgroundColor = new Color(37, 37, 45)};
|
|
||||||
PanelOverride.SetContentMarginOverride(StyleBox.Margin.All, 4);
|
|
||||||
|
|
||||||
var vBox = new VBoxContainer();
|
|
||||||
AddChild(vBox);
|
|
||||||
|
|
||||||
{
|
|
||||||
// Title bar.
|
|
||||||
var titleContainer = new HBoxContainer();
|
|
||||||
vBox.AddChild(titleContainer);
|
|
||||||
|
|
||||||
var lobbyTitle = new Label
|
|
||||||
{
|
|
||||||
Text = localization.GetString("Lobby"),
|
|
||||||
SizeFlagsHorizontal = SizeFlags.None
|
|
||||||
};
|
|
||||||
lobbyTitle.AddStyleClass(NanoStyle.StyleClassLabelHeading);
|
|
||||||
titleContainer.AddChild(lobbyTitle);
|
|
||||||
|
|
||||||
titleContainer.AddChild(ServerName = new Label
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter | SizeFlags.Expand
|
|
||||||
});
|
|
||||||
ServerName.AddStyleClass(NanoStyle.StyleClassLabelHeading);
|
|
||||||
|
|
||||||
titleContainer.AddChild(LeaveButton = new Button
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkEnd,
|
|
||||||
Text = localization.GetString("Leave")
|
|
||||||
});
|
|
||||||
LeaveButton.AddStyleClass(NanoStyle.StyleClassButtonBig);
|
|
||||||
}
|
|
||||||
|
|
||||||
var hBox = new HBoxContainer {SizeFlagsVertical = SizeFlags.FillExpand};
|
|
||||||
vBox.AddChild(hBox);
|
|
||||||
|
|
||||||
{
|
|
||||||
var leftVBox = new VBoxContainer {SizeFlagsHorizontal = SizeFlags.FillExpand};
|
|
||||||
hBox.AddChild(leftVBox);
|
|
||||||
|
|
||||||
leftVBox.AddChild(new Placeholder(resourceCache)
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
PlaceholderText = localization.GetString("Character UI\nPlaceholder")
|
|
||||||
});
|
|
||||||
|
|
||||||
var readyButtons = new HBoxContainer();
|
|
||||||
|
|
||||||
leftVBox.AddChild(readyButtons);
|
|
||||||
readyButtons.AddChild(ObserveButton = new Button
|
|
||||||
{
|
|
||||||
Text = localization.GetString("Observe")
|
|
||||||
});
|
|
||||||
ObserveButton.AddStyleClass(NanoStyle.StyleClassButtonBig);
|
|
||||||
|
|
||||||
readyButtons.AddChild(StartTime = new Label
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
|
||||||
Align = Label.AlignMode.Right
|
|
||||||
});
|
|
||||||
|
|
||||||
readyButtons.AddChild(ReadyButton = new Button
|
|
||||||
{
|
|
||||||
ToggleMode = true,
|
|
||||||
Text = localization.GetString("Ready Up")
|
|
||||||
});
|
|
||||||
ReadyButton.AddStyleClass(NanoStyle.StyleClassButtonBig);
|
|
||||||
|
|
||||||
leftVBox.AddChild(Chat = new ChatBox {SizeFlagsVertical = SizeFlags.FillExpand});
|
|
||||||
Chat.Input.PlaceHolder = localization.GetString("Say something!");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
var rightVBox = new VBoxContainer {SizeFlagsHorizontal = SizeFlags.FillExpand};
|
|
||||||
hBox.AddChild(rightVBox);
|
|
||||||
rightVBox.AddChild(new Label
|
|
||||||
{
|
|
||||||
Text = localization.GetString("Online Players:")
|
|
||||||
});
|
|
||||||
rightVBox.AddChild(OnlinePlayerItemList = new ItemList
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
//SelectMode = ItemList.ItemListSelectMode.None
|
|
||||||
});
|
|
||||||
rightVBox.AddChild(new Placeholder(resourceCache)
|
|
||||||
{
|
|
||||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
|
||||||
PlaceholderText = localization.GetString("Server Info\nPlaceholder")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,487 +0,0 @@
|
|||||||
using Content.Client.GameObjects.EntitySystems;
|
|
||||||
using Content.Client.Utility;
|
|
||||||
using Robust.Client.Graphics.Drawing;
|
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
|
||||||
{
|
|
||||||
public sealed class NanoStyle
|
|
||||||
{
|
|
||||||
public const string StyleClassLabelHeading = "LabelHeading";
|
|
||||||
public const string StyleClassLabelSubText = "LabelSubText";
|
|
||||||
public const string StyleClassButtonBig = "ButtonBig";
|
|
||||||
private static readonly Color NanoGold = Color.FromHex("#A88B5E");
|
|
||||||
|
|
||||||
//Used by the APC and SMES menus
|
|
||||||
public const string StyleClassPowerStateNone = "PowerStateNone";
|
|
||||||
public const string StyleClassPowerStateLow = "PowerStateLow";
|
|
||||||
public const string StyleClassPowerStateGood = "PowerStateGood";
|
|
||||||
|
|
||||||
public Stylesheet Stylesheet { get; }
|
|
||||||
|
|
||||||
public NanoStyle()
|
|
||||||
{
|
|
||||||
var resCache = IoCManager.Resolve<IResourceCache>();
|
|
||||||
var notoSans10 = resCache.GetFont("/Nano/NotoSans/NotoSans-Regular.ttf", 10);
|
|
||||||
var notoSans12 = resCache.GetFont("/Nano/NotoSans/NotoSans-Regular.ttf", 12);
|
|
||||||
var notoSansDisplayBold14 = resCache.GetFont("/Fonts/NotoSansDisplay/NotoSansDisplay-Bold.ttf", 14);
|
|
||||||
var notoSans16 = resCache.GetFont("/Nano/NotoSans/NotoSans-Regular.ttf", 16);
|
|
||||||
var notoSansBold16 = resCache.GetFont("/Nano/NotoSans/NotoSans-Bold.ttf", 16);
|
|
||||||
var textureCloseButton = resCache.GetTexture("/Nano/cross.svg.png");
|
|
||||||
var windowHeaderTex = resCache.GetTexture("/Nano/window_header.png");
|
|
||||||
var windowHeader = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = windowHeaderTex,
|
|
||||||
PatchMarginBottom = 3,
|
|
||||||
ExpandMarginBottom = 3,
|
|
||||||
};
|
|
||||||
var windowBackgroundTex = resCache.GetTexture("/Nano/window_background.png");
|
|
||||||
var windowBackground = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = windowBackgroundTex,
|
|
||||||
};
|
|
||||||
windowBackground.SetPatchMargin(StyleBox.Margin.Horizontal | StyleBox.Margin.Bottom, 2);
|
|
||||||
windowBackground.SetExpandMargin(StyleBox.Margin.Horizontal | StyleBox.Margin.Bottom, 2);
|
|
||||||
|
|
||||||
var buttonNormalTex = resCache.GetTexture("/Nano/button_normal.png");
|
|
||||||
var buttonNormal = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = buttonNormalTex,
|
|
||||||
};
|
|
||||||
buttonNormal.SetPatchMargin(StyleBox.Margin.All, 2);
|
|
||||||
buttonNormal.SetContentMarginOverride(StyleBox.Margin.Horizontal, 8);
|
|
||||||
|
|
||||||
var buttonHoverTex = resCache.GetTexture("/Nano/button_hover.png");
|
|
||||||
var buttonHover = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = buttonHoverTex,
|
|
||||||
};
|
|
||||||
buttonHover.SetPatchMargin(StyleBox.Margin.All, 2);
|
|
||||||
buttonHover.SetContentMarginOverride(StyleBox.Margin.Horizontal, 8);
|
|
||||||
|
|
||||||
var buttonPressedTex = resCache.GetTexture("/Nano/button_pressed.png");
|
|
||||||
var buttonPressed = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = buttonPressedTex,
|
|
||||||
};
|
|
||||||
buttonPressed.SetPatchMargin(StyleBox.Margin.All, 2);
|
|
||||||
buttonPressed.SetContentMarginOverride(StyleBox.Margin.Horizontal, 8);
|
|
||||||
|
|
||||||
var buttonDisabledTex = resCache.GetTexture("/Nano/button_disabled.png");
|
|
||||||
var buttonDisabled = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = buttonDisabledTex,
|
|
||||||
};
|
|
||||||
buttonDisabled.SetPatchMargin(StyleBox.Margin.All, 2);
|
|
||||||
buttonDisabled.SetContentMarginOverride(StyleBox.Margin.Horizontal, 8);
|
|
||||||
|
|
||||||
var lineEditTex = resCache.GetTexture("/Nano/lineedit.png");
|
|
||||||
var lineEdit = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = lineEditTex,
|
|
||||||
};
|
|
||||||
lineEdit.SetPatchMargin(StyleBox.Margin.All, 3);
|
|
||||||
lineEdit.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5);
|
|
||||||
|
|
||||||
var tabContainerPanelTex = resCache.GetTexture("/Nano/tabcontainer_panel.png");
|
|
||||||
var tabContainerPanel = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = tabContainerPanelTex,
|
|
||||||
};
|
|
||||||
tabContainerPanel.SetPatchMargin(StyleBox.Margin.All, 2);
|
|
||||||
|
|
||||||
var tabContainerBoxActive = new StyleBoxFlat {BackgroundColor = new Color(64, 64, 64)};
|
|
||||||
tabContainerBoxActive.SetContentMarginOverride(StyleBox.Margin.Horizontal, 3);
|
|
||||||
var tabContainerBoxInactive = new StyleBoxFlat {BackgroundColor = new Color(32, 32, 32)};
|
|
||||||
tabContainerBoxInactive.SetContentMarginOverride(StyleBox.Margin.Horizontal, 3);
|
|
||||||
|
|
||||||
var vScrollBarGrabberNormal = new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = Color.Gray.WithAlpha(0.35f), ContentMarginLeftOverride = 10
|
|
||||||
};
|
|
||||||
var vScrollBarGrabberHover = new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(140, 140, 140).WithAlpha(0.35f), ContentMarginLeftOverride = 10
|
|
||||||
};
|
|
||||||
var vScrollBarGrabberGrabbed = new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(160, 160, 160).WithAlpha(0.35f), ContentMarginLeftOverride = 10
|
|
||||||
};
|
|
||||||
|
|
||||||
var hScrollBarGrabberNormal = new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = Color.Gray.WithAlpha(0.35f), ContentMarginTopOverride = 10
|
|
||||||
};
|
|
||||||
var hScrollBarGrabberHover = new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(140, 140, 140).WithAlpha(0.35f), ContentMarginTopOverride = 10
|
|
||||||
};
|
|
||||||
var hScrollBarGrabberGrabbed = new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(160, 160, 160).WithAlpha(0.35f), ContentMarginTopOverride = 10
|
|
||||||
};
|
|
||||||
|
|
||||||
var progressBarBackground = new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(0.25f, 0.25f, 0.25f)
|
|
||||||
};
|
|
||||||
progressBarBackground.SetContentMarginOverride(StyleBox.Margin.Vertical, 5);
|
|
||||||
|
|
||||||
var progressBarForeground = new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(0.25f, 0.50f, 0.25f)
|
|
||||||
};
|
|
||||||
progressBarForeground.SetContentMarginOverride(StyleBox.Margin.Vertical, 5);
|
|
||||||
|
|
||||||
// CheckBox
|
|
||||||
var checkBoxTextureChecked = resCache.GetTexture("/Nano/checkbox_checked.svg.96dpi.png");
|
|
||||||
var checkBoxTextureUnchecked = resCache.GetTexture("/Nano/checkbox_unchecked.svg.96dpi.png");
|
|
||||||
|
|
||||||
// Tooltip box
|
|
||||||
var tooltipTexture = resCache.GetTexture("/Nano/tooltip.png");
|
|
||||||
var tooltipBox = new StyleBoxTexture
|
|
||||||
{
|
|
||||||
Texture = tooltipTexture,
|
|
||||||
};
|
|
||||||
tooltipBox.SetPatchMargin(StyleBox.Margin.All, 2);
|
|
||||||
tooltipBox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5);
|
|
||||||
|
|
||||||
// Placeholder
|
|
||||||
var placeholderTexture = resCache.GetTexture("/Nano/placeholder.png");
|
|
||||||
var placeholder = new StyleBoxTexture { Texture = placeholderTexture };
|
|
||||||
placeholder.SetPatchMargin(StyleBox.Margin.All, 24);
|
|
||||||
placeholder.SetExpandMargin(StyleBox.Margin.All, -5);
|
|
||||||
|
|
||||||
var itemListBackgroundSelected = new StyleBoxFlat {BackgroundColor = new Color(75, 75, 86)};
|
|
||||||
itemListBackgroundSelected.SetContentMarginOverride(StyleBox.Margin.Vertical, 2);
|
|
||||||
itemListBackgroundSelected.SetContentMarginOverride(StyleBox.Margin.Horizontal, 4);
|
|
||||||
var itemListItemBackgroundDisabled = new StyleBoxFlat {BackgroundColor = new Color(10, 10, 12)};
|
|
||||||
itemListItemBackgroundDisabled.SetContentMarginOverride(StyleBox.Margin.Vertical, 2);
|
|
||||||
itemListItemBackgroundDisabled.SetContentMarginOverride(StyleBox.Margin.Horizontal, 4);
|
|
||||||
var itemListItemBackground = new StyleBoxFlat {BackgroundColor = new Color(55, 55, 68)};
|
|
||||||
itemListItemBackground.SetContentMarginOverride(StyleBox.Margin.Vertical, 2);
|
|
||||||
itemListItemBackground.SetContentMarginOverride(StyleBox.Margin.Horizontal, 4);
|
|
||||||
|
|
||||||
Stylesheet = new Stylesheet(new[]
|
|
||||||
{
|
|
||||||
// Default font.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(null, null, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty("font", notoSans12),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Window title.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(Label), new[] {SS14Window.StyleClassWindowTitle}, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Label.StylePropertyFontColor, NanoGold),
|
|
||||||
new StyleProperty(Label.StylePropertyFont, notoSansDisplayBold14),
|
|
||||||
}),
|
|
||||||
// Window background.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(null, new[] {SS14Window.StyleClassWindowPanel}, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Panel.StylePropertyPanel, windowBackground),
|
|
||||||
}),
|
|
||||||
// Window header.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(Panel), new[] {SS14Window.StyleClassWindowHeader}, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Panel.StylePropertyPanel, windowHeader),
|
|
||||||
}),
|
|
||||||
// Window close button base texture.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(TextureButton), new[] {SS14Window.StyleClassWindowCloseButton}, null,
|
|
||||||
null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(TextureButton.StylePropertyTexture, textureCloseButton),
|
|
||||||
new StyleProperty(Control.StylePropertyModulateSelf, Color.FromHex("#4B596A")),
|
|
||||||
}),
|
|
||||||
// Window close button hover.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(TextureButton), new[] {SS14Window.StyleClassWindowCloseButton}, null,
|
|
||||||
TextureButton.StylePseudoClassHover),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Control.StylePropertyModulateSelf, Color.FromHex("#7F3636")),
|
|
||||||
}),
|
|
||||||
// Window close button pressed.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(TextureButton), new[] {SS14Window.StyleClassWindowCloseButton}, null,
|
|
||||||
TextureButton.StylePseudoClassPressed),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Control.StylePropertyModulateSelf, Color.FromHex("#753131")),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Regular buttons!
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(Button), null, null, Button.StylePseudoClassNormal),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Button.StylePropertyStyleBox, buttonNormal),
|
|
||||||
}),
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(Button), null, null, Button.StylePseudoClassHover),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Button.StylePropertyStyleBox, buttonHover),
|
|
||||||
}),
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(Button), null, null, Button.StylePseudoClassPressed),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Button.StylePropertyStyleBox, buttonPressed),
|
|
||||||
}),
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(Button), null, null, Button.StylePseudoClassDisabled),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Button.StylePropertyStyleBox, buttonDisabled),
|
|
||||||
new StyleProperty("font-color", Color.FromHex("#E5E5E581")),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Main menu: Make those buttons bigger.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorChild(
|
|
||||||
new SelectorElement(null, null, "mainMenuVBox", null),
|
|
||||||
new SelectorElement(typeof(Button), null, null, null)),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty("font", notoSansBold16),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Main menu: also make those buttons slightly more separated.
|
|
||||||
new StyleRule(new SelectorElement(typeof(BoxContainer), null, "mainMenuVBox", null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(BoxContainer.StylePropertySeparation, 2),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Fancy LineEdit
|
|
||||||
new StyleRule(new SelectorElement(typeof(LineEdit), null, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(LineEdit.StylePropertyStyleBox, lineEdit),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(LineEdit), new[] {LineEdit.StyleClassLineEditNotEditable}, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty("font-color", new Color(192, 192, 192)),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(LineEdit), null, null, LineEdit.StylePseudoClassPlaceholder),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty("font-color", Color.Gray),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// TabContainer
|
|
||||||
new StyleRule(new SelectorElement(typeof(TabContainer), null, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(TabContainer.StylePropertyPanelStyleBox, tabContainerPanel),
|
|
||||||
new StyleProperty(TabContainer.StylePropertyTabStyleBox, tabContainerBoxActive),
|
|
||||||
new StyleProperty(TabContainer.StylePropertyTabStyleBoxInactive, tabContainerBoxInactive),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Scroll bars
|
|
||||||
new StyleRule(new SelectorElement(typeof(VScrollBar), null, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(ScrollBar.StylePropertyGrabber,
|
|
||||||
vScrollBarGrabberNormal),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(VScrollBar), null, null, ScrollBar.StylePseudoClassHover),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(ScrollBar.StylePropertyGrabber,
|
|
||||||
vScrollBarGrabberHover),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(VScrollBar), null, null, ScrollBar.StylePseudoClassGrabbed),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(ScrollBar.StylePropertyGrabber,
|
|
||||||
vScrollBarGrabberGrabbed),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(HScrollBar), null, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(ScrollBar.StylePropertyGrabber,
|
|
||||||
hScrollBarGrabberNormal),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(HScrollBar), null, null, ScrollBar.StylePseudoClassHover),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(ScrollBar.StylePropertyGrabber,
|
|
||||||
hScrollBarGrabberHover),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(HScrollBar), null, null, ScrollBar.StylePseudoClassGrabbed),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(ScrollBar.StylePropertyGrabber,
|
|
||||||
hScrollBarGrabberGrabbed),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// ProgressBar
|
|
||||||
new StyleRule(new SelectorElement(typeof(ProgressBar), null, null, null),
|
|
||||||
new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(ProgressBar.StylePropertyBackground, progressBarBackground),
|
|
||||||
new StyleProperty(ProgressBar.StylePropertyForeground, progressBarForeground)
|
|
||||||
}),
|
|
||||||
|
|
||||||
// CheckBox
|
|
||||||
new StyleRule(new SelectorElement(typeof(CheckBox), null, null, null), new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(CheckBox.StylePropertyIcon, checkBoxTextureUnchecked),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(CheckBox), null, null, Button.StylePseudoClassPressed), new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(CheckBox.StylePropertyIcon, checkBoxTextureChecked),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(CheckBox), null, null, null), new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(CheckBox.StylePropertyHSeparation, 3),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Tooltip
|
|
||||||
new StyleRule(new SelectorElement(typeof(Tooltip), null, null, null), new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(PanelContainer.StylePropertyPanel, tooltipBox)
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(PanelContainer), new []{"tooltipBox"}, null, null), new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(PanelContainer.StylePropertyPanel, tooltipBox)
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Entity tooltip
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(PanelContainer), new[] {ExamineSystem.StyleClassEntityTooltip}, null,
|
|
||||||
null), new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(PanelContainer.StylePropertyPanel, tooltipBox)
|
|
||||||
}),
|
|
||||||
|
|
||||||
// ItemList
|
|
||||||
new StyleRule(new SelectorElement(typeof(ItemList), null, null, null), new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(ItemList.StylePropertyBackground,
|
|
||||||
new StyleBoxFlat {BackgroundColor = new Color(32, 32, 40)}),
|
|
||||||
new StyleProperty(ItemList.StylePropertyItemBackground,
|
|
||||||
itemListItemBackground),
|
|
||||||
new StyleProperty(ItemList.StylePropertyDisabledItemBackground,
|
|
||||||
itemListItemBackgroundDisabled),
|
|
||||||
new StyleProperty(ItemList.StylePropertySelectedItemBackground,
|
|
||||||
itemListBackgroundSelected)
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Tree
|
|
||||||
new StyleRule(new SelectorElement(typeof(Tree), null, null, null), new[]
|
|
||||||
{
|
|
||||||
new StyleProperty(Tree.StylePropertyBackground,
|
|
||||||
new StyleBoxFlat {BackgroundColor = new Color(32, 32, 40)}),
|
|
||||||
new StyleProperty(Tree.StylePropertyItemBoxSelected, new StyleBoxFlat
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(55, 55, 68),
|
|
||||||
ContentMarginLeftOverride = 4
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Placeholder
|
|
||||||
new StyleRule(new SelectorElement(typeof(Placeholder), null, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(PanelContainer.StylePropertyPanel, placeholder),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(Label), new []{Placeholder.StyleClassPlaceholderText}, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Label.StylePropertyFont, notoSans16),
|
|
||||||
new StyleProperty(Label.StylePropertyFontColor, new Color(103, 103, 103, 128)),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Big Label
|
|
||||||
new StyleRule(new SelectorElement(typeof(Label), new []{StyleClassLabelHeading}, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Label.StylePropertyFont, notoSansBold16),
|
|
||||||
new StyleProperty(Label.StylePropertyFontColor, NanoGold),
|
|
||||||
} ),
|
|
||||||
|
|
||||||
// Small Label
|
|
||||||
new StyleRule(new SelectorElement(typeof(Label), new []{StyleClassLabelSubText}, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Label.StylePropertyFont, notoSans10),
|
|
||||||
new StyleProperty(Label.StylePropertyFontColor, Color.DarkGray),
|
|
||||||
} ),
|
|
||||||
|
|
||||||
// Big Button
|
|
||||||
new StyleRule(new SelectorElement(typeof(Button), new []{StyleClassButtonBig}, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty("font", notoSans16)
|
|
||||||
}),
|
|
||||||
|
|
||||||
//APC and SMES power state label colors
|
|
||||||
new StyleRule(new SelectorElement(typeof(Label), new []{StyleClassPowerStateNone}, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Label.StylePropertyFontColor, new Color(0.8f, 0.0f, 0.0f))
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(Label), new []{StyleClassPowerStateLow}, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Label.StylePropertyFontColor, new Color(0.9f, 0.36f, 0.0f))
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(Label), new []{StyleClassPowerStateGood}, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Label.StylePropertyFontColor, new Color(0.024f, 0.8f, 0.0f))
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Those top menu buttons.
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(GameHud.TopButton), null, null, Button.StylePseudoClassNormal), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Button.StylePropertyStyleBox, buttonNormal),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(GameHud.TopButton), null, null, Button.StylePseudoClassPressed), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Button.StylePropertyStyleBox, buttonPressed),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(GameHud.TopButton), null, null, Button.StylePseudoClassHover), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Button.StylePropertyStyleBox, buttonHover),
|
|
||||||
}),
|
|
||||||
|
|
||||||
new StyleRule(
|
|
||||||
new SelectorElement(typeof(Label), new [] {GameHud.TopButton.StyleClassLabelTopButton}, null, null), new []
|
|
||||||
{
|
|
||||||
new StyleProperty(Label.StylePropertyFont, notoSansDisplayBold14),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
|
|
||||||
namespace Content.Client.UserInterface
|
|
||||||
{
|
|
||||||
public sealed class Placeholder : PanelContainer
|
|
||||||
{
|
|
||||||
public const string StyleClassPlaceholderText = "PlaceholderText";
|
|
||||||
|
|
||||||
private readonly Label _label;
|
|
||||||
|
|
||||||
public string PlaceholderText
|
|
||||||
{
|
|
||||||
get => _label.Text;
|
|
||||||
set => _label.Text = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Placeholder(IResourceCache _resourceCache)
|
|
||||||
{
|
|
||||||
_label = new Label
|
|
||||||
{
|
|
||||||
SizeFlagsHorizontal = SizeFlags.Fill,
|
|
||||||
SizeFlagsVertical = SizeFlags.Fill,
|
|
||||||
Align = Label.AlignMode.Center,
|
|
||||||
VAlign = Label.VAlignMode.Center
|
|
||||||
};
|
|
||||||
_label.AddStyleClass(StyleClassPlaceholderText);
|
|
||||||
AddChild(_label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user