Merge remote-tracking branch 'upstream/master' into upstream-sync

This commit is contained in:
Arthur 2022-03-22 04:48:30 +03:00
commit c4e6cdfbbd
72 changed files with 118596 additions and 97046 deletions

51
.github/workflows/build-docfx.yml vendored Normal file
View file

@ -0,0 +1,51 @@
name: Build & Publish Docfx
on:
push:
branches: [ master ]
paths:
- '**.cs'
- '**.csproj'
- '**.sln'
- '**.git**'
- '**.yml'
# no docs on which one of these is supposed to work, so
# why not just do both
- 'RobustToolbox'
- 'RobustToolbox/**'
jobs:
docfx:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup submodule
run: |
git submodule update --init --recursive
- name: Pull engine updates
uses: space-wizards/submodule-dependency@v0.1.5
- name: Update Engine Submodules
run: |
cd RobustToolbox/
git submodule update --init --recursive
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- name: Install dependencies
run: dotnet restore
- name: Build Project
run: dotnet build --no-restore /p:WarningsAsErrors=nullable
- name: Build DocFX
uses: nikeee/docfx-action@v1.0.0
with:
args: Content.Docfx/docfx.json
- name: Publish Docfx Documentation on GitHub Pages
uses: maxheld83/ghpages@master
env:
BUILD_DIR: Content.Docfx/_content-site
GH_PAT: ${{ secrets.GH_PAT }}

6
.gitignore vendored
View file

