Compare commits

...
Author SHA1 Message Date
Delta-V bot 1856f65a18 Automatic changelog update 2026-09-07 02:34:02 +02:00
brainslushie 9066c4af7f Surplus boots - cosmetic jackboots (#6472)
* +surplus boots

* surplus boots in vendor
2026-09-06 21:33:42 -03:00
Stxcking cf9a10af4e PORT: Thaven Markings and Organs from Macrocosm (#6162)
* Can't go wrong with Sprites

* .ftl and .yml files

* displacement + parts + organs

* marking and displacement yaml

* does arent real...yet

* Imp dupe nuke

* go my human+

* no shaders :<

* whoopsie

idk how
2026-09-06 21:18:44 -03:00
Delta-V bot 2d7af5622f Automatic changelog update 2026-09-07 02:17:42 +02:00
nlaky 974f5ff5fa Vulp alt tail wag + fade tip fix (#6480)
* Add wag markings for vulp alt tail

* Fix tip markings used for fade tails
2026-09-06 21:17:22 -03:00
Delta-V bot 88dc8af9a4 Automatic changelog update 2026-09-07 01:36:12 +02:00
BriBrooo 7c33759cbe Update Botanicals.xml (#6483)
Fixes a duplicate entry in the botanical reagent guidebook.
2026-09-06 20:35:52 -03:00
Delta-V bot baf009af3a Automatic changelog update 2026-09-05 16:03:30 +02:00
Field Command b59dfa8991 Central Command remake! (#6198)
* New Central Command

* Me forget

* typos and name change

* Fix and typo

* More polish

* Requested Fixes
2026-09-05 09:03:08 -05:00
github-actions[bot]andDeltaV-Bot e43a587ede Update Credits (#6465)
Co-authored-by: DeltaV-Bot <github@deltav.gay>
2026-08-30 05:00:27 +02:00
Delta-V bot 00d77213c6 Automatic changelog update 2026-08-29 01:54:53 +02:00
VapeandVanessa 389a616138 Ramping Scheduler adjustments and changes (#6440)
* Update roundstart.yml

* updakes

* Rnd 2 fight

* Changes done

* Apply suggestion from @ShepardToTheStars

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

* Apply batched suggestions from code review

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-08-28 23:54:33 +00:00
Delta-V bot 07b029ff2b Automatic changelog update 2026-08-28 18:38:29 +02:00
Carol 1043b40246 Added caseless shotgun shells (#6457)
added caseless shotgun shells
2026-08-28 11:38:08 -05:00
Delta-V bot d0385ab8bb Automatic changelog update 2026-08-27 21:26:28 +02:00
03347ed416 Inverse Labels and Handlabeler menu (#6432)
Merge pull request #1120 from oooielp/label-invert (#783)

Co-authored-by: Khaomi <46065349+Khaomi@users.noreply.github.com>
Co-authored-by: Superlagg <sprambersonson@gmail.com>
2026-08-27 14:26:07 -05:00
Delta-V bot e9f0148287 Automatic changelog update 2026-08-27 21:24:33 +02:00
SumofThreePartsandVanessa 0f7131d9e7 Buffing the Hushpup (#6438)
* Buffing the Hushpup

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* Doing the thing

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* doing the thang

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* Changing it back

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

---------

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-08-27 16:24:13 -03:00
Delta-V bot bf9b42c76c Automatic changelog update 2026-08-27 20:38:01 +02:00
a635429d3e Communications console & screens overhaul (#5954)
* i'm going insane from screens

* some wiring

* screemes

* holy shit adhd lock-in

* incomplete

* its FUCKING DONE

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* zeta

* mrrrp

* test fix

* fix arrivals

* fix misnetwork

* Fix iteration outline. Fixed all headers showing if all options where hidden. Added access requirement to keycard auth mechnism. Added countdown. Fixed ninja and fugitive. Fixed AI and aghost.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Vanessa <vanessalouwagie@gmail.com>
2026-08-27 13:37:40 -05:00
Delta-V bot bd1e4224cd Automatic changelog update 2026-08-27 20:32:18 +02:00
Vanessa 568621858e Trees are now actually rooted and cannot move. (#6456) 2026-08-27 13:31:58 -05:00
Delta-V bot 3df2209227 Automatic changelog update 2026-08-27 16:29:59 +02:00
1da052e36f Letting the patos be purchased (#6361)
* Making Patos a thing you can buy

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* Update armory.yml

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update cargo_armory.yml

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* Update armory.yml

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* Update armory.yml

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* Update armory.yml

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* Update magazine amount in armory.yml

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* thankies

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* thankies 2

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

---------

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-08-27 11:29:39 -03:00
Delta-V bot 66b95a46ed Automatic changelog update 2026-08-26 10:35:09 +02:00
Vanessa 92ba9edeee Small Midround Antag Balance Pass (#6410)
* Nerfed skia regen.

* Nerfed ninja dash

* Fix ninja agent id

* Skia tweak

* Add reveal to rev attack

* Apply suggestion from @ShepardToTheStars

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-08-26 10:34:48 +02:00
Delta-V bot 680092719f Automatic changelog update 2026-08-24 18:23:27 +02:00
Vanessa 1afbadd404 Fix Health Analyzer Not Showing Traits (#6446)
* Fixed some alerts not showing in the health analyzer

* This is upstream now so removing comments
2026-08-24 11:23:07 -05:00
Delta-V bot 2c190cf2f2 Automatic changelog update 2026-08-24 17:14:11 +02:00
Vanessa 17d798a3e8 Stole Thief Gloves from the Uplink (#6425)
Stole thief gloves from the uplink.
2026-08-24 10:13:51 -05:00
Delta-V bot 287714d87b Automatic changelog update 2026-08-23 17:00:54 +02:00
Vanessa 029aaf8127 Fix Mothroach Grenades (#6447)
Fix mothroach grenades
2026-08-23 10:00:34 -05:00
541 changed files with 141414 additions and 44709 deletions
@@ -28,7 +28,6 @@ namespace Content.Client.Communications.UI
_menu.OnBroadcast += BroadcastButtonPressed;
_menu.OnAlertLevel += AlertLevelSelected;
_menu.OnEmergencyLevel += EmergencyShuttleButtonPressed;
_menu.OnExfiltrationLevel += ExfiltrationShuttleButtonPressed; // DeltaV - Exfiltration shuttle
}
public void AlertLevelSelected(string level)
@@ -48,13 +47,6 @@ namespace Content.Client.Communications.UI
CallShuttle();
}
// Begin DeltaV - Exfiltration Shuttle
public void ExfiltrationShuttleButtonPressed()
{
SendMessage(new CommunicationsConsoleExfiltrationShuttleMessage(!_menu!.CountdownStarted));
}
// End DeltaV - Exfiltration Shuttle
public void AnnounceButtonPressed(string message)
{
var maxLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
@@ -94,13 +86,6 @@ namespace Content.Client.Communications.UI
_menu.CurrentLevel = commsState.CurrentAlert;
_menu.CountdownEnd = commsState.ExpectedCountdownEnd;
// Begin DeltaV - Exfiltration Shuttle
_menu.CanExfiltrate = commsState.CanCall;
_menu.ExfiltrationCountdownEnd = commsState.ExpectedExfiltrationCountdownEnd;
_menu.ExfiltrationShuttleButton.Disabled = !_menu.CanExfiltrate;
// End DeltaV - Exfiltration Shuttle
_menu.UpdateCountdown();
_menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel);
_menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable;
@@ -52,19 +52,10 @@
<RichTextLabel Name="CountdownLabel"/>
<!-- DeltaV - Exfiltration Shuttle -->
<RichTextLabel Name="ExfiltrationCountdownLabel"/>
<Button Name="EmergencyShuttleButton"
Access="Public"
Text="Placeholder Text"
ToolTip="{Loc 'comms-console-menu-emergency-shuttle-button-tooltip'}"/>
<!-- DeltaV - Exfiltration Shuttle -->
<Button Name="ExfiltrationShuttleButton"
Access="Public"
Text="Placeholder Text"
ToolTip="{Loc 'comms-console-menu-exfiltration-shuttle-button-tooltip'}"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
@@ -29,12 +29,6 @@ namespace Content.Client.Communications.UI
public event Action<string>? OnAnnounce;
public event Action<string>? OnBroadcast;
// Begin DeltaV - Exfiltration Shuttle
public bool CanExfiltrate;
public TimeSpan? ExfiltrationCountdownEnd;
public event Action? OnExfiltrationLevel;
// End DeltaV - Exfiltration Shuttle
public CommunicationsConsoleMenu()
{
IoCManager.InjectDependencies(this);
@@ -78,18 +72,12 @@ namespace Content.Client.Communications.UI
EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke();
EmergencyShuttleButton.Disabled = !CanCall;
// Begin DeltaV - Exfiltration Shuttle
ExfiltrationShuttleButton.OnPressed += _ => OnExfiltrationLevel?.Invoke();
ExfiltrationShuttleButton.Disabled = !CanExfiltrate;
// End DeltaV - Exfiltration Shuttle
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
UpdateCountdown();
UpdateExfiltrationCountdown(); // DeltaV - Exfiltration shuttle
}
// The current alert could make levels unselectable, so we need to ensure that the UI reacts properly.
@@ -129,25 +117,6 @@ namespace Content.Client.Communications.UI
}
}
// Begin DeltaV - Exfiltration Shuttle
public void UpdateExfiltrationCountdown()
{
if (ExfiltrationCountdownEnd is null)
{
ExfiltrationCountdownLabel.SetMessage(string.Empty);
ExfiltrationShuttleButton.Text = Loc.GetString("comms-console-menu-call-exfiltration");
return;
}
var exfiltrationDiff = MathHelper.Max((ExfiltrationCountdownEnd - _timing.CurTime) ?? TimeSpan.Zero, TimeSpan.Zero);
ExfiltrationShuttleButton.Text = Loc.GetString("comms-console-menu-recall-exfiltration");
var exfiltrationInfoText = Loc.GetString("comms-console-menu-exfiltration-time-remaining",
("time", exfiltrationDiff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
ExfiltrationCountdownLabel.SetMessage(exfiltrationInfoText);
}
// End DeltaV - Exfiltration Shuttle
public void UpdateCountdown()
{
if (!CountdownStarted)
@@ -179,9 +179,12 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
var unborgable = _unborgable.IsUnborgable(target.Value);
var redshirt = _redshirt.IsRedshirt(target.Value) && mobStateComponent?.CurrentState == MobState.Dead; // DeltaV - Redshirt
var uncloneable = _uncloneable.IsUncloneable(target.Value) && mobStateComponent?.CurrentState == MobState.Dead; // DeltaV - Unclonable
// I'm just going to lump them all into 'extraTraitAlerts' to group our modifications as a single bool in the next check
var extraTraitAlerts = unborgable || redshirt || uncloneable;
// END DeltaV
var showAlerts = state.Unrevivable == true || state.Bleeding == true;
var showAlerts = state.Unrevivable == true || state.Bleeding == true || extraTraitAlerts; // DeltaV - extra alerts
AlertsDivider.Visible = showAlerts;
AlertsContainer.Visible = showAlerts;
@@ -32,10 +32,10 @@ namespace Content.Client.Labels.UI
}
_window.OnLabelChanged += OnLabelChanged;
_window.OnLabelSelected += OnLabelSelected; // Starlight
Reload();
_window.SetInitialLabelState(); // Must be after Reload() has set the label text
}
private void OnLabelChanged(string newLabel)
{
// Focus moment
@@ -45,7 +45,17 @@ namespace Content.Client.Labels.UI
SendPredictedMessage(new HandLabelerLabelChangedMessage(newLabel));
}
// Starlight start
private void OnLabelSelected(string label)
{
// Update UI and send message to sync with server
if (_window != null)
{
_window.SetCurrentLabel(label);
}
SendPredictedMessage(new HandLabelerLabelChangedMessage(label));
}
// Starlight End
public void Reload()
{
if (_window == null || !_entManager.TryGetComponent(Owner, out HandLabelerComponent? component))
@@ -1,8 +1,10 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Title="{Loc 'hand-labeler-ui-header'}"
SetWidth="400"
MinWidth="150">
MinWidth="150"
SetHeight="400"> <!-- Starlight - include gfx and set default height to include saved labels section nicely -->
<BoxContainer Orientation="Vertical" SeparationOverride="4">
<Label Name="CurrentTextLabel" Text="{Loc 'hand-labeler-current-text-label'}" />
<LineEdit Name="LabelLineEdit" />
@@ -10,5 +12,19 @@
<Button Name="ResetLabelButton" Text="{Loc 'hand-labeler-ui-reset-label-text'}" StyleClasses="OpenRight" />
<Button Name="ClearLabelButton" Text="{Loc 'hand-labeler-ui-clear-label-text'}" StyleClasses="OpenLeft" />
</BoxContainer>
<!-- Starlight Begin -->
<Label Text="{Loc 'hand-labeler-saved-labels'}" />
<PanelContainer VerticalExpand="True" SizeFlagsStretchRatio="1">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1B1E" />
</PanelContainer.PanelOverride>
<ItemList Name="SavedLabelsList" VerticalExpand="True" SelectMode="Button" />
</PanelContainer>
<BoxContainer Orientation="Horizontal" Align="Center">
<Button Name="SaveLabelButton" Text="{Loc 'hand-labeler-save-label-text'}" StyleClasses="OpenRight" />
<Button Name="DeleteLabelButton" Text="{Loc 'hand-labeler-delete-label-text'}" StyleClasses="OpenLeft" />
</BoxContainer>
<!-- Starlight end -->
</BoxContainer>
</DefaultWindow>
@@ -1,13 +1,19 @@
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Client.UserInterface.Controls; // Starlight
using Robust.Shared.Configuration; // Starlight
using Content.Shared.Starlight.CCVar; // Starlight
namespace Content.Client.Labels.UI
{
[GenerateTypedNameReferences]
public sealed partial class HandLabelerWindow : DefaultWindow
{
[Dependency] private readonly IConfigurationManager _cfg = default!; // Starlight
public event Action<string>? OnLabelChanged;
public event Action<string>? OnLabelSelected; // Starlight
/// <summary>
/// Is the user currently entering text into the control?
@@ -17,10 +23,14 @@ namespace Content.Client.Labels.UI
private string _label = string.Empty;
private string _initialLabel = string.Empty;
private bool _deleteMode = false; // Starlight
private List<string> _savedLabels = []; // Starlight
public HandLabelerWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this); // Starlight
LoadSavedLabelsFromCVar(); // Starlight
LabelLineEdit.OnTextChanged += e =>
{
@@ -37,6 +47,42 @@ namespace Content.Client.Labels.UI
};
ResetLabelButton.OnPressed += _ => LabelLineEdit.SetText(_initialLabel, true);
ClearLabelButton.OnPressed += _ => LabelLineEdit.SetText("", true);
// Starlight Begin
SaveLabelButton.OnPressed += _ =>
{
if (!string.IsNullOrWhiteSpace(_label) && !_savedLabels.Contains(_label))
{
_savedLabels.Add(_label);
SaveSavedLabelsToCVar();
UpdateSavedLabels(_savedLabels);
}
};
DeleteLabelButton.OnPressed += _ =>
{
_deleteMode = !_deleteMode;
DeleteLabelButton.Pressed = _deleteMode;
UpdateButtons();
};
SavedLabelsList.OnItemSelected += args =>
{
if (_deleteMode)
{
_savedLabels.RemoveAt(args.ItemIndex);
SaveSavedLabelsToCVar();
UpdateSavedLabels(_savedLabels);
UpdateButtons();
}
else
{
if (SavedLabelsList[args.ItemIndex].Metadata is string label)
{
OnLabelSelected?.Invoke(label);
}
}
}; // Starlight End
}
protected override void Opened()
@@ -70,15 +116,68 @@ namespace Content.Client.Labels.UI
UpdateButtons();
}
// Starlight begin
public void UpdateSavedLabels(List<string> labels)
{
var items = new List<ItemList.Item>();
foreach (var label in labels)
{
var item = new ItemList.Item(SavedLabelsList)
{
Text = label,
Metadata = label
};
items.Add(item);
}
SavedLabelsList.SetItems(items);
UpdateButtons();
}
// Starlight end
public void UpdateButtons()
{
ResetLabelButton.Disabled = (LabelLineEdit.Text == _initialLabel);
ClearLabelButton.Disabled = (LabelLineEdit.Text == "");
}
// Starlight begin
var labelExists = false;
foreach (var item in SavedLabelsList)
{
if ((item.Metadata as string) == _label.Trim())
{
labelExists = true;
break;
}
}
SaveLabelButton.Disabled = string.IsNullOrWhiteSpace(_label) || labelExists;
DeleteLabelButton.Text = _deleteMode
? Loc.GetString("hand-labeler-delete-mode-text")
: Loc.GetString("hand-labeler-delete-label-text");
// Starlight end
}
public void SetMaxLabelLength(int maxLength)
{
LabelLineEdit.IsValid = s => s.Length <= maxLength;
}
// Starlight begin
private void LoadSavedLabelsFromCVar()
{
var savedLabelsStr = _cfg.GetCVar(StarlightCCVars.HandLabelerSavedLabels);
if (!string.IsNullOrEmpty(savedLabelsStr))
{
_savedLabels = new List<string>(savedLabelsStr.Split('\n', StringSplitOptions.RemoveEmptyEntries));
UpdateSavedLabels(_savedLabels);
}
}
private void SaveSavedLabelsToCVar()
{
var savedLabelsStr = string.Join('\n', _savedLabels);
_cfg.SetCVar(StarlightCCVars.HandLabelerSavedLabels, savedLabelsStr);
_cfg.SaveToFile();
}
// Starlight end
}
}
@@ -70,6 +70,11 @@ public sealed class ConfirmButton : Button
[ViewVariables]
public bool IsConfirming = false;
// Begin DeltaV
[ViewVariables]
public bool ForceDisabled = false;
// End DeltaV
public ConfirmButton()
{
IoCManager.InjectDependencies(this);
@@ -87,7 +92,7 @@ public sealed class ConfirmButton : Button
}
if (Disabled && _gameTiming.CurTime > _nextCooldown)
Disabled = false;
Disabled = ForceDisabled; // DeltaV
}
protected override void DrawModeChanged()
@@ -0,0 +1,30 @@
using Content.Shared._DV.Communications;
using Robust.Client.UserInterface;
namespace Content.Client._DV.Communications;
public sealed class DVCommunicationsConsoleBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IEntityManager _entity = default!;
private DVCommunicationsConsoleMenu? _menu;
public DVCommunicationsConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_menu = this.CreateWindow<DVCommunicationsConsoleMenu>();
_menu.OnMessage += SendMessage;
if (_entity.TryGetComponent<DVCommunicationsConsoleComponent>(Owner, out var comp))
Update((Owner, comp));
}
public void Update(Entity<DVCommunicationsConsoleComponent> ent)
{
_menu?.Update(ent, PlayerManager.LocalEntity!.Value);
}
}
@@ -0,0 +1,117 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'comms-console-menu-title'}"
MinSize="400 300">
<BoxContainer Name="HomeScreen" Orientation="Vertical" Margin="8">
<Label Text="{Loc 'comms-console-menu-station-title'}" Name="StationHeaderLabel" StyleClasses="LabelKeyText" />
<Button Name="AnnouncementTab" Text="{Loc 'comms-console-menu-tab.Announcement'}" />
<Button Name="ScreenTab" Text="{Loc 'comms-console-menu-tab.Screen'}" />
<Button Name="AlertLevelTab" Text="{Loc 'comms-console-menu-tab.AlertLevel'}" />
<Label Text="{Loc 'comms-console-menu-transit-title'}" Name="TransitHeaderLabel" StyleClasses="LabelKeyText" Margin="0 8 0 0" />
<Button Name="ShuttlesTab" Text="{Loc 'comms-console-menu-tab.Shuttles'}" />
<Label Text="{Loc 'comms-console-menu-emergency-title'}" Name="EmergencyHeaderLabel" StyleClasses="LabelKeyText" Margin="0 8 0 0" />
<Button Name="KeycardAuthenticationDeviceTab" Text="{Loc 'comms-console-menu-tab.KeycardAuthenticationDevice'}" />
</BoxContainer>
<BoxContainer Orientation="Vertical">
<Button Name="HomeButton" Text="{Loc 'comms-console-menu-home'}" Visible="False" />
<BoxContainer Name="AnnouncementScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" VerticalExpand="True">
<BoxContainer SeparationOverride="8" Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-announcement-text'}" StyleClasses="LabelKeyText" />
<TextEdit Name="AnnounceInput"
VerticalExpand="True"
HorizontalExpand="True"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
MinHeight="100" />
</BoxContainer>
</PanelContainer>
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True">
<Button Name="AnnounceButton" Margin="8" Text="{Loc 'comms-console-menu-send-announcement'}" />
</PanelContainer>
</BoxContainer>
<BoxContainer Name="ScreenScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True">
<BoxContainer SeparationOverride="8" Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-screen-configuration'}" StyleClasses="LabelKeyText" />
<BoxContainer>
<Label Text="{Loc 'comms-console-menu-screen-contents'}" HorizontalExpand="True" />
<OptionButton Name="ScreenContentsButton" />
</BoxContainer>
<BoxContainer>
<Label Text="{Loc 'comms-console-menu-alert-level-border'}" HorizontalExpand="True" />
<Button Name="ScreenAlertBorder" Text="{Loc 'comms-console-menu-enable-border'}" ToggleMode="True" />
</BoxContainer>
</BoxContainer>
</PanelContainer>
<PanelContainer StyleClasses="PanelDark">
<BoxContainer Margin="8" Orientation="Vertical" SeparationOverride="4">
<Label Text="{Loc 'comms-console-menu-screen-text'}" StyleClasses="LabelKeyText" />
<GridContainer Columns="2" HorizontalExpand="True">
<Label Text="{Loc 'comms-console-menu-line-1'}" />
<LineEdit Name="ScreenLine1" HorizontalExpand="True" StyleClasses="comms-console-display" />
<Label Text="{Loc 'comms-console-menu-line-2'}" />
<LineEdit Name="ScreenLine2" HorizontalExpand="True" StyleClasses="comms-console-display" />
</GridContainer>
<Button Name="ScreenUpdateTextButton" Text="{Loc 'comms-console-menu-update-screen-text'}" HorizontalAlignment="Right" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
<BoxContainer Name="ShuttlesScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-emergency-shuttle'}" StyleClasses="LabelKeyText" />
<RichTextLabel Name="EmergencyStatus" Text="{Loc 'comms-console-menu-shuttle-not-coming'}" />
<Button Name="ShuttleEmergencyButton" Text="{Loc 'comms-console-menu-call-emergency.True'}" HorizontalAlignment="Right" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-exfiltration-shuttle'}" StyleClasses="LabelKeyText" />
<RichTextLabel Name="ExfiltrationStatus" Text="{Loc 'comms-console-menu-shuttle-not-coming'}" />
<Button Name="ShuttleExfiltrationButton" Text="{Loc 'comms-console-menu-call-exfiltration.True'}" HorizontalAlignment="Right" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
<BoxContainer Name="AlertLevelScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" MaxWidth="400">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-alert-level'}" StyleClasses="LabelKeyText" />
<RichTextLabel Name="AlertLevel" HorizontalExpand="True" />
<Button Name="AlertLevelsDropdown" Text="{Loc 'comms-console-menu-change-alert-level'}" HorizontalAlignment="Right" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
<BoxContainer Name="KeycardAuthenticationDeviceScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" MaxWidth="400">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-declare-mayday.title'}" StyleClasses="LabelKeyText" />
<RichTextLabel Text="{Loc 'comms-console-menu-declare-mayday.desc'}" />
<controls:ConfirmButton Name="CallZeta" Text="{Loc 'comms-console-menu-declare-mayday.button'}" HorizontalAlignment="Stretch" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" MaxWidth="400">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-request-codes.title'}" StyleClasses="LabelKeyText" />
<RichTextLabel Text="{Loc 'comms-console-menu-request-codes.desc'}" />
<controls:ConfirmButton Name="RequestCodes" Text="{Loc 'comms-console-menu-request-codes.button'}" HorizontalAlignment="Stretch" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
@@ -0,0 +1,320 @@
using System.Globalization;
using System.Numerics;
using Content.Client.UserInterface.Controls;
using Content.Shared._DV.Communications;
using Content.Shared._DV.KeycardAuthenticationDevice;
using Content.Shared._DV.Screens;
using Content.Shared.Humanoid;
using Content.Shared.Station;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Content.Client._DV.Communications;
[GenerateTypedNameReferences]
public sealed partial class DVCommunicationsConsoleMenu : FancyWindow
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IEntityManager _entity = default!;
private readonly SharedStationSystem _station;
private readonly BoxContainer[] _screens;
private readonly ButtonGroup _group;
public event Action<BoundUserInterfaceMessage>? OnMessage;
private Entity<DVCommunicationsConsoleComponent>? _console;
private Entity<DVStationKeycardAuthenticationDeviceComponent>? _stationKeycardAuthenticationDevice;
private EntityUid? _user;
private readonly Popup _alertLevelsPopup;
private readonly BoxContainer _alertLevels = new()
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
};
private string _lastConfiguredLine1 = string.Empty;
private string _lastConfiguredLine2 = string.Empty;
public DVCommunicationsConsoleMenu()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_station = _entity.System<SharedStationSystem>();
_group = new();
_screens = new[]
{
HomeScreen, AnnouncementScreen, ScreenScreen, ShuttlesScreen, AlertLevelScreen,
KeycardAuthenticationDeviceScreen,
};
HomeButton.OnPressed += _ => SetScreen(HomeScreen);
AnnouncementTab.OnPressed += _ => SetScreen(AnnouncementScreen);
ScreenTab.OnPressed += _ => SetScreen(ScreenScreen);
ShuttlesTab.OnPressed += _ => SetScreen(ShuttlesScreen);
AlertLevelTab.OnPressed += _ => SetScreen(AlertLevelScreen);
KeycardAuthenticationDeviceTab.OnPressed += _ => SetScreen(KeycardAuthenticationDeviceScreen);
foreach (var value in Enum.GetValues<DVScreenContent>())
{
ScreenContentsButton.AddItem(Loc.GetString($"comms-console-menu-screen-content.{value}"), (int)value);
}
AnnounceButton.OnPressed += OnAnnouncePressed;
ScreenUpdateTextButton.OnPressed += OnUpdateScreenText;
ScreenContentsButton.OnItemSelected += OnScreenContentsSelected;
ScreenAlertBorder.OnToggled += OnScreenAlertBorderToggled;
ShuttleEmergencyButton.OnPressed += OnEmergencyPressed;
ShuttleExfiltrationButton.OnPressed += OnExfiltrationPressed;
AlertLevelsDropdown.OnPressed += OnAlertLevelsDropdownPressed;
CallZeta.OnPressed += OnCallZetaPressed;
RequestCodes.OnPressed += OnRequestCodesPressed;
_alertLevelsPopup = new()
{
Children = { _alertLevels },
};
_alertLevelsPopup.OnPopupHide += () => _alertLevelsPopup.Orphan();
AnnounceInput.Placeholder = new Rope.Leaf(Loc.GetString("comms-console-menu-announcement-placeholder"));
}
private void OnAlertLevelsDropdownPressed(BaseButton.ButtonEventArgs args)
{
var globalPos = AlertLevelsDropdown.GlobalPosition;
globalPos.Y += AlertLevelsDropdown.Size.Y + 1; // Place it below us, with a safety margin.
_alertLevels.Measure(Window?.Size ?? Vector2Helpers.Infinity);
var (minX, minY) = _alertLevels.DesiredSize;
var box = UIBox2.FromDimensions(globalPos, new Vector2(Math.Max(minX, AlertLevelsDropdown.Width), minY));
_alertLevelsPopup.Orphan();
Root?.ModalRoot.AddChild(_alertLevelsPopup);
_alertLevelsPopup.Open(box);
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_console is not { } console)
return;
AnnounceButton.Disabled = _timing.CurTime <= console.Comp.CanAnnounceAt;
AlertLevelsDropdown.Disabled = console.Comp.CanSetAlertAt is null || _timing.CurTime <= console.Comp.CanSetAlertAt;
if (AlertLevelsDropdown.Disabled)
_alertLevelsPopup.Close();
if (console.Comp.ExpectedEvacuationArrival is { } evacArrival)
{
var diff = MathHelper.Max(evacArrival - _timing.CurTime, TimeSpan.Zero);
var infoText = Loc.GetString($"comms-console-menu-shuttle-eta",
("time", diff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
EmergencyStatus.Text = infoText;
}
else
{
EmergencyStatus.Text = Loc.GetString("comms-console-menu-shuttle-not-coming");
}
if (console.Comp.ExpectedExfiltrationArrival is { } exfiltrationArrival)
{
var diff = MathHelper.Max(exfiltrationArrival - _timing.CurTime, TimeSpan.Zero);
var infoText = Loc.GetString($"comms-console-menu-shuttle-eta",
("time", diff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
ExfiltrationStatus.Text = infoText;
}
else
{
ExfiltrationStatus.Text = Loc.GetString("comms-console-menu-shuttle-not-coming");
}
UpdateKeycardAuthenticationDevice();
}
private void SetScreen(Control screen)
{
foreach (var other in _screens)
{
other.Visible = false;
}
screen.Visible = true;
HomeButton.Visible = screen != HomeScreen;
}
public void Update(Entity<DVCommunicationsConsoleComponent> console, EntityUid user)
{
_console = console;
_user = user;
if (_station.GetOwningStation(console) is { } station &&
_entity.TryGetComponent<DVStationKeycardAuthenticationDeviceComponent>(station,
out var keycardAuthenticationDevice))
{
_stationKeycardAuthenticationDevice = (station, keycardAuthenticationDevice);
}
// If they only have the ability to announce, there's no point in having a home button
if (console.Comp.CanAnnounce && !(console.Comp.CanAlertLevel || console.Comp.CanCallShuttles || console.Comp.CanConfigureScreens || console.Comp.CanKeycardAuthenticationDevice))
{
SetScreen(AnnouncementScreen);
HomeButton.Visible = false;
}
// Station
StationHeaderLabel.Visible = console.Comp.CanAnnounce || console.Comp.CanConfigureScreens || console.Comp.CanAlertLevel;
AnnouncementTab.Visible = console.Comp.CanAnnounce;
ScreenTab.Visible = console.Comp.CanConfigureScreens;
AlertLevelTab.Visible = console.Comp.CanAlertLevel;
// Shuttles
TransitHeaderLabel.Visible = console.Comp.CanCallShuttles; // Should be only hidden if all buttons under are also hidden.
ShuttlesTab.Visible = console.Comp.CanCallShuttles;
// Emergency
EmergencyHeaderLabel.Visible = console.Comp.CanKeycardAuthenticationDevice; // Should be only hidden if all buttons under are also hidden.
KeycardAuthenticationDeviceTab.Visible = console.Comp.CanKeycardAuthenticationDevice;
ShuttleEmergencyButton.Disabled = !console.Comp.ShuttlesCallable;
ShuttleExfiltrationButton.Disabled = !console.Comp.ShuttlesCallable;
ShuttleEmergencyButton.Text =
Loc.GetString($"comms-console-menu-call-emergency.{console.Comp.ExpectedEvacuationArrival is null}");
ShuttleExfiltrationButton.Text =
Loc.GetString($"comms-console-menu-call-exfiltration.{console.Comp.ExpectedExfiltrationArrival is null}");
_alertLevels.RemoveAllChildren();
foreach (var level in console.Comp.AlertLevels)
{
if (level.Id == console.Comp.CurrentAlertLevel)
{
AlertLevel.Text = Loc.GetString("comms-console-menu-current-alert-level",
("name", Loc.GetString(level.AlertLevel)),
("color", level.Color),
("description", Loc.GetString(level.Description)));
}
if (!level.CanSet)
continue;
var btn = new Button
{
Text = Loc.GetString(level.AlertLevel),
ToggleMode = true,
Group = _group,
Pressed = level.Id == console.Comp.CurrentAlertLevel,
};
_alertLevels.AddChild(btn);
btn.OnPressed += _ =>
{
_alertLevelsPopup.Close();
OnMessage?.Invoke(new DVCommunicationsConsoleAlertLevelMessage(level.Id));
};
}
if (console.Comp.LastConfiguredLine1 != _lastConfiguredLine1)
ScreenLine1.Text = console.Comp.LastConfiguredLine1;
if (console.Comp.LastConfiguredLine2 != _lastConfiguredLine2)
ScreenLine2.Text = console.Comp.LastConfiguredLine2;
ScreenContentsButton.SelectId((int)console.Comp.LastConfiguredContent);
ScreenAlertBorder.Pressed = console.Comp.LastConfiguredShowBorders;
_lastConfiguredLine1 = console.Comp.LastConfiguredLine1;
_lastConfiguredLine2 = console.Comp.LastConfiguredLine2;
UpdateKeycardAuthenticationDevice();
}
private void UpdateKeycardAuthenticationDevice()
{
if (_user is not { } user || _stationKeycardAuthenticationDevice is not { } station)
return;
var canCall = !_entity.HasComponent<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>(user)
&& _entity.HasComponent<HumanoidProfileComponent>(user) // Can't be AI or a borg
&& station.Comp.AccessibleAfter <= _timing.CurTime;
CallZeta.ForceDisabled = !(canCall && station.Comp.SwipingFor is null or DVStationKeycardAction.Mayday);
CallZeta.Disabled = CallZeta.ForceDisabled;
RequestCodes.ForceDisabled = !(canCall && station.Comp.SwipingFor is null or DVStationKeycardAction.Scuttling);
RequestCodes.Disabled = RequestCodes.ForceDisabled;
if (CallZeta.IsConfirming || RequestCodes.IsConfirming)
return;
// Kinda messy but it works
if (station.Comp.SwipesStartedAt is { } firstSwipeTime)
{
var countdown = firstSwipeTime + station.Comp.SwipeWindow;
var timeRemaining = countdown.Subtract(_timing.CurTime);
if (timeRemaining > TimeSpan.Zero && station.Comp.SwipingFor is DVStationKeycardAction.Mayday)
CallZeta.Text = $"{timeRemaining:ss\\.fff}";
if (timeRemaining > TimeSpan.Zero && station.Comp.SwipingFor is DVStationKeycardAction.Scuttling)
RequestCodes.Text = $"{timeRemaining:ss\\.fff}";
}
else
{
CallZeta.Text = Loc.GetString("comms-console-menu-declare-mayday.button");
RequestCodes.Text = Loc.GetString("comms-console-menu-request-codes.button");
}
}
private void OnAnnouncePressed(BaseButton.ButtonEventArgs args)
{
OnMessage?.Invoke(new DVCommunicationsConsoleAnnouncementMessage(Rope.Collapse(AnnounceInput.TextRope)));
}
private void UpdateScreens()
{
OnMessage?.Invoke(new DVCommunicationsConsoleScreenConfigurationMessage(
(DVScreenContent) ScreenContentsButton.SelectedId,
ScreenAlertBorder.Pressed,
ScreenLine1.Text,
ScreenLine2.Text));
}
private void OnUpdateScreenText(BaseButton.ButtonEventArgs buttonEventArgs)
{
UpdateScreens();
}
private void OnScreenContentsSelected(OptionButton.ItemSelectedEventArgs itemSelectedEventArgs)
{
ScreenContentsButton.SelectId(itemSelectedEventArgs.Id);
UpdateScreens();
}
private void OnScreenAlertBorderToggled(BaseButton.ButtonToggledEventArgs buttonToggledEventArgs)
{
UpdateScreens();
}
private void OnExfiltrationPressed(BaseButton.ButtonEventArgs args)
{
OnMessage?.Invoke(new DVCommunicationsConsoleExfiltrationShuttleMessage(_console?.Comp.ExpectedExfiltrationArrival is null));
}
private void OnEmergencyPressed(BaseButton.ButtonEventArgs args)
{
OnMessage?.Invoke(new DVCommunicationsConsoleEvacuationShuttleMessage(_console?.Comp.ExpectedEvacuationArrival is null));
}
private void OnCallZetaPressed(BaseButton.ButtonEventArgs obj)
{
OnMessage?.Invoke(new DVCommunicationsConsoleKeycardAuthenticationDeviceMessage(DVStationKeycardAction.Mayday));
}
private void OnRequestCodesPressed(BaseButton.ButtonEventArgs obj)
{
OnMessage?.Invoke(new DVCommunicationsConsoleKeycardAuthenticationDeviceMessage(DVStationKeycardAction.Scuttling));
}
}
@@ -0,0 +1,26 @@
using Content.Shared._DV.Communications;
using Robust.Client.GameObjects;
namespace Content.Client._DV.Communications;
public sealed class DVCommunicationsConsoleSystem : SharedDVCommunicationsConsoleSystem
{
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVCommunicationsConsoleComponent, AfterAutoHandleStateEvent>(OnHandleState);
}
private void OnHandleState(Entity<DVCommunicationsConsoleComponent> ent, ref AfterAutoHandleStateEvent args)
{
if (!_userInterface.TryGetOpenUi<DVCommunicationsConsoleBoundUserInterface>(ent.Owner,
DVCommunicationsConsoleUi.Key,
out var bui))
return;
bui.Update(ent);
}
}
@@ -0,0 +1,5 @@
using Content.Shared._DV.KeycardAuthenticationDevice;
namespace Content.Client._DV.KeycardAuthenticationDevice;
public sealed class DVStationKeycardAuthenticationDeviceSystem : SharedDVStationKeycardAuthenticationDeviceSystem;
@@ -0,0 +1,103 @@
using System.Globalization;
using Content.Client.GameTicking.Managers;
using Content.Client.Interactable.Components;
using Content.Client.TextScreen;
using Content.Shared._DV.Screens;
using Robust.Shared.Timing;
namespace Content.Client._DV.Screens;
public sealed class DVScreenSystem : DVSharedScreenSystem
{
[Dependency] private readonly DVTextVisualsSystem _textVisuals = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly ClientGameTicker _ticker = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVScreenComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<DVScreenComponent, AfterAutoHandleStateEvent>(OnScreenState);
}
public override void FrameUpdate(float frameTime)
{
base.FrameUpdate(frameTime);
var query = EntityQueryEnumerator<DVScreenComponent>();
while (query.MoveNext(out var uid, out var screen))
{
switch (screen.Content)
{
case DVScreenContent.Text:
break;
case DVScreenContent.CurrentTime:
CurrentTime((uid, screen));
break;
case DVScreenContent.EstimatedTimeOfArrival:
EstimatedTimeOfArrival((uid, screen));
break;
case DVScreenContent.AlertLevel:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
private void OnInit(Entity<DVScreenComponent> ent, ref ComponentInit args)
{
// Remove interaction outline because it outlines the offscreen text and looks bad
RemComp<InteractionOutlineComponent>(ent);
}
private void OnScreenState(Entity<DVScreenComponent> ent, ref AfterAutoHandleStateEvent args)
{
UpdateVisuals(ent);
switch (ent.Comp.Content)
{
case DVScreenContent.Text:
Text(ent);
break;
case DVScreenContent.CurrentTime:
CurrentTime(ent);
break;
case DVScreenContent.EstimatedTimeOfArrival:
EstimatedTimeOfArrival(ent);
break;
case DVScreenContent.AlertLevel:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private void Text(Entity<DVScreenComponent> ent)
{
_textVisuals.SetText(ent.Owner, ent.Comp.Line1, ent.Comp.Line2);
}
private void CurrentTime(Entity<DVScreenComponent> ent)
{
var time = (_timing.CurTime - _ticker.RoundStartTimeSpan).Duration();
_textVisuals.SetText(ent.Owner, Loc.GetString("status-display-time"), time.ToString("hh\\:mm"));
}
private void EstimatedTimeOfArrival(Entity<DVScreenComponent> ent)
{
if (ent.Comp.TargetTime <= _timing.CurTime)
{
_textVisuals.SetText(ent.Owner, string.Empty, string.Empty);
return;
}
var time = (_timing.CurTime - ent.Comp.TargetTime).Duration();
var formatted = time.ToString("mm\\:ss");
Log.Debug($"{_timing.CurTime} - {ent.Comp.TargetTime} = {time}");
var title = ent.Comp.ScreenIsAtDestination ? Loc.GetString("status-display-etd") : Loc.GetString("status-display-eta");
_textVisuals.SetText(ent.Owner, title, formatted);
}
}
@@ -0,0 +1,140 @@
using System.Linq;
using System.Numerics;
using System.Threading;
using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Enums;
namespace Content.Client._DV.Screens;
[UsedImplicitly]
public sealed class DVTextRenderingOverlay : Overlay
{
[Dependency] private readonly IClyde _clyde = default!;
private readonly SpriteSystem _sprite;
private readonly AnimationPlayerSystem _animationPlayer;
public override OverlaySpace Space => OverlaySpace.ScreenSpaceBelowWorld;
private readonly Queue<(Entity<DVTextVisualsComponent> Entity, Font Font, CancellationToken Cancellation)> _queue = new();
public const string MarqueeKey = "dv-text-screen-marquee";
public DVTextRenderingOverlay(SpriteSystem sprite, AnimationPlayerSystem animationPlayer)
{
IoCManager.InjectDependencies(this);
_sprite = sprite;
_animationPlayer = animationPlayer;
ZIndex = -100; // this needs to render before almost everything
}
public CancellationTokenSource QueueRender(
Entity<DVTextVisualsComponent> ent,
Font font)
{
var source = new CancellationTokenSource();
_queue.Enqueue((ent, font, source.Token));
return source;
}
protected override void Draw(in OverlayDrawArgs args)
{
var screenHandle = args.ScreenHandle;
while (_queue.TryDequeue(out var queued))
{
if (queued.Cancellation.IsCancellationRequested)
continue;
var font = queued.Font;
foreach (var row in queued.Entity.Comp.Rows)
{
if (row.Text == string.Empty)
{
_sprite.LayerSetTexture(queued.Entity.Owner, row.Layer, null);
continue;
}
var dimensions = screenHandle.GetDimensions(queued.Font, row.Text, 1f);
var dimensionsInt = new Vector2i((int)MathF.Round(dimensions.X), (int)MathF.Round(dimensions.Y));
if (row.Texture is null || row.Texture.Size != dimensionsInt)
{
row.Texture = _clyde.CreateRenderTarget(dimensionsInt,
new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8),
name: $"dv-text-visuals-{queued.Entity.Owner.Id}");
_sprite.LayerSetTexture(queued.Entity.Owner, row.Layer, row.Texture.Texture);
_sprite.LayerSetOffset(queued.Entity.Owner, row.Layer, row.Offset);
}
args.DrawingHandle.RenderInRenderTarget(row.Texture,
() =>
{
screenHandle.DrawString(font, Vector2.Zero, row.Text);
},
Color.Transparent);
}
_animationPlayer.Stop(queued.Entity.Owner, MarqueeKey);
if (CreateMarqueeAnimation(queued.Entity) is { } animation)
{
queued.Entity.Comp.Animation = animation;
_animationPlayer.Play(queued.Entity.Owner, animation, MarqueeKey);
}
}
}
private Animation? CreateMarqueeAnimation(Entity<DVTextVisualsComponent> ent)
{
var largestRowWidth = ent.Comp.Rows.Aggregate(0, (i, row) => Math.Max(i, row.Texture?.Size.X ?? 0));
var animationTime = ent.Comp.MarqueeRate * largestRowWidth;
var marqueeWidth = new Vector2((float)ent.Comp.MarqueeWidth / EyeManager.PixelsPerMeter, 0);
var animation = new Animation
{
Length = animationTime,
};
foreach (var row in ent.Comp.Rows)
{
if (row.Texture is null)
continue;
var rowHalfWidth = new Vector2(row.Texture.Size.X / 2f / EyeManager.PixelsPerMeter, 0f);
if (row.Texture.Size.X <= ent.Comp.MarqueeWidth)
continue;
animation.AnimationTracks.Add(new AnimationTrackLayerOffset()
{
Layer = row.Layer,
KeyFrames =
{
new AnimationTrackProperty.KeyFrame(row.Offset + rowHalfWidth + marqueeWidth, 0f),
new AnimationTrackProperty.KeyFrame(row.Offset - rowHalfWidth - marqueeWidth, (float)animationTime.TotalSeconds),
},
});
}
return animation.AnimationTracks.Count > 0 ? animation : null;
}
public sealed class AnimationTrackLayerOffset : AnimationTrackProperty
{
public required Enum Layer;
private readonly SpriteSystem _sprite = IoCManager.Resolve<IEntityManager>().System<SpriteSystem>();
protected override void ApplyProperty(object context, object value)
{
if (value is not Vector2 vector)
throw new InvalidOperationException("Value must be a .");
_sprite.LayerSetOffset((EntityUid) context, Layer, vector);
}
}
}
@@ -0,0 +1,43 @@
using System.Numerics;
using System.Threading;
using Content.Shared._DV.Screens;
using Robust.Client.Animations;
using Robust.Client.Graphics;
namespace Content.Client._DV.Screens;
[RegisterComponent]
[Access(typeof(DVTextVisualsSystem), typeof(DVTextRenderingOverlay))]
public sealed partial class DVTextVisualsComponent : Component
{
[DataField(required: true)]
public List<DVTextVisualsRow> Rows;
[DataField]
public TimeSpan MarqueeRate = TimeSpan.FromSeconds(0.045f);
[DataField]
public int MarqueeWidth = 24;
[DataField]
public int MarqueePadding = 8;
public Animation? Animation;
public CancellationTokenSource? Token;
}
[DataDefinition]
public sealed partial class DVTextVisualsRow
{
public IRenderTexture? Texture;
[DataField]
public string Text;
[DataField]
public Vector2 Offset;
[DataField(required: true)]
public Enum Layer = DVTextScreenVisualLayers.Line1;
}
@@ -0,0 +1,73 @@
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
namespace Content.Client._DV.Screens;
public sealed class DVTextVisualsSystem : EntitySystem
{
[Dependency] private readonly IOverlayManager _overlay = default!;
[Dependency] private readonly IResourceCache _resource = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
private DVTextRenderingOverlay _textRendering = default!;
private Font _font = default!;
public override void Initialize()
{
base.Initialize();
_textRendering = new(_sprite, _animationPlayer);
_overlay.AddOverlay(_textRendering);
_font = new VectorFont(_resource.GetResource<FontResource>("/Fonts/_DV/TinyUnicode.ttf"), 12);
SubscribeLocalEvent<DVTextVisualsComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<DVTextVisualsComponent, ComponentShutdown>(OnComponentShutdown);
SubscribeLocalEvent<DVTextVisualsComponent, AnimationCompletedEvent>(OnAnimationComplete);
}
public override void Shutdown()
{
_overlay.RemoveOverlay(_textRendering);
}
private void OnComponentInit(Entity<DVTextVisualsComponent> ent, ref ComponentInit args)
{
ent.Comp.Token = _textRendering.QueueRender(ent, _font);
}
private void OnComponentShutdown(Entity<DVTextVisualsComponent> ent, ref ComponentShutdown args)
{
foreach (var row in ent.Comp.Rows)
{
row.Texture?.Dispose();
}
ent.Comp.Token?.Cancel();
}
private void OnAnimationComplete(Entity<DVTextVisualsComponent> ent, ref AnimationCompletedEvent args)
{
if (args.Key != DVTextRenderingOverlay.MarqueeKey || !args.Finished || ent.Comp.Animation is not { } animation)
return;
_animationPlayer.Play(ent.Owner, animation, DVTextRenderingOverlay.MarqueeKey);
}
public void SetText(Entity<DVTextVisualsComponent?> ent, params string[] rows)
{
if (!Resolve(ent, ref ent.Comp))
return;
var count = Math.Min(rows.Length, ent.Comp.Rows.Count);
for (var i = 0; i < count; i++)
{
ent.Comp.Rows[i].Text = rows[i];
}
ent.Comp.Token?.Cancel();
ent.Comp.Token = _textRendering.QueueRender((ent, ent.Comp), _font);
}
}
@@ -0,0 +1,23 @@
using Content.Client.Resources;
using Content.Client.Stylesheets;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using static Content.Client.Stylesheets.StylesheetHelpers;
namespace Content.Client._DV.Stylesheets.Sheetlets;
[CommonSheetlet]
public sealed class DVLineEditSheetlet : Sheetlet<PalettedStylesheet>
{
public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
{
var tinyUnicode = ResCache.GetFont("/Fonts/_DV/TinyUnicode.ttf", size: 24);
return
[
E<LineEdit>()
.Class("comms-console-display")
.Font(tinyUnicode),
];
}
}
@@ -1,6 +1,7 @@
using Content.Server.Chat.Systems;
using Content.Server.GameTicking;
using Content.Server.Ninja.Systems;
using Content.Shared._DV.Communications; // DeltaV Comms Console
using Content.Shared.Communications;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
@@ -35,7 +36,7 @@ public sealed class CommsHackerSystem : SharedCommsHackerSystem
/// </summary>
private void OnBeforeInteractHand(EntityUid uid, CommsHackerComponent comp, BeforeInteractHandEvent args)
{
if (args.Handled || !HasComp<CommunicationsConsoleComponent>(args.Target))
if (args.Handled || !HasComp<DVCommunicationsConsoleComponent>(args.Target)) // DeltaV - Comms Console
return;
// TODO: generic check event
@@ -23,7 +23,7 @@ using Robust.Shared.Configuration;
namespace Content.Server.Communications
{
public sealed partial class CommunicationsConsoleSystem : EntitySystem // DeltaV - Partial Class
public sealed class CommunicationsConsoleSystem : EntitySystem
{
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
[Dependency] private readonly AlertLevelSystem _alertLevelSystem = default!;
@@ -53,8 +53,6 @@ namespace Content.Server.Communications
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleCallEmergencyShuttleMessage>(OnCallShuttleMessage);
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleRecallEmergencyShuttleMessage>(OnRecallShuttleMessage);
InitializeExfiltration(); // DeltaV - Exfiltration shuttle
// On console init, set cooldown
SubscribeLocalEvent<CommunicationsConsoleComponent, MapInitEvent>(OnCommunicationsConsoleMapInit);
}
@@ -138,7 +136,6 @@ namespace Content.Server.Communications
List<string>? levels = null;
string currentLevel = default!;
float currentDelay = 0;
TimeSpan? exfiltrationTime = null; // DeltaV - exfiltration shuttle
if (stationUid != null)
{
@@ -160,12 +157,6 @@ namespace Content.Server.Communications
currentLevel = alertComp.CurrentLevel;
currentDelay = _alertLevelSystem.GetAlertLevelDelay(stationUid.Value, alertComp);
}
// Begin DeltaV - exfiltration shuttle
if (TryComp<StationExfiltrationComponent>(stationUid, out var exfiltration))
{
exfiltrationTime = exfiltration.ArrivalTime;
}
// End DeltaV - exfiltration shuttle
}
_uiSystem.SetUiState(uid, CommunicationsConsoleUiKey.Key, new CommunicationsConsoleInterfaceState(
@@ -174,8 +165,7 @@ namespace Content.Server.Communications
levels,
currentLevel,
currentDelay,
_roundEndSystem.ExpectedCountdownEnd,
exfiltrationTime // DeltaV - exfiltration shuttle
_roundEndSystem.ExpectedCountdownEnd
));
}
@@ -30,6 +30,17 @@ public sealed partial class EmergencyLightComponent : SharedEmergencyLightCompon
[DataField("chargingEfficiency")]
public float ChargingEfficiency = 0.85f;
// Begin DeltaV Additions
[DataField]
public float MaydayRadius = 10f;
[DataField]
public float MaydayFalloff = 0f;
[DataField]
public float MaydayEnergy = 0.7f;
// End DeltaV Additions
public Dictionary<EmergencyLightState, string> BatteryStateText = new()
{
{ EmergencyLightState.Full, "emergency-light-component-light-state-full" },
@@ -85,11 +85,11 @@ public sealed partial class HealthAnalyzerSystem : EntitySystem // DeltaV - Made
if (component.MaxScanRange != null && !_transformSystem.InRange(patientCoordinates, transform.Coordinates, component.MaxScanRange.Value))
{
//Range too far, disable updates
PauseAnalyzingEntity((uid, component), patient); // DeltaV - Analyzer Reactivation
PauseAnalyzingEntity((uid, component), patient);
continue;
}
component.IsAnalyzerActive = true; // DeltaV - Analyzer Reactivation
component.IsAnalyzerActive = true;
UpdateScannedUser(uid, patient, true);
}
}
@@ -197,7 +197,7 @@ public sealed partial class HealthAnalyzerSystem : EntitySystem // DeltaV - Made
}
/// <summary>
/// DeltaV - If the scanner is active, sends one last update and sets it to inactive.
/// If the scanner is active, sends one last update and sets it to inactive.
/// </summary>
/// <param name="healthAnalyzer">The health analyzer that's receiving the updates</param>
/// <param name="target">The entity to analyze</param>
@@ -22,6 +22,7 @@ using Content.Shared.StatusEffect;
using Content.Shared.Store.Components;
using Content.Shared.Stunnable;
using Content.Shared.Tag;
using Content.Shared.Weapons.Melee.Events; // DeltaV
using Robust.Server.GameObjects;
using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes;
@@ -64,6 +65,7 @@ public sealed partial class RevenantSystem : EntitySystem
SubscribeLocalEvent<RevenantComponent, StatusEffectAddedEvent>(OnStatusAdded);
SubscribeLocalEvent<RevenantComponent, StatusEffectEndedEvent>(OnStatusEnded);
SubscribeLocalEvent<RoundEndTextAppendEvent>(_ => MakeVisible(true));
SubscribeLocalEvent<RevenantComponent, MeleeAttackEvent>(OnMeleeAttack); // DeltaV
SubscribeLocalEvent<RevenantComponent, GetVisMaskEvent>(OnRevenantGetVis);
@@ -131,6 +133,14 @@ public sealed partial class RevenantSystem : EntitySystem
ChangeEssenceAmount(uid, essenceDamage, component);
}
/// <summary>
/// DeltaV - No more attack spam and remaining invisible
/// </summary>
private void OnMeleeAttack(Entity<RevenantComponent> ent, ref MeleeAttackEvent args)
{
_statusEffects.TryAddStatusEffect<CorporealComponent>(ent, "Corporeal", ent.Comp.MeleeRevealTime, false);
}
public bool ChangeEssenceAmount(EntityUid uid, FixedPoint2 amount, RevenantComponent? component = null, bool allowDeath = true, bool regenCap = false)
{
if (!Resolve(uid, ref component))
@@ -1,32 +0,0 @@
using Content.Server._DV.Station.Components;
using Content.Server._DV.Station.Systems;
using Content.Shared._DV.Communications;
namespace Content.Server.Communications;
public sealed partial class CommunicationsConsoleSystem : EntitySystem
{
[Dependency] private readonly StationExfiltrationSystem _stationExfiltration = default!;
private void InitializeExfiltration()
{
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleExfiltrationShuttleMessage>(OnExfiltrationMessage);
}
private void OnExfiltrationMessage(Entity<CommunicationsConsoleComponent> ent, ref CommunicationsConsoleExfiltrationShuttleMessage args)
{
if (_stationSystem.GetOwningStation(ent) is not { } station)
return;
if (!CanUse(args.Actor, ent))
{
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), ent, args.Actor);
return;
}
if (args.Call)
_stationExfiltration.Call(station);
else
_stationExfiltration.Recall(station);
}
}
@@ -0,0 +1,184 @@
using Content.Server._DV.Station.Components;
using Content.Server._DV.Station.Systems;
using Content.Server.AlertLevel;
using Content.Server.Communications;
using Content.Server.RoundEnd;
using Content.Server.Shuttles.Systems;
using Content.Shared._DV.Communications;
using Content.Shared.CCVar;
using Content.Shared.Database;
using Content.Shared.Station;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
namespace Content.Server._DV.Communications;
public sealed class DVCommunicationsConsoleSystem : SharedDVCommunicationsConsoleSystem
{
[Dependency] private readonly SharedStationSystem _station = default!;
[Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
[Dependency] private readonly IConfigurationManager _configuration = default!;
[Dependency] private readonly AlertLevelSystem _alertLevel = default!;
[Dependency] private readonly StationExfiltrationSystem _stationExfiltration = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RoundEndSystemChangedEvent>(OnRoundEndChanged);
SubscribeLocalEvent<StationExfiltrationChangedEvent>(OnExfiltrationChanged);
SubscribeLocalEvent<AlertLevelChangedEvent>(OnAlertLevelChanged);
}
private void OnAlertLevelChanged(AlertLevelChangedEvent ev)
{
var query = EntityQueryEnumerator<DVCommunicationsConsoleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (_station.GetOwningStation(uid) != ev.Station)
continue;
var alertLevel = Comp<AlertLevelComponent>(ev.Station);
comp.CanSetAlertAt = Timing.CurTime + TimeSpan.FromSeconds(alertLevel.CurrentDelay);
comp.CurrentAlertLevel = ev.AlertLevel;
if (alertLevel.IsLevelLocked)
comp.CanSetAlertAt = null;
Dirty(uid, comp);
}
}
private void OnExfiltrationChanged(ref StationExfiltrationChangedEvent ev)
{
var query = EntityQueryEnumerator<DVCommunicationsConsoleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (_station.GetOwningStation(uid) != ev.Station)
continue;
comp.ExpectedExfiltrationArrival = ev.Station.Comp.ArrivalTime;
Dirty(uid, comp);
}
}
private void OnRoundEndChanged(RoundEndSystemChangedEvent ev)
{
var query = EntityQueryEnumerator<DVCommunicationsConsoleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
comp.ExpectedEvacuationArrival = _roundEnd.ExpectedCountdownEnd;
comp.ExpectedEvacuationDuration = _roundEnd.ExpectedShuttleLength;
comp.ShuttlesCallable = ShuttlesCallable();
Dirty(uid, comp);
}
}
protected override void OnMapInit(Entity<DVCommunicationsConsoleComponent> ent, ref MapInitEvent args)
{
base.OnMapInit(ent, ref args);
if (_station.GetOwningStation(ent) is not { } station)
return;
if (!TryComp<AlertLevelComponent>(station, out var alertLevel))
return;
ent.Comp.CurrentAlertLevel = alertLevel.CurrentLevel;
var proto = _prototype.Index<AlertLevelPrototype>(alertLevel.AlertLevelPrototype);
foreach (var (name, detail) in proto.Levels)
{
ent.Comp.AlertLevels.Add(new($"alert-level-{name}", $"alert-level-{name}-announcement", name, !detail.DisableSelection, detail.Color));
}
ent.Comp.CanSetAlertAt = Timing.CurTime + TimeSpan.FromSeconds(alertLevel.CurrentDelay);
if (alertLevel.IsLevelLocked)
ent.Comp.CanSetAlertAt = null;
ent.Comp.ShuttlesCallable = ShuttlesCallable();
ent.Comp.ExpectedEvacuationArrival = _roundEnd.ExpectedCountdownEnd;
ent.Comp.ExpectedEvacuationDuration = _roundEnd.ExpectedShuttleLength;
if (TryComp<StationExfiltrationComponent>(station, out var exfiltration))
ent.Comp.ExpectedExfiltrationArrival = exfiltration.ArrivalTime;
Dirty(ent);
}
private bool ShuttlesCallable()
{
// Defer to what the round end system thinks we should be able to do.
if (_emergencyShuttle.EmergencyShuttleArrived || !_roundEnd.CanCallOrRecall())
return false;
// Calling shuttle checks
if (_roundEnd.ExpectedCountdownEnd is null)
return true;
// Recalling shuttle checks
var recallThreshold = _configuration.GetCVar(CCVars.EmergencyRecallTurningPoint);
// shouldn't really be happening if we got here
if (_roundEnd.ShuttleTimeLeft is not { } left
|| _roundEnd.ExpectedShuttleLength is not { } expected)
return false;
return !(left.TotalSeconds / expected.TotalSeconds < recallThreshold);
}
protected override void OnAlertLevel(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleAlertLevelMessage args)
{
base.OnAlertLevel(ent, ref args);
if (!AccessReader.IsAllowed(ent, args.Actor))
return;
if (_station.GetOwningStation(ent) is not { } station)
return;
_alertLevel.SetLevel(station, args.AlertLevel, true, true);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has set the alert level to {args.AlertLevel:level} on {ToPrettyString(station):station} using {ToPrettyString(ent):console}");
}
protected override void OnEvacuationShuttle(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleEvacuationShuttleMessage args)
{
base.OnEvacuationShuttle(ent, ref args);
if (!AccessReader.IsAllowed(ent, args.Actor))
return;
if (args.Call)
{
var ev = new CommunicationConsoleCallShuttleAttemptEvent(ent, default!, args.Actor);
RaiseLocalEvent(ref ev);
_roundEnd.RequestRoundEnd(args.Actor);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has called the evacuation shuttle using {ToPrettyString(ent):console}");
}
else
{
_roundEnd.CancelRoundEndCountdown(args.Actor);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has recalled the evacuation shuttle using {ToPrettyString(ent):console}");
}
}
protected override void OnExfiltrationShuttle(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleExfiltrationShuttleMessage args)
{
base.OnExfiltrationShuttle(ent, ref args);
if (!AccessReader.IsAllowed(ent, args.Actor))
return;
if (_station.GetOwningStation(ent) is not { } station)
return;
if (args.Call)
{
_stationExfiltration.Call(station);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has called the exfiltration shuttle using {ToPrettyString(ent):console}");
}
else
{
_stationExfiltration.Recall(station);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has recalled the exfiltration shuttle using {ToPrettyString(ent):console}");
}
}
}
@@ -0,0 +1,88 @@
using Content.Server.AlertLevel;
using Content.Server.Audio.Jukebox;
using Content.Server.Instruments;
using Content.Server.Light.Components;
using Content.Server.Light.EntitySystems;
using Content.Server.Nuke;
using Content.Server.RoundEnd;
using Content.Shared._DV.KeycardAuthenticationDevice;
using Content.Shared.Audio.Jukebox;
using Content.Shared.Light.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Server._DV.KeycardAuthenticationDevice;
public sealed class DVStationKeycardAuthenticationDeviceSystem : SharedDVStationKeycardAuthenticationDeviceSystem
{
[Dependency] private readonly NukeCodePaperSystem _nukeCodePaper = default!;
[Dependency] private readonly AlertLevelSystem _alertLevel = default!;
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly PoweredLightSystem _poweredLight = default!;
[Dependency] private readonly PointLightSystem _pointLight = default!;
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
[Dependency] private readonly JukeboxSystem _jukebox = default!;
protected override void Mayday(Entity<DVStationKeycardAuthenticationDeviceComponent> station)
{
base.Mayday(station);
_alertLevel.SetLevel(station, "zeta", true, true, true, true);
var alertLevel = Comp<AlertLevelComponent>(station);
var level = _prototype.Index<AlertLevelPrototype>(alertLevel.AlertLevelPrototype).Levels[alertLevel.CurrentLevel];
_roundEnd.RequestRoundEnd(level.ShuttleTime, null, null, false, cantRecall: true);
var bulbQuery = GetEntityQuery<LightBulbComponent>();
var tubeQuery = EntityQueryEnumerator<PoweredLightComponent>();
while (tubeQuery.MoveNext(out var uid, out var light))
{
if (Station.GetOwningStation(uid) != station.Owner)
continue;
if (_poweredLight.GetBulb(uid, light) is not { } bulb || !bulbQuery.TryComp(bulb, out var bulbComp))
continue;
bulbComp.LightEnergy /= 2;
bulbComp.PowerUse /= 2;
_poweredLight.SetState(uid, light.On, light);
}
var emergencyQuery = EntityQueryEnumerator<EmergencyLightComponent, PointLightComponent>();
while (emergencyQuery.MoveNext(out var uid, out var emergency, out var light))
{
if (Station.GetOwningStation(uid) != station.Owner)
continue;
_pointLight.SetEnergy(uid, emergency.MaydayEnergy, light);
_pointLight.SetRadius(uid, emergency.MaydayRadius, light);
_pointLight.SetFalloff(uid, emergency.MaydayFalloff, light);
}
var instrumentQuery = EntityQueryEnumerator<InstrumentComponent>();
while (instrumentQuery.MoveNext(out var uid, out _))
{
if (Station.GetOwningStation(uid) != station.Owner)
continue;
_userInterface.CloseUis(uid);
}
var jukeboxQuery = EntityQueryEnumerator<JukeboxComponent>();
while (jukeboxQuery.MoveNext(out var uid, out var jukebox))
{
if (Station.GetOwningStation(uid) != station.Owner)
continue;
_jukebox.Stop((uid, jukebox));
}
}
protected override void Scuttling(Entity<DVStationKeycardAuthenticationDeviceComponent> station)
{
base.Scuttling(station);
_nukeCodePaper.SendNukeCodes(station);
}
}
@@ -0,0 +1,111 @@
using Content.Server.AlertLevel;
using Content.Server.Screens.Components;
using Content.Shared._DV.Communications;
using Content.Shared._DV.Screens;
using Content.Shared.DeviceNetwork.Events;
using Content.Shared.Station;
using Robust.Shared.Timing;
namespace Content.Server._DV.Screens;
public sealed class DVScreenSystem : DVSharedScreenSystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedStationSystem _station = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVScreenComponent, DeviceNetworkPacketEvent>(OnPacket);
SubscribeLocalEvent<AlertLevelChangedEvent>(OnAlertLevelChanged);
}
private void OnPacket(Entity<DVScreenComponent> ent, ref DeviceNetworkPacketEvent args)
{
if (args.Data.TryGetValue(ShuttleTimerMasks.ShuttleMap, out _))
OnShuttlePacket(ent, ref args);
if (args.Data.TryGetValue(DVScreenPackets.Text, out (string, string)? text))
OnTextPacket(ent, text.Value, ref args);
if (args.Data.TryGetValue(DVScreenPackets.ShowBorders, out bool? showBorders))
OnBordersPacket(ent, showBorders.Value, ref args);
if (args.Data.TryGetValue(DVScreenPackets.Content, out DVScreenContent? content))
OnContentPacket(ent, content.Value, ref args);
}
private void OnShuttlePacket(Entity<DVScreenComponent> ent, ref DeviceNetworkPacketEvent args)
{
var xform = Transform(ent);
args.Data.TryGetValue(ShuttleTimerMasks.ShuttleMap, out EntityUid? shuttleMap);
args.Data.TryGetValue(ShuttleTimerMasks.SourceMap, out EntityUid? source);
args.Data.TryGetValue(ShuttleTimerMasks.DestMap, out EntityUid? dest);
args.Data.TryGetValue(ShuttleTimerMasks.Docked, out bool docked);
var screenIsAtDestination = docked;
string key;
switch (xform.MapUid)
{
// sometimes the timer transforms on FTL shuttles have a hyperspace mapuid, so matching by grid works as a fallback.
case var local when local == shuttleMap || xform.GridUid == shuttleMap:
key = ShuttleTimerMasks.ShuttleTime;
break;
case var origin when origin == source:
key = ShuttleTimerMasks.SourceTime;
break;
case var remote when remote == dest:
key = ShuttleTimerMasks.DestTime;
screenIsAtDestination = false;
break;
default:
return;
}
if (!args.Data.TryGetValue(key, out TimeSpan duration))
return;
ent.Comp.ScreenIsAtDestination = screenIsAtDestination;
ent.Comp.TargetTime = _timing.CurTime + duration;
Dirty(ent);
UpdateVisuals(ent);
}
private void OnTextPacket(Entity<DVScreenComponent> ent, (string, string) text, ref DeviceNetworkPacketEvent args)
{
ent.Comp.Line1 = text.Item1;
ent.Comp.Line2 = text.Item2;
Dirty(ent);
UpdateVisuals(ent);
}
private void OnBordersPacket(Entity<DVScreenComponent> ent, bool showBorders, ref DeviceNetworkPacketEvent args)
{
ent.Comp.ShowAlertBorder = showBorders;
Dirty(ent);
UpdateVisuals(ent);
}
private void OnContentPacket(Entity<DVScreenComponent> ent, DVScreenContent content, ref DeviceNetworkPacketEvent args)
{
ent.Comp.Content = content;
Dirty(ent);
UpdateVisuals(ent);
}
private void OnAlertLevelChanged(AlertLevelChangedEvent ev)
{
var query = EntityQueryEnumerator<DVScreenComponent>();
while (query.MoveNext(out var uid, out var screen))
{
if (_station.GetOwningStation(uid) != ev.Station)
continue;
screen.AlertLevel = ev.AlertLevel;
Dirty(uid, screen);
UpdateVisuals((uid, screen));
}
}
}
@@ -32,7 +32,6 @@ public sealed class StationExfiltrationSystem : EntitySystem
[Dependency] private readonly ShuttleSystem _shuttle = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly NavMapSystem _navMap = default!;
[Dependency] private readonly CommunicationsConsoleSystem _communicationsConsole = default!;
public override void Initialize()
{
@@ -169,7 +168,8 @@ public sealed class StationExfiltrationSystem : EntitySystem
_chat.DispatchStationAnnouncement(ent, Loc.GetString(ent.Comp.CalledAnnouncement, ("time", ent.Comp.TravelTime.TotalSeconds), ("station", Name(ent))), sender: Loc.GetString(ent.Comp.Sender), colorOverride: Color.Gold);
}
_communicationsConsole.UpdateCommsConsoleInterface();
var evt = new StationExfiltrationChangedEvent((ent, ent.Comp), true);
RaiseLocalEvent(ref evt);
}
public void Recall(Entity<StationExfiltrationComponent?> ent)
@@ -180,6 +180,10 @@ public sealed class StationExfiltrationSystem : EntitySystem
ent.Comp.ArrivalTime = null;
_chat.DispatchStationAnnouncement(ent, Loc.GetString(ent.Comp.RecalledAnnouncement, ("station", Name(ent))), sender: Loc.GetString(ent.Comp.Sender), colorOverride: Color.Gold);
_communicationsConsole.UpdateCommsConsoleInterface();
var evt = new StationExfiltrationChangedEvent((ent, ent.Comp), false);
RaiseLocalEvent(ref evt);
}
}
[ByRefEvent]
public readonly record struct StationExfiltrationChangedEvent(Entity<StationExfiltrationComponent> Station, bool Exfiltrating);
@@ -1,7 +1,7 @@
using Content.Server._DV.StationEvents.Components;
using Content.Server.Antag;
using Content.Server.Communications;
using Content.Server.StationEvents.Events;
using Content.Shared._DV.Communications;
using Content.Shared.Forensics.Components;
using Content.Shared.GameTicking.Components;
using Content.Shared.Ghost;
@@ -43,7 +43,7 @@ public sealed class FugitiveRule : StationEventSystem<FugitiveRuleComponent>
ChatSystem.DispatchGlobalAnnouncement(announcement, sender: sender, colorOverride: comp.Color);
// send the report to every comms console on the station
var query = EntityQueryEnumerator<TransformComponent, CommunicationsConsoleComponent>();
var query = EntityQueryEnumerator<TransformComponent, DVCommunicationsConsoleComponent>();
var consoles = new List<TransformComponent>();
while (query.MoveNext(out var console, out var xform, out _))
{
@@ -18,9 +18,8 @@ namespace Content.Shared.Communications
public List<string>? AlertLevels;
public string CurrentAlert;
public float CurrentAlertDelay;
public readonly TimeSpan? ExpectedExfiltrationCountdownEnd;
public CommunicationsConsoleInterfaceState(bool canAnnounce, bool canCall, List<string>? alertLevels, string currentAlert, float currentAlertDelay, TimeSpan? expectedCountdownEnd, TimeSpan? expectedExfiltrationCountdownEnd) // DeltaV - Exfiltration Shuttle
public CommunicationsConsoleInterfaceState(bool canAnnounce, bool canCall, List<string>? alertLevels, string currentAlert, float currentAlertDelay, TimeSpan? expectedCountdownEnd)
{
CanAnnounce = canAnnounce;
CanCall = canCall;
@@ -29,7 +28,6 @@ namespace Content.Shared.Communications
AlertLevels = alertLevels;
CurrentAlert = currentAlert;
CurrentAlertDelay = currentAlertDelay;
ExpectedExfiltrationCountdownEnd = expectedExfiltrationCountdownEnd; // DeltaV - Exfiltration Shuttle
}
}
@@ -90,7 +90,7 @@ public sealed partial class LabelSystem : EntitySystem
private void OnRefreshNameModifiers(Entity<LabelComponent> entity, ref RefreshNameModifiersEvent args)
{
if (!string.IsNullOrEmpty(entity.Comp.CurrentLabel))
args.AddModifier("comp-label-format", extraArgs: ("label", entity.Comp.CurrentLabel));
args.AddModifier("comp-label-format", 100, extraArgs: ("label", entity.Comp.CurrentLabel)); // Coyote: add priority of 100 to reverse order of label and baseName
}
private void OnComponentInit(Entity<PaperLabelComponent> ent, ref ComponentInit args)
@@ -300,4 +300,12 @@ public sealed partial class RevenantComponent : Component
public string HarvestingState = "harvesting";
#endregion
[DataField] public EntityUid? HauntAction; // Imp
#region Melee
/// <summary>
/// DeltaV - The amount of time a rev is revealed after making a melee attack.
/// </summary>
[DataField]
public TimeSpan MeleeRevealTime = TimeSpan.FromSeconds(2);
#endregion
}
@@ -1,9 +0,0 @@
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Communications;
[Serializable, NetSerializable]
public sealed class CommunicationsConsoleExfiltrationShuttleMessage(bool call) : BoundUserInterfaceMessage
{
public readonly bool Call = call;
}
@@ -0,0 +1,136 @@
using Content.Shared._DV.KeycardAuthenticationDevice;
using Content.Shared._DV.Screens;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Communications;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedDVCommunicationsConsoleSystem))]
public sealed partial class DVCommunicationsConsoleComponent : Component
{
[DataField]
public LocId AnnouncementTitle = "comms-console-announcement-title-station";
[DataField]
public Color AnnouncementColor = Color.Gold;
[DataField]
public SoundSpecifier AnnouncementSound = new SoundPathSpecifier("/Audio/Announcements/announce.ogg");
[DataField, AutoNetworkedField]
public bool GlobalAnnouncements;
[DataField, AutoNetworkedField]
public bool CanAnnounce = true;
[DataField, AutoNetworkedField]
public bool CanAlertLevel = true;
[DataField, AutoNetworkedField]
public bool CanCallShuttles = true;
[DataField, AutoNetworkedField]
public bool CanConfigureScreens = true;
[DataField, AutoNetworkedField]
public bool CanKeycardAuthenticationDevice = true;
[DataField, AutoNetworkedField]
public TimeSpan CanAnnounceAt = TimeSpan.Zero;
[DataField]
public TimeSpan AnnouncementInterval = TimeSpan.FromSeconds(90f);
[DataField]
public TimeSpan InitialAnnouncementDelay = TimeSpan.FromSeconds(30f);
[DataField, AutoNetworkedField]
public string CurrentAlertLevel = string.Empty;
[DataField, AutoNetworkedField]
public List<DVCommunicationsConsoleAlertLevel> AlertLevels = new();
[DataField, AutoNetworkedField]
public TimeSpan? CanSetAlertAt = TimeSpan.Zero;
[DataField, AutoNetworkedField]
public bool ShuttlesCallable = true;
[DataField, AutoNetworkedField]
public TimeSpan? ExpectedEvacuationArrival;
[DataField, AutoNetworkedField]
public TimeSpan? ExpectedEvacuationDuration;
[DataField, AutoNetworkedField]
public TimeSpan? ExpectedExfiltrationArrival;
[DataField, AutoNetworkedField]
public DVScreenContent LastConfiguredContent = DVScreenContent.Text;
[DataField, AutoNetworkedField]
public bool LastConfiguredShowBorders;
[DataField, AutoNetworkedField]
public string LastConfiguredLine1 = string.Empty;
[DataField, AutoNetworkedField]
public string LastConfiguredLine2 = string.Empty;
}
[Serializable, NetSerializable]
public readonly record struct DVCommunicationsConsoleAlertLevel(LocId AlertLevel, LocId Description, string Id, bool CanSet, Color Color);
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleEvacuationShuttleMessage(bool call) : BoundUserInterfaceMessage
{
public readonly bool Call = call;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleExfiltrationShuttleMessage(bool call) : BoundUserInterfaceMessage
{
public readonly bool Call = call;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleKeycardAuthenticationDeviceMessage(DVStationKeycardAction action) : BoundUserInterfaceMessage
{
public readonly DVStationKeycardAction Action = action;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleAnnouncementMessage(string announcement) : BoundUserInterfaceMessage
{
public readonly string Announcement = announcement;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleAlertLevelMessage(string alertLevel) : BoundUserInterfaceMessage
{
public readonly string AlertLevel = alertLevel;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleScreenConfigurationMessage(DVScreenContent content, bool showBorder, string line1, string line2) : BoundUserInterfaceMessage
{
public readonly DVScreenContent Content = content;
public readonly bool ShowBorder = showBorder;
public readonly string Line1 = line1;
public readonly string Line2 = line2;
}
[Serializable, NetSerializable]
public enum DVCommunicationsConsoleUi : byte
{
Key,
}
public static class DVScreenPackets
{
public const string Content = "dv-screen-content";
public const string ShowBorders = "dv-screen-borders";
public const string Text = "dv-screen-text";
}
@@ -0,0 +1,148 @@
using Content.Shared._DV.KeycardAuthenticationDevice;
using Content.Shared._DV.Screens;
using Content.Shared.Access.Systems;
using Content.Shared.Administration.Logs;
using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Events;
using Content.Shared.DeviceNetwork.Systems;
using Content.Shared.IdentityManagement;
using Robust.Shared.Timing;
namespace Content.Shared._DV.Communications;
public abstract class SharedDVCommunicationsConsoleSystem : EntitySystem
{
[Dependency] private readonly SharedDeviceNetworkSystem _deviceNetwork = default!;
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] private readonly SharedChatSystem _chat = default!;
[Dependency] protected readonly AccessReaderSystem AccessReader = default!;
[Dependency] protected readonly ISharedAdminLogManager AdminLog = default!;
[Dependency] private readonly SharedDVStationKeycardAuthenticationDeviceSystem _stationKeycardAuthenticationDevice = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVCommunicationsConsoleComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<DVCommunicationsConsoleComponent, DeviceNetworkPacketEvent>(OnPacketReceive);
Subs.BuiEvents<DVCommunicationsConsoleComponent>(DVCommunicationsConsoleUi.Key,
subs =>
{
subs.Event<DVCommunicationsConsoleEvacuationShuttleMessage>(OnEvacuationShuttle);
subs.Event<DVCommunicationsConsoleExfiltrationShuttleMessage>(OnExfiltrationShuttle);
subs.Event<DVCommunicationsConsoleScreenConfigurationMessage>(OnConfiguration);
subs.Event<DVCommunicationsConsoleAnnouncementMessage>(OnAnnouncement);
subs.Event<DVCommunicationsConsoleAlertLevelMessage>(OnAlertLevel);
subs.Event<DVCommunicationsConsoleKeycardAuthenticationDeviceMessage>(OnKeycardAuthenticationDevice);
});
}
private void OnPacketReceive(Entity<DVCommunicationsConsoleComponent> ent, ref DeviceNetworkPacketEvent args)
{
if (args.Data.TryGetValue(DVScreenPackets.Text, out (string, string)? text))
{
ent.Comp.LastConfiguredLine1 = text.Value.Item1;
ent.Comp.LastConfiguredLine2 = text.Value.Item2;
Dirty(ent);
}
if (args.Data.TryGetValue(DVScreenPackets.ShowBorders, out bool? showBorders))
{
ent.Comp.LastConfiguredShowBorders = showBorders.Value;
Dirty(ent);
}
if (args.Data.TryGetValue(DVScreenPackets.Content, out DVScreenContent? content))
{
ent.Comp.LastConfiguredContent = content.Value;
Dirty(ent);
}
}
protected virtual void OnMapInit(Entity<DVCommunicationsConsoleComponent> ent, ref MapInitEvent args)
{
ent.Comp.CanAnnounceAt = Timing.CurTime + ent.Comp.InitialAnnouncementDelay;
Dirty(ent);
}
private void OnAnnouncement(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleAnnouncementMessage args)
{
if (!ent.Comp.CanAnnounce)
return;
if (Timing.CurTime <= ent.Comp.CanAnnounceAt)
return;
if (!AccessReader.IsAllowed(args.Actor, ent))
return;
var identity = new TryGetIdentityShortInfoEvent(ent, args.Actor);
RaiseLocalEvent(identity);
Loc.TryGetString(ent.Comp.AnnouncementTitle, out var title);
title ??= ent.Comp.AnnouncementTitle;
var msg = args.Announcement;
msg += "\n" + Loc.GetString("comms-console-announcement-sent-by") + " " + identity.Title;
if (ent.Comp.GlobalAnnouncements)
{
_chat.DispatchGlobalAnnouncement(msg, title, announcementSound: ent.Comp.AnnouncementSound, colorOverride: ent.Comp.AnnouncementColor);
AdminLog.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(args.Actor):player} sent the following global announcement using {ToPrettyString(ent):console}: {msg:message}");
}
else
{
_chat.DispatchStationAnnouncement(ent, msg, title, announcementSound: ent.Comp.AnnouncementSound, colorOverride: ent.Comp.AnnouncementColor);
AdminLog.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(args.Actor):player} sent the following station announcement using {ToPrettyString(ent):console}: {msg:message}");
}
ent.Comp.CanAnnounceAt = Timing.CurTime + ent.Comp.AnnouncementInterval;
Dirty(ent);
}
private void OnConfiguration(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleScreenConfigurationMessage args)
{
if (!ent.Comp.CanConfigureScreens)
return;
if (!AccessReader.IsAllowed(args.Actor, ent))
return;
ent.Comp.LastConfiguredLine1 = args.Line1;
ent.Comp.LastConfiguredLine2 = args.Line2;
ent.Comp.LastConfiguredShowBorders = args.ShowBorder;
ent.Comp.LastConfiguredContent = args.Content;
Dirty(ent);
var payload = new NetworkPayload
{
[DVScreenPackets.Content] = args.Content,
[DVScreenPackets.ShowBorders] = args.ShowBorder,
[DVScreenPackets.Text] = (args.Line1, args.Line2),
};
AdminLog.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(args.Actor):player} configured the following text using {ToPrettyString(ent):console}: {args.Line1:line1} {args.Line2:line2}");
_deviceNetwork.QueuePacket(ent, null, payload);
}
protected virtual void OnExfiltrationShuttle(Entity<DVCommunicationsConsoleComponent> ent,
ref DVCommunicationsConsoleExfiltrationShuttleMessage args)
{
}
protected virtual void OnEvacuationShuttle(Entity<DVCommunicationsConsoleComponent> ent,
ref DVCommunicationsConsoleEvacuationShuttleMessage args)
{
}
protected virtual void OnAlertLevel(Entity<DVCommunicationsConsoleComponent> ent,
ref DVCommunicationsConsoleAlertLevelMessage args)
{
}
private void OnKeycardAuthenticationDevice(Entity<DVCommunicationsConsoleComponent> ent,
ref DVCommunicationsConsoleKeycardAuthenticationDeviceMessage args)
{
_stationKeycardAuthenticationDevice.TrySwipe(args.Actor, ent, args.Action);
}
}
@@ -0,0 +1,7 @@
using Robust.Shared.GameStates;
namespace Content.Shared._DV.KeycardAuthenticationDevice;
[RegisterComponent, NetworkedComponent]
[Access(typeof(SharedDVStationKeycardAuthenticationDeviceSystem))]
public sealed partial class DVStationKeycardAuthenticationDeviceAlreadySwipedComponent : Component;
@@ -0,0 +1,50 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared._DV.KeycardAuthenticationDevice;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause]
[Access(typeof(SharedDVStationKeycardAuthenticationDeviceSystem))]
public sealed partial class DVStationKeycardAuthenticationDeviceComponent : Component
{
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField, AutoPausedField]
public TimeSpan AccessibleAfter = TimeSpan.Zero;
[DataField]
public TimeSpan FailureDelay = TimeSpan.FromMinutes(2);
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField, AutoPausedField]
public TimeSpan? SwipesStartedAt = null;
[DataField]
public TimeSpan SwipeWindow = TimeSpan.FromSeconds(20);
[DataField(required: true)]
public Dictionary<DVStationKeycardAction, int> ActionThresholds;
[DataField, AutoNetworkedField]
public int Swipes;
[DataField, AutoNetworkedField]
public DVStationKeycardAction? SwipingFor;
[DataField]
public LocId FailureAnnouncementSender = "keycard-authentication-device-sender";
[DataField]
public LocId FailureAnnouncement = "keycard-authentication-device-warning";
[DataField]
public Color FailureAnnouncementColor = Color.FromHex("#e93a9a");
[DataField]
public TimeSpan FailureElectrocutionDuration = TimeSpan.FromSeconds(5);
}
[Serializable, NetSerializable]
public enum DVStationKeycardAction
{
Mayday,
Scuttling,
}
@@ -0,0 +1,124 @@
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Chat;
using Content.Shared.Electrocution;
using Content.Shared.Station;
using Robust.Shared.Audio;
using Robust.Shared.Timing;
namespace Content.Shared._DV.KeycardAuthenticationDevice;
public abstract class SharedDVStationKeycardAuthenticationDeviceSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] protected readonly SharedStationSystem Station = default!;
[Dependency] private readonly SharedElectrocutionSystem _electrocution = default!;
[Dependency] private readonly SharedChatSystem _chat = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<DVStationKeycardAuthenticationDeviceComponent>();
while (query.MoveNext(out var uid, out var keycard))
{
if (keycard.SwipesStartedAt is not { } startedAt || _timing.CurTime <= startedAt + keycard.SwipeWindow)
continue;
StopSwipes((uid, keycard), true);
}
}
private void StopSwipes(Entity<DVStationKeycardAuthenticationDeviceComponent> station, bool failed)
{
station.Comp.SwipesStartedAt = null;
station.Comp.Swipes = 0;
station.Comp.SwipingFor = null;
if (failed)
{
station.Comp.AccessibleAfter = _timing.CurTime + station.Comp.FailureDelay;
_chat.DispatchStationAnnouncement(station,
Loc.GetString(station.Comp.FailureAnnouncement),
Loc.GetString(station.Comp.FailureAnnouncementSender),
announcementSound: new SoundPathSpecifier("/Audio/_DV/Announcements/attention.ogg"),
colorOverride: station.Comp.FailureAnnouncementColor);
}
Dirty(station);
var query = EntityQueryEnumerator<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>();
while (query.MoveNext(out var uid, out _))
{
if (failed)
{
_electrocution.TryDoElectrocution(uid,
null,
10,
station.Comp.FailureElectrocutionDuration,
true,
ignoreInsulation: true);
}
RemCompDeferred<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>(uid);
}
}
private void Swipe(Entity<DVStationKeycardAuthenticationDeviceComponent> station, EntityUid user, DVStationKeycardAction action)
{
if (!station.Comp.ActionThresholds.TryGetValue(action, out var threshold))
return;
station.Comp.SwipesStartedAt ??= _timing.CurTime;
station.Comp.SwipingFor = action;
station.Comp.Swipes++;
AddComp<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>(user);
Dirty(station);
if (station.Comp.Swipes >= threshold)
{
StopSwipes(station, false);
DoAction(station, action);
}
}
private void DoAction(Entity<DVStationKeycardAuthenticationDeviceComponent> station, DVStationKeycardAction action)
{
switch (action)
{
case DVStationKeycardAction.Mayday:
Mayday(station);
break;
case DVStationKeycardAction.Scuttling:
Scuttling(station);
break;
}
}
protected virtual void Mayday(Entity<DVStationKeycardAuthenticationDeviceComponent> station)
{
}
protected virtual void Scuttling(Entity<DVStationKeycardAuthenticationDeviceComponent> station)
{
}
public void TrySwipe(EntityUid user, EntityUid console, DVStationKeycardAction action)
{
if (HasComp<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>(console))
return;
if (Station.GetOwningStation(user) is not { } station || !TryComp<DVStationKeycardAuthenticationDeviceComponent>(station, out var keycard))
return;
if (TryComp<AccessReaderComponent>(console, out var accessReader) && !_accessReader.IsAllowed(user, console, accessReader))
return;
if (keycard.SwipingFor is { } swipingFor && swipingFor != action)
return;
if (_timing.CurTime <= keycard.AccessibleAfter)
return;
Swipe((station, keycard), user, action);
}
}
@@ -0,0 +1,55 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Screens;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true), AutoGenerateComponentPause]
[Access(typeof(DVSharedScreenSystem))]
public sealed partial class DVScreenComponent : Component
{
[DataField, AutoNetworkedField]
public string? AlertLevel; // I don't like this but uhhh the prototype isn't client-accessible
[DataField, AutoNetworkedField]
public bool ShowAlertBorder;
[DataField, AutoNetworkedField]
public DVScreenContent Content = DVScreenContent.Text;
#region Text Screens
[DataField, AutoNetworkedField]
public string Line1 = string.Empty;
[DataField, AutoNetworkedField]
public string Line2 = string.Empty;
#endregion
#region ETA Screens
[DataField, AutoNetworkedField]
public bool ScreenIsAtDestination;
[DataField, AutoNetworkedField, AutoPausedField]
public TimeSpan TargetTime = TimeSpan.Zero;
#endregion
}
[Serializable, NetSerializable]
public enum DVScreenVisuals : byte
{
AlertLevel,
ShowAlertBorder,
Content,
}
[Serializable, NetSerializable]
public enum DVScreenContent : byte
{
Text,
CurrentTime,
EstimatedTimeOfArrival,
AlertLevel,
}
@@ -0,0 +1,13 @@
namespace Content.Shared._DV.Screens;
public abstract class DVSharedScreenSystem : EntitySystem
{
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
protected void UpdateVisuals(Entity<DVScreenComponent> ent)
{
_appearance.SetData(ent.Owner, DVScreenVisuals.AlertLevel, ent.Comp.AlertLevel ?? string.Empty);
_appearance.SetData(ent.Owner, DVScreenVisuals.ShowAlertBorder, ent.Comp.ShowAlertBorder);
_appearance.SetData(ent.Owner, DVScreenVisuals.Content, ent.Comp.Content);
}
}
@@ -0,0 +1,10 @@
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Screens;
[Serializable, NetSerializable]
public enum DVTextScreenVisualLayers : byte
{
Line1,
Line2,
}
@@ -0,0 +1,10 @@
using Robust.Shared.Configuration;
using Content.Shared.CCVar.CVarAccess;
using Content.Shared.Administration;
namespace Content.Shared.Starlight.CCVar;
[CVarDefs]
public sealed partial class StarlightCCVars
{
}
@@ -0,0 +1,13 @@
using Robust.Shared.Configuration;
namespace Content.Shared.Starlight.CCVar;
public sealed partial class StarlightCCVars
{
/// <summary>
/// A newline-separated list of saved labels for the hand labeler tool
/// </summary>
public static readonly CVarDef<string> HandLabelerSavedLabels =
CVarDef.Create("interface.hand_labeler_saved_labels", "", CVar.CLIENTONLY | CVar.ARCHIVE);
}
Binary file not shown.
+142 -119
View File
@@ -1,123 +1,4 @@
Entries:
- author: zelezniciar
changes:
- message: Added a generic Slavic accent that can be selected as a character trait.
Very Nice!
type: Add
id: 2136
time: '2026-02-27T18:30:56.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5264
- author: kotobdev
changes:
- message: You can now always equip items to your suit storage, even without any
outer clothing!
type: Add
id: 2137
time: '2026-02-27T18:55:24.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5300
- author: verybigman311
changes:
- message: The Crusher can now Wideswing with right click.
type: Tweak
id: 2138
time: '2026-02-28T08:50:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5327
- author: AeraAuling
changes:
- message: Removed PKA upgrade kits for Fire-Rate and Indoors.
type: Remove
- message: PKA damage stats have been tweaked.
type: Tweak
id: 2139
time: '2026-02-28T10:26:37.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5311
- author: makyo
changes:
- message: Some clothing/item/etc forced accents removed; they can still be added
in traits!
type: Tweak
id: 2140
time: '2026-02-28T12:31:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5343
- author: Cepelinas1
changes:
- message: NanoTrasen has permitted Engineering to choose between a voidsuit and
a hardsuit for their work. Check your lockers!
type: Add
- message: Increased Engineering Voidsuit speed by 5%.
type: Tweak
id: 2141
time: '2026-02-28T14:23:13.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5317
- author: Darklyac
changes:
- message: Added 9 new Lobby Music and 11 new Jukebox Music!
type: Add
id: 2142
time: '2026-02-28T18:13:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5424
- author: Pharaz4
changes:
- message: Added cloth wraps!
type: Add
id: 2143
time: '2026-02-28T20:06:08.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5335
- author: Stxcking
changes:
- message: Fixed medborg crew monitor not getting power and being able to remove
power cell.
type: Fix
id: 2144
time: '2026-02-28T20:42:44.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5342
- author: Pharaz4
changes:
- message: Fixed blukie and paramed suit not displaying for harpy.
type: Fix
id: 2145
time: '2026-03-01T11:18:43.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5414
- author: Velcroboy
changes:
- message: Wizard now starts in the Wizard's Den and gets a teleport scroll
type: Tweak
id: 2146
time: '2026-03-01T13:38:18.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5215
- author: rebe83
changes:
- message: Bottles, vials, and chem injectors no longer fit inside cigarette boxes.
Use a combat kit like the rest of us!
type: Tweak
id: 2147
time: '2026-03-01T14:12:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5402
- author: Stxcking
changes:
- message: Health analyzer can show who claimed a patient.
type: Tweak
id: 2148
time: '2026-03-01T19:47:57.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5110
- author: pootslap
changes:
- message: Rat servants are slightly faster but weaker.
type: Tweak
- message: Rat Kings have a few new titles and are now more clearly labelled as
antagonists.
type: Tweak
id: 2149
time: '2026-03-02T17:48:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5326
- author: JoulesBerg
changes:
- message: Vents, air injectors, and pumps can be pipes in their alternate configurations
now.
type: Add
id: 2150
time: '2026-03-02T18:17:30.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5372
- author: Halo3moth
changes:
- message: Hos has a new robe for a significant aura increase, amazing sprites by
@@ -4420,4 +4301,146 @@
id: 2636
time: '2026-08-23T12:57:01.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6439
- author: ShepardToTheStars
changes:
- message: Mothroach grenades actually work again.
type: Fix
id: 2637
time: '2026-08-23T15:00:35.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6447
- author: ShepardToTheStars
changes:
- message: Chameleon thieving gloves have been removed from the syndicate uplink.
You can always ask nicely, right?
type: Remove
id: 2638
time: '2026-08-24T15:13:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6425
- author: ShepardToTheStars
changes:
- message: The health analyzer will again show if the patient is unborgable, unrevivable,
or uncloneable.
type: Fix
id: 2639
time: '2026-08-24T16:23:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6446
- author: ShepardToTheStars
changes:
- message: Ninja's katana dash now has a 5 second cooldown between uses.
type: Tweak
- message: Ninja's katana dash now takes 30 seconds to recharge each use, up from
20 seconds.
type: Tweak
- message: Reduced skia's healing in the dark from 5 of each damage type to 2 of
each damage type.
type: Tweak
- message: Increased skia's damage from light from 1.5 brute to 2 brute.
type: Tweak
- message: Revenant's melee attack will now reveal them for 2 seconds.
type: Tweak
id: 2640
time: '2026-08-26T08:34:48.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6410
- author: SumofThreeParts
changes:
- message: The Patos can now be purchased from logistics.
type: Add
id: 2641
time: '2026-08-27T14:29:39.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6361
- author: ShepardToTheStars
changes:
- message: Diona who become trees are 'rooted' in place again.
type: Fix
id: 2642
time: '2026-08-27T18:31:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6456
- author: sowelipililimute, ShepardToTheStars
changes:
- message: Communications consoles have been redesigned!
type: Add
- message: Command can now declare alert level Zeta as a form of mayday to call
an expedited evacuation. Two authorizations are required.
type: Add
- message: Command can now request the nuclear authentication codes to scuttle the
station. Three authorizations are required.
type: Add
- message: Status displays have been redesigned and can now be configured to show
scrolling text, an image for the alert level, borders for the alert level, the
current time, or shuttle ETA/ETD
type: Add
- message: Code Orange has been removed because Zeta now exists.
type: Remove
id: 2643
time: '2026-08-27T18:37:40.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5954
- author: SumofThreeParts
changes:
- message: the hushpup now makes less sound when fired.
type: Tweak
id: 2644
time: '2026-08-27T19:24:13.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6438
- author: Coryler
changes:
- message: You can now save labels between rounds.
type: Add
- message: The original item name and label are now swapped.
type: Tweak
id: 2645
time: '2026-08-27T19:26:08.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6432
- author: CarolCuchara
changes:
- message: New caseless shotgun shells that wont leave behind a trace!
type: Add
- message: The Hushpup now comes equiped with caseless shotgun shells!
type: Tweak
id: 2646
time: '2026-08-28T16:38:08.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6457
- author: Vapetastic-Gaming
changes:
- message: Survival Scheduler has been slightly tamed, and will give moments of
calm, while also applying pressure via spawns. Survival Scheduler refused to
read you a bedtime story, sorry chat.
type: Tweak
id: 2647
time: '2026-08-28T23:54:33.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6440
- author: BriBrooo
changes:
- message: Hydroponics' booklet on reagents contained an error.
type: Fix
id: 2648
time: '2026-09-06T23:35:52.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6483
- author: nlaky
changes:
- message: Vulp alt tail can now wag
type: Tweak
id: 2649
time: '2026-09-07T00:17:23.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6480
- author: Macrocosm, Stxcking
changes:
- message: Added 20+ new Thaven markings, most notably, tails!
type: Add
- message: Thavens can select their undergarments again.
type: Fix
- message: Thaven markings display the correct locale marking name.
type: Fix
- message: Thavens have unique organ sprites now.
type: Tweak
id: 2650
time: '2026-09-07T00:18:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6162
- author: AnimatorBrie
changes:
- message: Added surplus boots, a strictly-cosmetic variant of jackboots. Available
now at your local Clothesmate vendor.
type: Add
id: 2651
time: '2026-09-07T00:33:43.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6472
Order: 1
+7
View File
@@ -1087,4 +1087,11 @@
id: 125
time: '2026-07-14T00:30:06.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6242
- author: Field Command
changes:
- message: 'Central Command: New CC is here!'
type: Add
id: 126
time: '2026-09-05T14:03:09.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6198
Order: 3
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,5 +1,60 @@
comms-console-announcement-title-unauthorized = Unauthorized
comms-console-menu-call-exfiltration = Call exfiltration shuttle
comms-console-menu-exfiltration-shuttle-button-tooltip = Calls or recalls the exfiltration shuttle.
comms-console-menu-exfiltration-time-remaining = ETA of exfiltration shuttle: {$time}
comms-console-menu-recall-exfiltration = Recall exfiltration shuttle
comms-console-menu-screen-content =
.Text = Text
.CurrentTime = Current Time
.EstimatedTimeOfArrival = ETA / ETD
.AlertLevel = Alert Level
comms-console-menu-tab =
.Announcement = Make an announcement
.Screen = Configure status displays
.Shuttles = Manage shuttles
.AlertLevel = Set the alert level
.KeycardAuthenticationDevice = Keycard Authentication Device
comms-console-menu-line-1 = Line 1:
comms-console-menu-line-2 = Line 2:
comms-console-menu-alert-level-border = Alert level border:
comms-console-menu-alert-level = Alert level
comms-console-menu-screen-contents = Screen contents:
comms-console-menu-send-announcement = Send announcement
comms-console-menu-update-screen-text = Update text
comms-console-menu-enable-border = Enable alert level border
comms-console-menu-home = Home
comms-console-menu-emergency-shuttle = Emergency shuttle
comms-console-menu-exfiltration-shuttle = Exfiltration shuttle
comms-console-menu-shuttle-not-coming = This shuttle is not currently requested.
comms-console-menu-shuttle-eta = This shuttle will arrive in {$time}.
comms-console-menu-screen-text = Screen text
comms-console-menu-screen-configuration = Screen options
comms-console-menu-current-alert-level = The current alert level is [color={$color}]{$name}[/color]. {$description}
comms-console-menu-change-alert-level = Change alert level
comms-console-menu-station-title = Station
comms-console-menu-transit-title = Transit
comms-console-menu-emergency-title = Emergency
comms-console-menu-declare-mayday =
.title = Declare mayday
.desc = Declare the station unfit for life and send out a distress signal to all nearby vessels. Requires two simultaneous authorizations.
.button = Declare Code Zeta
comms-console-menu-request-codes =
.title = Scuttle the station
.desc = Order the destruction of the station to prevent capture, containment breach, or further threats to the sector. Requires three simultaneous authorizations.
.button = Request nuclear authorization codes
comms-console-menu-call-emergency =
.True = Call emergency shuttle
.False = Recall emergency shuttle
comms-console-menu-call-exfiltration =
.True = Call exfiltration shuttle
.False = Recall exfiltration shuttle
comms-console-menu-announcement-text = Announcement text
@@ -0,0 +1,2 @@
keycard-authentication-device-sender = Keycard Authentication Device
keycard-authentication-device-warning = Unsuccessful authorization attempt of the keycard authentication device detected. Administering deterrence measures and initiating keycard authentication device lockdown.
@@ -0,0 +1,3 @@
status-display-eta = -ETA-
status-display-etd = -ETD-
status-display-time = TIME
@@ -1,207 +0,0 @@
marking-ThavenHairAfro = Afro
marking-ThavenHairAfro2 = Afro 2
marking-ThavenHairBigafro = Afro (Large)
marking-ThavenHairAntenna = Ahoge
marking-ThavenHairBalding = Balding Hair
marking-ThavenHairBedhead = Bedhead
marking-ThavenHairBedheadv2 = Bedhead 2
marking-ThavenHairBedheadv3 = Bedhead 3
marking-ThavenHairLongBedhead = Long Bedhead
marking-ThavenHairLongBedhead2 = Long Bedhead 2
marking-ThavenHairFloorlengthBedhead = Floorlength Bedhead
marking-ThavenHairBeehive = Beehive
marking-ThavenHairBeehive2 = Beehive 2
marking-ThavenHairBob = Bob Hair
marking-ThavenHairBob2 = Bob Hair 2
marking-ThavenHairBobcut = Bob Hair 3
marking-ThavenHairBob4 = Bob Hair 4
marking-ThavenHairBob5 = Bob Hair 5
marking-ThavenHairBobcurl = Bobcurl
marking-ThavenHairBoddicker = Boddicker
marking-ThavenHairBowlcut = Bowlcut
marking-ThavenHairBowlcut2 = Bowlcut 2
marking-ThavenHairBraid = Braid (Floorlength)
marking-ThavenHairBraided = Braided
marking-ThavenHairBraidfront = Braided Front
marking-ThavenHairBraid2 = Braid (High)
marking-ThavenHairHbraid = Braid (Low)
marking-ThavenHairShortbraid = Braid (Short)
marking-ThavenHairBraidtail = Braided Tail
marking-ThavenHairBun = Bun Head
marking-ThavenHairBunhead2 = Bun Head 2
marking-ThavenHairBun3 = Bun Head 3
marking-ThavenHairLargebun = Bun (Large)
marking-ThavenHairManbun = Bun (Manbun)
marking-ThavenHairTightbun = Bun (Tight)
marking-ThavenHairBusiness = Business Hair
marking-ThavenHairBusiness2 = Business Hair 2
marking-ThavenHairBusiness3 = Business Hair 3
marking-ThavenHairBusiness4 = Business Hair 4
marking-ThavenHairBuzzcut = Buzzcut
marking-ThavenHairCia = CIA
marking-ThavenHairClassicAfro = Classic Afro
marking-ThavenHairClassicBigAfro = Classic Big Afro
marking-ThavenHairClassicBusiness = Classic Business Hair
marking-ThavenHairClassicciaBusiness = Classic CIA
marking-ThavenHairClassicCornrows = Classic Cornrows
marking-ThavenHairClassicCornrows2 = Classic Cornrows 2
marking-ThavenHairClassicFloorlengthBedhead = Classic Floorlength Bedhead
marking-ThavenHairClassicLong2 = Classic Long Hair 2
marking-ThavenHairClassicLong3 = Classic Long Hair 3
marking-ThavenHairClassicModern = Classic Modern
marking-ThavenHairClassicMulder = Classic Mulder
marking-ThavenHairClassicWisp = Classic Wisp
marking-ThavenHairCoffeeHouse = Coffee House
marking-ThavenHairCombover = Combover
marking-ThavenHairCornrows = Cornrows
marking-ThavenHairCornrows2 = Cornrows 2
marking-ThavenHairCornrowbun = Cornrow Bun
marking-ThavenHairCornrowbraid = Cornrow Braid
marking-ThavenHairCornrowtail = Cornrow Tail
marking-ThavenHairCrewcut = Crewcut
marking-ThavenHairCrewcut2 = Crewcut 2
marking-ThavenHairCurls = Curls
marking-ThavenHairC = Cut Hair
marking-ThavenHairDandypompadour = Dandy Pompadour
marking-ThavenHairDevilock = Devil Lock
marking-ThavenHairDoublebun = Double Bun
marking-ThavenHairDoublebunLong = Double Bun Long
marking-ThavenHairDreads = Dreadlocks
marking-ThavenHairDrillHair = Drill Hair
marking-ThavenHairDrillruru = Drillruru
marking-ThavenHairDrillhairextended = Drill Hair (Extended)
marking-ThavenHairEmo = Emo
marking-ThavenHairEmo2 = Emo2
marking-ThavenHairLongeremo = Longer Emo
marking-ThavenHairEmofringe = Emo Fringe
marking-ThavenHairNofade = Fade (None)
marking-ThavenHairHighfade = Fade (High)
marking-ThavenHairMedfade = Fade (Medium)
marking-ThavenHairLowfade = Fade (Low)
marking-ThavenHairBaldfade = Fade (Bald)
marking-ThavenHairFeather = Feather
marking-ThavenHairFather = Father
marking-ThavenHairSargeant = Flat Top
marking-ThavenHairFlair = Flair
marking-ThavenHairBigflattop = Flat Top (Big)
marking-ThavenHairFlow = Flow Hair
marking-ThavenHairGelled = Gelled Back
marking-ThavenHairGentle = Gentle
marking-ThavenHairHalfbang = Half-banged Hair
marking-ThavenHairHalfbang2 = Half-banged Hair 2
marking-ThavenHairHalfshaved = Half-shaved
marking-ThavenHairHedgehog = Hedgehog Hair
marking-ThavenHairHimecut = Hime Cut
marking-ThavenHairHimecut2 = Hime Cut 2
marking-ThavenHairShorthime = Hime Cut (Short)
marking-ThavenHairHimeup = Hime Updo
marking-ThavenHairHitop = Hitop
marking-ThavenHairJade = Jade
marking-ThavenHairJensen = Jensen Hair
marking-ThavenHairJoestar = Joestar
marking-ThavenHairKeanu = Keanu Hair
marking-ThavenHairKusanagi = Kusanagi Hair
marking-ThavenHairLongBow = Long Bow
marking-ThavenHairLong = Long Hair 1
marking-ThavenHairLong2 = Long Hair 2
marking-ThavenHairLong3 = Long Hair 3
marking-ThavenHairLongWithBundles = Long With Bundles
marking-ThavenHairLongovereye = Long Over Eye
marking-ThavenHairLbangs = Long Bangs
marking-ThavenHairLongemo = Long Emo
marking-ThavenHairLongfringe = Long Fringe
marking-ThavenHairLongsidepart = Long Side Part
marking-ThavenHairMediumSidepart = Medium Side Part
marking-ThavenHairMegaeyebrows = Mega Eyebrows
marking-ThavenHairMessy = Messy
marking-ThavenHairModern = Modern
marking-ThavenHairMohawk = Mohawk
marking-ThavenHairNitori = Nitori
marking-ThavenHairReversemohawk = Mohawk (Reverse)
marking-ThavenHairUnshavenMohawk = Mohawk (Unshaven)
marking-ThavenHairMulder = Mulder
marking-ThavenHairOdango = Odango
marking-ThavenHairOmbre = Ombre
marking-ThavenHairOneshoulder = One Shoulder
marking-ThavenHairShortovereye = Over Eye
marking-ThavenHairOxton = Oxton
marking-ThavenHairParted = Parted
marking-ThavenHairPart = Parted (Side)
marking-ThavenHairKagami = Pigtails
marking-ThavenHairPigtails = Pigtails 2
marking-ThavenHairPigtails2 = Pigtails 3
marking-ThavenHairPixie = Pixie Cut
marking-ThavenHairPompadour = Pompadour
marking-ThavenHairBigpompadour = Pompadour (Big)
marking-ThavenHairPonytail = Ponytail
marking-ThavenHairPonytail2 = Ponytail 2
marking-ThavenHairPonytail3 = Ponytail 3
marking-ThavenHairPonytail4 = Ponytail 4
marking-ThavenHairPonytail5 = Ponytail 5
marking-ThavenHairPonytail6 = Ponytail 6
marking-ThavenHairPonytail7 = Ponytail 7
marking-ThavenHairHighponytail = Ponytail (High)
marking-ThavenHairStail = Ponytail (Short)
marking-ThavenHairLongstraightponytail = Ponytail (Long)
marking-ThavenHairCountry = Ponytail (Country)
marking-ThavenHairFringetail = Ponytail (Fringe)
marking-ThavenHairSidetail = Ponytail (Side)
marking-ThavenHairSidetail2 = Ponytail (Side) 2
marking-ThavenHairSidetail3 = Ponytail (Side) 3
marking-ThavenHairSidetail4 = Ponytail (Side) 4
marking-ThavenHairSpikyponytail = Ponytail (Spiky)
marking-ThavenHairPoofy = Poofy
marking-ThavenHairBald = Bald
marking-ThavenHairClassicCia = Classic CIA
marking-ThavenHairQuiff = Quiff
marking-ThavenHairRonin = Ronin
marking-ThavenHairShaped = Shaped
marking-ThavenHairShaved = Shaved
marking-ThavenHairShavedMohawk = Shaved Mohawk
marking-ThavenHairShavedpart = Shaved Part
marking-ThavenHairShortbangs = Short Bangs
marking-ThavenHairA = Short Hair
marking-ThavenHairShorthair2 = Short Hair 2
marking-ThavenHairShorthair3 = Short Hair 3
marking-ThavenHairShorthair9 = Short Hair 9
marking-ThavenHairD = Short Hair 4
marking-ThavenHairE = Short Hair 5
marking-ThavenHairF = Short Hair 6
marking-ThavenHairShorthairg = Short Hair 7
marking-ThavenHair80s = Short Hair 80s
marking-ThavenHairRosa = Short Hair Rosa
marking-ThavenHairB = Shoulder-length Hair
marking-ThavenHairShoulderLengthOverEye = Shoulder-length Over Eye
marking-ThavenHairSidecut = Sidecut
marking-ThavenHairSkinhead = Skinhead
marking-ThavenHairProtagonist = Slightly Long Hair
marking-ThavenHairSpikey = Spiky
marking-ThavenHairSpiky = Spiky 2
marking-ThavenHairSpiky2 = Spiky 3
marking-ThavenHairSpookyLong = Spooky Long
marking-ThavenHairSwept = Swept Back Hair
marking-ThavenHairSwept2 = Swept Back Hair 2
marking-ThavenHairTailed = Tailed
marking-ThavenHairThinning = Thinning
marking-ThavenHairThinningfront = Thinning (Front)
marking-ThavenHairThinningrear = Thinning (Rear)
marking-ThavenHairTopknot = Topknot
marking-ThavenHairTressshoulder = Tress Shoulder
marking-ThavenHairTrimmed = Trimmed
marking-ThavenHairTrimflat = Trim Flat
marking-ThavenHairTwintail = Twintails
marking-ThavenHairTwoStrands = Two Strands
marking-ThavenHairUndercut = Undercut
marking-ThavenHairUndercutleft = Undercut Left
marking-ThavenHairUndercutright = Undercut Right
marking-ThavenHairUneven = Uneven
marking-ThavenHairUnkept = Unkept
marking-ThavenHairUpdo = Updo
marking-ThavenHairVlong = Very Long Hair
marking-ThavenHairLongest = Very Long Hair 2
marking-ThavenHairLongest2 = Very Long Over Eye
marking-ThavenHairVeryshortovereyealternate = Very Short Over Eye
marking-ThavenHairVlongfringe = Very Long with Fringe
marking-ThavenHairVolaju = Volaju
marking-ThavenHairWisp = Wisp
marking-ThavenHairFrenchbraid = French Braid
@@ -1,27 +0,0 @@
marking-ThavenEars1-ears1 = Small Ears
marking-ThavenEars1 = Small Ears
marking-ThavenEars2-ears2 = Medium Ears
marking-ThavenEars2 = Medium Ears
marking-ThavenEars3-ears3 = Long Ears
marking-ThavenEars3 = Long Ears
marking-ThavenEars4-ears4 = Droopy Ears
marking-ThavenEars4 = Droopy Ears
marking-ThavenPiercings-piercings = Helix Piercing
marking-ThavenPiercings = Helix Piercing
marking-ThavenPiercings2-piercings2 = Hoop Piercing
marking-ThavenPiercings2 = Hoop Piercing
marking-ThavenChestTattoo1-chesttat1 = Back Tattoo
marking-ThavenChestTattoo1 = Back Tattoo
marking-ThavenLArmTattoo1-larmtat1 = Arm Band (Left)
marking-ThavenLArmTattoo1 = Arm Band (Left)
marking-ThavenRArmTattoo1-larmtat1 = Arm Band (Right)
marking-ThavenRArmTattoo1 = Arm Band (Right)
@@ -0,0 +1,877 @@
# Chest
marking-BodyhairThaven = Body Hair
marking-BodyhairThaven-hair = Body Hair
marking-Gills = Gills
marking-Gills-gills = Gills
marking-ThavenAbs = Muscles
marking-ThavenAbs-muscular = Muscles
marking-ThavenBiteMark = Big Bite Scar
marking-ThavenBiteMark-bitemark = Big Bite Scar
marking-ThavenBodyStripes = Pinstripes
marking-ThavenBodyStripes-stripes = Pinstripes
marking-ThavenChestScales = Scales
marking-ThavenChestScales-scales = Scales
marking-ThavenChestTattoo1 = Back Tattoo
marking-ThavenChestTattoo1-tat1 = Back Tattoo
marking-ThavenSpinechill = Spinechill
marking-ThavenSpinechill-spinechill = Spinechill
marking-ThavenSpines = Spines
marking-ThavenSpines-spines = Spines
marking-ThavenTattooWave = Wave Tattoo
marking-ThavenTattooWave-tattoowave = Wave Tattoo
marking-ThavenTattooVines = Vine Tattoo
marking-ThavenTattooVines-tattoovines = Vine Tattoo
marking-ThavenTiger = Tiger Stripes
marking-ThavenTiger-tiger1 = Tiger Belly
marking-ThavenTiger-tiger2 = Tiger Stripes
marking-ThavenTopSurgery = Top Surgery
marking-ThavenTopSurgery-nonaturals = Top Surgery
# Head
marking-ThavenHeadCap = Dappled Crown
marking-ThavenHeadCap-cap1 = Crown
marking-ThavenHeadCap-cap2 = Dapples
marking-ThavenHeadScales = Scales
marking-ThavenHeadScales-scales = Scales
marking-ThavenHeadStripes = Pinstripes
marking-ThavenHeadStripes-stripes = Pinstripes
marking-ThavenShadow = Gloomy
marking-ThavenShadow-shadowthaven = Gloomy
# Snout
# Eyes
marking-SharkminnowEyeliner = Sharkminnow Eyeliner
marking-SharkminnowEyeliner-sharkminnoweyeliner = Sharkminnow Eyeliner
marking-ThavenEyesSharkminnow = Sharkminnow Eyes
marking-ThavenEyesSharkminnow-sharkminnow = Sharkminnow Eyes
marking-ThavenEyesSharkminnowGlowing = Glowing Sharkminnow Eyes
marking-ThavenEyesSharkminnowGlowing-sharkminnow = Glowing Sharkminnow Eyes
marking-ThavenLEyeGlow = Glowing Eye (Left)
marking-ThavenLEyeGlow-glowleft = Glowing Eye (Left)
marking-ThavenREyeGlow = Glowing Eye (Right)
marking-ThavenREyeGlow-glowright = Glowing Eye (Right)
# RArm
marking-ThavenRArmScales = Scales (Right Arm)
marking-ThavenRArmScales-scales = Scales (Right Arm)
marking-ThavenRArmTattoo1 = Arm Band (Right)
marking-ThavenRArmTattoo1-tat1 = Arm Band (Right)
marking-ThavenTigerRArm = Tiger Stripes (Right)
marking-ThavenTigerRArm-tiger = Tiger Stripes (Right)
# LArm
marking-ThavenLArmScales = Scales (Left Arm)
marking-ThavenLArmScales-scales = Scales (Left Arm)
marking-ThavenLArmTattoo1 = Arm Band (Left)
marking-ThavenLArmTattoo1-tat1 = Arm Band (Left)
marking-ThavenTigerLArm = Tiger Stripes (Left)
marking-ThavenTigerLArm-tiger = Tiger Stripes (Left)
# RLeg
marking-ThavenRLegScales = Scales (Right)
marking-ThavenRLegScales-scales = Scales (Right)
# LLeg
marking-ThavenLLegScales = Scales (Left)
marking-ThavenLLegScales-scales = Scales (Left)
# UndergarmentBottom
marking-UnderwearBriefsT = Briefs
marking-UnderwearBriefsT-briefs = Underwear
marking-UnderwearDefaultT = Boxers
marking-UnderwearDefaultT-boxers = Underwear
marking-UnderwearLowridersT = Lowriders
marking-UnderwearLowridersT-lowriders = Underwear
marking-UnderwearSatinT = Satin
marking-UnderwearSatinT-satin = Underwear
marking-UnderwearTangaT = Tanga
marking-UnderwearTangaT-tanga = Underwear
# UndergarmentTop
marking-UndergarmentTopBinderT = Binder
marking-UndergarmentTopBinderT-binder = Binder
marking-UndershirtBraClassicT = Bra
marking-UndershirtBraClassicT-classic = Bra
marking-UndershirtBraSportsT = Bra (Sports)
marking-UndershirtBraSportsT-sports = Bra
marking-UndershirtBraStraplessT = Bra (Strapless)
marking-UndershirtBraStraplessT-strapless = Bra
marking-UndershirtDefaultT = Undershirt
marking-UndershirtDefaultT-undershirt = Undershirt
marking-UndershirtGrossSleevelessT = Tanktop (Gross)
marking-UndershirtGrossSleevelessT-grosssleeveless = Tanktop
marking-UndershirtNanotrasenT = Undershirt (Nanotrasen)
marking-UndershirtNanotrasenT-nanotrasen = Undershirt
marking-UndershirtRolledT = Undershirt (Cropped)
marking-UndershirtRolledT-rolledundershirt = Undershirt
# LFoot
# RFoot
# LHand
# RHand
# FacialHair
# Hair
marking-BurqaSolidThaven = Burqa
marking-BurqaSolidThaven-burqa = Burqa
marking-HairFloralLongThaven = Floral hair (Long)
marking-HairFloralLongThaven-florallong1 = Hair
marking-HairFloralLongThaven-florallong2 = Flowers
marking-HairFloralMidThaven = Floral hair (Medium)
marking-HairFloralMidThaven-floralmid1 = Hair
marking-HairFloralMidThaven-floralmid2 = Flowers
marking-HijabFashionableThaven = Hijab (Fashionable)
marking-HijabFashionableThaven-hijabchic = Hijab (Fashionable)
marking-HijabSimpleThaven = Hijab (Simple)
marking-HijabSimpleThaven-hijabsimple = Hijab (Simple)
marking-MessyPonytailThaven = Messy Ponytail
marking-MessyPonytailThaven-messyponytail = Messy Ponytail
marking-NiqabThaven = Niqab
marking-NiqabThaven-niqab = Niqab
marking-ThavenHair80s = Short Hair 80s
marking-ThavenHair80s-80s = Short Hair 80s
marking-ThavenHairA = Short Hair
marking-ThavenHairA-a = Short Hair
# did anyone else hear just one single angelic note
marking-ThavenHairB = Shoulder-length Hair
marking-ThavenHairB-b = Shoulder-length Hair
marking-ThavenHairBald = Bald
marking-ThavenHairBald-bald = Bald
marking-ThavenHairBaldfade = Fade (Bald)
marking-ThavenHairBaldfade-baldface = Fade (Bald)
marking-ThavenHairBalding = Balding Hair
marking-ThavenHairBalding-e = Balding Hair
marking-ThavenHairBedhead = Bedhead
marking-ThavenHairBedhead-bedhead = Bedhead
marking-ThavenHairBedheadv2 = Bedhead 2
marking-ThavenHairBedheadv2-bedhead2 = Bedhead 2
marking-ThavenHairBedheadv3 = Bedhead 3
marking-ThavenHairBedheadv3-bedhead3 = Bedhead 3
marking-ThavenHairBeehive = Beehive
marking-ThavenHairBeehive-beehive = Beehive
marking-ThavenHairBeehive2 = Beehive 2
marking-ThavenHairBeehive2-beehive2 = Beehive 2
marking-ThavenHairBigflattop = Flat Top (Big)
marking-ThavenHairBigflattop-bigflattop = Flat Top (Big)
marking-ThavenHairBigpompadour = Pompadour (Big)
marking-ThavenHairBigpompadour-bigpompadour = Pompadour (Big)
marking-ThavenHairBob = Bob Hair
marking-ThavenHairBob-bob = Bob Hair
marking-ThavenHairBob2 = Bob Hair 2
marking-ThavenHairBob2-bob2 = Bob Hair 2
marking-ThavenHairBob4 = Bob Hair 4
marking-ThavenHairBob4-bob4 = Bob Hair 4
marking-ThavenHairBob5 = Bob Hair 5
marking-ThavenHairBob5-bob5 = Bob Hair 5
marking-ThavenHairBobcurl = Bobcurl
marking-ThavenHairBobcurl-bobcurl = Bobcurl
marking-ThavenHairBobcut = Bob Hair 3
marking-ThavenHairBobcut-bobcut = Bob Hair 3
marking-ThavenHairBowlcut = Bowlcut
marking-ThavenHairBowlcut-bowlcut = Bowlcut
marking-ThavenHairBowlcut2 = Bowlcut 2
marking-ThavenHairBowlcut2-bowlcut2 = Bowlcut 2
marking-ThavenHairBraid = Braid (Floorlength)
marking-ThavenHairBraid-braid = Braid (Floorlength)
marking-ThavenHairBraid2 = Braid (High)
marking-ThavenHairBraid2-braid2 = Braid (High)
marking-ThavenHairBraided = Braided
marking-ThavenHairBraided-braided = Braided
marking-ThavenHairBraidfront = Braided Front
marking-ThavenHairBraidfront-braidfront = Braided Front
marking-ThavenHairBraidtail = Braided Tail
marking-ThavenHairBraidtail-braidtail = Braided Tail
marking-ThavenHairBun = Bun Head
marking-ThavenHairBun-bun = Bun Head
marking-ThavenHairBun3 = Bun Head 3
marking-ThavenHairBun3-bun3 = Bun Head 3
marking-ThavenHairBunhead2 = Bun Head 2
marking-ThavenHairBunhead2-bunhead2 = Bun Head 2
marking-ThavenHairBusiness = Business Hair
marking-ThavenHairBusiness-business = Business Hair
marking-ThavenHairBusiness2 = Business Hair 2
marking-ThavenHairBusiness2-business2 = Business Hair 2
marking-ThavenHairBusiness3 = Business Hair 3
marking-ThavenHairBusiness3-business3 = Business Hair 3
marking-ThavenHairBusiness4 = Business Hair 4
marking-ThavenHairBusiness4-business4 = Business Hair 4
marking-ThavenHairBuzzcut = Buzzcut
marking-ThavenHairBuzzcut-buzzcut = Buzzcut
marking-ThavenHairC = Cut Hair
marking-ThavenHairC-c = Cut Hair
marking-ThavenHairCia = CIA
marking-ThavenHairCia-cia = CIA
marking-ThavenHairClassicAfro = Classic Afro
marking-ThavenHairClassicAfro-classicafro = Classic Afro
marking-ThavenHairClassicCia = Classic CIA
marking-ThavenHairClassicCia-classiccia = Classic CIA
marking-ThavenHairClassicciaBusiness = Classic CIA Business
marking-ThavenHairClassicciaBusiness-classicciabusiness = Classic CIA Business
marking-ThavenHairClassicCornrows = Classic Cornrows
marking-ThavenHairClassicCornrows-classiccornrows = Classic Cornrows
marking-ThavenHairClassicCornrows2 = Classic Cornrows 2
marking-ThavenHairClassicCornrows2-cornrows2 = Classic Cornrows 2
marking-ThavenHairClassicFloorlengthBedhead = Classic Floorlength Bedhead
marking-ThavenHairClassicFloorlengthBedhead-classicfloorlengthbedhead = Classic Floorlength Bedhead
marking-ThavenHairClassicLong2 = Classic Long Hair 2
marking-ThavenHairClassicLong2-classiclong2 = Classic Long Hair 2
marking-ThavenHairClassicLong3 = Classic Long Hair 3
marking-ThavenHairClassicLong3-classiclong3 = Classic Long Hair 3
marking-ThavenHairClassicModern = Classic Modern
marking-ThavenHairClassicModern-modern = Classic Modern
marking-ThavenHairClassicMulder = Classic Mulder
marking-ThavenHairClassicMulder-classicmulder = Classic Mulder
marking-ThavenHairClassicWisp = Classic Wisp
marking-ThavenHairClassicWisp-classicwisp = Classic Wisp
marking-ThavenHairCoffeeHouse = Coffee House
marking-ThavenHairCoffeeHouse-coffeehouse = Coffee House
marking-ThavenHairCombover = Combover
marking-ThavenHairCombover-combover = Combover
marking-ThavenHairCornrowbraid = Cornrow Braid
marking-ThavenHairCornrowbraid-cornrowbraid = Cornrow Braid
marking-ThavenHairCornrowbun = Cornrow Bun
marking-ThavenHairCornrowbun-cornrowbun = Cornrow Bun
marking-ThavenHairCornrows = Cornrows
marking-ThavenHairCornrows-cornrows = Cornrows
marking-ThavenHairCornrows2 = Cornrows 2
marking-ThavenHairCornrows2-cornrows2 = Cornrows 2
marking-ThavenHairCornrowtail = Cornrow Tail
marking-ThavenHairCornrowtail-cornrowtail = Cornrow Tail
marking-ThavenHairCountry = Ponytail (Country)
marking-ThavenHairCountry-country = Ponytail (Country)
marking-ThavenHairCrewcut = Crewcut
marking-ThavenHairCrewcut-crewcut = Crewcut
marking-ThavenHairCrewcut2 = Crewcut 2
marking-ThavenHairCrewcut2-crewcut2 = Crewcut 2
marking-ThavenHairCurls = Curls
marking-ThavenHairCurls-curls = Curls
marking-ThavenHairDandypompadour = Dandy Pompadour
marking-ThavenHairDandypompadour-dandypompadour = Dandy Pompadour
marking-ThavenHairDevilock = Devil Lock
marking-ThavenHairDevilock-devilock = Devil Lock
marking-ThavenHairDoublebun = Double Bun
marking-ThavenHairDoublebun-doublebun = Double Bun
marking-ThavenHairDoublebunLong = Double Bun Long
marking-ThavenHairDoublebunLong-doublebunlong = Double Bun Long
marking-ThavenHairDreads = Dreadlocks
marking-ThavenHairDreads-dreads = Dreadlocks
marking-ThavenHairDrillHair = Drill Hair
marking-ThavenHairDrillHair-drillhair = Drill Hair
marking-ThavenHairDrillhairextended = Drill Hair (Extended)
marking-ThavenHairDrillhairextended-drillhairextended = Drill Hair (Extended)
marking-ThavenHairDrillruru = Drillruru
marking-ThavenHairDrillruru-drillruru = Drillruru
marking-ThavenHairDyedLong = Dyed Long
marking-ThavenHairDyedLong-dyedlong1 = Dyed Long
marking-ThavenHairDyedShort = Dyed Short
marking-ThavenHairDyedShort-dyedshort1 = Dyed Short
marking-ThavenHairEmo2 = Emo
marking-ThavenHairEmo2-emo2 = Emo
marking-ThavenHairEmofringe = Emo Fringe
marking-ThavenHairEmofringe-emofringe = Emo Fringe
marking-ThavenHairFather = Father
marking-ThavenHairFather-father = Father
marking-ThavenHairFeather = Feather
marking-ThavenHairFeather-feather = Feather
marking-ThavenHairFlair = Flair
marking-ThavenHairFlair-flair = Flair
marking-ThavenHairFloorlengthBedhead = Floorlength Bedhead
marking-ThavenHairFloorlengthBedhead-floorlengthbedhead = Floorlength Bedhead
marking-ThavenHairFlow = Flow Hair
marking-ThavenHairFlow-f = Flow Hair
marking-ThavenHairFrenchbraid = French Braid
marking-ThavenHairFrenchbraid-frenchbraid = French Braid
marking-ThavenHairFringetail = Ponytail (Fringe)
marking-ThavenHairFringetail-fringetail = Ponytail (Fringe)
marking-ThavenHairGelled = Gelled Back
marking-ThavenHairGelled-gelled = Gelled Back
marking-ThavenHairGentle = Gentle
marking-ThavenHairGentle-gentle = Gentle
marking-ThavenHairHalfbang = Half-banged Hair
marking-ThavenHairHalfbang-halfbang = Half-banged Hair
marking-ThavenHairHalfbang2 = Half-banged Hair 2
marking-ThavenHairHalfbang2-halfbang2 = Half-banged Hair 2
marking-ThavenHairHalfshaved = Half-shaved
marking-ThavenHairHalfshaved-halfshaved = Half-shaved
marking-ThavenHairHalfUpLong = Half-Up (Long)
marking-ThavenHairHalfUpLong-halfuplong = Half-Up (Long)
marking-ThavenHairHalfUpShort = Half-Up (Short)
marking-ThavenHairHalfUpShort-halfupshort = Half-Up (Short)
marking-ThavenHairHalfUpUndercut = Half-Up (Undercut)
marking-ThavenHairHalfUpUndercut-halfupundercut = Half-Up (Undercut)
marking-ThavenHairHbraid = Braid (Low)
marking-ThavenHairHbraid-hbraid = Braid (Low)
marking-ThavenHairHedgehog = Hedgehog Hair
marking-ThavenHairHedgehog-hedgehog = Hedgehog Hair
marking-ThavenHairHighfade = Fade (High)
marking-ThavenHairHighfade-highfade = Fade (High)
marking-ThavenHairHighponytail = Ponytail (High)
marking-ThavenHairHighponytail-highponytail = Ponytail (High)
marking-ThavenHairHimecut = Hime Cut
marking-ThavenHairHimecut-himecut = Hime Cut
marking-ThavenHairHimecut2 = Hime Cut 2
marking-ThavenHairHimecut2-himecut2 = Hime Cut 2
marking-ThavenHairHimeup = Hime Updo
marking-ThavenHairHimeup-himeup = Hime Updo
marking-ThavenHairHitop = Hitop
marking-ThavenHairHitop-hitop = Hitop
marking-ThavenHairJade = Jade
marking-ThavenHairJade-jade = Jade
marking-ThavenHairJensen = Jensen Hair
marking-ThavenHairJensen-jensen = Jensen Hair
marking-ThavenHairJoestar = Joestar
marking-ThavenHairJoestar-joestar = Joestar
marking-ThavenHairKagami = Pigtails
marking-ThavenHairKagami-kagami = Pigtails
marking-ThavenHairKeanu = Keanu Hair
marking-ThavenHairKeanu-keanu = Keanu Hair
marking-ThavenHairKusanagi = Kusanagi Hair
marking-ThavenHairKusanagi-kusanagi = Kusanagi Hair
marking-ThavenHairLargebun = Bun (Large)
marking-ThavenHairLargebun-largebun = Bun (Large)
marking-ThavenHairLbangs = Long Bangs
marking-ThavenHairLbangs-lbangs = Long Bangs
marking-ThavenHairLong = Long Hair 1
marking-ThavenHairLong-long = Long Hair 1
marking-ThavenHairLong2 = Long Hair 2
marking-ThavenHairLong2-long2 = Long Hair 2
marking-ThavenHairLong3 = Long Hair 3
marking-ThavenHairLong3-long3 = Long Hair 3
marking-ThavenHairLongBedhead = Long Bedhead
marking-ThavenHairLongBedhead-longbedhead = Long Bedhead
marking-ThavenHairLongBedhead2 = Long Bedhead 2
marking-ThavenHairLongBedhead2-longbedhead2 = Long Bedhead 2
marking-ThavenHairLongeremo = Longer Emo
marking-ThavenHairLongeremo-longeremo = Longer Emo
marking-ThavenHairLongest = Very Long Hair 2
marking-ThavenHairLongest-longest = Very Long Hair 2
marking-ThavenHairLongest2 = Very Long Over Eye
marking-ThavenHairLongest2-longest2 = Very Long Over Eye
marking-ThavenHairLongfringe = Long Fringe
marking-ThavenHairLongfringe-longfringe = Long Fringe
marking-ThavenHairLongovereye = Long Over Eye
marking-ThavenHairLongovereye-longovereye = Long Over Eye
marking-ThavenHairLongsidepart = Long Side Part
marking-ThavenHairLongstraightponytail = Ponytail (Long)
marking-ThavenHairLongstraightponytail-longsidepart = Ponytail (Long)
marking-ThavenHairLongWithBundles = Long With Bundles
marking-ThavenHairLongWithBundles-longbundled = Long With Bundles
marking-ThavenHairLowfade = Fade (Low)
marking-ThavenHairLowfade-lowfade = Fade (Low)
marking-ThavenHairManbun = Bun (Manbun)
marking-ThavenHairManbun-manbun = Bun (Manbun)
marking-ThavenHairMedfade = Fade (Medium)
marking-ThavenHairMedfade-medfade = Fade (Medium)
marking-ThavenHairMediumSidepart = Medium Side Part
marking-ThavenHairMediumSidepart-mediumsidepart = Medium Side Part
marking-ThavenHairMegaeyebrows = Mega Eyebrows
marking-ThavenHairMegaeyebrows-megaeyebrows = Mega Eyebrows
marking-ThavenHairMessy = Messy
marking-ThavenHairMessy-messy = Messy
marking-ThavenHairMidPartLong = Middle Part (Long)
marking-ThavenHairMidPartLong-midpartlong = Middle Part (Long)
marking-ThavenHairMidPartLonger = Middle Part (Longer)
marking-ThavenHairMidPartLonger-midpartlonger = Middle Part (Longer)
marking-ThavenHairModern = Modern
marking-ThavenHairModern-modern = Modern
marking-ThavenHairMohawk = Mohawk
marking-ThavenHairMohawk-d = Mohawk
marking-ThavenHairMulder = Mulder
marking-ThavenHairMulder-mulder = Mulder
marking-ThavenHairMullet = Mullet
marking-ThavenHairMullet-mullet = Mullet
marking-ThavenHairMulletSideshave = Mullet (Sideshave)
marking-ThavenHairMulletSideshave-mulletsideshave = Mullet (Sideshave)
marking-ThavenHairNitori = Nitori
marking-ThavenHairNitori-nitori = Nitori
marking-ThavenHairNofade = Fade (None)
marking-ThavenHairNofade-nofade = Fade (None)
marking-ThavenHairOdango = Odango
marking-ThavenHairOdango-odango = Odango
marking-ThavenHairOmbre = Ombre
marking-ThavenHairOmbre-ombre = Ombre
marking-ThavenHairOneshoulder = One Shoulder
marking-ThavenHairOneshoulder-oneshoulder = One Shoulder
marking-ThavenHairOxton = Oxton
marking-ThavenHairOxton-oxton = Oxton
marking-ThavenHairPart = Parted (Side)
marking-ThavenHairPart-part = Parted (Side)
marking-ThavenHairParted = Parted
marking-ThavenHairParted-parted = Parted
marking-ThavenHairPigtails = Pigtails 2
marking-ThavenHairPigtails-pigtails = Pigtails 2
marking-ThavenHairPigtails2 = Pigtails 3
marking-ThavenHairPigtails2-pigtails2 = Pigtails 3
marking-ThavenHairPixie = Pixie Cut
marking-ThavenHairPixie-pixie = Pixie Cut
marking-ThavenHairPompadour = Pompadour
marking-ThavenHairPompadour-pompadour = Pompadour
marking-ThavenHairPonytail = Ponytail
marking-ThavenHairPonytail-ponytail = Ponytail
marking-ThavenHairPonytail2 = Ponytail 2
marking-ThavenHairPonytail2-ponytail2 = Ponytail 2
marking-ThavenHairPonytail3 = Ponytail 3
marking-ThavenHairPonytail3-ponytail3 = Ponytail 3
marking-ThavenHairPonytail4 = Ponytail 4
marking-ThavenHairPonytail4-ponytail4 = Ponytail 4
marking-ThavenHairPonytail5 = Ponytail 5
marking-ThavenHairPonytail5-ponytail5 = Ponytail 5
marking-ThavenHairPonytail6 = Ponytail 6
marking-ThavenHairPonytail6-ponytail6 = Ponytail 6
marking-ThavenHairPonytail7 = Ponytail 7
marking-ThavenHairPonytail7-ponytail7 = Ponytail 7
marking-ThavenHairPoofy = Poofy
marking-ThavenHairPoofy-poofy = Poofy
marking-ThavenHairProtagonist = Slightly Long Hair
marking-ThavenHairProtagonist-protagonist = Slightly Long Hair
marking-ThavenHairQuiff = Quiff
marking-ThavenHairQuiff-quiff = Quiff
marking-ThavenHairReversemohawk = Mohawk (Reverse)
marking-ThavenHairReversemohawk-reversemohawk = Mohawk (Reverse)
marking-ThavenHairRonin = Ronin
marking-ThavenHairRonin-ronin = Ronin
marking-ThavenHairRosa = Short Hair Rosa
marking-ThavenHairRosa-rosa = Short Hair Rosa
marking-ThavenHairSargeant = Flat Top
marking-ThavenHairSargeant-sargeant = Flat Top
marking-ThavenHairShaved = Shaved
marking-ThavenHairShaved-shaved = Shaved
marking-ThavenHairShavedMohawk = Shaved Mohawk
marking-ThavenHairShavedMohawk-shavedmohawk = Shaved Mohawk
marking-ThavenHairShavedpart = Shaved Part
marking-ThavenHairShavedpart-shavedpart = Shaved Part
marking-ThavenHairShortbangs = Short Bangs
marking-ThavenHairShortbangs-shortbangs = Short Bangs
marking-ThavenHairShortbraid = Braid (Short)
marking-ThavenHairShortbraid-shortbraid = Braid (Short)
marking-ThavenHairShorthair2 = Short Hair 2
marking-ThavenHairShorthair2-shorthair2 = Short Hair 2
marking-ThavenHairShorthair3 = Short Hair 3
marking-ThavenHairShorthair3-shorthair3 = Short Hair 3
marking-ThavenHairShorthair9 = Short Hair 9
marking-ThavenHairShorthair9-shorthair9 = Short Hair 9
marking-ThavenHairShorthime = Hime Cut (Short)
marking-ThavenHairShorthime-shorthime = Hime Cut (Short)
marking-ThavenHairShortovereye = Over Eye
marking-ThavenHairShortovereye-shortovereye = Over Eye
marking-ThavenHairShoulderLengthOverEye = Shoulder-length Over Eye
marking-ThavenHairShoulderLengthOverEye-shoulderlengthovereye = Shoulder-length Over Eye
marking-ThavenHairSidecut = Sidecut
marking-ThavenHairSidecut-sidecut = Sidecut
marking-ThavenHairSideshaveCurly = Sideshave (Curly)
marking-ThavenHairSideshaveCurly-sideshavecurly = Sideshave (Curly)
marking-ThavenHairSidetail = Ponytail (Side)
marking-ThavenHairSidetail-sidetail = Ponytail (Side)
marking-ThavenHairSidetail2 = Ponytail (Side) 2
marking-ThavenHairSidetail2-sidetail2 = Ponytail (Side) 2
marking-ThavenHairSidetail3 = Ponytail (Side) 3
marking-ThavenHairSidetail3-sidetail3 = Ponytail (Side) 3
marking-ThavenHairSidetail4 = Ponytail (Side) 4
marking-ThavenHairSidetail4-sidetail4 = Ponytail (Side) 4
marking-ThavenHairSkinhead = High And Tight
marking-ThavenHairSkinhead-skinhead = High And Tight
marking-ThavenHairSpiky = Spiky 2
marking-ThavenHairSpiky-spiky = Spiky 2
marking-ThavenHairSpikyponytailLong = Ponytail (Spiky Long)
marking-ThavenHairSpikyponytailLong-spikyponytaillong = Ponytail (Spiky Long)
marking-ThavenHairSpikyponytail = Ponytail (Spiky)
marking-ThavenHairSpikyponytail-spikyponytail = Ponytail (Spiky)
marking-ThavenHairSpookyLong = Spooky Long
marking-ThavenHairSpookyLong-spookylong = Spooky Long
marking-ThavenHairStail = Ponytail (Short)
marking-ThavenHairStail-stail = Ponytail (Short)
marking-ThavenHairSwept = Swept Back Hair
marking-ThavenHairSwept-swept = Swept Back Hair
marking-ThavenHairSwept2 = Swept Back Hair 2
marking-ThavenHairSwept2-swept2 = Swept Back Hair 2
marking-ThavenHairTailed = Tailed
marking-ThavenHairTailed-tailed = Tailed
marking-ThavenHairThinning = Thinning
marking-ThavenHairThinning-thinning = Thinning
marking-ThavenHairThinningfront = Thinning (Front)
marking-ThavenHairThinningfront-thinningfront = Thinning (Front)
marking-ThavenHairThinningrear = Thinning (Rear)
marking-ThavenHairThinningrear-thinningrear = Thinning (Rear)
marking-ThavenHairTightbun = Bun (Tight)
marking-ThavenHairTightbun-tightbun = Bun (Tight)
marking-ThavenHairTopknot = Topknot
marking-ThavenHairTopknot-topknot = Topknot
marking-ThavenHairTressshoulder = Tress Shoulder
marking-ThavenHairTressshoulder-tressshoulder = Tress Shoulder
marking-ThavenHairTrimflat = Trim Flat
marking-ThavenHairTrimflat-trimflat = Trim Flat
marking-ThavenHairTrimmed = Trimmed
marking-ThavenHairTrimmed-trimmed = Trimmed
marking-ThavenHairTwintail = Twintails
marking-ThavenHairTwintail-twintail = Twintails
marking-ThavenHairTwoStrands = Two Strands
marking-ThavenHairTwoStrands-twostrands = Two Strands
marking-ThavenHairUndercut = Undercut
marking-ThavenHairUndercut-undercut = Undercut
marking-ThavenHairUndercutCurly = Undercut (Curly)
marking-ThavenHairUndercutCurly-undercutcurly = Undercut (Curly)
marking-ThavenHairUndercutleft = Undercut Left
marking-ThavenHairUndercutleft-undercutleft = Undercut Left
marking-ThavenHairUndercutright = Undercut Right
marking-ThavenHairUndercutright-undercutright = Undercut Right
marking-ThavenHairUneven = Uneven
marking-ThavenHairUneven-uneven = Uneven
marking-ThavenHairUnkept = Unkept
marking-ThavenHairUnkept-unkept = Unkept
marking-ThavenHairVeryshortovereyealternate = Very Short Over Eye
marking-ThavenHairVeryshortovereyealternate-veryshortovereyealternate = Very Short Over Eye
marking-ThavenHairVlong = Very Long Hair
marking-ThavenHairVlong-vlong = Very Long Hair
marking-ThavenHairVlongfringe = Very Long with Fringe
marking-ThavenHairVlongfringe-vlongfringe = Very Long with Fringe
marking-ThavenHairVolaju = Volaju
marking-ThavenHairVolaju-volaju = Volaju
marking-ThavenHairWisp = Wisp
marking-ThavenHairWisp-wisp = Wisp
marking-TichelFashionableThaven = Tichel (Fashionable)
marking-TichelFashionableThaven-tichelfashionable = Tichel (Fashionable)
marking-TichelSimpleThaven = Tichel (Simple)
marking-TichelSimpleThaven-tichelsimple = Tichel (Simple)
marking-ShaggyThaven = Shaggy
marking-ShaggyThaven-shaggythaven = Shaggy
marking-ShaggyLongerThaven = Shaggy (Longer)
marking-ShaggyLongerThaven-shaggylongerthaven = Shaggy (Longer)
marking-SusieThaven = Mean Girl (Bangs)
marking-SusieThaven-susiethaven = Mean Girl (Bangs)
marking-SusieNoBangsThaven = Mean Girl
marking-SusieNoBangsThaven-susienobangsthaven = Mean Girl
# HeadSide
marking-ThavenEars1 = Small Ears
marking-ThavenEars1-ears1 = Small Ears
marking-ThavenEars2 = Medium Ears
marking-ThavenEars2-ears2 = Medium Ears
marking-ThavenEars3 = Long Ears
marking-ThavenEars3-ears3 = Long Ears
marking-ThavenEars4 = Droopy Ears
marking-ThavenEars4-ears4 = Droopy Ears
marking-ThavenEarsBigFins = Big Fins
marking-ThavenEarsBigFins-bigfins = Outer
marking-ThavenEarsBigFins-bigfins2 = Inner
marking-ThavenEarsTwinFins = Twin Fins
marking-ThavenEarsTwinFins-twinfin = Twin Fins
marking-ThavenFishEars = Finned Ears
marking-ThavenFishEars-fishears = Finned Ears
marking-ThavenNoEars = Recolorable ears
marking-ThavenNoEars-noears = For use with head coverings
# HeadTop
marking-ThavenHibiscus = Hibiscus
marking-ThavenHibiscus-hibiscus1 = Petals
marking-ThavenHibiscus-hibiscus2 = Anthers
marking-ThavenPiercings = Helix Piercing
marking-ThavenPiercings-piercings = Helix Piercing
marking-ThavenPiercings2 = Hoop Piercing
marking-ThavenPiercings2-piercings2 = Hoop Piercing
# Tail
marking-ThavenBasicTail = Basic Tail
marking-ThavenBasicTail-basic = Basic Tail
marking-ThavenBigTail = Big Tail
marking-ThavenBigTail-big1 = Tail
marking-ThavenBigTail-big2 = Fin
marking-ThavenTadpoleTail = Tadpole Tail
marking-ThavenTadpoleTail-tadpole1 = Tail
marking-ThavenTadpoleTail-tadpole2 = Fin
marking-ThavenTailEel = Eel Tail
marking-ThavenTailEel-eel1 = Eel Tail Trunk
marking-ThavenTailEel-eel2 = Eel Tail Tip
marking-ThavenTailEelOverlay = Eel Tail (Overlay)
marking-ThavenTailEelOverlay-eel3 = Eel Inner
marking-ThavenTailEelOverlay-eel4 = Eel Outer
marking-ThavenTailNurse = Swept Tail
marking-ThavenTailNurse-nurse1 = Tail
marking-ThavenTailNurse-nurse2 = Stripes
marking-ThavenTailStub = Stub Tail
marking-ThavenTailStub-stub1 = Tail
marking-ThavenTailStub-stub2 = Stripes
marking-ThavenTailThresher = Thresher Tail
marking-ThavenTailThresher-thresher1 = Tail
marking-ThavenTailThresher-thresher2 = Stripes
# RArmExtension
@@ -1,3 +0,0 @@
alert-level-orange = Orange
alert-level-orange-announcement = There is a critical station-wide structural or atmospheric threat and recovery is unlikely. Engineering staff are advised to minimize hazards and secure the Evacuation Dock. Crewmembers are advised to stay away from hazardous areas, and prepare for Evacuation. MAYDAY signals have been activated
alert-level-orange-instructions = Avoid hazards and prepare for Evacuation.
@@ -0,0 +1,12 @@
hand-labeler-saved-labels = Saved Labels:
# The text on the button in the ui to save a label to the saved label list.
hand-labeler-save-label-text = Save Label
# The text on the button in the ui to delete a label from the saved label list.
hand-labeler-delete-label-text = Delete Label
# The text on the button when in delete mode.
hand-labeler-delete-mode-text = Deleting...
@@ -45,3 +45,7 @@ alert-level-octarine = Octarine
alert-level-octarine-announcement = A cataclysmic noospheric event threatens to envelop realspace. Station crew are to contain the event if possible, or else evacuate.
alert-level-octarine-instructions = Crewmembers are advised to listen to heads of staff for more information.
## DeltaV - Zeta
alert-level-zeta = Zeta
alert-level-zeta-announcement = The station is unrecoverable, and all important assets and crewmembers are to be evacuated. A distress signal has been sent to all nearby vessels. Security and Engineering staff are advised to minimize hazards and secure the Evacuation Dock. Crewmembers are advised to disembark the station by any means necessary. Godspeed.
alert-level-zeta-instructions = Avoid hazards and prepare for Evacuation.
@@ -1 +1,2 @@
comp-label-format = {$baseName} ({$label})
# Coyote: reverse order of label and baseName
comp-label-format = {$label} ({$baseName})
@@ -358,9 +358,6 @@ uplink-chameleon-desc = A backpack full of items that contain chameleon technolo
uplink-clothing-no-slips-shoes-name = No-slip Shoes
uplink-clothing-no-slips-shoes-desc = Chameleon shoes that protect you from slips.
uplink-clothing-chameleon-thieving-gloves-name = Chameleon Thieving Gloves
uplink-clothing-chameleon-thieving-gloves-desc = Discreetly steal from pockets and improve your thieving technique with these fancy new gloves. They can change appearance to match any pair of gloves!
uplink-clothing-outer-vest-web-name = Web Vest
uplink-clothing-outer-vest-web-desc = A synthetic armor vest. This one has added webbing and ballistic plates.
File diff suppressed because it is too large Load Diff
+89645 -41311
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -28978,8 +28978,6 @@ entities:
- type: Transform
pos: 12.5,39.5
parent: 8
- type: CommunicationsConsole
announcementCooldownRemaining: -0.0166666
- proto: ComputerCrewMonitoring
entities:
- uid: 678
+5 -1
View File
@@ -252,5 +252,9 @@ BoxPerformer: BoxPerformerDV
SpawnPointMedicalBorg: SpawnPointBorg
SpawnPointSecurityBorg: SpawnPointBorg
# 2026-06-02
Screen: StatusDisplay
ArrivalsShuttleTimer: StatusDisplayShuttle
# 2026-08-10
BookSecretDocuments: BookMedicalDocuments
BookSecretDocuments: BookMedicalDocuments
+1
View File
@@ -87,6 +87,7 @@
params:
volume: 5
priority: -12
useDelay: 5 # DeltaV - small cooldown
- type: TargetAction
checkCanAccess: false
range: 0
@@ -43,17 +43,6 @@
emergencyLightColor: Red
forceEnableEmergencyLights: true
shuttleTime: 600 #No reduction in time as we don't have swiping for red alert like in /tg/. Shuttle times are intended to create friction, so having a way to brainlessly bypass that would be dumb.
# Begin Starlight Additions
orange:
announcement: alert-level-orange-announcement
selectable: true
sound:
path: /Audio/_Starlight/misc/orange.ogg
color: "#ff8119"
emergencyLightColor: "#ff8119"
forceEnableEmergencyLights: true
shuttleTime: 480
# End Starlight Additions
gamma:
announcement: alert-level-gamma-announcement
selectable: false
@@ -90,3 +79,13 @@
emergencyLightColor: CadetBlue
forceEnableEmergencyLights: true
shuttleTime: 600
zeta: # DeltaV - zeta
announcement: alert-level-zeta-announcement
selectable: false
disableSelection: true
sound:
path: /Audio/_DV/Announcements/Alerts/code_zeta.ogg
color: "#fe8401"
emergencyLightColor: "#fe8401"
forceEnableEmergencyLights: true
shuttleTime: 480
@@ -447,5 +447,5 @@
storagebase: !type:AllSelector
children:
- id: WeaponShotgunHushpup
- id: BoxLethalshot
- id: BoxShellCaseless # DeltaV switched default to caseless shells
- id: TreasureCoinIron
@@ -142,6 +142,7 @@
ClothingUniformBrownSuitSkirt: 2
ClothingShoesLeather: 2
ClothingShoesBootsLaceup: 2
ClothingShoesBootsSurplus: 3
# End DeltaV additions
contrabandInventory:
ClothingMaskNeckGaiter: 2
@@ -1783,21 +1783,6 @@
categories:
- UplinkWearables
# DeltaV - add back thieving gloves
- type: listing
id: UplinkgClothingThievingGloves
name: uplink-clothing-chameleon-thieving-gloves-name
description: uplink-clothing-chameleon-thieving-gloves-desc
productEntity: ClothingHandsChameleonThief
discountCategory: veryRareDiscounts
discountDownTo:
Telecrystal: 4 # DeltaV - was 3
cost:
Telecrystal: 7 # DeltaV - Was 5, 5TC was too cheap for the items power
categories:
- UplinkWearables
# DeltaV - end of changes
- type: listing
id: UplinkClothingOuterVestWeb
name: uplink-clothing-outer-vest-web-name
@@ -57,8 +57,12 @@
interfaces:
enum.SolarControlConsoleUiKey.Key:
type: SolarControlConsoleBoundUserInterface
enum.CommunicationsConsoleUiKey.Key:
type: CommunicationsConsoleBoundUserInterface
# BEGIN DeltaV - our own thing
#enum.CommunicationsConsoleUiKey.Key:
# type: CommunicationsConsoleBoundUserInterface
enum.DVCommunicationsConsoleUi.Key:
type: DVCommunicationsConsoleBoundUserInterface
# END DeltaV
enum.RadarConsoleUiKey.Key:
type: RadarConsoleBoundUserInterface
enum.CargoConsoleUiKey.Orders:
@@ -76,7 +80,8 @@
uis:
enum.SolarControlConsoleUiKey.Key:
toggleAction: ActionAGhostShowSolar
enum.CommunicationsConsoleUiKey.Key:
#enum.CommunicationsConsoleUiKey.Key: # DeltaV - comms console
enum.DVCommunicationsConsoleUi.Key: # DeltaV - comms console
toggleAction: ActionAGhostShowCommunications
enum.RadarConsoleUiKey.Key:
toggleAction: ActionAGhostShowRadar
@@ -91,12 +96,22 @@
toggleAction: ActionAGhostShowCharacterRecords
# End CD - Character Records
- type: SolarControlConsole # look ma i AM the computer!
- type: CommunicationsConsole
title: comms-console-announcement-title-centcom
color: "#1d8bad"
delay: 10
initialDelay: 0
global: true
# Begin DeltaV - our own thing
#- type: CommunicationsConsole
# title: comms-console-announcement-title-centcom
# color: "#1d8bad"
# delay: 10
# initialDelay: 0
# global: true
- type: DVCommunicationsConsole
announcementTitle: comms-console-announcement-title-centcom
announcementColor: "#1d8bad"
canAlertLevel: true
canCallShuttles: true
canConfigureScreens: false
canKeycardAuthenticationDevice: false
globalAnnouncements: true
# End DeltaV
- type: RadarConsole
followEntity: true
- type: CargoOrderConsole
@@ -112,7 +127,7 @@
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: NTNet # DeltaV - NTNet
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet # DeltaV - DVComms Console
- type: WirelessNetworkConnection
range: 10000 # DeltaV
#- type: StationLimitedNetwork # DeltaV - Off-station coordinates
@@ -164,7 +179,7 @@
keywords: [ "AI", "console", "interface" ]
priority: -4
- type: InstantAction
event: !type:ToggleIntrinsicUIEvent { key: enum.CommunicationsConsoleUiKey.Key }
event: !type:ToggleIntrinsicUIEvent { key: enum.DVCommunicationsConsoleUi.Key } # DeltaV - was enum.CommunicationsConsoleUiKey.Key
- type: entity
parent: BaseAGhostAction
@@ -58,8 +58,12 @@
type: GeneralStationRecordConsoleBoundUserInterface
enum.SiliconLawsUiKey.Key:
type: SiliconLawBoundUserInterface
enum.CommunicationsConsoleUiKey.Key:
type: CommunicationsConsoleBoundUserInterface
# BEGIN DeltaV - comms console rework
#enum.CommunicationsConsoleUiKey.Key:
# type: CommunicationsConsoleBoundUserInterface
enum.DVCommunicationsConsoleUi.Key:
type: DVCommunicationsConsoleBoundUserInterface
# END DeltaV
enum.StoreUiKey.Key: # DeltaV - AI shop system
type: StoreBoundUserInterface
# Begin DeltaV - AI PDAs
@@ -80,7 +84,8 @@
toggleAction: ActionAGhostShowCrewMonitoring
enum.GeneralStationRecordConsoleKey.Key:
toggleAction: ActionAGhostShowStationRecords
enum.CommunicationsConsoleUiKey.Key:
#enum.CommunicationsConsoleUiKey.Key: # DeltaV - comms console
enum.DVCommunicationsConsoleUi.Key: # DeltaV - comms console
toggleAction: ActionAGhostShowCommunications
# Begin DeltaV - AI fax
enum.FaxUiKey.Key:
@@ -94,10 +99,20 @@
transmitFrequencyId: NTNet # DeltaV
- type: RadarConsole
followEntity: false
- type: CommunicationsConsole
canShuttle: false
title: comms-console-announcement-title-station-ai
color: "#5ed7aa"
# BEGIN DeltaV - our own thing
#- type: CommunicationsConsole
# canShuttle: false
# title: comms-console-announcement-title-station-ai
# color: "#5ed7aa"
- type: DVCommunicationsConsole
announcementTitle: comms-console-announcement-title-station-ai
announcementColor: "#5ed7aa"
canAlertLevel: true
canCallShuttles: false
canConfigureScreens: true
canKeycardAuthenticationDevice: false
globalAnnouncements: true
# END DeltaV
- type: ShowJobIcons
#- type: ShowCrewIcons # DeltaV - Disable crew icons
- type: DamagedSiliconAccent
@@ -241,6 +241,7 @@
- Rootsong
- type: TypingIndicator
proto: diona
- type: BlockMovement # They should never be moving!
# DeltaV end
- type: entity
@@ -313,13 +313,14 @@
- 0,0,3,0 # smaller than BaseShotgun by 1 tile
- type: BallisticAmmoProvider
capacity: 4
proto: ShellShotgunCaseless # DeltaV - Use caseless shells
- type: GunRequiresWield
- type: Gun
soundGunshot:
path: /Audio/Weapons/Guns/Gunshots/hushpup.ogg
params:
volume: -3
rolloffFactor: 1.3
volume: -6
rolloffFactor: 1.7
fireRate: 2
- type: GunSpreadModifier
spread: 1.2
@@ -163,7 +163,7 @@
- type: LimitedCharges
maxCharges: 3
- type: AutoRecharge
rechargeDuration: 20
rechargeDuration: 30 # DeltaV - was 20
- type: Clothing
sprite: Objects/Weapons/Melee/energykatana.rsi
slots:
@@ -32,6 +32,7 @@
- BaseStationStockMarket
- BaseStationLavaland
- BaseStationExfiltration
- BaseStationKeycardAuthenticationDevice
# End DeltaV - Station additions
categories: [ HideSpawnMenu ]
components:
@@ -695,17 +695,23 @@
state: generic_panel_open
- type: AccessReader
access: [[ "Command" ]]
- type: CommunicationsConsole
title: comms-console-announcement-title-station
# Begin DeltaV - DV Comms Console
# - type: CommunicationsConsole
# title: comms-console-announcement-title-station
- type: ActivatableUIRequiresAccess
- type: DVCommunicationsConsole # DeltaV - new functionality
announcementTitle: comms-console-announcement-title-station
# End DeltaV
- type: DeviceNetwork
deviceNetId: Wireless
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet # DeltaV - DVComms console
receiveFrequencyId: NTNet # DeltaV - DVComms console
- type: ActivatableUI
key: enum.CommunicationsConsoleUiKey.Key
key: enum.DVCommunicationsConsoleUi.Key # DeltaV - new UI
- type: UserInterface
interfaces:
enum.CommunicationsConsoleUiKey.Key:
type: CommunicationsConsoleBoundUserInterface
enum.DVCommunicationsConsoleUi.Key: # DeltaV - new UI
type: DVCommunicationsConsoleBoundUserInterface
enum.WiresUiKey.Key:
type: WiresBoundUserInterface
- type: Computer
@@ -741,13 +747,25 @@
state: generic_panel_open
- type: AccessReader
access: [[ "NuclearOperative" ]]
- type: CommunicationsConsole
title: comms-console-announcement-title-unauthorized # DeltaV
color: "#ff0000"
canShuttle: false
global: true #announce to everyone they're about to fuck shit up
sound: /Audio/Announcements/intercept.ogg # DeltaV
announceSentBy: false # The title already says who they are.
# Begin DeltaV Changes
# - type: CommunicationsConsole
# title: comms-console-announcement-title-unauthorized # DeltaV
# color: "#ff0000"
# canShuttle: false
# global: true #announce to everyone they're about to fuck shit up
# sound: /Audio/Announcements/intercept.ogg # DeltaV
# announceSentBy: false # The title already says who they are.
- type: DVCommunicationsConsole
announcementTitle: comms-console-announcement-title-unauthorized
announcementColor: "#ff0000"
announcementSound:
path: /Audio/Announcements/intercept.ogg
canAlertLevel: false
canCallShuttles: false
canConfigureScreens: false
canKeycardAuthenticationDevice: false
globalAnnouncements: true
# End DeltaV Changes
- type: Computer
board: SyndicateCommsComputerCircuitboard
- type: PointLight
@@ -775,13 +793,23 @@
state: generic_panel_open
- type: AccessReader
access: [[ "Wizard" ]]
- type: CommunicationsConsole
title: comms-console-announcement-title-wizard
color: "#ff00ff"
canShuttle: false
global: true #announce to everyone they're about to fuck shit up
announceSentBy: false
sound: /Audio/Announcements/announce.ogg # DeltaV - changed from war.oog to announce.ogg
# Begin DeltaV Changes
# - type: CommunicationsConsole
# title: comms-console-announcement-title-wizard
# color: "#ff00ff"
# canShuttle: false
# global: true #announce to everyone they're about to fuck shit up
# announceSentBy: false
# sound: /Audio/Announcements/announce.ogg # DeltaV - changed from war.oog to announce.ogg
- type: DVCommunicationsConsole
announcementTitle: comms-console-announcement-title-wizard
announcementColor: "#ff00ff"
canAlertLevel: false
canCallShuttles: false
canConfigureScreens: false
canKeycardAuthenticationDevice: false
globalAnnouncements: true
# End DeltaV Changes
- type: Computer
board: WizardCommsComputerCircuitboard
- type: PointLight
@@ -809,11 +837,21 @@
state: generic_panel_open
- type: AccessReader
access: [[ "CentralCommand" ]]
- type: CommunicationsConsole
title: comms-console-announcement-title-centcom
color: "#1d8bad"
canShuttle: false
global: true
# Begin DeltaV Changes
# - type: CommunicationsConsole
# title: comms-console-announcement-title-centcom
# color: "#1d8bad"
# canShuttle: false
# global: true
- type: DVCommunicationsConsole
announcementTitle: comms-console-announcement-title-centcom
announcementColor: "#1d8bad"
canAlertLevel: false
canCallShuttles: false
canConfigureScreens: false
canKeycardAuthenticationDevice: false
globalAnnouncements: true
# End DeltaV Changes
- type: Computer
board: CentcommCommsComputerCircuitboard
- type: PointLight
@@ -1,4 +1,5 @@
- type: entity
categories: [ HideSpawnMenu ] # DeltaV - use the other one
parent: BaseWallmountMachine
id: Screen
name: screen
@@ -32,9 +33,10 @@
- type: Screen
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: ShuttleTimer
receiveFrequencyId: NTNet # DeltaV - comms console
- type: entity
categories: [ HideSpawnMenu ] # DeltaV - use the other one
id: ArrivalsShuttleTimer
parent: Screen
name: arrivals screen
+15 -8
View File
@@ -600,16 +600,23 @@
- type: NextEvent # DeltaV: Queue Event for precognition
- type: RampingStationEventScheduler
timeKeyPoints: # DeltaV
- 10, 10
- 10, 7
- 10, 6
- 10, 1
- 10, 3
- 15, 5
- 15, 4
- 20, 2
- 10, 1
- 10, 5
- 5, 2 # Heavy event density from minute 35 through 40
- 15, 10
- 10, 2 # Heavy event density from minute 50 through 60
- 10, 4
- 10, 3
- 15, 6
- 10, 2 # Heavy density from minute 85 through 95
# Probable EOR, start winding down
- 10, 5
- 10, 7
- 20, 10
# Crew decided to stay so wind back up
- 10, 6
- 20, 4
- 20, 2
- 70, 4
scheduledGameRules: !type:NestedSelector
tableId: BasicGameRulesTable
@@ -99,3 +99,13 @@
cost: 7600
category: Armory
group: market
- type: cargoProduct
id: CargoArmoryPatos
icon:
sprite: _DV/Objects/Weapons/Guns/SMGs/patos.rsi
state: icon
product: CrateCargoArmoryPatos
cost: 7500
category: Armory
group: market
@@ -118,3 +118,18 @@
amount: 2
- id: ClothingShoesBootsCowboyBlackFilled
amount: 2
- type: entity
parent: [ CrateWeaponSecure, BaseSecurityContraband ]
id: CrateCargoArmoryPatos
name: patos crate
description: Contains two lightweight patos SMGs with four high-capacity clips. Requires Armory access to open.
components:
- type: EntityTableContainerFill
containers:
entity_storage: !type:AllSelector
children:
- id: WeaponSubMachineGunPatos
amount: 2
- id: MagazinePistolHighCapacity
amount: 4
@@ -20,3 +20,14 @@
sprite: _DV/Clothing/Shoes/Boots/fishing_boots.rsi
- type: Clothing
sprite: _DV/Clothing/Shoes/Boots/fishing_boots.rsi
- type: entity
parent: [ClothingShoesBaseButcherable]
id: ClothingShoesBootsSurplus
name: surplus boots
description: An old pair of boots. Not so useful for combat, but still plenty stylish.
components:
- type: Sprite
sprite: Clothing/Shoes/Boots/jackboots.rsi
- type: Clothing
sprite: Clothing/Shoes/Boots/jackboots.rsi
@@ -400,7 +400,7 @@
- sprite: _DV/Mobs/Customization/Vulpkanin/tail_markings.rsi
state: vulp_wag
- sprite: _DV/Mobs/Customization/Vulpkanin/tail_markings.rsi
state: vulp_wag-tip #fade
state: vulp_wag-fade #fade
- type: marking
id: VulpTailTipAnimated
@@ -412,6 +412,26 @@
- sprite: _DV/Mobs/Customization/Vulpkanin/tail_markings.rsi
state: vulp_wag-tip
- type: marking
id: VulpTailAltAnimated
bodyPart: Tail
groupWhitelist: []
sprites:
- sprite: _DV/Mobs/Customization/Vulpkanin/tail_markings.rsi
state: vulp_wag
- sprite: _DV/Mobs/Customization/Vulpkanin/tail_markings.rsi
state: vulp_wag-fade #fade
- type: marking
id: VulpTailAltTipAnimated
bodyPart: Tail
groupWhitelist: []
sprites:
- sprite: _DV/Mobs/Customization/Vulpkanin/tail_markings.rsi
state: vulp_wag
- sprite: _DV/Mobs/Customization/Vulpkanin/tail_markings.rsi
state: vulp_wag-tip
- type: marking
id: VulpTailFoxAnimated
bodyPart: Tail
@@ -84,20 +84,20 @@
lightThreshold: 0.7
darkDamage:
types:
Blunt: -5
Piercing: -5
Slash: -5
Heat: -5
Poison: -5
Asphyxiation: -2.5
Bloodloss: -2.5
Cellular: -5
Blunt: -2
Piercing: -2
Slash: -2
Heat: -2
Poison: -2
Asphyxiation: -2
Bloodloss: -2
Cellular: -2
Soul: -1
lightDamage:
types:
Blunt: 1.5
Piercing: 1.5
Slash: 1.5
Blunt: 2
Piercing: 2
Slash: 2
healWhenDead: true
darkMovementSpeedMultiplier: 1.25
lightMovementSpeedMultiplier: 1.0
@@ -6,3 +6,20 @@
components:
- type: BallisticAmmoProvider
proto: ShellSoulbreaker
- type: entity
parent: AmmoProviderShotgunShell
id: BoxShellCaseless
name: ammunition box (.50 caseless)
description: A box full of caseless shotgun cartridges, designed to leave no trace behind.
components:
- type: BallisticAmmoProvider
proto: ShellShotgunCaseless
- type: Sprite
sprite: _DV/Objects/Weapons/Guns/Ammunition/Boxes/shotgun.rsi
layers:
- state: base
map: [ "enum.GunVisualLayers.Base" ]
- state: mag-1
map: [ "enum.GunVisualLayers.Mag" ]
- state: caseless
@@ -0,0 +1,14 @@
- type: entity
parent: [ ShellShotgun ]
id: ShellShotgunCaseless
name: caseless shell (.50 pellet)
description: An advanced caseless cartridge used by most modern shotguns. Leaves no trace behind while firing standard kinetic ammunition.
components:
- type: CartridgeAmmo
proto: PelletShotgunSpread
deleteOnSpawn: true
- type: Sprite
sprite: _DV/Objects/Weapons/Guns/Ammunition/Casings/caseless_shotgun_shell.rsi
layers:
- state: base
map: [ "enum.AmmoVisualLayers.Base" ]
@@ -1,7 +1,7 @@
- type: entity
name: mothroach grenade
description: A grenade containing 8 dehydrated mothroaches, trained to attack everything nearby.
parent: [ScatteringGrenadeBase, BaseSyndicateContraband]
parent: [ScatteringGrenadeBase, TimerGrenadeBase, BaseSyndicateContraband]
id: MothroachGrenade
components:
- type: Sprite
@@ -16,8 +16,6 @@
Primed: { state: primed }
Unprimed: { state: icon }
- type: TimerTrigger
keysIn:
- trigger
beepSound:
path: "/Audio/Effects/beep1.ogg"
params:
@@ -42,3 +42,12 @@
- type: StationPlanetSpawner
planet: Lavaland
gridPath: /Maps/_DV/Nonstations/lavaland_mining_base.yml
- type: entity
abstract: true
id: BaseStationKeycardAuthenticationDevice
components:
- type: DVStationKeycardAuthenticationDevice
actionThresholds:
Mayday: 2
Scuttling: 3
@@ -805,7 +805,7 @@
containers:
board: [ DoorElectronicsERT ]
# Centcomm external doors
# Centcomm doors
- type: entity
parent: AirlockExternal
id: AirlockExternalCentralCommandLocked
@@ -823,3 +823,21 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsCentralCommand ]
- type: entity
parent: AirlockFreezer
id: AirlockFreezerCentralCommanLocked
suffix: Freezer, Centcomm, Locked
components:
- type: ContainerFill
containers:
board: [ DoorElectronicsCentralCommand ]
- type: entity
parent: AirlockMaint
id: AirlockMaintCentcommLocked
suffix: Maint, Centcomm, Locked
components:
- type: ContainerFill
containers:
board: [ DoorElectronicsCentralCommand ]
@@ -495,3 +495,46 @@
stateDoorClosed: eng_evac_door
- type: AccessReader
access: [ [ "Maintenance" ] ]
# CC Safe
- type: entity
id: SafeCentralCommandDV
parent: GunSafe
name: safe
description: The perfect place for all the secret documents.
components:
- type: Appearance
- type: Sprite
sprite: _DV/Structures/Storage/Closets/ccsgunsafe.rsi
noRot: true
layers:
- state: base
map: ["enum.StorageVisualLayers.Base"]
- state: door
map: ["enum.StorageVisualLayers.Door"]
- state: locked
map: ["enum.LockVisualLayers.Lock"]
shader: unshaded
- state: welded
visible: false
map: ["enum.WeldableLayers.BaseWelded"]
- type: EntityStorageVisuals
stateBaseClosed: base
stateDoorOpen: open
stateDoorClosed: door
- type: entity
id: SafeCentralCommandLockedDV
parent: SafeCentralCommandDV
suffix: CC, Locked
components:
- type: AccessReader
access: [["CentralCommand"]]
- type: entity
id: SafeERTLockedDV
parent: SafeCentralCommandDV
suffix: ERT, Locked
components:
- type: AccessReader
access: [["ERT"]]
@@ -0,0 +1,105 @@
- type: entity
parent: BaseWallmountMachine
id: StatusDisplay
name: status display
description: Displays the current status of the station.
components:
- type: Rotatable
- type: DVTextVisuals
rows:
- text: ""
layer: enum.DVTextScreenVisualLayers.Line1
offset: 0.03125,0.15625 # 1/32, 5/32
- text: ""
layer: enum.DVTextScreenVisualLayers.Line2
offset: 0.03125,-0.0625 # 1/32, 0/32
- type: DVScreen
- type: Sprite
drawdepth: WallMountedItems
sprite: _DV/Structures/Wallmounts/screen.rsi
noRot: true
layers:
- state: frame
- shader: StencilClear
state: mask
- shader: StencilMask
state: mask
- map: ["enum.DVTextScreenVisualLayers.Line1"]
shader: StencilDraw
color: "#22ccff"
visible: false
- map: ["enum.DVTextScreenVisualLayers.Line2"]
shader: StencilDraw
color: "#22ccff"
visible: false
- map: ["alert_status"]
visible: false
state: status_display_green
- map: ["alert_border"]
visible: false
state: alert_border_green
- type: Appearance
- type: ApcPowerReceiver
- type: ExtensionCableReceiver
- type: GenericVisualizer
visuals:
enum.DVScreenVisuals.ShowAlertBorder:
alert_border:
True: { visible: true }
False: { visible: false }
enum.DVScreenVisuals.AlertLevel:
alert_border:
green: { state: alert_border_green }
blue: { state: alert_border_blue }
red: { state: alert_border_red }
white: { state: alert_border_white }
yellow: { state: alert_border_yellow }
violet: { state: alert_border_violet }
delta: { state: alert_border_delta }
epsilon: { state: alert_border_epsilon }
gamma: { state: alert_border_gamma }
octarine: { state: alert_border_octarine }
zeta: { state: alert_border_zeta }
alert_status:
green: { state: status_display_green }
blue: { state: status_display_blue }
red: { state: status_display_red }
white: { state: status_display_white }
yellow: { state: status_display_yellow }
violet: { state: status_display_violet }
delta: { state: status_display_delta }
epsilon: { state: status_display_epsilon }
gamma: { state: status_display_gamma }
octarine: { state: status_display_octarine }
zeta: { state: status_display_zeta }
enum.DVScreenVisuals.Content:
enum.DVTextScreenVisualLayers.Line1:
Text: { visible: true }
CurrentTime: { visible: true }
EstimatedTimeOfArrival: { visible: true }
AlertLevel: { visible: false }
enum.DVTextScreenVisualLayers.Line2:
Text: { visible: true }
CurrentTime: { visible: true }
EstimatedTimeOfArrival: { visible: true }
AlertLevel: { visible: false }
alert_status:
Text: { visible: false }
CurrentTime: { visible: false }
EstimatedTimeOfArrival: { visible: false }
AlertLevel: { visible: true }
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: NTNet
- type: entity
parent: StatusDisplay
id: StatusDisplayShuttle
name: arrivals status display
description: Displays the current status of the arrivals shuttle.
components:
- type: DeviceNetwork
deviceNetId: Private
receiveFrequencyId: ArrivalsShuttleTimer
- type: DVScreen
content: EstimatedTimeOfArrival
@@ -14,6 +14,13 @@
- Centcomm
- Stamps # no CC official locker to put the stamp in
- type: mapCategories
id: CentcommLegacy
map: /Maps/_DV/Nonstations/centcommlegacy.yml
allowed:
- Centcomm
- Stamps # no CC official locker to put the stamp in
# Stations
- type: mapCategories
+5
View File
@@ -30,3 +30,8 @@
id: MonumentPulse
kind: source
path: "/Textures/_DV/Shaders/monument_pulse.swsl"
- type: shader
id: Masked
kind: source
path: "/Textures/_DV/Shaders/mask.swsl"
@@ -1,4 +1,6 @@
- type: markingsGroup
# Begin DeltaV Changes - This entire file was restructured for Nubody
- type: markingsGroup
parent: Undergarments
id: Thaven
onlyGroupWhitelisted: true
limits:
@@ -15,6 +17,9 @@
enum.HumanoidVisualLayers.Head:
limit: 4
required: false
enum.HumanoidVisualLayers.FacialHair:
limit: 1
required: false
enum.HumanoidVisualLayers.Chest:
limit: 4
required: false
@@ -24,60 +29,69 @@
enum.HumanoidVisualLayers.RArm:
limit: 4
required: false
enum.HumanoidVisualLayers.LHand:
limit: 1
required: false
enum.HumanoidVisualLayers.RHand:
limit: 1
required: false
enum.HumanoidVisualLayers.LLeg:
limit: 3
required: false
enum.HumanoidVisualLayers.RLeg:
limit: 3
required: false
enum.HumanoidVisualLayers.LFoot:
limit: 1
required: false
enum.HumanoidVisualLayers.RFoot:
limit: 1
required: false
enum.HumanoidVisualLayers.Overlay:
limit: 6
required: false
enum.HumanoidVisualLayers.Snout:
limit: 1
required: false
enum.HumanoidVisualLayers.Tail:
limit: 1
required: false
enum.HumanoidVisualLayers.TailOverlay:
limit: 6
required: false
enum.HumanoidVisualLayers.Special:
limit: 1
required: false
- type: entity
parent: BaseSpeciesAppearance
id: AppearanceThaven
categories: [ HideSpawnMenu ]
name: thaven appearance
components:
- type: Inventory
speciesId: thaven
templateId: thaven
displacements:
jumpsuit:
sizeMaps:
32:
sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
sprite: _MACRO/Mobs/Species/Thaven/displacement.rsi
state: jumpsuit
head:
sizeMaps:
32:
sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
state: head
eyes:
sizeMaps:
32:
sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
state: eyes
ears:
sizeMaps:
32:
sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
state: head
mask:
sizeMaps:
32:
sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
state: mask
neck:
sizeMaps:
32:
sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
state: neck
outerClothing:
sizeMaps:
32:
sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
sprite: _MACRO/Mobs/Species/Thaven/displacement.rsi
state: outerclothing_hardsuit
head:
sizeMaps:
32:
sprite: _MACRO/Mobs/Species/Thaven/displacement.rsi
state: head
gloves:
sizeMaps:
32:
sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
sprite: _MACRO/Mobs/Species/Thaven/displacement.rsi
state: hands
- type: InitialBody
organs:
@@ -85,21 +99,19 @@
Head: OrganThavenHead
ArmLeft: OrganThavenArmLeft
ArmRight: OrganThavenArmRight
HandLeft: OrganThavenHandLeft
HandRight: OrganThavenHandRight
HandLeft: OrganThavenHandLeft
LegLeft: OrganThavenLegLeft
LegRight: OrganThavenLegRight
FootLeft: OrganThavenFootLeft
FootRight: OrganThavenFootRight
Brain: OrganThavenBrain
Eyes: OrganThavenEyes
Ears: OrganHumanEars
Appendix: OrganHumanAppendix
Lungs: OrganHumanLungs
Heart: OrganHumanHeart
Stomach: OrganHumanStomach
Liver: OrganHumanLiver
Kidneys: OrganHumanKidneys
Lungs: OrganThavenLungs
Heart: OrganThavenHeart
Stomach: OrganThavenStomach
Liver: OrganThavenLiver
Kidneys: OrganThavenKidneys
- type: HumanoidProfile
species: Thaven
@@ -111,7 +123,7 @@
name: Urist McEars
components:
- type: Icon
sprite: _Impstation/Mobs/Species/Thaven/parts.rsi # Unlike dwarves elves are NOT made of slime
sprite: _MACRO/Mobs/Species/Thaven/parts.rsi
state: full
- type: ThavenMoods
- type: Respirator
@@ -153,7 +165,7 @@
layer:
- MobLayer
- type: TypingIndicator
proto: Thaven # DeltaV unique typing indicator
proto: Thaven # DeltaV - unique typing indicator
- type: Vocal
sounds:
Male: MaleThaven
@@ -173,21 +185,21 @@
enum.StrippingUiKey.Key:
type: StrippableBoundUserInterface
- type: CosmicMarkVisuals # DeltaV - cosmic cult
offset: 0, 0.0625 #2 pixels up
offset: 0, 0.0625 # 2 pixels up
- type: entity
abstract: true
parent: OrganBase
id: OrganThaven
abstract: true
suffix: Thaven
- type: entity
abstract: true
parent: OrganThaven
id: OrganThavenInternal
abstract: true
components:
- type: Sprite
sprite: Mobs/Species/Human/organs.rsi
sprite: _MACRO/Mobs/Species/Thaven/organs.rsi
- type: entity
parent: OrganThaven
@@ -195,69 +207,55 @@
abstract: true
components:
- type: Sprite
sprite: _Impstation/Mobs/Species/Thaven/parts.rsi
sprite: _MACRO/Mobs/Species/Thaven/parts.rsi
- type: VisualOrgan
data:
sprite: _Impstation/Mobs/Species/Thaven/parts.rsi
sprite: _MACRO/Mobs/Species/Thaven/parts.rsi
- type: VisualOrganMarkings
markingData:
group: Thaven
- type: entity
parent: [ OrganBaseEyes, OrganThavenExternal, OrganThavenInternal ]
id: OrganThavenEyes
components:
- type: Sprite
sprite: Mobs/Species/Human/organs.rsi
- type: VisualOrgan
layer: enum.HumanoidVisualLayers.Eyes
data:
sprite: _Impstation/Mobs/Species/Thaven/parts.rsi # Delta V - Using DV Eyes
state: eyes
# DV - Marking Displacement requires additional pr from may.
# - type: VisualOrganMarkings
# markingsDisplacement:
# Eyes:
# sizeMaps:
# 32:
# sprite: _Impstation/Mobs/Species/Thaven/displacement.rsi
# state: eyes
- type: entity
parent: [ OrganBaseHead, OrganThavenExternal ]
id: OrganThavenHead
- type: entity
parent: [ OrganBaseTorso, OrganThavenExternal ]
id: OrganThavenTorso
- type: entity
parent: [ OrganBaseLegLeft, OrganThavenExternal ]
id: OrganThavenLegLeft
- type: entity
parent: [ OrganBaseHandLeft, OrganThavenExternal ]
id: OrganThavenHandLeft
parent: [ OrganBaseHead, OrganThavenExternal ]
id: OrganThavenHead
components:
- type: VisualOrganMarkings
hideableLayers:
- enum.HumanoidVisualLayers.Hair
- enum.HumanoidVisualLayers.HeadSide
- enum.HumanoidVisualLayers.Snout
- type: entity
parent: [ OrganBaseArmLeft, OrganThavenExternal ]
id: OrganThavenArmLeft
- type: entity
parent: [ OrganBaseFootLeft, OrganThavenExternal ]
id: OrganThavenFootLeft
parent: [ OrganBaseArmRight, OrganThavenExternal ]
id: OrganThavenArmRight
- type: entity
parent: [ OrganBaseLegRight, OrganThavenExternal ]
id: OrganThavenLegRight
parent: [ OrganBaseHandLeft, OrganThavenExternal ]
id: OrganThavenHandLeft
- type: entity
parent: [ OrganBaseHandRight, OrganThavenExternal ]
id: OrganThavenHandRight
- type: entity
parent: [ OrganBaseArmRight, OrganThavenExternal ]
id: OrganThavenArmRight
parent: [ OrganBaseLegLeft, OrganThavenExternal ]
id: OrganThavenLegLeft
- type: entity
parent: [ OrganBaseLegRight, OrganThavenExternal ]
id: OrganThavenLegRight
- type: entity
parent: [ OrganBaseFootLeft, OrganThavenExternal ]
id: OrganThavenFootLeft
- type: entity
parent: [ OrganBaseFootRight, OrganThavenExternal ]
@@ -266,5 +264,40 @@
- type: entity
parent: [ OrganBaseBrain, OrganThavenInternal ]
id: OrganThavenBrain
name: thaven brain
description: "An organic positronic brain. Quite remarkable, really."
- type: entity
parent: [ OrganBaseEyes, OrganThavenInternal, OrganThavenExternal ]
id: OrganThavenEyes
description: "The dark sclera have a faint, iridescent coating."
components:
- type: VisualOrgan
data:
sprite: _MACRO/Mobs/Species/Thaven/parts.rsi
state: eyes
- type: entity
parent: [ OrganBaseLungs, OrganThavenInternal, OrganHumanMetabolizer ]
id: OrganThavenLungs
description: "Technically not lungs since they don't draw chemicals from the air, these strange, durable organs use the motion of respiration to provide energy for cell maintenance."
- type: entity
parent: [ OrganBaseHeart, OrganThavenInternal, OrganHumanMetabolizer ]
id: OrganThavenHeart
description: "The toxic heart of a thaven. You're wearing gloves, right?"
- type: entity
parent: [ OrganBaseStomach, OrganThavenInternal, OrganHumanMetabolizer ]
id: OrganThavenStomach
description: "Surprisingly similar to the stomach of a sharkminnow."
- type: entity
parent: [ OrganBaseLiver, OrganThavenInternal, OrganHumanMetabolizer ]
id: OrganThavenLiver
description: "It loosely resembles a slab of dragon flesh."
- type: entity
parent: [ OrganBaseKidneys, OrganThavenInternal, OrganHumanMetabolizer ]
id: OrganThavenKidneys
description: "Shiny, coppery veins make these the most ornate kidneys known to modern science."
# End DeltaV Changes - This entire file was restructured for Nubody
@@ -1,238 +0,0 @@
##i did markings for a lot of different species so for now theyre are all here##
##if no one else does it ill do a cleanup of all marking coding in a few months##
##-carousel##
#- type: marking
# id: FullID
# bodyPart: Part
# groupWhitelist: [Species, Species]
# youre on your own for figuring out the coloring system, my friend
# sprites:
# - sprite: _Impstation/Mobs/Customization/filelocation.rsi
# state: filename
# shaded: unshaded //use for markings that ignore shader
- type: marking
id: Gills
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenchestgills
- type: marking
id: ThavenChestScales
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenchestscales
- type: marking
id: ThavenHeadScales
bodyPart: Head
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenheadscales
- type: marking
id: ThavenLArmScales
bodyPart: LArm
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenleftarmscales
- type: marking
id: ThavenRArmScales
bodyPart: RArm
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenrightarmscales
- type: marking
id: ThavenLLegScales
bodyPart: LLeg
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenleftlegscales
- type: marking
id: ThavenRLegScales
bodyPart: RLeg
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenrightlegscales
#- type: marking
# id: ThavenLHandScales
# bodyPart: LHand
# groupWhitelist: [ Thaven ]
# forcedColoring: false
# sprites:
# - sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
# state: thavenlefthandscales
#- type: marking
# id: ThavenRHandScales
# bodyPart: RHand
# groupWhitelist: [ Thaven ]
# forcedColoring: false
# sprites:
# - sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
# state: thavenrighthandscales
#- type: marking
# id: Thiddies
# bodyPart: Chest
# groupWhitelist: [ Thaven ]
# forcedColoring: true
# sprites:
# - sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
# state: thavenbignaturals
#commented out until i find a way to hide them under clothes
- type: marking
id: ThavenTopSurgery
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: true
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavennonaturals
- type: marking
id: ThavenFishEars
bodyPart: HeadSide
groupWhitelist: [ Thaven ]
forcedColoring: true
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenfishears
- type: marking
id: ThavenTattooVines
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thaventattoovines
- type: marking
id: ThavenSpines
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenspines
- type: marking
id: ThavenBiteMark
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenbitemark
- type: marking
id: ThavenTattooWave
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thaventattoowave
- type: marking
id: SharkminnowEyeliner
bodyPart: HeadTop
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thaventattoosharkminnoweyeliner
- type: marking
id: ThavenTiger
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thaventiger1
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thaventiger2
- type: marking
id: ThavenTigerRArm
bodyPart: RArm
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thaventigerarmsr
- type: marking
id: ThavenTigerLArm
bodyPart: LArm
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thaventigerarmsl
- type: marking
id: ThavenHeadStripes
bodyPart: Head
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenheadstripes
- type: marking
id: ThavenBodyStripes
bodyPart: Chest
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenbodystripes
- type: marking
id: ThavenEarsBigFins
bodyPart: HeadSide
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenearsbigfins
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenearsbigfins2
- type: marking
id: ThavenHeadCap
bodyPart: Head
groupWhitelist: [ Thaven ]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenheadcap1
- sprite: _Impstation/Mobs/Customization/markingsbundle1.rsi
state: thavenheadcap2
@@ -1,92 +0,0 @@
- type: marking
id: ThavenEars1
bodyPart: HeadSide
groupWhitelist: [Thaven]
forcedColoring: true
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: ears1
- type: marking
id: ThavenEars2
bodyPart: HeadSide
groupWhitelist: [Thaven]
forcedColoring: true
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: ears2
- type: marking
id: ThavenEars3
bodyPart: HeadSide
groupWhitelist: [Thaven]
forcedColoring: true
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: ears3
- type: marking
id: ThavenEars4
bodyPart: HeadSide
groupWhitelist: [Thaven]
forcedColoring: true
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: ears4
- type: marking
id: ThavenPiercings
bodyPart: HeadTop
groupWhitelist: [Thaven]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: piercings
- type: marking
id: ThavenPiercings2
bodyPart: HeadTop
groupWhitelist: [Thaven]
forcedColoring: false
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: piercings2
- type: marking
id: ThavenChestTattoo1
bodyPart: Chest
groupWhitelist: [Thaven]
coloring:
default:
type:
!type:TattooColoring
fallbackColor: "#666666"
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: chesttat1
- type: marking
id: ThavenLArmTattoo1
bodyPart: LArm
groupWhitelist: [Thaven]
coloring:
default:
type:
!type:TattooColoring
fallbackColor: "#666666"
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: larmtat1
- type: marking
id: ThavenRArmTattoo1
bodyPart: RArm
groupWhitelist: [Thaven]
coloring:
default:
type:
!type:TattooColoring
fallbackColor: "#666666"
sprites:
- sprite: _Impstation/Mobs/Customization/thaven/thaven.rsi
state: rarmtat1
@@ -1,90 +0,0 @@
- type: marking
id: UndershirtDefault
bodyPart: UndergarmentTop
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/undershirt.rsi
state: undershirt
- type: marking
id: UndershirtRolled
bodyPart: UndergarmentTop
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/undershirt.rsi
state: rolled_undershirt
- type: marking
id: UndershirtSleeveless
bodyPart: UndergarmentTop
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/undershirt.rsi
state: sleeveless
- type: marking
id: UndershirtRolledSleeveless
bodyPart: UndergarmentTop
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/undershirt.rsi
state: rolled_undershirt_sleeveless
- type: marking
id: UndershirtGrossSleeveless
bodyPart: UndergarmentTop
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/undershirt.rsi
state: gross_sleeveless
- type: marking
id: UndershirtNanotrasen
bodyPart: UndergarmentTop
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/undershirt.rsi
state: nanotrasen
- type: marking
id: UndershirtBraStrapless
bodyPart: UndergarmentTop
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/undershirt.rsi
state: strapless
@@ -1,25 +0,0 @@
- type: marking
id: UnderwearLowriders
bodyPart: UndergarmentBottom
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/underwear.rsi
state: lowriders
- type: marking
id: UnderwearTanga
bodyPart: UndergarmentBottom
groupWhitelist: null # DeltaV - removed restrictions
coloring:
default:
type:
!type:SimpleColoring
color: "#FFFFFF"
sprites:
- sprite: _Impstation/Mobs/Customization/underwear.rsi
state: tanga
@@ -34,12 +34,14 @@
uiWindowPos: 0,2
strippingWindowPos: 0,1
displayName: Neck
offset: 0, 0.03
- name: mask
slotTexture: mask
slotFlags: MASK
uiWindowPos: 1,2
strippingWindowPos: 1,1
displayName: Mask
offset: 0, 0.0655
- name: eyes
slotTexture: glasses
slotFlags: EYES
@@ -47,6 +49,7 @@
uiWindowPos: 0,3
strippingWindowPos: 0,0
displayName: Eyes
offset: 0, 0.0655
- name: ears
slotTexture: ears
slotFlags: EARS
@@ -54,12 +57,14 @@
uiWindowPos: 2,2
strippingWindowPos: 2,0
displayName: Ears
offset: 0, 0.0615
- name: head
slotTexture: head
slotFlags: HEAD
uiWindowPos: 1,3
strippingWindowPos: 1,0
displayName: Head
offset: 0, 0.06
- name: pocket1
slotTexture: pocket
fullTextureName: template_small
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More