@ -252,6 +252,7 @@ paket-files/
# JetBrains Rider
.idea/
*.sln.iml
.editorconfig
# CodeRush
.cr/
@ -295,3 +296,8 @@ desktop.ini
# Images generated using the MapRenderer
Resources/MapImages
## Docfx stuff
/Content.Docfx/api/
/Content.Docfx/*site

View file

@ -24,6 +24,7 @@ namespace Content.Client.Audio
public sealed class AmbientSoundSystem : SharedAmbientSoundSystem
{
[Dependency] private EntityLookupSystem _lookup = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
@ -33,25 +34,28 @@ namespace Content.Client.Audio
private float _maxAmbientRange;
private float _cooldown;
private float _accumulator;
private float _ambienceVolume = 0.0f;
/// <summary>
/// How many times we can be playing 1 particular sound at once.
/// </summary>
private int _maxSingleSound = 8;
private int MaxSingleSound => (int) (_maxAmbientCount / (16.0f / 6.0f));
private Dictionary<AmbientSoundComponent, (IPlayingAudioStream? Stream, string Sound)> _playingSounds = new();
private const float RangeBuffer = 3f;
public override void Initialize()
{
base.Initialize();
UpdatesOutsidePrediction = true;
var configManager = IoCManager.Resolve<IConfigurationManager>();
configManager.OnValueChanged(CCVars.AmbientCooldown, SetCooldown, true);
configManager.OnValueChanged(CCVars.MaxAmbientSources, SetAmbientCount, true);
configManager.OnValueChanged(CCVars.AmbientRange, SetAmbientRange, true);
_cfg.OnValueChanged(CCVars.AmbientCooldown, SetCooldown, true);
_cfg.OnValueChanged(CCVars.MaxAmbientSources, SetAmbientCount, true);
_cfg.OnValueChanged(CCVars.AmbientRange, SetAmbientRange, true);
_cfg.OnValueChanged(CCVars.AmbienceVolume, SetAmbienceVolume, true);
SubscribeLocalEvent<AmbientSoundComponent, ComponentShutdown>(OnShutdown);
}
@ -61,6 +65,7 @@ namespace Content.Client.Audio
sound.Stream?.Stop();
}
private void SetAmbienceVolume(float value) => _ambienceVolume = value;
private void SetCooldown(float value) => _cooldown = value;
private void SetAmbientCount(int value) => _maxAmbientCount = value;
private void SetAmbientRange(float value) => _maxAmbientRange = value;
@ -69,10 +74,11 @@ namespace Content.Client.Audio
{
base.Shutdown();
ClearSounds();
var configManager = IoCManager.Resolve<IConfigurationManager>();
configManager.UnsubValueChanged(CCVars.AmbientCooldown, SetCooldown);
configManager.UnsubValueChanged(CCVars.MaxAmbientSources, SetAmbientCount);
configManager.UnsubValueChanged(CCVars.AmbientRange, SetAmbientRange);
_cfg.UnsubValueChanged(CCVars.AmbientCooldown, SetCooldown);
_cfg.UnsubValueChanged(CCVars.MaxAmbientSources, SetAmbientCount);
_cfg.UnsubValueChanged(CCVars.AmbientRange, SetAmbientRange);
_cfg.UnsubValueChanged(CCVars.AmbienceVolume, SetAmbienceVolume);
}
private int PlayingCount(string countSound)
@ -143,7 +149,7 @@ namespace Content.Client.Audio
var key = ambientComp.Sound.GetSound();
if (!sourceDict.ContainsKey(key))
sourceDict[key] = new List<AmbientSoundComponent>(_maxSingleSound);
sourceDict[key] = new List<AmbientSoundComponent>(MaxSingleSound);
sourceDict[key].Add(ambientComp);
}
@ -151,7 +157,7 @@ namespace Content.Client.Audio
foreach (var (key, val) in sourceDict)
{
sourceDict[key] = val.OrderByDescending(x =>
Transform(x.Owner).Coordinates.TryDistance(EntityManager, coordinates, out var dist) ? dist : float.MaxValue).ToList();
Transform(x.Owner).Coordinates.TryDistance(EntityManager, coordinates, out var dist) ? dist * (x.Volume + 32) : float.MaxValue).ToList();
}
return sourceDict;
@ -198,7 +204,7 @@ namespace Content.Client.Audio
var sound = comp.Sound.GetSound();
if (PlayingCount(sound) >= _maxSingleSound)
if (PlayingCount(sound) >= MaxSingleSound)
{
keys.Remove(key);
/*foreach (var toRemove in compsInRange[key])
@ -212,7 +218,7 @@ namespace Content.Client.Audio
var audioParams = AudioHelpers
.WithVariation(0.01f)
.WithVolume(comp.Volume)
.WithVolume(comp.Volume + _ambienceVolume)
.WithLoop(true)
.WithAttenuation(Attenuation.LinearDistance)
// Randomise start so 2 sources don't increase their volume.

View file

@ -29,8 +29,8 @@ namespace Content.Client.Audio
private SoundCollectionPrototype _ambientCollection = default!;
private AudioParams _ambientParams = new(-10f, 1, "Master", 0, 0, 0, true, 0f);
private AudioParams _lobbyParams = new(-5f, 1, "Master", 0, 0, 0, true, 0f);
private readonly AudioParams _ambientParams = new(-10f, 1, "Master", 0, 0, 0, true, 0f);
private readonly AudioParams _lobbyParams = new(-5f, 1, "Master", 0, 0, 0, true, 0f);
private IPlayingAudioStream? _ambientStream;
private IPlayingAudioStream? _lobbyStream;
@ -41,7 +41,7 @@ namespace Content.Client.Audio
_ambientCollection = _prototypeManager.Index<SoundCollectionPrototype>("AmbienceBase");
_configManager.OnValueChanged(CCVars.AmbienceBasicEnabled, AmbienceCVarChanged);
_configManager.OnValueChanged(CCVars.AmbienceVolume, AmbienceCVarChanged);
_configManager.OnValueChanged(CCVars.LobbyMusicEnabled, LobbyMusicCVarChanged);
_stateManager.OnStateChanged += StateManagerOnStateChanged;
@ -75,7 +75,7 @@ namespace Content.Client.Audio
{
StartLobbyMusic();
}
else if (args.NewState is GameScreen && _configManager.GetCVar(CCVars.AmbienceBasicEnabled))
else if (args.NewState is GameScreen)
{
StartAmbience();
}
@ -94,10 +94,7 @@ namespace Content.Client.Audio
else
{
EndLobbyMusic();
if (_configManager.GetCVar(CCVars.AmbienceBasicEnabled))
{
StartAmbience();
}
StartAmbience();
}
}
@ -107,13 +104,9 @@ namespace Content.Client.Audio
EndLobbyMusic();
}
private void AmbienceCVarChanged(bool ambienceEnabled)
private void AmbienceCVarChanged(float volume)
{
if (!ambienceEnabled)
{
EndAmbience();
}
else if (_stateManager.CurrentState is GameScreen)
if (_stateManager.CurrentState is GameScreen)
{
StartAmbience();
}
@ -127,7 +120,7 @@ namespace Content.Client.Audio
{
EndAmbience();
var file = _robustRandom.Pick(_ambientCollection.PickFiles).ToString();
_ambientStream = SoundSystem.Play(Filter.Local(), file, _ambientParams);
_ambientStream = SoundSystem.Play(Filter.Local(), file, _ambientParams.WithVolume(_ambientParams.Volume + _configManager.GetCVar(CCVars.AmbienceVolume)));
}
private void EndAmbience()

View file

@ -84,7 +84,8 @@ public sealed class ClothingSystem : EntitySystem
var key = layer.MapKeys?.FirstOrDefault();
if (key == null)
{
key = i == 0 ? args.Slot : $"{args.Slot}-{i}";
// using the $"{args.Slot}" layer key as the "bookmark" for layer ordering until layer draw depths get added
key = $"{args.Slot}-{i}";
i++;
}
@ -254,6 +255,10 @@ public sealed class ClothingSystem : EntitySystem
return;
}
// temporary, until layer draw depths get added. Basically: a layer with the key "slot" is being used as a
// bookmark to determine where in the list of layers we should insert the clothing layers.
bool slotLayerExists = sprite.LayerMapTryGet(slot, out var index);
// add the new layers
foreach (var (key, layerData) in ev.Layers)
{
@ -263,7 +268,16 @@ public sealed class ClothingSystem : EntitySystem
continue;
}
var index = sprite.LayerMapReserveBlank(key);
if (slotLayerExists)
{
index++;
// note that every insertion requires reshuffling & remapping all the existing layers.
sprite.AddBlankLayer(index);
sprite.LayerMapSet(key, index);
}
else
index = sprite.LayerMapReserveBlank(key);
if (sprite[index] is not Layer layer)
return;

View file

@ -198,6 +198,7 @@ namespace Content.Client.Entry
"Rehydratable",
"Headset",
"ComputerBoard",
"GasAnalyzable",
"GasCanister",
"GasPort",
"GasPortable",

View file

@ -35,8 +35,33 @@
<Label Name="MidiVolumeLabel" MinSize="48 0" Align="Right" />
<Control MinSize="4 0"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="5 0 0 0">
<Label Text="{Loc 'ui-options-ambience-volume'}" />
<Control MinSize="8 0" />
<Slider Name="AmbienceVolumeSlider"
MinValue="0"
MaxValue="300"
HorizontalExpand="True"
MinSize="80 0"
Rounded="True" />
<Control MinSize="8 0" />
<Label Name="AmbienceVolumeLabel" MinSize="48 0" Align="Right" />
<Control MinSize="4 0"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="5 0 0 0">
<Label Text="{Loc 'ui-options-ambience-max-sounds'}" />
<Control MinSize="8 0" />
<Slider Name="AmbienceSoundsSlider"
MinValue="0"
MaxValue="1"
HorizontalExpand="True"
MinSize="80 0"
Rounded="True" />
<Control MinSize="8 0" />
<Label Name="AmbienceSoundsLabel" MinSize="48 0" Align="Right" />
<Control MinSize="4 0"/>
</BoxContainer>
<Control MinSize="0 8" />
<CheckBox Name="AmbienceCheckBox" Text="{Loc 'ui-options-ambient-hum'}" />
<CheckBox Name="LobbyMusicCheckBox" Text="{Loc 'ui-options-lobby-music'}" />
</BoxContainer>
</BoxContainer>

View file

@ -1,16 +1,12 @@
using System;
using Content.Shared.CCVar;
using Robust.Client.Audio.Midi;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared;
using Robust.Shared.Maths;
using Robust.Shared.Configuration;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Range = Robust.Client.UserInterface.Controls.Range;
namespace Content.Client.EscapeMenu.UI.Tabs
{
@ -25,16 +21,19 @@ namespace Content.Client.EscapeMenu.UI.Tabs
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
AmbienceCheckBox.Pressed = _cfg.GetCVar(CCVars.AmbienceBasicEnabled);
LobbyMusicCheckBox.Pressed = _cfg.GetCVar(CCVars.LobbyMusicEnabled);
ApplyButton.OnPressed += OnApplyButtonPressed;
ResetButton.OnPressed += OnResetButtonPressed;
MasterVolumeSlider.OnValueChanged += OnMasterVolumeSliderChanged;
MidiVolumeSlider.OnValueChanged += OnMidiVolumeSliderChanged;
AmbienceCheckBox.OnToggled += OnAmbienceCheckToggled;
AmbienceVolumeSlider.OnValueChanged += OnAmbienceVolumeSliderChanged;
AmbienceSoundsSlider.OnValueChanged += OnAmbienceSoundsSliderChanged;
LobbyMusicCheckBox.OnToggled += OnLobbyMusicCheckToggled;
AmbienceSoundsSlider.MinValue = _cfg.GetCVar(CCVars.MinMaxAmbientSourcesConfigured);
AmbienceSoundsSlider.MaxValue = _cfg.GetCVar(CCVars.MaxMaxAmbientSourcesConfigured);
Reset();
}
@ -44,22 +43,27 @@ namespace Content.Client.EscapeMenu.UI.Tabs
ResetButton.OnPressed -= OnResetButtonPressed;
MasterVolumeSlider.OnValueChanged -= OnMasterVolumeSliderChanged;
MidiVolumeSlider.OnValueChanged -= OnMidiVolumeSliderChanged;
AmbienceCheckBox.OnToggled -= OnAmbienceCheckToggled;
AmbienceVolumeSlider.OnValueChanged -= OnAmbienceVolumeSliderChanged;
base.Dispose(disposing);
}
private void OnMasterVolumeSliderChanged(Robust.Client.UserInterface.Controls.Range range)
private void OnAmbienceVolumeSliderChanged(Range obj)
{
UpdateChanges();
}
private void OnAmbienceSoundsSliderChanged(Range obj)
{
UpdateChanges();
}
private void OnMasterVolumeSliderChanged(Range range)
{
_clydeAudio.SetMasterVolume(MasterVolumeSlider.Value / 100);
UpdateChanges();
}
private void OnMidiVolumeSliderChanged(Robust.Client.UserInterface.Controls.Range range)
{
UpdateChanges();
}
private void OnAmbienceCheckToggled(BaseButton.ButtonEventArgs args)
private void OnMidiVolumeSliderChanged(Range range)
{
UpdateChanges();
}
@ -73,7 +77,8 @@ namespace Content.Client.EscapeMenu.UI.Tabs
{
_cfg.SetCVar(CVars.AudioMasterVolume, MasterVolumeSlider.Value / 100);
_cfg.SetCVar(CVars.MidiVolume, LV100ToDB(MidiVolumeSlider.Value));
_cfg.SetCVar(CCVars.AmbienceBasicEnabled, AmbienceCheckBox.Pressed);
_cfg.SetCVar(CCVars.AmbienceVolume, LV100ToDB(AmbienceVolumeSlider.Value));
_cfg.SetCVar(CCVars.MaxAmbientSources, (int)AmbienceSoundsSlider.Value);
_cfg.SetCVar(CCVars.LobbyMusicEnabled, LobbyMusicCheckBox.Pressed);
_cfg.SaveToFile();
UpdateChanges();
@ -88,7 +93,8 @@ namespace Content.Client.EscapeMenu.UI.Tabs
{
MasterVolumeSlider.Value = _cfg.GetCVar(CVars.AudioMasterVolume) * 100;
MidiVolumeSlider.Value = DBToLV100(_cfg.GetCVar(CVars.MidiVolume));
AmbienceCheckBox.Pressed = _cfg.GetCVar(CCVars.AmbienceBasicEnabled);
AmbienceVolumeSlider.Value = DBToLV100(_cfg.GetCVar(CCVars.AmbienceVolume));
AmbienceSoundsSlider.Value = _cfg.GetCVar(CCVars.MaxAmbientSources);
LobbyMusicCheckBox.Pressed = _cfg.GetCVar(CCVars.LobbyMusicEnabled);
UpdateChanges();
}
@ -109,18 +115,23 @@ namespace Content.Client.EscapeMenu.UI.Tabs
private void UpdateChanges()
{
var isMasterVolumeSame =
System.Math.Abs(MasterVolumeSlider.Value - _cfg.GetCVar(CVars.AudioMasterVolume) * 100) < 0.01f;
Math.Abs(MasterVolumeSlider.Value - _cfg.GetCVar(CVars.AudioMasterVolume) * 100) < 0.01f;
var isMidiVolumeSame =
System.Math.Abs(MidiVolumeSlider.Value - DBToLV100(_cfg.GetCVar(CVars.MidiVolume))) < 0.01f;
var isAmbienceSame = AmbienceCheckBox.Pressed == _cfg.GetCVar(CCVars.AmbienceBasicEnabled);
Math.Abs(MidiVolumeSlider.Value - DBToLV100(_cfg.GetCVar(CVars.MidiVolume))) < 0.01f;
var isAmbientVolumeSame =
Math.Abs(AmbienceVolumeSlider.Value - DBToLV100(_cfg.GetCVar(CCVars.AmbienceVolume))) < 0.01f;
var isAmbientSoundsSame = (int)AmbienceSoundsSlider.Value == _cfg.GetCVar(CCVars.MaxAmbientSources);
var isLobbySame = LobbyMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.LobbyMusicEnabled);
var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbienceSame && isLobbySame;
var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbientVolumeSame && isAmbientSoundsSame && isLobbySame;
ApplyButton.Disabled = isEverythingSame;
ResetButton.Disabled = isEverythingSame;
MasterVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", MasterVolumeSlider.Value / 100));
MidiVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", MidiVolumeSlider.Value / 100));
AmbienceVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", AmbienceVolumeSlider.Value / 100));
AmbienceSoundsLabel.Text = ((int)AmbienceSoundsSlider.Value).ToString();
}
}
}

View file

@ -0,0 +1 @@
# Add your introductions here!

View file

@ -0,0 +1,2 @@
- name: Example-article
href: example-article.md

134
Content.Docfx/docfx.json Normal file
View file

@ -0,0 +1,134 @@
{
"metadata": [
{
"src":
[
{
"files": [
"**.csproj"
],
"exclude": [
"**/bin/**",
"**/obj/**",
"_site/**",
"**.xaml"
],
"src": "../Content.Client"
}
],
"disableGitFeatures": false,
"disableDefaultFilter": false,
"dest": "api/Content.Client"
},
{
"src":
[
{
"files": [
"**.csproj"
],
"exclude": [
"**/bin/**",
"**/obj/**",
"_site/**",
"**.xaml"
],
"src": "../Content.Server"
}
],
"disableGitFeatures": false,
"disableDefaultFilter": false,
"dest": "api/Content.Server"
},
{
"src":
[
{
"files": [
"**.csproj"
],
"exclude": [
"**/bin/**",
"**/obj/**",
"_site/**",
"**.xaml"
],
"src": "../Content.Shared"
}
],
"disableGitFeatures": false,
"disableDefaultFilter": false,
"dest": "api/Content.Shared"
},
{
"src":
[
{
"files": [
"**.csproj"
],
"exclude": [
"**/bin/**",
"**/obj/**",
"_site/**",
"**.xaml"
],
"src": "../Content.Tests"
}
],
"disableGitFeatures": false,
"disableDefaultFilter": false,
"dest": "api/Content.Tests"
}
],
"build": {
"content": [
{
"files": [
"api/**/**.yml"
]
},
{
"files": [
"articles/**.md",
"articles/**/toc.yml",
"toc.yml",
"*.md"
]
}
],
"resource": [
{
"files": [
"images/**",
"favicon.ico",
"icon.svg"
]
}
],
"overwrite": [
{
"files": [
"apidoc/**.md"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
"dest": "_content-site",
"globalMetadataFiles": [],
"fileMetadataFiles": [],
"template": [
"default",
"templates/darkfx"
],
"postProcessors": [],
"markdownEngineName": "markdig",
"noLangKeyword": false,
"keepFileLink": false,
"cleanupCacheHistory": false,
"disableGitFeatures": false
}
}

9
Content.Docfx/index.md Normal file
View file

@ -0,0 +1,9 @@
# Space Station 14 DocFX
![](https://i.imgur.com/0h6VoRZ.png)
## Welcome to the Space Station 14 DocFX instance.
### Click one of the tabs above to see documentation for that particular project/namespace
## Links
[Website](https://spacestation14.io/) | [Discord](https://discord.gg/t2jac3p) | [Forum](https://forum.spacestation14.io/) | [Steam](https://store.steampowered.com/app/1255460/Space_Station_14/) | [Standalone Download](https://spacestation14.io/about/nightlies/)

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Steffen Wilke
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,40 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
{{^_disableContribution}}
<div class="contribution">
<ul class="nav">
{{#docurl}}
<li>
<a href="{{docurl}}" class="contribution-link">{{__global.improveThisDoc}}</a>
</li>
{{/docurl}}
{{#sourceurl}}
<li>
<a href="{{sourceurl}}" class="contribution-link">{{__global.viewSource}}</a>
</li>
{{/sourceurl}}
</ul>
</div>
{{/_disableContribution}}
<div class="toggle-mode">
<div class="icon">
<i aria-hidden="true">☀</i>
</div>
<label class="switch">
<input type="checkbox" id="switch-style">
<span class="slider round"></span>
</label>
<div class="icon">
<i aria-hidden="true">☾</i>
</div>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<h5>{{__global.inThisArticle}}</h5>
<div></div>
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>

View file

@ -0,0 +1,108 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<h1 id="{{id}}" data-uid="{{uid}}" class="text-break">{{>partials/title}}</h1>
<div class="markdown level0 summary">{{{summary}}}</div>
<div class="markdown level0 conceptual">{{{conceptual}}}</div>
{{#inClass}}
<div class="inheritance">
<h5>{{__global.inheritance}}</h5>
{{#inheritance}}
<div class="level{{index}}">{{{specName.0.value}}}</div>
{{/inheritance}}
<div class="level{{level}}"><span class="xref">{{name.0.value}}</span></div>
{{#derivedClasses}}
<div class="level{{index}}">{{{specName.0.value}}}</div>
{{/derivedClasses}}
</div>
{{/inClass}}
{{#implements.0}}
<div classs="implements">
<h5>{{__global.implements}}</h5>
{{/implements.0}}
{{#implements}}
<div>{{{specName.0.value}}}</div>
{{/implements}}
{{#implements.0}}
</div>
{{/implements.0}}
{{#inheritedMembers.0}}
<div class="inheritedMembers">
</div>
{{/inheritedMembers.0}}
<h6><strong>{{__global.namespace}}</strong>: {{{namespace.specName.0.value}}}</h6>
<h6><strong>{{__global.assembly}}</strong>: {{assemblies.0}}.dll</h6>
<h5 id="{{id}}_syntax">{{__global.syntax}}</h5>
<div class="codewrapper">
<pre><code class="lang-{{_lang}} hljs">{{syntax.content.0.value}}</code></pre>
</div>
{{#syntax.parameters.0}}
<h5 class="parameters">{{__global.parameters}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.name}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
{{/syntax.parameters.0}}
{{#syntax.parameters}}
<tr>
<td>{{{type.specName.0.value}}}</td>
<td><span class="parametername">{{{id}}}</span></td>
<td>{{{description}}}</td>
</tr>
{{/syntax.parameters}}
{{#syntax.parameters.0}}
</tbody>
</table>
{{/syntax.parameters.0}}
{{#syntax.return}}
<h5 class="returns">{{__global.returns}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.type}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{{type.specName.0.value}}}</td>
<td>{{{description}}}</td>
</tr>
</tbody>
</table>
{{/syntax.return}}
{{#syntax.typeParameters.0}}
<h5 class="typeParameters">{{__global.typeParameters}}</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{{__global.name}}</th>
<th>{{__global.description}}</th>
</tr>
</thead>
<tbody>
{{/syntax.typeParameters.0}}
{{#syntax.typeParameters}}
<tr>
<td><span class="parametername">{{{id}}}</span></td>
<td>{{{description}}}</td>
</tr>
{{/syntax.typeParameters}}
{{#syntax.typeParameters.0}}
</tbody>
</table>
{{/syntax.typeParameters.0}}
{{#remarks}}
<h5 id="{{id}}_remarks"><strong>{{__global.remarks}}</strong></h5>
<div class="markdown level0 remarks">{{{remarks}}}</div>
{{/remarks}}
{{#example.0}}
<h5 id="{{id}}_examples"><strong>{{__global.examples}}</strong></h5>
{{/example.0}}
{{#example}}
{{{.}}}
{{/example}}

View file

@ -0,0 +1,29 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<div class="pull-left">
{{{_appFooter}}}
{{^_appFooter}}<span>Generated by <strong>DocFX</strong></span>{{/_appFooter}}
</div>
<div class="toggle-mode pull-right visible-sm visible-xs">
<div class="icon">
<i aria-hidden="true">☀</i>
</div>
<label class="switch">
<input type="checkbox" id="switch-style-m">
<span class="slider round"></span>
</label>
<div class="icon">
<i aria-hidden="true">☾</i>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="{{_rel}}styles/toggle-theme.js"></script>
</footer>

View file

@ -0,0 +1,20 @@
{{!Copyright (c) Oscar Vasquez. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}">
<meta name="generator" content="docfx {{_docfxVersion}}">
{{#_description}}<meta name="description" content="{{_description}}">{{/_description}}
<link rel="shortcut icon" href="{{_rel}}{{{_appFaviconPath}}}{{^_appFaviconPath}}favicon.ico{{/_appFaviconPath}}">
<link rel="stylesheet" href="{{_rel}}styles/docfx.vendor.css">
<link rel="stylesheet" href="{{_rel}}styles/docfx.css">
<link rel="stylesheet" href="{{_rel}}styles/main.css">
<meta property="docfx:navrel" content="{{_navRel}}">
<meta property="docfx:tocrel" content="{{_tocRel}}">
{{#_noindex}}<meta name="searchOption" content="noindex">{{/_noindex}}
{{#_enableSearch}}<meta property="docfx:rel" content="{{_rel}}">{{/_enableSearch}}
{{#_enableNewTab}}<meta property="docfx:newtab" content="true">{{/_enableNewTab}}
</head>

View file

@ -0,0 +1,470 @@
:root, body.dark-theme {
--color-foreground: #ccd5dc;
--color-navbar: #66666d;
--color-breadcrumb: #999;
--color-underline: #ddd;
--color-toc-hover: #fff;
--color-background: #2d2d30;
--color-background-subnav: #333337;
--color-background-dark: #1e1e1e;
--color-background-table-alt: #212123;
--color-background-quote: #69696e;
}
body.light-theme {
--color-foreground: #171717;
--color-breadcrumb: #4a4a4a;
--color-toc-hover: #4c4c4c;
--color-background: #ffffff;
--color-background-subnav: #f5f5f5;
--color-background-dark: #ddd;
--color-background-table-alt: #f9f9f9;
}
body {
color: var(--color-foreground);
line-height: 1.5;
font-size: 14px;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
word-wrap: break-word;
background-color: var(--color-background);
}
.btn.focus, .btn:focus, .btn:hover {
color: var(--color-foreground);
}
h1 {
font-weight: 600;
font-size: 32px;
}
h2 {
font-weight: 600;
font-size: 24px;
line-height: 1.8;
}
h3 {
font-weight: 600;
font-size: 20px;
line-height: 1.8;
}
h5 {
font-size: 14px;
padding: 10px 0px;
}
article h1, article h2, article h3, article h4 {
margin-top: 35px;
margin-bottom: 15px;
}
article h4 {
padding-bottom: 8px;
border-bottom: 2px solid var(--color-underline);
}
.navbar-brand>img {
color: var(--color-background);
}
.navbar {
border: none;
}
.subnav {
border-top: 1px solid var(--color-underline);
background-color: var(--color-background-subnav);
}
.sidenav, .fixed_header, .toc {
background-color: var(--color-background);
}
.navbar-inverse {
background-color: var(--color-background-dark);
z-index: 100;
}
.navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-text {
color: var(--color-navbar);
background-color: var(--color-background-dark);
border-bottom: 3px solid transparent;
padding-bottom: 12px;
}
.navbar-inverse .navbar-nav>li>a:focus, .navbar-inverse .navbar-nav>li>a:hover {
color: var(--color-foreground);
background-color: var(--color-background-dark);
border-bottom: 3px solid var(--color-background-subnav);
transition: all ease 0.25s;
}
.navbar-inverse .navbar-nav>.active>a, .navbar-inverse .navbar-nav>.active>a:focus, .navbar-inverse .navbar-nav>.active>a:hover {
color: var(--color-foreground);
background-color: var(--color-background-dark);
border-bottom: 3px solid var(--color-foreground);
transition: all ease 0.25s;
}
.navbar-form .form-control {
border: none;
border-radius: 0;
}
.light-theme .navbar-brand svg {
filter: brightness(20%);
}
.toc .level1>li {
font-weight: 400;
}
.toc .nav>li>a {
color: var(--color-foreground);
}
.sidefilter {
background-color: var(--color-background);
border-left: none;
border-right: none;
}
.sidefilter {
background-color: var(--color-background);
border-left: none;
border-right: none;
}
.toc-filter {
padding: 10px;
margin: 0;
background-color: var(--color-background);
}
.toc-filter>input {
border: none;
border-radius: unset;
background-color: var(--color-background-subnav);
padding: 5px 0 5px 20px;
font-size: 90%
}
.toc-filter>.clear-icon {
position: absolute;
top: 17px;
right: 15px;
}
.toc-filter>input:focus {
color: var(--color-foreground);
transition: all ease 0.25s;
}
.toc-filter>.filter-icon {
display: none;
}
.sidetoc>.toc {
background-color: var(--color-background);
overflow-x: hidden;
}
.sidetoc {
background-color: var(--color-background);
border: none;
}
.alert {
background-color: inherit;
border: none;
padding: 10px 0;
border-radius: 0;
}
.alert>p {
margin-bottom: 0;
padding: 5px 10px;
border-bottom: 1px solid;
background-color: var(--color-background-dark);
}
.alert>h5 {
padding: 10px 15px;
margin-top: 0;
margin-bottom: 0;
text-transform: uppercase;
font-weight: bold;
border-top: 2px solid;
background-color: var(--color-background-dark);
border-radius: none;
}
.alert>ul {
margin-bottom: 0;
padding: 5px 40px;
}
.alert-info {
color: #1976d2;
}
.alert-warning {
color: #f57f17;
}
.alert-danger {
color: #d32f2f;
}
pre {
padding: 9.5px;
margin: 0 0 10px;
font-size: 13px;
word-break: break-all;
word-wrap: break-word;
background-color: var(--color-background-dark);
border-radius: 0;
border: none;
}
code {
background: var(--color-background-dark) !important;
border-radius: 2px;
}
.hljs {
color: var(--color-foreground);
}
.toc .nav>li.active>.expand-stub::before, .toc .nav>li.in>.expand-stub::before, .toc .nav>li.in.active>.expand-stub::before, .toc .nav>li.filtered>.expand-stub::before {
content: "▾";
}
.toc .nav>li>.expand-stub::before, .toc .nav>li.active>.expand-stub::before {
content: "▸";
}
.affix ul ul>li>a:before {
content: "|";
}
.breadcrumb {
background-color: var(--color-background-subnav);
}
.breadcrumb .label.label-primary {
background: #444;
border-radius: 0;
font-weight: normal;
font-size: 100%;
}
#breadcrumb .breadcrumb>li a {
border-radius: 0;
font-weight: normal;
font-size: 85%;
display: inline;
padding: 0 .6em 0;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
color: var(--color-breadcrumb);
}
#breadcrumb .breadcrumb>li a:hover {
color: var(--color-foreground);
transition: all ease 0.25s;
}
.breadcrumb>li+li:before {
content: "⯈";
font-size: 75%;
color: var(--color-background-dark);
padding: 0;
}
.light-theme .breadcrumb>li+li:before {
color: var(--color-foreground)
}
.toc .level1>li {
font-weight: 600;
font-size: 130%;
padding-left: 5px;
}
.footer {
border-top: none;
background-color: var(--color-background-dark);
padding: 15px 0;
font-size: 90%;
}
.toc .nav>li>a:hover, .toc .nav>li>a:focus {
color: var(--color-toc-hover);
transition: all ease 0.1s;
}
.form-control {
background-color: var(--color-background-subnav);
border: none;
border-radius: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.form-control:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
input#search-query:focus {
color: var(--color-foreground);
}
.table-bordered, .table-bordered>tbody>tr>td, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>td, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>thead>tr>th {
border: 1px solid var(--color-background-dark);
}
.table-striped>tbody>tr:nth-of-type(odd) {
background-color: var(--color-background-table-alt);
}
blockquote {
padding: 10px 20px;
margin: 0 0 10px;
font-size: 110%;
border-left: 5px solid var(--color-background-quote);
color: var(--color-background-quote);
}
.pagination>.disabled>a, .pagination>.disabled>a:focus, .pagination>.disabled>a:hover, .pagination>.disabled>span, .pagination>.disabled>span:focus, .pagination>.disabled>span:hover {
background-color: var(--color-background-subnav);
border-color: var(--color-background-subnav);
}
.breadcrumb>li, .pagination {
display: inline;
}
.tabGroup a[role="tab"] {
border-bottom: 2px solid var(--color-background-dark);
}
.tabGroup a[role="tab"][aria-selected="true"] {
color: var(--color-foreground);
}
.tabGroup section[role="tabpanel"] {
border: 1px solid var(--color-background-dark);
}
.sideaffix > div.contribution > ul > li > a.contribution-link:hover {
background-color: var(--color-background);
}
.switch {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 14px;
width: 14px;
left: 4px;
bottom: 3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #337ab7;
}
input:focus + .slider {
box-shadow: 0 0 1px #337ab7;
}
input:checked + .slider:before {
-webkit-transform: translateX(19px);
-ms-transform: translateX(19px);
transform: translateX(19px);
}
/* Rounded sliders */
.slider.round {
border-radius: 20px;
}
.slider.round:before {
border-radius: 50%;
}
.toggle-mode .icon {
display: inline-block;
}
.toggle-mode .icon i {
font-style: normal;
font-size: 17px;
display: inline-block;
padding-right: 7px;
padding-left: 7px;
vertical-align: middle;
}
@media (min-width: 1600px) {
.container {
width: 100%;
}
.sidefilter {
width: 18%;
}
.sidetoc {
width: 18%;
}
.article.grid-right {
margin-left: 19%;
}
.sideaffix {
width: 11.5%;
}
.affix ul>li.active>a {
white-space: initial;
}
.affix ul>li>a {
width: 99%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}

View file

@ -0,0 +1,35 @@
const sw = document.getElementById("switch-style"), sw_mobile = document.getElementById("switch-style-m"), b = document.body;
if (b) {
function toggleTheme(target, dark) {
target.classList.toggle("dark-theme", dark)
target.classList.toggle("light-theme", !dark)
}
function switchEventListener() {
toggleTheme(b, this.checked);
if (window.localStorage) {
this.checked ? localStorage.setItem("theme", "dark-theme") : localStorage.setItem("theme", "light-theme")
}
}
var isDarkTheme = !window.localStorage || !window.localStorage.getItem("theme") || window.localStorage && localStorage.getItem("theme") === "dark-theme";
if(sw && sw_mobile){
sw.checked = isDarkTheme;
sw_mobile.checked = isDarkTheme;
sw.addEventListener("change", switchEventListener);
sw_mobile.addEventListener("change", switchEventListener);
// sync state between switches
sw.addEventListener("change", function() {
sw_mobile.checked = this.checked;
});
sw_mobile.addEventListener("change", function() {
sw.checked = this.checked;
});
}
toggleTheme(b, isDarkTheme);
}

18
Content.Docfx/toc.yml Normal file
View file

@ -0,0 +1,18 @@
- name: Articles
href: articles/
# Client
- name: Content.Client
href: api/Content.Client/
# Server
- name: Content.Server
href: api/Content.Server/
# Shared
- name: Content.Shared
href: api/Content.Shared/
# Unit testing
- name: Content.Tests
href: api/Content.Tests/

View file

@ -0,0 +1,18 @@
using Content.Server.Atmos.Piping.EntitySystems;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
/**
* GasAnalyzableComponent is a component for anything that can be examined with a gas analyzer.
*/
namespace Content.Server.Atmos.Components
{
[RegisterComponent]
public sealed class GasAnalyzableComponent : Component
{
// Empty
}
}

View file

@ -0,0 +1,88 @@
using Content.Server.Atmos.Components;
using Content.Server.NodeContainer.NodeGroups;
using Content.Server.NodeContainer.Nodes;
using Content.Server.NodeContainer;
using Content.Server.Tools;
using Content.Shared.Atmos.Components;
using Content.Shared.Examine;
using Content.Shared.Temperature;
using Content.Shared.Verbs;
using JetBrains.Annotations;
using Robust.Shared.Utility;
using System.Linq;
namespace Content.Server.Atmos.EntitySystems
{
[UsedImplicitly]
public sealed class GasAnalyzableSystem : EntitySystem
{
[Dependency] private readonly ToolSystem _toolSystem = default!;
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GasAnalyzableComponent, GetVerbsEvent<ExamineVerb>>(OnGetExamineVerbs);
}
private void OnGetExamineVerbs(EntityUid uid, GasAnalyzableComponent component, GetVerbsEvent<ExamineVerb> args)
{
// Must be in details range to try this.
if (_examineSystem.IsInDetailsRange(args.User, args.Target))
{
var held = args.Using;
var enabled = held != null && EntityManager.HasComponent<SharedGasAnalyzerComponent>(held);
var verb = new ExamineVerb
{
Disabled = !enabled,
Message = Loc.GetString("gas-analyzable-system-verb-tooltip"),
Text = Loc.GetString("gas-analyzable-system-verb-name"),
Category = VerbCategory.Examine,
IconTexture = "/Textures/Interface/VerbIcons/examine.svg.192dpi.png",
Act = () =>
{
var markup = FormattedMessage.FromMarkup(GeneratePipeMarkup(uid));
_examineSystem.SendExamineTooltip(args.User, uid, markup, false, false);
}
};
args.Verbs.Add(verb);
}
}
private string GeneratePipeMarkup(EntityUid uid, NodeContainerComponent? nodeContainer = null)
{
if (!Resolve(uid, ref nodeContainer))
return Loc.GetString("gas-analyzable-system-internal-error-missing-component");
List<string> portNames = new List<string>();
List<string> portData = new List<string>();
foreach (var node in nodeContainer.Nodes)
{
if (node.Value is not PipeNode pn)
continue;
float pressure = pn.Air.Pressure;
float temp = pn.Air.Temperature;
portNames.Add(node.Key);
portData.Add(Loc.GetString("gas-analyzable-system-statistics",
("pressure", pressure),
("tempK", $"{temp:0.#}"),
("tempC", $"{TemperatureHelpers.KelvinToCelsius(temp):0.#}")
));
}
int count = portNames.Count;
if (count == 0)
return Loc.GetString("gas-anlayzable-system-internal-error-no-gas-node");
else if (count == 1)
// omit names if only one node
return Loc.GetString("gas-analyzable-system-header") + "\n" + portData[0];
else
{
var outputs = portNames.Zip(portData, ((name, data) => name + ":\n" + data));
return Loc.GetString("gas-analyzable-system-header") + "\n\n" + String.Join("\n\n", outputs);
}
}
}
}

View file

@ -1,6 +1,8 @@
using Content.Shared.Disease;
using Content.Shared.FixedPoint;
using Content.Shared.Chemistry.Reagent;
using Content.Server.Body.Components;
using Robust.Shared.Prototypes;
namespace Content.Server.Disease.Cures
{
@ -30,9 +32,10 @@ namespace Content.Server.Disease.Cures
public override string CureText()
{
if (Reagent == null)
var prototypeMan = IoCManager.Resolve<IPrototypeManager>();
if (Reagent == null || !prototypeMan.TryIndex<ReagentPrototype>(Reagent, out var reagentProt))
return string.Empty;
return (Loc.GetString("diagnoser-cure-reagent", ("units", Min), ("reagent", Reagent)));
return (Loc.GetString("diagnoser-cure-reagent", ("units", Min), ("reagent", reagentProt.Name)));
}
}
}

View file

@ -3,6 +3,7 @@ using Content.Server.Chat.Managers;
using Content.Server.Disease.Components;
using Content.Server.Disease;
using Content.Shared.Disease;
using Content.Shared.MobState.Components;
using Robust.Shared.Random;
using Robust.Shared.Prototypes;
@ -32,16 +33,21 @@ public sealed class DiseaseOutbreak : StationEvent
public override float Weight => WeightNormal;
protected override float EndAfter => 1.0f;
/// <summary>
/// Finds 2-5 random entities that can host diseases
/// Finds 2-5 random, alive entities that can host diseases
/// and gives them a randomly selected disease.
/// They all get the same disease.
/// </summary>
public override void Startup()
{
base.Startup();
var targetList = _entityManager.EntityQuery<DiseaseCarrierComponent>().ToList();
_random.Shuffle(targetList);
List<DiseaseCarrierComponent> aliveList = new();
foreach (var (carrier, mobState) in _entityManager.EntityQuery<DiseaseCarrierComponent, MobStateComponent>())
{
if (!mobState.IsDead())
aliveList.Add(carrier);
}
_random.Shuffle(aliveList);
/// We're going to filter the above out to only alive mobs. Might change after future mobstate rework
var toInfect = _random.Next(2, 5);
@ -51,8 +57,8 @@ public sealed class DiseaseOutbreak : StationEvent
return;
var diseaseSystem = EntitySystem.Get<DiseaseSystem>();
foreach (var target in targetList)
/// Now we give it to people in the list of living disease carriers earlier
foreach (var target in aliveList)
{
if (toInfect-- == 0)
break;

View file

@ -43,12 +43,13 @@ namespace Content.Server.Traitor.Uplink.Telecrystal
if (!_accounts.AddToBalance(acc, tcCount))
return;
EntityManager.DeleteEntity(uid);
var msg = Loc.GetString("telecrystal-component-sucs-inserted",
("source", args.Used), ("target", args.Target));
("source", args.Used), ("target", args.Target));
args.User.PopupMessage(args.User, msg);
EntityManager.DeleteEntity(uid);
args.Handled = true;
}
}

View file

@ -22,23 +22,40 @@ namespace Content.Shared.CCVar
*/
/// <summary>
/// Whether the basic 'hum' ambience will be enabled.
/// </summary>
public static readonly CVarDef<bool> AmbienceBasicEnabled =
CVarDef.Create("ambience.basic_enabled", true, CVar.ARCHIVE | CVar.CLIENTONLY);
/// <summary>
/// How long we'll wait until re-sampling nearby objects for ambience.
/// How long we'll wait until re-sampling nearby objects for ambience. Should be pretty fast, but doesn't have to match the tick rate.
/// </summary>
public static readonly CVarDef<float> AmbientCooldown =
CVarDef.Create("ambience.cooldown", 0.1f, CVar.REPLICATED | CVar.SERVER);
CVarDef.Create("ambience.cooldown", 0.1f, CVar.ARCHIVE | CVar.CLIENTONLY);
/// <summary>
/// How large of a range to sample for ambience.
/// </summary>
public static readonly CVarDef<float> AmbientRange =
CVarDef.Create("ambience.range", 5f, CVar.REPLICATED | CVar.SERVER);
/// <summary>
/// Maximum simultaneous ambient sounds.
/// </summary>
public static readonly CVarDef<int> MaxAmbientSources =
CVarDef.Create("ambience.max_sounds", 64, CVar.REPLICATED | CVar.SERVER);
CVarDef.Create("ambience.max_sounds", 16, CVar.ARCHIVE | CVar.CLIENTONLY);
/// <summary>
/// The minimum value the user can set for ambience.max_sounds
/// </summary>
public static readonly CVarDef<int> MinMaxAmbientSourcesConfigured =
CVarDef.Create("ambience.min_max_sounds_configured", 16, CVar.REPLICATED | CVar.SERVER | CVar.CHEAT);
/// <summary>
/// The maximum value the user can set for ambience.max_sounds
/// </summary>
public static readonly CVarDef<int> MaxMaxAmbientSourcesConfigured =
CVarDef.Create("ambience.max_max_sounds_configured", 64, CVar.REPLICATED | CVar.SERVER | CVar.CHEAT);
/// <summary>
/// Ambience volume.
/// </summary>
public static readonly CVarDef<float> AmbienceVolume =
CVarDef.Create("ambience.volume", 0.0f, CVar.ARCHIVE | CVar.CLIENTONLY);
/*
* Status
*/

View file

@ -1,4 +1,6 @@
circular_saw.ogg - https://freesound.org/people/derjuli/sounds/448133/ and clipped - CC0-1.0
gas_pump - https://freesound.org/people/karinalarasart/sounds/441419/ - CC0-1.0
gas_hiss - https://freesound.org/people/geodylabs/sounds/122803/ - CC BY 3.0
gas_hiss - https://freesound.org/people/geodylabs/sounds/122803/ - CC-BY-3.0
gas_vent - https://freesound.org/people/kyles/sounds/453642/ - CC0-1.0
flowing_water_open - https://freesound.org/people/sterferny/sounds/382322/ - CC0-1.0
server_fans - https://freesound.org/people/DeVern/sounds/610761/ - CC-BY-3.0

Binary file not shown.

View file

@ -1,65 +1,4 @@
Entries:
- author: shaeone
changes:
- {message: Added a decorated tree and presents!, type: Add}
id: 733
time: '2021-12-13T21:21:15.0000000+00:00'
- author: Peptide90
changes:
- {message: Cargonia didn't learn. Crates are now buffed harder so no more cargo
AME or laser crates., type: Tweak}
- {message: Buffed some secure lockers too., type: Tweak}
id: 734
time: '2021-12-14T00:44:59.0000000+00:00'
- author: Venomii
changes:
- {message: Added automatic laugh emote when saying "lol" or "lmao"., type: Add}
id: 735
time: '2021-12-14T01:33:46.0000000+00:00'
- author: ElectroJr
changes:
- {message: Pointing at entities works again., type: Fix}
id: 736
time: '2021-12-14T02:21:55.0000000+00:00'
- author: Mith-randalf
changes:
- {message: 'Using information extracted from captured Assistants, security now
have access to single-use zipties from the security dispenser and cargo''s new
restraints crate.', type: Add}
id: 737
time: '2021-12-14T05:17:27.0000000+00:00'
- author: vulppine
changes:
- {message: NanoTrasen has supplied its stations with t-ray scanners. No longer
will engineers (or other curious crewmembers) have to rip up floor tiles to
reveal what is underneath., type: Add}
id: 738
time: '2021-12-14T07:46:47.0000000+00:00'
- author: zlodo
changes:
- {message: Combat gloves now actually work., type: Fix}
id: 739
time: '2021-12-14T13:08:19.0000000+00:00'
- author: Peptide90
changes:
- {message: T-Ray Scanner can now be obtained from Youtool! As well as some engineering
toolboxes and lockers., type: Add}
id: 740
time: '2021-12-14T20:21:41.0000000+00:00'
- author: metalgearsloth
changes:
- {message: Nanotrasen has thrown a clown into the singularity to improve stability
by 20%., type: Fix}
id: 741
time: '2021-12-15T02:47:13.0000000+00:00'
- author: Matz05
changes:
- {message: Added burger buns! Craftable using one dough slice in the microwave
for 5 seconds., type: Add}
- {message: Changed burger recipes to use one bun instead of two bread slices.,
type: Tweak}
id: 742
time: '2021-12-15T09:24:27.0000000+00:00'
- author: Pancake
changes:
- {message: Rolling paper packs with filters added to cigarette vending machines.,
@ -3013,3 +2952,72 @@ Entries:
take items from other users inventories., type: Fix}
id: 1232
time: '2022-03-20T01:46:08.0000000+00:00'
- author: moonheart08
changes:
- {message: Nanotrasen finally figured out that still water in hydroponics trays
attracts space mosquitos and installed micropumps., type: Add}
- {message: Nanotrasen has finally installed ventilation on their R&D servers.,
type: Add}
- {message: The volume and quality of the game's ambience can be adjusted in settings.,
type: Add}
id: 1233
time: '2022-03-20T04:45:52.0000000+00:00'
- author: notafet
changes:
- {message: Gas analyzers can now be used to examine contents of pipes., type: Add}
id: 1234
time: '2022-03-20T05:10:48.0000000+00:00'
- author: Macoron
changes:
- {message: Pineapple botany sprite was fixed., type: Fix}
id: 1235
time: '2022-03-20T12:46:41.0000000+00:00'
- author: CrudeWax
changes:
- {message: fixed holoparasite ToS not being readable, type: Fix}
id: 1236
time: '2022-03-20T13:04:47.0000000+00:00'
- author: CrudeWax
changes:
- {message: fixed the popup for inserting TC into the uplink, type: Fix}
- {message: updated emag to look more like the rest of the ID cards, type: Tweak}
id: 1237
time: '2022-03-20T21:59:50.0000000+00:00'
- author: CrudeWax
changes:
- {message: fixes all written information to be actually readable. You are finally
free to enjoy books!, type: Fix}
id: 1238
time: '2022-03-20T21:59:57.0000000+00:00'
- author: Rane
changes:
- {message: Disease Outbreak event will no longer infect dead mobs., type: Fix}
- {message: Fixed typo in the name of a drink., type: Fix}
- {message: Renamed 'Medicine Resistance' in the disease report to 'Spaceacillin
Resistance' to make it more clear., type: Tweak}
- {message: Disease reports now use the player-facing name of any special cure reagents.,
type: Tweak}
- {message: Updated vaccine description to help out people who have somehow made
it to 2022 anno Domini without understanding what a vaccine is for., type: Tweak}
id: 1239
time: '2022-03-20T22:29:12.0000000+00:00'
- author: ElectroJr
changes:
- {message: Fixed a bug causing clothing layers to be drawn in the order that they
were equipped., type: Fix}
id: 1240
time: '2022-03-20T22:29:20.0000000+00:00'
- author: TimrodDX
changes:
- {message: Delta Station's beta atmos system is now complete!, type: Tweak}
- {message: Fixed the chemistry desk and EVA on Delta., type: Tweak}
- {message: Added some lights to Delta. Please let me know of any spots that are
too dim., type: Tweak}
id: 1241
time: '2022-03-20T23:04:53.0000000+00:00'
- author: DogZeroX
changes:
- {message: Touching a lightbulb no longer causes third-degree burns (20 -> 5),
type: Tweak}
id: 1242
time: '2022-03-21T04:48:58.0000000+00:00'

View file

@ -0,0 +1,7 @@
gas-analyzable-system-internal-error-missing-component = Your gas analyzer whirrs for a while, then stops.
gas-anlayzable-system-internal-error-no-gas-node = Your gas analyzer reads, "NO GAS FOUND".
gas-analyzable-system-verb-name = Analyze
gas-analyzable-system-verb-tooltip = Analyze Contents
gas-analyzable-system-header = Your gas analyzer shows a list of statistics:
gas-analyzable-system-statistics = Pressure: {PRESSURE($pressure)}
Temperature: {$tempK}K ({$tempC}°C)

View file

@ -6,10 +6,10 @@ diagnoser-disease-report-none-contents = [color=green]No diseases were found in
diagnoser-disease-report-name = Disease Name: {CAPITALIZE($disease)}
diagnoser-disease-report-infectious = Infectious: [color=red]Yes[/color]
diagnoser-disease-report-not-infectious = Infectious: [color=green]No[/color]
diagnoser-disease-report-cureresist-none = Medication Resistance: [color=green]None[/color]
diagnoser-disease-report-cureresist-low = Medication Resistance: [color=yellow]Low[/color]
diagnoser-disease-report-cureresist-medium = Medication Resistance: [color=orange]Medium[/color]
diagnoser-disease-report-cureresist-high = Medication Resistance: [color=red]High[/color]
diagnoser-disease-report-cureresist-none = Spaceacillin Resistance: [color=green]None[/color]
diagnoser-disease-report-cureresist-low = Spaceacillin Resistance: [color=yellow]Low[/color]
diagnoser-disease-report-cureresist-medium = Spaceacillin Resistance: [color=orange]Medium[/color]
diagnoser-disease-report-cureresist-high = Spaceacillin Resistance: [color=red]High[/color]
diagnoser-cure-none = The disease has no specific cures.
diagnoser-cure-has = The disease has the following cures:
diagnoser-cure-bedrest = Rest in bed for {$time} seconds.

View file

@ -13,7 +13,8 @@ ui-options-reset-all = Reset All
ui-options-master-volume = Master Volume:
ui-options-midi-volume = MIDI (Instrument) Volume:
ui-options-ambient-hum = Ambient Hum
ui-options-ambience-volume = Ambience volume:
ui-options-ambience-max-sounds = Ambience simultaneous sounds:
ui-options-lobby-music = Lobby Music
ui-options-volume-label = Volume
ui-options-volume-percent = { TOSTRING($volume, "P0") }
@ -152,4 +153,4 @@ ui-options-function-loadout9 = Hotbar Loadout 9
## Network menu
ui-options-net-interp-ratio = Network Smoothing
ui-options-net-interp-ratio = Network Smoothing

View file

@ -1 +1 @@
telecrystal-component-sucs-inserted = You slot {$source} into the {$target}.
telecrystal-component-sucs-inserted = You slot {THE($source)} into {THE($target)}.

File diff suppressed because it is too large Load diff

View file

@ -26,6 +26,8 @@
netsync: false
sprite: Objects/Misc/guardian_info.rsi
state: guardian_info
- type: ActivatableUI
key: enum.PaperUiKey.Key
- type: UserInterface
interfaces:
- key: enum.PaperUiKey.Key

View file

@ -125,7 +125,7 @@
id: UplinkEmag
category: Utility
itemId: Emag
description: This sequencer, or "emag", can be used to open or hack a huge variety of items around the station.
description: The business card of the syndicate, this sequencer is able to break open airlocks and tamper with a variety of station devices. Recharges automatically.
icon: /Textures/Objects/Tools/emag.rsi/icon.png
price: 8

View file

@ -135,4 +135,3 @@
min: 420 ## Reachable with a flamer
- !type:DiseaseReagentCure
reagent: Theobromine
amount: 10

View file

@ -9,6 +9,8 @@
layers:
- state: book0
- type: Paper
- type: ActivatableUI
key: enum.PaperUiKey.Key
- type: UserInterface
interfaces:
- key: enum.PaperUiKey.Key

View file

@ -42,6 +42,12 @@
# Changing it here is fine - if the PaperStatus key is actually added,
# something happened, so that ought to override this either way.
- state: paper_words
- type: ActivatableUI
key: enum.PaperUiKey.Key
- type: UserInterface
interfaces:
- key: enum.PaperUiKey.Key
type: PaperBoundUserInterface
- type: entity
parent: PaperWritten

View file

@ -19,7 +19,7 @@
parent: BaseItem
id: Vaccine
name: Vaccine
description: There's no way you don't already have an opinion on these.
description: Prevents people who DON'T already have a disease from catching it.
components:
- type: Item
size: 3

View file

@ -2,7 +2,7 @@
parent: BaseItem
id: Emag
name: cryptographic sequencer
description: The iconic card of ill omen.
description: The all-in-one hacking solution. The thinking man's lockpick. The iconic EMAG.
components:
- type: Emag
- type: Sprite

View file

@ -29,7 +29,11 @@
SheetSteel1:
min: 1
max: 2
- type: AmbientSound
volume: -9
range: 5
sound:
path: /Audio/Ambience/Objects/server_fans.ogg
- type: entity
id: BaseResearchAndDevelopmentPointSource
parent: BaseMachinePowered

View file

@ -71,6 +71,7 @@
range: 2
sound:
path: /Audio/Ambience/Objects/gas_hiss.ogg
- type: GasAnalyzable
#Note: The PipeDirection of the PipeNode should be the south-facing version, because the entity starts at an angle of 0 (south)

View file

@ -84,7 +84,7 @@
bulb: Tube
damage:
types:
Heat: 20
Heat: 5
- type: ApcPowerReceiver
- type: ExtensionCableReceiver
- type: DeviceNetworkComponent
@ -108,7 +108,7 @@
hasLampOnSpawn: LightTube
damage:
types:
Heat: 20
Heat: 5
- type: entity
id: PoweredlightLED
@ -120,7 +120,7 @@
hasLampOnSpawn: LedLightTube
damage:
types:
Heat: 20
Heat: 5
- type: entity
parent: WallLight
@ -143,7 +143,7 @@
hasLampOnSpawn: ExteriorLightTube
damage:
types:
Heat: 20
Heat: 5
- type: entity
parent: WallLight
@ -167,7 +167,7 @@
hasLampOnSpawn: SodiumLightTube
damage:
types:
Heat: 20
Heat: 5
- type: entity
parent: WallLight
@ -250,7 +250,7 @@
bulb: Bulb
damage:
types:
Heat: 20
Heat: 5
- type: ApcPowerReceiver
- type: ExtensionCableReceiver
- type: DeviceNetworkComponent
@ -271,4 +271,4 @@
hasLampOnSpawn: LightBulb
damage:
types:
Heat: 20
Heat: 5

View file

@ -39,4 +39,8 @@
- type: Wires
BoardName: "HydroponicsTray"
LayoutId: HydroponicsTray
- type: AmbientSound
volume: -9
range: 5
sound:
path: /Audio/Ambience/Objects/flowing_water_open.ogg

View file

@ -139,6 +139,7 @@
yield: 4
potency: 10
idealLight: 8
growthStages: 3
chemicals:
Nutriment:
Min: 1

View file

@ -276,7 +276,7 @@
- type: reagent
id: BananaHonk
name: banana mama
name: banana honk
parent: BaseAlcohol
desc: A drink from Clown Heaven.
physicalDesc: strong-smelling

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 B

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 404 B

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 388 B

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

After

Width:  |  Height:  |  Size: 365 B

@ -1 +1 @@
Subproject commit 452ad5a6e533316afba8284d526772ff12bc28bd
Subproject commit 7378cc50a17487a7d42293276ca0d7a6e96c2d8b